예제 #1
0
        /// <summary>
        /// Encrypt dataToEncrypt using the specified encodingParams (RSA only).
        /// </summary>
        /// <param name="plainText"></param>
        /// <param name="label"></param>
        /// <returns></returns>
        public byte[] EncryptOaep(byte[] plainText, byte[] label)
        {
            if (plainText == null)
            {
                plainText = new byte[0];
            }
            if (label == null)
            {
                label = new byte[0];
            }
#if TSS_USE_BCRYPT
            var    paddingInfo = new BCryptOaepPaddingInfo(OaepHash, label);
            byte[] cipherText  = Key.Encrypt(plainText, paddingInfo);
#elif false
            var    rr         = new RawRsa(RsaProvider.ExportParameters(false), RsaProvider.KeySize);
            byte[] cipherText = rr.OaepEncrypt(plainText, OaepHash, label);
#else
            RSAParameters parms       = RsaProvider.ExportParameters(false);
            var           alg         = new BCryptAlgorithm(Native.BCRYPT_RSA_ALGORITHM);
            var           key         = alg.LoadRSAKey(parms.Exponent, parms.Modulus);
            var           paddingInfo = new BCryptOaepPaddingInfo(OaepHash, label);
            byte[]        cipherText  = key.Encrypt(plainText, paddingInfo);
            key.Destroy();
            alg.Close();
#endif
            return(cipherText);
        }
예제 #2
0
        internal static BCryptKey Generate(string algName, uint numBits)
        {
            var alg = new BCryptAlgorithm(algName);
            var key = alg.GenerateKeyPair(numBits);

            alg.Close();
            return(key);
        }
        public static byte[] Decrypt(byte[] bytes, Dictionary <ulong, Smb2CryptoInfo> cryptoInfoTable, Smb2Role role)
        {
            // Client: If the size of the message received from the server is not greater than the size of SMB2 TRANSFORM_HEADER as specified, the client MUST discard the message.
            // Server: If the size of the message received from the client is not greater than the size of the SMB2 TRANSFORM_HEADER, the server MUST disconnect the connection.
            int minimumLength = Marshal.SizeOf(typeof(Transform_Header));

            if (bytes.Length < minimumLength)
            {
                throw new InvalidOperationException(
                          String.Format(
                              "Too less data for encrypted message. Expected length more than {0}, actual {1}.",
                              minimumLength,
                              bytes.Length
                              )
                          );
            }

            Transform_Header transformHeader = Smb2Utility.UnmarshalStructure <Transform_Header>(bytes);

            // Client: If the Flags/EncryptionAlgorithm in the SMB2 TRANSFORM_HEADER is not 0x0001, the client MUST discard the message.
            // Server: If the Flags/EncryptionAlgorithm in the SMB2 TRANSFORM_HEADER is not 0x0001, the server MUST disconnect the connection.
            if (transformHeader.Flags != TransformHeaderFlags.Encrypted)
            {
                throw new InvalidOperationException(
                          String.Format(
                              "Flags/EncryptionAlgorithm field is invalid for encrypted message. Expected value 0x0001, actual {0}.",
                              (ushort)transformHeader.Flags
                              )
                          );
            }

            if (transformHeader.SessionId == 0 || !cryptoInfoTable.ContainsKey(transformHeader.SessionId))
            {
                throw new InvalidOperationException("Invalid SessionId in TRANSFORM_HEADER.");
            }

            Smb2CryptoInfo cryptoInfo = cryptoInfoTable[transformHeader.SessionId];

            using (var bcrypt = new BCryptAlgorithm("AES"))
            {
                int nonceLength       = 0;
                BCryptCipherMode mode = BCryptCipherMode.NotAvailable;
                GetCryptoParams(cryptoInfo, CryptoOperationType.Decrypt, out mode, out nonceLength);
                bcrypt.Mode = mode;
                bcrypt.Key  = role == Smb2Role.Server ? cryptoInfo.ServerInKey : cryptoInfo.ServerOutKey;
                return(bcrypt.Decrypt(bytes.Skip(52).ToArray(), transformHeader.Nonce.ToByteArray().Take(nonceLength).ToArray(), bytes.Skip(20).Take(32).ToArray(), transformHeader.Signature));
            }
        }
