mirror of
https://github.com/stefanberger/libtpms
synced 2026-08-07 08:20:20 +00:00
tpm2: Consume padding bytes in TPM2_ContextLoad() (Win2k19, issue #217)
Windows 2019 Server padds the TPM_ContextLoad() command with additional bytes up to TPM_PT_MAX_OBJECT_CONTEXT for the TPMS_CONTEXT part. Since libtpms does not use an OBJECT to serialize the keys (anymore) it now uses less bytes than the MAXimum of TPM_PT_MAX_OBJECT_CONTEXT bytes and the padding leaves some unconsumed bytes that end up failing the command since no left-over bytes are allowed in any command. When unconsumed bytes are left in TPMS_CONTEXT_Unmarshal() we check that the original passed in size was that of TPM_PT_MAX_OBJECT_CONTEXT and only then consume the additional padding bytes. Luckily only one command calls TPMS_CONTEXT_Unmarshal() so that no unwanted side effects should occur anywhere else, such as no bytes left for unmarshalling the next structure. The wisdom behind the padding is not quite clear but it feels like ill-fixing the code to work around a Windows 2019 server bug... This patch fixes issed #217 Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
This commit is contained in:
parent
a3bdddaa8e
commit
be5fabf155
2
CHANGES
2
CHANGES
@ -5,6 +5,8 @@ version 0.9.0:
|
||||
- The size of the context gap has been adjusted to 0xffff from 0xff.
|
||||
As a consequence of this the volatile state's format (STATE_RESET_DATA)
|
||||
has changed and cannot be downgraded.
|
||||
- Applied work-around for Win 2016 & 2019 server related to
|
||||
TPM2_ContextLoad (issue #217)
|
||||
|
||||
version 0.8.0
|
||||
- NOTE: Downgrade to previous versions is not possible. See below.
|
||||
|
||||
@ -4308,6 +4308,7 @@ TPM_RC
|
||||
TPMS_CONTEXT_Unmarshal(TPMS_CONTEXT *target, BYTE **buffer, INT32 *size)
|
||||
{
|
||||
TPM_RC rc = TPM_RC_SUCCESS;
|
||||
INT32 orig_size = *size; // libtpms added
|
||||
|
||||
if (rc == TPM_RC_SUCCESS) {
|
||||
rc = UINT64_Unmarshal(&target->sequence, buffer, size);
|
||||
@ -4321,6 +4322,35 @@ TPMS_CONTEXT_Unmarshal(TPMS_CONTEXT *target, BYTE **buffer, INT32 *size)
|
||||
if (rc == TPM_RC_SUCCESS) {
|
||||
rc = TPM2B_CONTEXT_DATA_Unmarshal(&target->contextBlob, buffer, size);
|
||||
}
|
||||
// libtpms added begin
|
||||
if (rc == TPM_RC_SUCCESS) {
|
||||
if (*size > 0) {
|
||||
/* Windows 2019 server pads the command TPM_ContextLoad up to the value of
|
||||
* TPM_PT_MAX_OBJECT_CONTENT for the TPMS_CONTEXT part and we end up with
|
||||
* left-over padding bytes here that will make the TPM2_ContextLoad command
|
||||
* fail. This is because we don't just write an OBJECT as the context but use
|
||||
* ANY_OBJECT_Marshal to write it, which consumes less bytes. We had to do
|
||||
* this due to a Linux TPM resource manager bug that couldn't deal with the
|
||||
* larger context sizes once RSA 3072 was enabled and it ran out of memory
|
||||
* when receiving contexts.
|
||||
* Luckily only one command needs TPMS_CONTEXT unmarshalled, so we can adjust
|
||||
* for the left-over padding here but also ONLY do this if
|
||||
* 'orig_size' == value(TPM_PT_MAX_OBJECT_CONTENT).
|
||||
*/
|
||||
static UINT32 tpm_pt_max_object_context;
|
||||
|
||||
if (tpm_pt_max_object_context == 0) {
|
||||
TPML_TAGGED_TPM_PROPERTY tttp;
|
||||
|
||||
TPMCapGetProperties(TPM_PT_MAX_OBJECT_CONTEXT, 1, &tttp);
|
||||
if (tttp.count == 1)
|
||||
tpm_pt_max_object_context = tttp.tpmProperty[0].value;
|
||||
}
|
||||
if ((UINT32)orig_size == tpm_pt_max_object_context)
|
||||
*size = 0; /* consume the padding bytes */
|
||||
}
|
||||
}
|
||||
// libtpms added end
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user