/// <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 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 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 }