in src/tpm_codec.c [302:389]
UINT32 SignData(TSS_DEVICE* tpm, TSS_SESSION* sess, BYTE* tokenData, UINT32 tokenSize, BYTE* signatureBuffer, UINT32 sigBufSize)
{
UINT32 result;
TPM_RC rc;
TPM2B_DIGEST digest;
TPM_ALG_ID idKeyHashAlg = ALG_SHA256_VALUE;
UINT32 sigSize = TSS_GetDigestSize(idKeyHashAlg); //32
UINT32 MaxInputBuffer = 0;
if (sigBufSize < sigSize)
{
LogError("Signature buffer size (%uz) is less than required size (%uz)", sigBufSize, sigSize);
result = sigSize;
}
else
{
sigBufSize = 0;
MaxInputBuffer = TSS_GetTpmProperty(tpm, TPM_PT_INPUT_BUFFER); // 1024
if (tokenSize > MaxInputBuffer) // 68
{
TPMI_DH_OBJECT hSeq = TPM_RH_NULL;
BYTE *curPos = tokenData;
UINT32 bytesLeft = tokenSize;
rc = TPM2_HMAC_Start(tpm, sess, DPS_ID_KEY_HANDLE, NULL, idKeyHashAlg, &hSeq);
if (rc != TPM_RC_SUCCESS)
{
LogError("Failed to start HMAC sequence %s", TSS_StatusValueName(rc) );
result = 0;
}
else
{
bool seq_complete = true;
// Above condition 'if (tokenSize > MaxInputBuffer)' ensures that the first
// iteration is always valid.
do
{
rc = TSS_SequenceUpdate(tpm, sess, hSeq, curPos, MaxInputBuffer);
if (rc != TPM_RC_SUCCESS)
{
LogError("Failed to update HMAC sequence %s", TSS_StatusValueName(rc));
seq_complete = false;
break;
}
bytesLeft -= MaxInputBuffer;
curPos += MaxInputBuffer;
} while (bytesLeft > MaxInputBuffer);
if (seq_complete)
{
rc = TSS_SequenceComplete(tpm, sess, hSeq, curPos, bytesLeft, &digest);
if (rc != TPM_RC_SUCCESS)
{
LogError("Failed to complete HMAC sequence %s", TSS_StatusValueName(rc));
result = 0;
}
else
{
MemoryCopy(signatureBuffer, digest.t.buffer, sigSize);
sigBufSize = sigSize;
result = sigBufSize;
}
}
else
{
result = 0;
}
}
}
else
{
rc = TSS_HMAC(tpm, sess, DPS_ID_KEY_HANDLE, tokenData, tokenSize, &digest);
if (rc != TPM_RC_SUCCESS)
{
LogError("Hashing token data failed %s", TSS_StatusValueName(rc));
result = 0;
}
else
{
MemoryCopy(signatureBuffer, digest.t.buffer, sigSize);
sigBufSize = sigSize;
result = sigBufSize;
}
}
}
return result;
}