예제 #4
0
        public static byte[] HmacData(TpmAlgId hashAlgId, byte[] key, byte[] dataToHash)
        {
#if TSS_USE_BCRYPT
            string algName = Native.BCryptHashAlgName(hashAlgId);
            if (string.IsNullOrEmpty(algName))
            {
                Globs.Throw <ArgumentException>("HmacData(): Unsupported hash algorithm " + hashAlgId);
                return(null);
            }

            var alg    = new BCryptAlgorithm(algName, Native.BCRYPT_ALG_HANDLE_HMAC);
            var digest = alg.HmacData(key, dataToHash);
            alg.Close();
            return(digest);
#else
            switch (hashAlgId)
            {
            case TpmAlgId.Sha1:
                using (var h = new HMACSHA1(key))
                {
                    return(h.ComputeHash(dataToHash));
                }

            case TpmAlgId.Sha256:
                using (var h2 = new HMACSHA256(key))
                {
                    return(h2.ComputeHash(dataToHash));
                }

            case TpmAlgId.Sha384:
                using (var h3 = new HMACSHA384(key))
                {
                    return(h3.ComputeHash(dataToHash));
                }

            case TpmAlgId.Sha512:
                using (var h4 = new HMACSHA512(key))
                {
                    return(h4.ComputeHash(dataToHash));
                }

            default:
                Globs.Throw <ArgumentException>("HmacData(): Unsupported hash algorithm " + hashAlgId);
                return(null);
            }
#endif // !TSS_USE_BCRYPT
        }
예제 #5
0
        public static byte[] HashData(TpmAlgId algId, byte[] dataToHash)
        {
            if (dataToHash == null)
            {
                dataToHash = new byte[0];
            }

#if TSS_USE_BCRYPT
            string algName = Native.BCryptHashAlgName(algId);
            if (string.IsNullOrEmpty(algName))
            {
                Globs.Throw <ArgumentException>("HashData(): Unsupported hash algorithm " + algId);
                return(null);
            }

            var alg    = new BCryptAlgorithm(algName);
            var digest = alg.HashData(dataToHash);
            alg.Close();
            return(digest);
#else
            HashAlgorithm hashAlg = null;
            switch (algId)
            {
            case TpmAlgId.Sha1:
                hashAlg = new SHA1Managed();
                break;

            case TpmAlgId.Sha256:
                hashAlg = new SHA256Managed();
                break;

            case TpmAlgId.Sha384:
                hashAlg = new SHA384Managed();
                break;

            case TpmAlgId.Sha512:
                hashAlg = new SHA512Managed();
                break;

            default:
                Globs.Throw <ArgumentException>("AlgId is not a supported hash algorithm");
                return(null);
            }
            return(hashAlg.ComputeHash(dataToHash));
#endif
        }
예제 #6
0
        public byte[] Export(string bcryptBlobType)
        {
#if !TSS_USE_BCRYPT
            if (RsaProvider == null)
            {
                return(null);
            }
            RSAParameters parms = RsaProvider.ExportParameters(bcryptBlobType == Native.BCRYPT_RSAPRIVATE_BLOB);
            var           alg   = new BCryptAlgorithm(Native.BCRYPT_RSA_ALGORITHM);
            var           Key   = alg.LoadRSAKey(parms.Exponent, parms.Modulus, parms.P, parms.Q);
#endif
            byte[] keyBlob = Key.Export(bcryptBlobType);
#if !TSS_USE_BCRYPT
            Key.Destroy();
            alg.Close();
#endif
            return(keyBlob);
        }
예제 #7
0
        public byte[] DecryptOaep(byte[] cipherText, byte[] label)
        {
#if TSS_USE_BCRYPT
            var    paddingInfo = new BCryptOaepPaddingInfo(OaepHash, label);
            byte[] plainText   = Key.Decrypt(cipherText, paddingInfo);
#elif true
            var    rr        = new RawRsa(RsaProvider.ExportParameters(true), RsaProvider.KeySize);
            byte[] plainText = rr.OaepDecrypt(cipherText, OaepHash, label);
#else
            RSAParameters parms       = RsaProvider.ExportParameters(true);
            var           alg         = new BCryptAlgorithm(Native.BCRYPT_RSA_ALGORITHM);
            var           key         = alg.LoadRSAKey(parms.Exponent, parms.Modulus, parms.P, parms.Q);
            var           paddingInfo = new BCryptOaepPaddingInfo(OaepHash, label);
            byte[]        plainText   = key.Decrypt(cipherText, paddingInfo);
            key.Destroy();
            alg.Close();
#endif
            return(plainText);
        }
