internal byte[] ParmEncrypt(byte[] parm, Direction inOrOut)
{
if (Symmetric == null)
{
Globs.Throw("parameter encryption cipher not defined");
return parm;
}
if (Symmetric.Algorithm == TpmAlgId.Null)
{
return parm;
}
byte[] nonceNewer, nonceOlder;
if (inOrOut == Direction.Command)
{
nonceNewer = NonceCaller;
nonceOlder = NonceTpm;
}
else
{
nonceNewer = NonceTpm;
nonceOlder = NonceCaller;
}
byte[] encKey = (AuthHandle != null && AuthHandle.Auth != null)
? SessionKey.Concat(Globs.TrimTrailingZeros(AuthHandle.Auth)).ToArray()
: SessionKey;
if (Symmetric.Algorithm == TpmAlgId.Xor)
{
return CryptoLib.KdfThenXor(AuthHash, encKey, nonceNewer, nonceOlder, parm);
}
int keySize = (Symmetric.KeyBits + 7) / 8,
blockSize = SymmCipher.GetBlockSize(Symmetric),
bytesRequired = keySize + blockSize;
byte[] keyInfo = KDF.KDFa(AuthHash, encKey, "CFB", nonceNewer, nonceOlder, bytesRequired * 8);
var key = new byte[keySize];
Array.Copy(keyInfo, 0, key, 0, keySize);
var iv = new byte[blockSize];
Array.Copy(keyInfo, keySize, iv, 0, blockSize);
// Make a new SymmCipher from the key and IV and do the encryption.
using (SymmCipher s = SymmCipher.Create(Symmetric, key, iv))
{
return inOrOut == Direction.Command ? s.Encrypt(parm) : s.Decrypt(parm);
}
}