internal byte[] GetAuthHmac(byte[] parmHash, Direction direction, byte[] nonceDec = null, byte[] nonceEnc = null)
{
// special case. If this is a policy session and the session includes PolicyPassword the
// TPM expects and assumes that the HMAC field will have the plaintext entity field as in
// a PWAP session (the related PolicyAuthValue demands an HMAC as usual)
if (PlaintextAuth)
{
return Handle.Auth ?? AuthHandle.Auth;
}
byte[] nonceNewer, nonceOlder;
if (direction == Direction.Command)
{
nonceNewer = NonceCaller;
nonceOlder = NonceTpm;
}
else
{
nonceNewer = NonceTpm;
nonceOlder = NonceCaller;
}
byte[] sessionAttrs = Marshaller.GetTpmRepresentation(Attrs);
byte[] auth = Handle.Auth;
if (AuthHandle != null && Handle != TpmRh.TpmRsPw && auth == null &&
((SessionType != TpmSe.Policy && BindObject != AuthHandle) ||
(SessionType == TpmSe.Policy && SessIncludesAuth)))
{
auth = Globs.TrimTrailingZeros(AuthHandle.Auth);
}
byte[] hmacKey = Globs.Concatenate(SessionKey, auth);
byte[] bufToHmac = Globs.Concatenate(new[] {parmHash, nonceNewer, nonceOlder,
nonceDec, nonceEnc, sessionAttrs});
byte[] hmac = CryptoLib.HmacData(AuthHash, hmacKey, bufToHmac);
#if false
Console.WriteLine(Globs.FormatBytesCompact("hmacKey: ", hmacKey));
Console.WriteLine(Globs.FormatBytesCompact("nonceNewer: ", nonceNewer));
Console.WriteLine(Globs.FormatBytesCompact("nonceOlder: ", nonceOlder));
Console.WriteLine(Globs.FormatBytesCompact("nonceDec: ", nonceDec));
Console.WriteLine(Globs.FormatBytesCompact("nonceEnc: ", nonceEnc));
Console.WriteLine(Globs.FormatBytesCompact("attrs: ", sessionAttrs));
Console.WriteLine(Globs.FormatBytesCompact("HMAC: ", hmac));
#endif
return hmac;
}