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
}