예제 #8
0
        public static byte[] Decrypt(byte[] bytes, Dictionary <ulong, Smb2CryptoInfo> cryptoInfoTable, Smb2Role role, out Transform_Header transformHeader)
        {
            var encryptedPacket = new Smb2EncryptedPacket();

            int consumedLen;
            int expectedLen;

            encryptedPacket.FromBytes(bytes, out consumedLen, out expectedLen);

            transformHeader = encryptedPacket.Header;

            // For client: If the Flags/EncryptionAlgorithm in the SMB2 TRANSFORM_HEADER is not 0x0001, the client MUST discard the message.
            // For server: If the Flags/EncryptionAlgorithm in the SMB2 TRANSFORM_HEADER is not 0x0001, the server MUST disconnect the connection.
            if (transformHeader.Flags != TransformHeaderFlags.Encrypted)
            {
                throw new InvalidOperationException(
                          String.Format(
                              "Flags/EncryptionAlgorithm field is invalid for encrypted message. Expected value 0x0001, actual {0}.",
                              (ushort)transformHeader.Flags
                              )
                          );
            }

            if (transformHeader.SessionId == 0 || !cryptoInfoTable.ContainsKey(transformHeader.SessionId))
            {
                throw new InvalidOperationException("Invalid SessionId in TRANSFORM_HEADER.");
            }

            Smb2CryptoInfo cryptoInfo = cryptoInfoTable[transformHeader.SessionId];

            using (var bcrypt = new BCryptAlgorithm("AES"))
            {
                int nonceLength       = 0;
                BCryptCipherMode mode = BCryptCipherMode.NotAvailable;
                GetCryptoParams(cryptoInfo, CryptoOperationType.Decrypt, out mode, out nonceLength);
                bcrypt.Mode = mode;
                bcrypt.Key  = role == Smb2Role.Server ? cryptoInfo.ServerInKey : cryptoInfo.ServerOutKey;
                // Auth data is Transform_Header start from Nonce, excluding ProtocolId and Signature.
                var authData = Smb2Utility.MarshalStructure(transformHeader).Skip((int)Marshal.OffsetOf <Transform_Header>("Nonce")).ToArray();
                return(bcrypt.Decrypt(encryptedPacket.EncryptdData, transformHeader.Nonce.ToByteArray().Take(nonceLength).ToArray(), authData, transformHeader.Signature));
            }
        }
        public static byte[] Decrypt(byte[] bytes, Dictionary <ulong, Smb2CryptoInfo> cryptoInfoTable, Smb2Role role)
        {
            Transform_Header transformHeader = Smb2Utility.UnmarshalStructure <Transform_Header>(bytes);

            if (transformHeader.SessionId == 0 || !cryptoInfoTable.ContainsKey(transformHeader.SessionId))
            {
                throw new InvalidOperationException("Invalid SessionId in TRANSFORM_HEADER.");
            }

            Smb2CryptoInfo cryptoInfo = cryptoInfoTable[transformHeader.SessionId];

            using (var bcrypt = new BCryptAlgorithm("AES"))
            {
                int nonceLength       = 0;
                BCryptCipherMode mode = BCryptCipherMode.NotAvailable;
                GetCryptoParams(cryptoInfo, CryptoOperationType.Decrypt, out mode, out nonceLength);
                bcrypt.Mode = mode;
                bcrypt.Key  = role == Smb2Role.Server ? cryptoInfo.ServerInKey : cryptoInfo.ServerOutKey;
                return(bcrypt.Decrypt(bytes.Skip(52).ToArray(), transformHeader.Nonce.ToByteArray().Take(nonceLength).ToArray(), bytes.Skip(20).Take(32).ToArray(), transformHeader.Signature));
            }
        }
예제 #10
0
        public static byte[] HashData(TpmAlgId algId, byte[] dataToHash)
        {
#if TSS_USE_BCRYPT
            string algName = Native.BCryptHashAlgName(algId);
            if (string.IsNullOrEmpty(algName))
            {
                Globs.Throw<ArgumentException>("HashData(): Unsupported hash algorithm " + algId);
                return null;
            }

            var alg = new BCryptAlgorithm(algName);
            var digest = alg.HashData(dataToHash);
            alg.Close();
            return digest;
#else
            HashAlgorithm hashAlg = null;
            switch (algId)
            {
                case TpmAlgId.Sha1:
                    hashAlg = new SHA1Managed();
                    break;
                case TpmAlgId.Sha256:
                    hashAlg = new SHA256Managed();
                    break;
                case TpmAlgId.Sha384:
                    hashAlg = new SHA384Managed();
                    break;
                case TpmAlgId.Sha512:
                    hashAlg = new SHA512Managed();
                    break;
                default:
                    Globs.Throw<ArgumentException>("AlgId is not a supported hash algorithm");
                    return null;
            }
            return hashAlg.ComputeHash(dataToHash);
#endif
        }
