Beispiel #1
0
        public override byte[] DeriveKeyFromHmac(
            ECDiffieHellmanPublicKey otherPartyPublicKey,
            HashAlgorithmName hashAlgorithm,
            byte[] hmacKey,
            byte[] secretPrepend,
            byte[] secretAppend)
        {
            Contract.Ensures(Contract.Result <byte[]>() != null);

            if (otherPartyPublicKey == null)
            {
                throw new ArgumentNullException("otherPartyPublicKey");
            }
            if (string.IsNullOrEmpty(hashAlgorithm.Name))
            {
                throw new ArgumentException(SR.GetString(SR.Cryptography_HashAlgorithmNameNullOrEmpty), "hashAlgorithm");
            }

            using (SafeNCryptSecretHandle secretAgreement = DeriveSecretAgreementHandle(otherPartyPublicKey))
            {
                NCryptNative.SecretAgreementFlags flags = hmacKey == null ?
                                                          NCryptNative.SecretAgreementFlags.UseSecretAsHmacKey :
                                                          NCryptNative.SecretAgreementFlags.None;

                return(NCryptNative.DeriveKeyMaterialHmac(
                           secretAgreement,
                           hashAlgorithm.Name,
                           hmacKey,
                           secretPrepend,
                           secretAppend,
                           flags));
            }
        }
Beispiel #2
0
        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));
            }
        }
Beispiel #3
0
        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));
                        }
                    }
                }
        }
 internal static extern NCryptNative.ErrorCode NCryptDeriveKey(SafeNCryptSecretHandle hSharedSecret, string pwszKDF, [In] ref NCryptNative.NCryptBufferDesc pParameterList, [Out, MarshalAs(UnmanagedType.LPArray)] byte[] pbDerivedKey, int cbDerivedKey, out int pcbResult, NCryptNative.SecretAgreementFlags dwFlags);