/// <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); }
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[] 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 }
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 }
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); }
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); }
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 }
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 }
/// <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()
/// <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); }
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> /// 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 }
/// <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 }