예제 #11
0
        public static byte[] Mac(TpmAlgId symAlg, TpmAlgId macScheme, byte[] key, byte[] data)
        {
            if (symAlg != TpmAlgId.Aes)
            {
                Globs.Throw <ArgumentException>("CryptoLib.Mac(): Unsupported symmetric algorithm" + symAlg);
                return(null);
            }
            if (macScheme != TpmAlgId.Cmac)
            {
                Globs.Throw <ArgumentException>("CryptoLib.Mac(): Unsupported MAC scheme " + macScheme);
                return(null);
            }

#if TSS_USE_BCRYPT
            var alg    = new BCryptAlgorithm(Native.BCRYPT_AES_CMAC_ALGORITHM);
            var digest = alg.HmacData(key, data);
            alg.Close();
            return(digest);
#else
            Globs.Throw <ArgumentException>("Mac(): .Net Crypto API does not support symmetric cipher based MAC." +
                                            "Complile TSS.Net with BCrypt enabled.");
            return(null);
#endif // !TSS_USE_BCRYPT
        }
예제 #12
0
        /// <summary>
        /// Create a new SymmCipher object with a random key based on the alg and mode supplied.
        /// </summary>
        /// <param name="algId"></param>
        /// <param name="numBits"></param>
        /// <param name="mode"></param>
        /// <returns></returns>
        public static SymmCipher Create(SymDefObject symDef = null, byte[] keyData = null, byte[] iv = null)
        {
            if (symDef == null)
            {
                symDef = new SymDefObject(TpmAlgId.Aes, 128, TpmAlgId.Cfb);
            }

#if TSS_USE_BCRYPT
            BCryptAlgorithm alg = null;

            switch (symDef.Algorithm)
            {
                case TpmAlgId.Aes:
                    alg = new BCryptAlgorithm(Native.BCRYPT_AES_ALGORITHM);
                    break;
                case TpmAlgId.Tdes:
                    alg = new BCryptAlgorithm(Native.BCRYPT_3DES_ALGORITHM);
                    break;
                default:
                    Globs.Throw<ArgumentException>("Unsupported symmetric algorithm " + symDef.Algorithm);
                    break;
            }

            if (keyData == null)
            {
                keyData = Globs.GetRandomBytes(symDef.KeyBits / 8);
            }
            var key = alg.GenerateSymKey(symDef, keyData, GetBlockSize(symDef));
            //key = BCryptInterface.ExportSymKey(keyHandle);
            //keyHandle = alg.LoadSymKey(key, symDef, GetBlockSize(symDef));
            alg.Close();
            return key == null ? null : new SymmCipher(key, keyData, iv);
#else
            SymmetricAlgorithm alg = null; // = new RijndaelManaged();
            bool limitedSupport = false;
            // DES and __3DES are not supported in TPM 2.0 rev. 0.96 to 1.30
            switch (symDef.Algorithm) {
                case TpmAlgId.Aes:
                    alg = new RijndaelManaged();
                    break;
                case TpmAlgId.Tdes:
                    alg = new TripleDESCryptoServiceProvider();
                    limitedSupport = true;
                    break;
                default:
                    Globs.Throw<ArgumentException>("Unsupported symmetric algorithm " + symDef.Algorithm);
                    break;
            }

            int blockSize = GetBlockSize(symDef);
            alg.KeySize = symDef.KeyBits;
            alg.BlockSize = blockSize * 8;
            alg.Padding = PaddingMode.None;
            alg.Mode = GetCipherMode(symDef.Mode);

            // REVISIT: Get this right for other modes
            if (symDef.Algorithm == TpmAlgId.Tdes && symDef.Mode == TpmAlgId.Cfb)
            {
                alg.FeedbackSize = 8;
            }
            else
            {
                alg.FeedbackSize = alg.BlockSize;
            }

            if (keyData == null)
            {
                // Generate random key
                alg.IV = Globs.GetZeroBytes(blockSize);
                try
                {
                    alg.GenerateKey();
                }
                catch (Exception)
                {
                    alg.Dispose();
                    throw;
                }
            }
            else
            {
                // Use supplied key bits
                alg.Key = keyData;
                if (iv == null)
                {
                    iv = Globs.GetZeroBytes(blockSize);
                }
                else if (iv.Length != blockSize)
                {
                    Array.Resize(ref iv, blockSize);
                }
                alg.IV = iv;
            }

            var symCipher = new SymmCipher(alg);
            symCipher.LimitedSupport = limitedSupport;
            return symCipher;
#endif
        }
