public override byte[] DeriveKeyFromHmac( ECDiffieHellmanPublicKey otherPartyPublicKey, HashAlgorithmName hashAlgorithm, byte[]?hmacKey, byte[]?secretPrepend, byte[]?secretAppend) { if (otherPartyPublicKey == null) { throw new ArgumentNullException(nameof(otherPartyPublicKey)); } if (string.IsNullOrEmpty(hashAlgorithm.Name)) { throw new ArgumentException(SR.Cryptography_HashAlgorithmNameNullOrEmpty, nameof(hashAlgorithm)); } using (SafeNCryptSecretHandle secretAgreement = DeriveSecretAgreementHandle(otherPartyPublicKey)) { Interop.NCrypt.SecretAgreementFlags flags = hmacKey == null ? Interop.NCrypt.SecretAgreementFlags.UseSecretAsHmacKey : Interop.NCrypt.SecretAgreementFlags.None; return(Interop.NCrypt.DeriveKeyMaterialHmac( secretAgreement, hashAlgorithm.Name, hmacKey, secretPrepend, secretAppend, flags)); } }
public byte[] DeriveKeyMaterial(CngKey otherPartyPublicKey) { ArgumentNullException.ThrowIfNull(otherPartyPublicKey); if (otherPartyPublicKey.AlgorithmGroup != CngAlgorithmGroup.ECDiffieHellman) { throw new ArgumentException(SR.Cryptography_ArgECDHRequiresECDHKey, nameof(otherPartyPublicKey)); } if (otherPartyPublicKey.KeySize != KeySize) { throw new ArgumentException(SR.Cryptography_ArgECDHKeySizeMismatch, nameof(otherPartyPublicKey)); } // Setting the flag to UseSecretAsHmacKey even when the KDF isn't HMAC, because that's what .NET Framework does. Interop.NCrypt.SecretAgreementFlags flags = UseSecretAgreementAsHmacKey ? Interop.NCrypt.SecretAgreementFlags.UseSecretAsHmacKey : Interop.NCrypt.SecretAgreementFlags.None; using (SafeNCryptSecretHandle handle = DeriveSecretAgreementHandle(otherPartyPublicKey)) { switch (KeyDerivationFunction) { case ECDiffieHellmanKeyDerivationFunction.Hash: return(Interop.NCrypt.DeriveKeyMaterialHash( handle, HashAlgorithm.Algorithm, _secretPrepend, _secretAppend, flags)); case ECDiffieHellmanKeyDerivationFunction.Hmac: return(Interop.NCrypt.DeriveKeyMaterialHmac( handle, HashAlgorithm.Algorithm, _hmacKey, _secretPrepend, _secretAppend, flags)); case ECDiffieHellmanKeyDerivationFunction.Tls: if (_label == null || _seed == null) { throw new InvalidOperationException(SR.Cryptography_TlsRequiresLabelAndSeed); } return(Interop.NCrypt.DeriveKeyMaterialTls( handle, _label, _seed, flags)); default: Debug.Fail($"Unknown KDF ({KeyDerivationFunction})"); // Match .NET Framework behavior goto case ECDiffieHellmanKeyDerivationFunction.Tls; } } }