/// <summary> /// Generate the "well-known constant" /// [RFC 3961, Page 15] /// the "well-known constant" used for the DK function is the key usage number, /// expressed as four octets in big-endian order, followed by one octet indicated below: /// Kc = DK(base-key, usage | 0x99); /// Ke = DK(base-key, usage | 0xAA); /// Ki = DK(base-key, usage | 0x55); /// </summary> /// <param name="usage">key usage number</param> /// <param name="derivedKeyType">the derived key type</param> /// <returns>the "well-known constant"</returns> private static byte[] GetWellKnownConstant(int usage, DerivedKeyType derivedKeyType) { // the "well-known constant" contains 5 bytes byte[] wellKnownConstant = new byte[5]; // the first 4 bytes = usage number in big endian byte[] usageBytes = BitConverter.GetBytes(usage); Array.Reverse(usageBytes); usageBytes.CopyTo(wellKnownConstant, 0); // the 5th byte = the derivedKeyType wellKnownConstant[4] = (byte)derivedKeyType; return(wellKnownConstant); }
/// <summary> /// Generate a derived key from base key /// [RFC 3961 Section 5.1 A Key Derivation Function] /// </summary> /// <param name="baseKey">the base key</param> /// <param name="usage">key usage</param> /// <param name="derivedKeyType">the derived key type</param> /// <param name="aesKeyType">AES key type which decides key size</param> /// <returns>the derived key in bytes</returns> internal static byte[] MakeDerivedKey( byte[] baseKey, int usage, DerivedKeyType derivedKeyType, AesKeyType aesKeyType) { if (null == baseKey) { throw new ArgumentNullException("baseKey"); } // generate the well-known constant byte[] wellKnownConstant = GetWellKnownConstant(usage, derivedKeyType); // generate the derived key return(DK(baseKey, wellKnownConstant, aesKeyType)); }
/// <summary> /// Generate the "well-known constant" /// [RFC 3961, Page 15] /// the "well-known constant" used for the DK function is the key usage number, /// expressed as four octets in big-endian order, followed by one octet indicated below: /// Kc = DK(base-key, usage | 0x99); /// Ke = DK(base-key, usage | 0xAA); /// Ki = DK(base-key, usage | 0x55); /// </summary> /// <param name="usage">key usage number</param> /// <param name="derivedKeyType">the derived key type</param> /// <returns>the "well-known constant"</returns> private static byte[] GetWellKnownConstant(int usage, DerivedKeyType derivedKeyType) { // the "well-known constant" contains 5 bytes byte[] wellKnownConstant = new byte[5]; // the first 4 bytes = usage number in big endian byte[] usageBytes = BitConverter.GetBytes(usage); Array.Reverse(usageBytes); usageBytes.CopyTo(wellKnownConstant, 0); // the 5th byte = the derivedKeyType wellKnownConstant[4] = (byte)derivedKeyType; return wellKnownConstant; }
/// <summary> /// Generate a derived key from base key /// [RFC 3961 Section 5.1 A Key Derivation Function] /// </summary> /// <param name="baseKey">the base key</param> /// <param name="usage">key usage</param> /// <param name="derivedKeyType">the derived key type</param> /// <param name="aesKeyType">AES key type which decides key size</param> /// <returns>the derived key in bytes</returns> internal static byte[] MakeDerivedKey( byte[] baseKey, int usage, DerivedKeyType derivedKeyType, AesKeyType aesKeyType) { if (null == baseKey) { throw new ArgumentNullException("baseKey"); } // generate the well-known constant byte[] wellKnownConstant = GetWellKnownConstant(usage, derivedKeyType); // generate the derived key return DK(baseKey, wellKnownConstant, aesKeyType); }