예제 #13
0
파일: CryptoSymm.cs 프로젝트: rgl/TSS.MSR
        /// <summary>
        /// Create a new SymCipher object with a random key based on the alg and mode supplied.
        /// </summary>
        /// <param name="symDef"></param>
        /// <param name="keyData"></param>
        /// <param name="iv"></param>
        /// <returns></returns>
        public static SymCipher Create(SymDefObject symDef = null,
                                       byte[] keyData      = null, byte[] iv = null)
        {
            if (symDef == null)
            {
                symDef = new SymDefObject(TpmAlgId.Aes, 128, TpmAlgId.Cfb);
            }

#if TSS_USE_BCRYPT
            BCryptAlgorithm alg = null;

            switch (symDef.Algorithm)
            {
            case TpmAlgId.Aes:
                alg = new BCryptAlgorithm(Native.BCRYPT_AES_ALGORITHM);
                break;

            case TpmAlgId.Tdes:
                alg = new BCryptAlgorithm(Native.BCRYPT_3DES_ALGORITHM);
                break;

            default:
                Globs.Throw <ArgumentException>("Unsupported symmetric algorithm "
                                                + symDef.Algorithm);
                return(null);
            }

            if (keyData == null)
            {
                keyData = Globs.GetRandomBytes(symDef.KeyBits / 8);
            }
            var key = alg.GenerateSymKey(symDef, keyData, GetBlockSize(symDef));
            //key = BCryptInterface.ExportSymKey(keyHandle);
            //keyHandle = alg.LoadSymKey(key, symDef, GetBlockSize(symDef));
            alg.Close();
            return(key == null ? null : new SymCipher(key, keyData, iv, GetBlockSize(symDef)));
#else // !TSS_USE_BCRYPT
            if (symDef.Mode == TpmAlgId.Ofb)
            {
                return(null);
            }

            var mode = GetCipherMode(symDef.Mode);
            if (mode == CipherMode_None)
            {
                return(null);
            }

            SymmetricAlgorithm alg = null; // = new RijndaelManaged();
            bool limitedSupport    = false;
            int  feedbackSize      = 0;

            switch (symDef.Algorithm)
            {
            case TpmAlgId.Aes:
                alg      = new RijndaelManaged();
                alg.Mode = mode == CipherMode.CFB ? CipherMode.ECB : mode;
                break;

            case TpmAlgId.Tdes:
                // DES and __3DES are not supported in TPM 2.0 rev. < 1.32
                alg      = new TripleDESCryptoServiceProvider();
                alg.Mode = mode;
                if (mode == CipherMode.CFB)
                {
                    feedbackSize = 8;
                }
                limitedSupport = true;
                break;

            default:
                //Globs.Throw<ArgumentException>("Unsupported symmetric algorithm " + symDef.Algorithm);
                return(null);
            }

            int blockSize = GetBlockSize(symDef);
            alg.KeySize      = symDef.KeyBits;
            alg.BlockSize    = blockSize * 8;
            alg.Padding      = PaddingMode.None;
            alg.FeedbackSize = feedbackSize == 0 ? alg.BlockSize : feedbackSize;

            if (keyData == null)
            {
                // Generate random key
                alg.IV = Globs.GetZeroBytes(blockSize);
                try
                {
                    alg.GenerateKey();
                }
                catch (Exception)
                {
                    alg.Dispose();
                    throw;
                }
            }
            else
            {
                // Use supplied key bits
                alg.Key = keyData;
                if (iv == null)
                {
                    iv = Globs.GetZeroBytes(blockSize);
                }
                else if (iv.Length != blockSize)
                {
                    Array.Resize(ref iv, blockSize);
                }
                alg.IV = iv;
            }

            var symCipher = new SymCipher(alg, mode);
            symCipher.LimitedSupport = limitedSupport;
            return(symCipher);
#endif // !TSS_USE_BCRYPT
        } // Create()
        private static byte[] Encrypt(ulong sessionId, Smb2CryptoInfo cryptoInfo, Smb2Role role, Smb2Packet originalPacket)
        {
            Packet_Header header;

            if (originalPacket is Smb2SinglePacket)
            {
                header = (originalPacket as Smb2SinglePacket).Header;
            }
            else
            {
                header = (originalPacket as Smb2CompoundPacket).Packets[0].Header;
            }

            // Encrypt all messages after session setup if global encryption enabled.
            // Encrypt all messages after tree connect if global encryption disabled but share encryption enabled.
            if ((cryptoInfo.EnableSessionEncryption ||
                 (cryptoInfo.EnableTreeEncryption.Contains(header.TreeId) &&
                  header.Command != Smb2Command.TREE_CONNECT
                 )
                 )
                )
            {
                using (var bcrypt = new BCryptAlgorithm("AES"))
                {
                    byte[]           originalBinary  = originalPacket.ToBytes();
                    Transform_Header transformHeader = new Transform_Header
                    {
                        ProtocolId          = Smb2Consts.ProtocolIdInTransformHeader,
                        OriginalMessageSize = (uint)originalBinary.Length,
                        SessionId           = sessionId,
                        Signature           = new byte[16]
                    };

                    if (cryptoInfo.Dialect == DialectRevision.Smb311)
                    {
                        transformHeader.Flags = TransformHeaderFlags.Encrypted;
                    }
                    else
                    {
                        transformHeader.EncryptionAlgorithm = EncryptionAlgorithm.ENCRYPTION_AES128_CCM;
                    }

                    byte[] tag;

                    int nonceLength       = 0;
                    BCryptCipherMode mode = BCryptCipherMode.NotAvailable;
                    GetCryptoParams(cryptoInfo, CryptoOperationType.Encrypt, out mode, out nonceLength);
                    bcrypt.Mode = mode;
                    bcrypt.Key  = role == Smb2Role.Server ? cryptoInfo.ServerOutKey : cryptoInfo.ServerInKey;
                    // The reserved field (5 bytes for CCM, 4 bytes for GCM) must be set to zero.
                    byte[] nonce = new byte[16];
                    Buffer.BlockCopy(Guid.NewGuid().ToByteArray(), 0, nonce, 0, nonceLength);
                    transformHeader.Nonce = new Guid(nonce);

                    byte[] output = bcrypt.Encrypt(
                        originalBinary,
                        transformHeader.Nonce.ToByteArray().Take(nonceLength).ToArray(),
                        // Use the fields including and after Nonce field as auth data
                        Smb2Utility.MarshalStructure(transformHeader).Skip(20).ToArray(),
                        // Signature is 16 bytes in length
                        16,
                        out tag);
                    transformHeader.Signature = tag;
                    return(Smb2Utility.MarshalStructure(transformHeader).Concat(output).ToArray());
                }
            }

            // Return null if the message is not required to be encrypted.
            return(null);
        }
