trousers: Add boundary check functions
Add some safe primitives for parsing TPM_DELEGATE_LABEL,
TPM_DELEGATIONS, TPM_DELEGATE_PUBLIC, TPM_DELEGATE_OWNER_BLOB...
BUG=b:169392230, b:233949215, b:174816474
TEST=Manually check Trspi_UnloadBlob_TPM_DELEGATE_OWNER_BLOB_s works
Change-Id: Ic695d75af47652b54c40ff4815fc7c0b761957ed
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/trousers/+/3669929
Tested-by: Yi Chou <yich@google.com>
Reviewed-by: Andrey Pronin <apronin@chromium.org>
Commit-Queue: Yi Chou <yich@google.com>
diff --git a/src/include/trousers/trousers.h b/src/include/trousers/trousers.h
index 83233d5..3dee970 100644
--- a/src/include/trousers/trousers.h
+++ b/src/include/trousers/trousers.h
@@ -81,9 +81,13 @@
void Trspi_UnloadBlob_TPM_FAMILY_LABEL(UINT64 *offset, BYTE *blob, TPM_FAMILY_LABEL *label);
void Trspi_UnloadBlob_TPM_FAMILY_TABLE_ENTRY(UINT64 *offset, BYTE *blob, TPM_FAMILY_TABLE_ENTRY *entry);
void Trspi_UnloadBlob_TPM_DELEGATE_LABEL(UINT64 *offset, BYTE *blob, TPM_DELEGATE_LABEL *label);
+TSS_RESULT Trspi_UnloadBlob_TPM_DELEGATE_LABEL_s(UINT64 *offset, BYTE *blob, UINT64 capacity, TPM_DELEGATE_LABEL *label);
void Trspi_UnloadBlob_TPM_DELEGATIONS(UINT64 *offset, BYTE *blob, TPM_DELEGATIONS *delegations);
+TSS_RESULT Trspi_UnloadBlob_TPM_DELEGATIONS_s(UINT64 *offset, BYTE *blob, UINT64 capacity, TPM_DELEGATIONS *delegations);
TSS_RESULT Trspi_UnloadBlob_TPM_DELEGATE_PUBLIC(UINT64 *offset, BYTE *blob, TPM_DELEGATE_PUBLIC *pub);
+TSS_RESULT Trspi_UnloadBlob_TPM_DELEGATE_PUBLIC_s(UINT64 *offset, BYTE *blob, UINT64 capacity, TPM_DELEGATE_PUBLIC *pub);
TSS_RESULT Trspi_UnloadBlob_TPM_DELEGATE_OWNER_BLOB(UINT64 *offset, BYTE *blob, TPM_DELEGATE_OWNER_BLOB *owner);
+TSS_RESULT Trspi_UnloadBlob_TPM_DELEGATE_OWNER_BLOB_s(UINT64 *offset, BYTE *blob, UINT64 capacity, TPM_DELEGATE_OWNER_BLOB *owner);
TSS_RESULT Trspi_UnloadBlob_TPM_DELEGATE_KEY_BLOB(UINT64 *offset, BYTE *blob, TPM_DELEGATE_KEY_BLOB *key);
void Trspi_UnloadBlob_TSS_FAMILY_TABLE_ENTRY(UINT64 *offset, BYTE *blob, TSS_FAMILY_TABLE_ENTRY *entry);
TSS_RESULT Trspi_UnloadBlob_TSS_PCR_INFO_SHORT(UINT64 *offset, BYTE *blob, TSS_PCR_INFO_SHORT *pcr);
diff --git a/src/trspi/trousers.c b/src/trspi/trousers.c
index dbfc715..10e57f8 100644
--- a/src/trspi/trousers.c
+++ b/src/trspi/trousers.c
@@ -2842,6 +2842,17 @@
Trspi_UnloadBlob_BYTE(offset, &label->label, blob);
}
+TSS_RESULT
+Trspi_UnloadBlob_TPM_DELEGATE_LABEL_s(UINT64 *offset, BYTE *blob, UINT64 capacity, TPM_DELEGATE_LABEL *label)
+{
+ BYTE *internal_label = NULL;
+
+ if (label)
+ internal_label = &label->label;
+
+ return Trspi_UnloadBlob_BYTE_s(offset, internal_label, blob, capacity);
+}
+
void
Trspi_LoadBlob_TPM_DELEGATE_LABEL(UINT64 *offset, BYTE *blob, TPM_DELEGATE_LABEL *label)
{
@@ -2866,6 +2877,36 @@
Trspi_UnloadBlob_UINT32(offset, &delegations->per2, blob);
}
+TSS_RESULT
+Trspi_UnloadBlob_TPM_DELEGATIONS_s(UINT64 *offset, BYTE *blob, UINT64 capacity, TPM_DELEGATIONS *delegations)
+{
+ TSS_RESULT result;
+
+ if (!delegations) {
+ if ((result = Trspi_UnloadBlob_UINT16_s(offset, NULL, blob, capacity)))
+ return result;
+ if ((result = Trspi_UnloadBlob_UINT32_s(offset, NULL, blob, capacity)))
+ return result;
+ if ((result = Trspi_UnloadBlob_UINT32_s(offset, NULL, blob, capacity)))
+ return result;
+ if ((result = Trspi_UnloadBlob_UINT32_s(offset, NULL, blob, capacity)))
+ return result;
+
+ return TSS_SUCCESS;
+ }
+
+ if ((result = Trspi_UnloadBlob_UINT16_s(offset, &delegations->tag, blob, capacity)))
+ return result;
+ if ((result = Trspi_UnloadBlob_UINT32_s(offset, &delegations->delegateType, blob, capacity)))
+ return result;
+ if ((result = Trspi_UnloadBlob_UINT32_s(offset, &delegations->per1, blob, capacity)))
+ return result;
+ if ((result = Trspi_UnloadBlob_UINT32_s(offset, &delegations->per2, blob, capacity)))
+ return result;
+
+ return TSS_SUCCESS;
+}
+
void
Trspi_LoadBlob_TPM_DELEGATIONS(UINT64 *offset, BYTE *blob, TPM_DELEGATIONS *delegations)
{
@@ -2902,6 +2943,55 @@
return TSS_SUCCESS;
}
+TSS_RESULT
+Trspi_UnloadBlob_TPM_DELEGATE_PUBLIC_s(UINT64 *offset, BYTE *blob, UINT64 capacity, TPM_DELEGATE_PUBLIC *pub)
+{
+ TSS_RESULT result;
+
+ if (!pub) {
+ if ((result = Trspi_UnloadBlob_UINT16_s(offset, NULL, blob, capacity)))
+ return result;
+ if ((result = Trspi_UnloadBlob_TPM_DELEGATE_LABEL_s(offset, blob, capacity, NULL)))
+ return result;
+ if ((result = Trspi_UnloadBlob_PCR_INFO_SHORT_s(offset, blob, capacity, NULL)))
+ return result;
+ if ((result = Trspi_UnloadBlob_TPM_DELEGATIONS_s(offset, blob, capacity, NULL)))
+ return result;
+ if ((result = Trspi_UnloadBlob_UINT32_s(offset, NULL, blob, capacity)))
+ return result;
+ if ((result = Trspi_UnloadBlob_UINT32_s(offset, NULL, blob, capacity)))
+ return result;
+
+ return TSS_SUCCESS;
+ }
+
+ if ((result = Trspi_UnloadBlob_UINT16_s(offset, &pub->tag, blob, capacity)))
+ return result;
+ if ((result = Trspi_UnloadBlob_TPM_DELEGATE_LABEL_s(offset, blob, capacity, &pub->label)))
+ return result;
+ if ((result = Trspi_UnloadBlob_PCR_INFO_SHORT_s(offset, blob, capacity, &pub->pcrInfo)))
+ return result;
+ if ((result = Trspi_UnloadBlob_TPM_DELEGATIONS_s(offset, blob, capacity, &pub->permissions))) {
+ free(pub->pcrInfo.pcrSelection.pcrSelect);
+ pub->pcrInfo.pcrSelection.sizeOfSelect = 0;
+ pub->pcrInfo.pcrSelection.pcrSelect = NULL;
+ return result;
+ }
+ if ((result = Trspi_UnloadBlob_UINT32_s(offset, &pub->familyID, blob, capacity))) {
+ free(pub->pcrInfo.pcrSelection.pcrSelect);
+ pub->pcrInfo.pcrSelection.sizeOfSelect = 0;
+ pub->pcrInfo.pcrSelection.pcrSelect = NULL;
+ return result;
+ }
+ if ((result = Trspi_UnloadBlob_UINT32_s(offset, &pub->verificationCount, blob, capacity))) {
+ free(pub->pcrInfo.pcrSelection.pcrSelect);
+ pub->pcrInfo.pcrSelection.sizeOfSelect = 0;
+ pub->pcrInfo.pcrSelection.pcrSelect = NULL;
+ return result;
+ }
+ return TSS_SUCCESS;
+}
+
void
Trspi_LoadBlob_TPM_DELEGATE_PUBLIC(UINT64 *offset, BYTE *blob, TPM_DELEGATE_PUBLIC *pub)
{
@@ -2961,6 +3051,103 @@
return TSS_SUCCESS;
}
+TSS_RESULT
+Trspi_UnloadBlob_TPM_DELEGATE_OWNER_BLOB_s(UINT64 *offset, BYTE *blob, UINT64 capacity, TPM_DELEGATE_OWNER_BLOB *owner)
+{
+ TSS_RESULT result;
+
+ if (!owner) {
+ UINT32 additionalSize, sensitiveSize;
+
+ if ((result = Trspi_UnloadBlob_UINT16_s(offset, NULL, blob, capacity)))
+ return result;
+ if ((result = Trspi_UnloadBlob_TPM_DELEGATE_PUBLIC_s(offset, blob, capacity, NULL)))
+ return result;
+ if ((result = Trspi_UnloadBlob_DIGEST_s(offset, blob, capacity, NULL)))
+ return result;
+ if ((result = Trspi_UnloadBlob_UINT32_s(offset, &additionalSize, blob, capacity)))
+ return result;
+ if ((result = Trspi_UnloadBlob_s(offset, additionalSize, blob, capacity, NULL)))
+ return result;
+ if ((result = Trspi_UnloadBlob_UINT32_s(offset, &sensitiveSize, blob, capacity)))
+ return result;
+ if ((result = Trspi_UnloadBlob_s(offset, sensitiveSize, blob, capacity, NULL)))
+ return result;
+
+ return TSS_SUCCESS;
+ }
+
+ if ((result = Trspi_UnloadBlob_UINT16_s(offset, &owner->tag, blob, capacity)))
+ goto error0;
+ if ((result = Trspi_UnloadBlob_TPM_DELEGATE_PUBLIC_s(offset, blob, capacity, &owner->pub)))
+ goto error0;
+ if ((result = Trspi_UnloadBlob_DIGEST_s(offset, blob, capacity, &owner->integrityDigest)))
+ goto error1;
+ if ((result = Trspi_UnloadBlob_UINT32_s(offset, &owner->additionalSize, blob, capacity)))
+ goto error1;
+
+ if (*offset + owner->additionalSize > capacity) {
+ result = TSPERR(TSS_E_BAD_PARAMETER);
+ goto error1;
+ }
+
+ if (owner->additionalSize > 0) {
+ owner->additionalArea = malloc(owner->additionalSize);
+ if (owner->additionalArea == NULL) {
+ LogError("malloc of %u bytes failed.", owner->additionalSize);
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto error2;
+ }
+
+ if ((result = Trspi_UnloadBlob_s(offset, owner->additionalSize, blob, capacity, owner->additionalArea)))
+ goto error2;
+ } else {
+ owner->additionalArea = NULL;
+ }
+
+ if ((result = Trspi_UnloadBlob_UINT32_s(offset, &owner->sensitiveSize, blob, capacity)))
+ goto error2;
+
+ if (*offset + owner->sensitiveSize > capacity) {
+ result = TSPERR(TSS_E_BAD_PARAMETER);
+ goto error2;
+ }
+
+ if (owner->sensitiveSize > 0) {
+ owner->sensitiveArea = malloc(owner->sensitiveSize);
+ if (owner->sensitiveArea == NULL) {
+ LogError("malloc of %u bytes failed.", owner->sensitiveSize);
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto error3;
+ }
+
+ if ((result = Trspi_UnloadBlob_s(offset, owner->sensitiveSize, blob, capacity, owner->sensitiveArea)))
+ goto error3;
+ } else {
+ owner->sensitiveArea = NULL;
+ }
+
+ return TSS_SUCCESS;
+
+error3:
+ free(owner->sensitiveArea);
+ owner->sensitiveArea = NULL;
+ owner->sensitiveSize = 0;
+
+error2:
+ free(owner->additionalArea);
+ owner->additionalArea = NULL;
+ owner->additionalSize = 0;
+
+error1:
+ free(owner->pub.pcrInfo.pcrSelection.pcrSelect);
+ owner->pub.pcrInfo.pcrSelection.pcrSelect = NULL;
+ owner->pub.pcrInfo.pcrSelection.sizeOfSelect = 0;
+
+error0:
+ return result;
+}
+
void
Trspi_LoadBlob_TPM_DELEGATE_OWNER_BLOB(UINT64 *offset, BYTE *blob, TPM_DELEGATE_OWNER_BLOB *owner)
{