public SafeNCryptSecretHandle DeriveSecretAgreementHandle(CngKey otherPartyPublicKey) { if (otherPartyPublicKey == null) { throw new ArgumentNullException("otherPartyPublicKey"); } if (otherPartyPublicKey.AlgorithmGroup != CngAlgorithmGroup.ECDiffieHellman) { throw new ArgumentException(System.SR.GetString("Cryptography_ArgECDHRequiresECDHKey"), "otherPartyPublicKey"); } if (otherPartyPublicKey.KeySize != this.KeySize) { throw new ArgumentException(System.SR.GetString("Cryptography_ArgECDHKeySizeMismatch"), "otherPartyPublicKey"); } return(NCryptNative.DeriveSecretAgreement(this.Key.Handle, otherPartyPublicKey.Handle)); }
public byte[] DeriveKeyMaterial(CngKey otherPartyPublicKey) { if (otherPartyPublicKey == null) { throw new ArgumentNullException("otherPartyPublicKey"); } if (otherPartyPublicKey.AlgorithmGroup != CngAlgorithmGroup.ECDiffieHellman) { throw new ArgumentException(System.SR.GetString("Cryptography_ArgECDHRequiresECDHKey"), "otherPartyPublicKey"); } if (otherPartyPublicKey.KeySize != this.KeySize) { throw new ArgumentException(System.SR.GetString("Cryptography_ArgECDHKeySizeMismatch"), "otherPartyPublicKey"); } NCryptNative.SecretAgreementFlags flags = this.UseSecretAgreementAsHmacKey ? NCryptNative.SecretAgreementFlags.UseSecretAsHmacKey : NCryptNative.SecretAgreementFlags.None; new SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Assert(); SafeNCryptKeyHandle privateKey = this.Key.Handle; SafeNCryptKeyHandle handle = otherPartyPublicKey.Handle; CodeAccessPermission.RevertAssert(); using (SafeNCryptSecretHandle handle3 = NCryptNative.DeriveSecretAgreement(privateKey, handle)) { if (this.KeyDerivationFunction == ECDiffieHellmanKeyDerivationFunction.Hash) { byte[] secretAppend = (this.SecretAppend == null) ? null : (this.SecretAppend.Clone() as byte[]); byte[] secretPrepend = (this.SecretPrepend == null) ? null : (this.SecretPrepend.Clone() as byte[]); return(NCryptNative.DeriveKeyMaterialHash(handle3, this.HashAlgorithm.Algorithm, secretPrepend, secretAppend, flags)); } if (this.KeyDerivationFunction == ECDiffieHellmanKeyDerivationFunction.Hmac) { byte[] hmacKey = (this.HmacKey == null) ? null : (this.HmacKey.Clone() as byte[]); byte[] buffer4 = (this.SecretAppend == null) ? null : (this.SecretAppend.Clone() as byte[]); byte[] buffer5 = (this.SecretPrepend == null) ? null : (this.SecretPrepend.Clone() as byte[]); return(NCryptNative.DeriveKeyMaterialHmac(handle3, this.HashAlgorithm.Algorithm, hmacKey, buffer5, buffer4, flags)); } byte[] label = (this.Label == null) ? null : (this.Label.Clone() as byte[]); byte[] seed = (this.Seed == null) ? null : (this.Seed.Clone() as byte[]); if ((label == null) || (seed == null)) { throw new InvalidOperationException(System.SR.GetString("Cryptography_TlsRequiresLabelAndSeed")); } return(NCryptNative.DeriveKeyMaterialTls(handle3, label, seed, flags)); } }
public SafeNCryptSecretHandle DeriveSecretAgreementHandle(CngKey otherPartyPublicKey) { if (otherPartyPublicKey == null) { throw new ArgumentNullException("otherPartyPublicKey"); } if (otherPartyPublicKey.AlgorithmGroup != CngAlgorithmGroup.ECDiffieHellman) { throw new ArgumentException(SR.GetString(SR.Cryptography_ArgECDHRequiresECDHKey), "otherPartyPublicKey"); } if (otherPartyPublicKey.KeySize != KeySize) { throw new ArgumentException(SR.GetString(SR.Cryptography_ArgECDHKeySizeMismatch), "otherPartyPublicKey"); } // This looks strange, but the Handle property returns a duplicate so we need to dispose of it when we're done using (SafeNCryptKeyHandle localHandle = Key.Handle) using (SafeNCryptKeyHandle otherPartyHandle = otherPartyPublicKey.Handle) { return(NCryptNative.DeriveSecretAgreement(localHandle, otherPartyHandle)); } }
public byte[] DeriveKeyMaterial(CngKey otherPartyPublicKey) { Contract.Ensures(Contract.Result <byte[]>() != null); Contract.Assert(m_kdf >= ECDiffieHellmanKeyDerivationFunction.Hash && m_kdf <= ECDiffieHellmanKeyDerivationFunction.Tls); if (otherPartyPublicKey == null) { throw new ArgumentNullException("otherPartyPublicKey"); } if (otherPartyPublicKey.AlgorithmGroup != CngAlgorithmGroup.ECDiffieHellman) { throw new ArgumentException(SR.GetString(SR.Cryptography_ArgECDHRequiresECDHKey), "otherPartyPublicKey"); } if (otherPartyPublicKey.KeySize != KeySize) { throw new ArgumentException(SR.GetString(SR.Cryptography_ArgECDHKeySizeMismatch), "otherPartyPublicKey"); } NCryptNative.SecretAgreementFlags flags = UseSecretAgreementAsHmacKey ? NCryptNative.SecretAgreementFlags.UseSecretAsHmacKey : NCryptNative.SecretAgreementFlags.None; // We require access to the handles for generating key material. This is safe since we will never // expose these handles to user code new SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Assert(); // This looks horribly wrong - but accessing the handle property actually returns a duplicate handle, which // we need to dispose of - otherwise, we're stuck keepign the resource alive until the GC runs. This explicitly // is not disposing of the handle underlying the key dispite what the syntax looks like. using (SafeNCryptKeyHandle localKey = Key.Handle) using (SafeNCryptKeyHandle otherKey = otherPartyPublicKey.Handle) { CodeAccessPermission.RevertAssert(); // // Generating key material is a two phase process. // 1. Generate the secret agreement // 2. Pass the secret agreement through a KDF to get key material // using (SafeNCryptSecretHandle secretAgreement = NCryptNative.DeriveSecretAgreement(localKey, otherKey)) { if (KeyDerivationFunction == ECDiffieHellmanKeyDerivationFunction.Hash) { byte[] secretAppend = SecretAppend == null ? null : SecretAppend.Clone() as byte[]; byte[] secretPrepend = SecretPrepend == null ? null : SecretPrepend.Clone() as byte[]; return(NCryptNative.DeriveKeyMaterialHash(secretAgreement, HashAlgorithm.Algorithm, secretPrepend, secretAppend, flags)); } else if (KeyDerivationFunction == ECDiffieHellmanKeyDerivationFunction.Hmac) { byte[] hmacKey = HmacKey == null ? null : HmacKey.Clone() as byte[]; byte[] secretAppend = SecretAppend == null ? null : SecretAppend.Clone() as byte[]; byte[] secretPrepend = SecretPrepend == null ? null : SecretPrepend.Clone() as byte[]; return(NCryptNative.DeriveKeyMaterialHmac(secretAgreement, HashAlgorithm.Algorithm, hmacKey, secretPrepend, secretAppend, flags)); } else { Debug.Assert(KeyDerivationFunction == ECDiffieHellmanKeyDerivationFunction.Tls, "Unknown KDF"); byte[] label = Label == null ? null : Label.Clone() as byte[]; byte[] seed = Seed == null ? null : Seed.Clone() as byte[]; if (label == null || seed == null) { throw new InvalidOperationException(SR.GetString(SR.Cryptography_TlsRequiresLabelAndSeed)); } return(NCryptNative.DeriveKeyMaterialTls(secretAgreement, label, seed, flags)); } } } }