예제 #15
0
 private static string HashPassword(string password, string salt)
 {
     return(BCryptAlgorithm.HashPassword(password, salt));
 }
예제 #16
0
 public static string HashPassword(string password, uint rounds)
 {
     return(BCryptAlgorithm.HashPassword(password, BCryptAlgorithm.GenerateSalt(rounds)));
 }
예제 #17
0
        /// <summary>
        /// Create a new AsymCryptoSystem from TPM public parameter. This can then
        /// be used to validate TPM signatures or encrypt data destined for a TPM.
        /// </summary>
        /// <param name="pubKey"></param>
        /// <param name="privKey"></param>
        /// <returns></returns>
        public static AsymCryptoSystem CreateFrom(TpmPublic pubKey, TpmPrivate privKey = null)
        {
            var cs = new AsymCryptoSystem();

            TpmAlgId keyAlgId = pubKey.type;

            cs.PublicParms = pubKey.Copy();

            // Create an algorithm provider from the provided PubKey
            switch (keyAlgId)
            {
            case TpmAlgId.Rsa:
            {
                RawRsa rr     = null;
                byte[] prime1 = null,
                prime2 = null;
                if (privKey != null)
                {
                    rr     = new RawRsa(pubKey, privKey);
                    prime1 = RawRsa.ToBigEndian(rr.P);
                    prime2 = RawRsa.ToBigEndian(rr.Q);
                }
                var rsaParams = (RsaParms)pubKey.parameters;
                var exponent  = rsaParams.exponent != 0
                                            ? Globs.HostToNet(rsaParams.exponent)
                                            : RsaParms.DefaultExponent;
                var modulus = (pubKey.unique as Tpm2bPublicKeyRsa).buffer;
#if TSS_USE_BCRYPT
                var alg = new BCryptAlgorithm(Native.BCRYPT_RSA_ALGORITHM);
                cs.Key = alg.LoadRSAKey(exponent, modulus, prime1, prime2);
                alg.Close();
#else
                var dotNetPubParms = new RSAParameters()
                {
                    Exponent = exponent, Modulus = modulus
                };
                if (privKey != null)
                {
                    dotNetPubParms.P        = prime1;
                    dotNetPubParms.Q        = prime2;
                    dotNetPubParms.D        = RawRsa.ToBigEndian(rr.D);
                    dotNetPubParms.InverseQ = RawRsa.ToBigEndian(rr.InverseQ);
                    dotNetPubParms.DP       = RawRsa.ToBigEndian(rr.DP);
                    dotNetPubParms.DQ       = RawRsa.ToBigEndian(rr.DQ);
                }
                cs.RsaProvider = new RSACryptoServiceProvider();
                cs.RsaProvider.ImportParameters(dotNetPubParms);
#endif
                break;
            }

#if !__MonoCS__
            case TpmAlgId.Ecc:
            {
                var eccParms = (EccParms)pubKey.parameters;
                var eccPub   = (EccPoint)pubKey.unique;
                var algId    = RawEccKey.GetEccAlg(pubKey);
                if (algId == null)
                {
                    return(null);
                }
                bool   isEcdsa = eccParms.scheme.GetUnionSelector() == TpmAlgId.Ecdsa;
                byte[] keyBlob = RawEccKey.GetKeyBlob(eccPub.x, eccPub.y, keyAlgId,
                                                      !isEcdsa, eccParms.curveID);
#if TSS_USE_BCRYPT
                var alg = new BCryptAlgorithm(algId);
                cs.Key = alg.ImportKeyPair(Native.BCRYPT_ECCPUBLIC_BLOB, keyBlob);
                alg.Close();
                if (cs.Key == UIntPtr.Zero)
                {
                    Globs.Throw("Failed to create new RSA key");
                    return(null);
                }
#else
                CngKey eccKey = CngKey.Import(keyBlob, CngKeyBlobFormat.EccPublicBlob);

                if (pubKey.objectAttributes.HasFlag(ObjectAttr.Sign))
                {
                    cs.EcdsaProvider = new ECDsaCng(eccKey);
                }
                else
                {
                    cs.EcDhProvider = new ECDiffieHellmanCng(eccKey);
                }
#endif // !TSS_USE_BCRYPT
                break;
            }
#endif // !__MonoCS__
            default:
                Globs.Throw <ArgumentException>("Algorithm not supported");
                cs = null;
                break;
            }
            return(cs);
        }
예제 #18
0
 public static bool VerifyPassword(string password, string hashed)
 {
     return(BCryptAlgorithm.VerifyPassword(password, hashed));
 }
예제 #19
0
        public static byte[] HmacData(TpmAlgId hashAlgId, byte[] key, byte[] dataToHash)
        {
#if TSS_USE_BCRYPT
            string algName = Native.BCryptHashAlgName(hashAlgId);
            if (string.IsNullOrEmpty(algName))
            {
                Globs.Throw<ArgumentException>("HmacData(): Unsupported hash algorithm " + hashAlgId);
                return null;
            }

            var alg = new BCryptAlgorithm(algName, Native.BCRYPT_ALG_HANDLE_HMAC);
            var digest = alg.HmacData(key, dataToHash);
            alg.Close();
            return digest;
#else
            switch (hashAlgId)
            {
                case TpmAlgId.Sha1:
                    using (var h = new HMACSHA1(key))
                    {
                        return h.ComputeHash(dataToHash);
                    }
                case TpmAlgId.Sha256:
                    using (var h2 = new HMACSHA256(key))
                    {
                        return h2.ComputeHash(dataToHash);
                    }
                case TpmAlgId.Sha384:
                    using (var h3 = new HMACSHA384(key))
                    {
                        return h3.ComputeHash(dataToHash);
                    }
                case TpmAlgId.Sha512:
                    using (var h4 = new HMACSHA512(key))
                    {
                        return h4.ComputeHash(dataToHash);
                    }
                default:
                    Globs.Throw<ArgumentException>("HmacData(): Unsupported hash algorithm " + hashAlgId);
                    return null;
            }
#endif // !TSS_USE_BCRYPT
        }
    /// <summary>
    /// Hash a password using the OpenBSD bcrypt scheme.
    /// </summary>
    /// <param name="password">The password to hash.</param>
    /// <param name="salt">The salt to hash with (perhaps generated
    /// using <c>BCrypt.GenerateSalt</c>).</param>
    /// <returns>The hashed password.</returns>
    public static string HashPassword(string password, string salt)
    {
        if (password == null)
        {
            throw new ArgumentNullException("password");
        }
        if (salt == null)
        {
            throw new ArgumentNullException("salt");
        }

        char minor = (char)0;

        if (salt[0] != '$' || salt[1] != '2')
        {
            throw new ArgumentException("Invalid salt version");
        }

        int offset;

        if (salt[1] != '$')
        {
            minor = salt[2];
            if (minor != 'a' || salt[3] != '$')
            {
                throw new ArgumentException("Invalid salt revision");
            }
            offset = 4;
        }
        else
        {
            offset = 3;
        }

        // Extract number of rounds
        if (salt[offset + 2] > '$')
        {
            throw new ArgumentException("Missing salt rounds");
        }

        int rounds = Int32.Parse(salt.Substring(offset, 2), NumberFormatInfo.InvariantInfo);

        byte[] passwordBytes = Encoding.UTF8.GetBytes(password + (minor >= 'a' ? "\0" : String.Empty));
        byte[] saltBytes     = DecodeBase64(salt.Substring(offset + 3, 22),
                                            BCRYPT_SALT_LEN);

        BCryptAlgorithm bcrypt = new BCryptAlgorithm();

        byte[] hashed = bcrypt.CryptRaw(passwordBytes, saltBytes, rounds);

        StringBuilder rs = new StringBuilder();

        rs.Append("$2");
        if (minor >= 'a')
        {
            rs.Append(minor);
        }
        rs.Append('$');
        if (rounds < 10)
        {
            rs.Append('0');
        }
        rs.Append(rounds);
        rs.Append('$');
        rs.Append(EncodeBase64(saltBytes, saltBytes.Length));
        rs.Append(EncodeBase64(hashed,
                               (bf_crypt_ciphertext.Length * 4) - 1));

        return(rs.ToString());
    }
예제 #21
0
 public static string HashPassword(string password)
 {
     return(HashPassword(password, BCryptAlgorithm.GenerateSalt()));
 }
예제 #22
0
        /// <summary>
        /// Create a new SymmCipher object with a random key based on the alg and mode supplied.
        /// </summary>
        /// <param name="algId"></param>
        /// <param name="numBits"></param>
        /// <param name="mode"></param>
        /// <returns></returns>
        public static SymmCipher Create(SymDefObject symDef = null, byte[] keyData = null, byte[] iv = null)
        {
            if (symDef == null)
            {
                symDef = new SymDefObject(TpmAlgId.Aes, 128, TpmAlgId.Cfb);
            }
            else if (symDef.Algorithm != TpmAlgId.Aes)
            {
                Globs.Throw <ArgumentException>("Unsupported symmetric algorithm " + symDef.Algorithm);
                return(null);
            }

#if TSS_USE_BCRYPT
            var alg = new BCryptAlgorithm(Native.BCRYPT_AES_ALGORITHM);

            if (keyData == null)
            {
                keyData = Globs.GetRandomBytes(symDef.KeyBits / 8);
            }
            var key = alg.GenerateSymKey(symDef, keyData, GetBlockSize(symDef));
            //key = BCryptInterface.ExportSymKey(keyHandle);
            //keyHandle = alg.LoadSymKey(key, symDef, GetBlockSize(symDef));
            alg.Close();
            return(new SymmCipher(key, keyData, iv));
#else
            SymmetricAlgorithm alg = new RijndaelManaged();
            // DES and __3DES are not supported in TPM 2.0 v 0.96 and above
            //switch (algId) {
            //    case TpmAlgId.Aes: alg = new RijndaelManaged(); break;
            //    case TpmAlgId.__3DES: alg = new TripleDESCryptoServiceProvider(); break;
            //    case TpmAlgId.Des: alg = new DESCryptoServiceProvider(); break;
            //}
            int blockSize = GetBlockSize(symDef);
            alg.KeySize   = symDef.KeyBits;
            alg.BlockSize = blockSize * 8;
            alg.Padding   = PaddingMode.None;
            alg.Mode      = GetCipherMode(symDef.Mode);
            // REVISIT: Get this right for other modes
            alg.FeedbackSize = alg.BlockSize;
            if (keyData == null)
            {
                // Generate random key
                alg.IV = Globs.GetZeroBytes(blockSize);
                try
                {
                    alg.GenerateKey();
                }
                catch (Exception)
                {
                    alg.Dispose();
                    throw;
                }
            }
            else
            {
                // Use supplied key bits
                alg.Key = keyData;
                if (iv == null)
                {
                    iv = Globs.GetZeroBytes(blockSize);
                }
                else if (iv.Length != blockSize)
                {
                    Array.Resize(ref iv, blockSize);
                }
                alg.IV = iv;
            }
            return(new SymmCipher(alg));
#endif
        }