F-3738: fix policySz uint16_t underflow in wolfBoot_unseal_blob for short policy

The guard `policySz <= 0` was dead for unsigned uint16_t, so values 1-3
passed. The subsequent `policySz -= sizeof(pcrMask)` (4) then wrapped to
65533-65535, passing a garbage length to wolfTPM2_VerifyHashTicket. Replace
the guard with `policySz < sizeof(pcrMask)` to reject policies too short to
hold a pcrMask.
pull/795/head
Daniele Lacamera 2026-06-11 18:30:49 +02:00
parent a10a993cd2
commit ddf05a9625
2 changed files with 25 additions and 2 deletions

View File

@ -1007,8 +1007,8 @@ int wolfBoot_unseal_blob(const uint8_t* pubkey_hint,
uint8_t* policyRef = NULL; /* optional nonce */
uint32_t policyRefSz = 0;
if (policy == NULL || policySz <= 0 || secret == NULL ||
secret_sz == NULL) {
if (policy == NULL || policySz < (uint16_t)sizeof(pcrMask) ||
secret == NULL || secret_sz == NULL) {
return -1;
}

View File

@ -691,6 +691,28 @@ START_TEST(test_wolfBoot_unseal_blob_rejects_negative_auth_size)
}
END_TEST
START_TEST(test_wolfBoot_unseal_blob_rejects_short_policy)
{
uint8_t secret[WOLFBOOT_MAX_SEAL_SZ];
WOLFTPM2_KEYBLOB blob;
uint8_t pubkey_hint[WOLFBOOT_SHA_DIGEST_SIZE] = {0};
uint8_t policy[4] = {0xAA, 0xBB, 0xCC, 0xDD};
int secret_sz;
int rc;
int i;
memset(&blob, 0, sizeof(blob));
memset(secret, 0, sizeof(secret));
for (i = 1; i <= 3; i++) {
secret_sz = (int)sizeof(secret);
rc = wolfBoot_unseal_blob(pubkey_hint, policy, (uint16_t)i, &blob,
secret, &secret_sz, NULL, 0);
ck_assert_int_eq(rc, -1);
}
}
END_TEST
START_TEST(test_wolfBoot_unseal_blob_rejects_output_larger_than_capacity)
{
struct {
@ -757,6 +779,7 @@ static Suite *tpm_blob_suite(void)
tcase_add_test(tc, test_wolfBoot_unseal_blob_zeroes_unseal_output);
tcase_add_test(tc, test_wolfBoot_unseal_blob_rejects_oversized_auth);
tcase_add_test(tc, test_wolfBoot_unseal_blob_rejects_negative_auth_size);
tcase_add_test(tc, test_wolfBoot_unseal_blob_rejects_short_policy);
tcase_add_test(tc, test_wolfBoot_unseal_blob_rejects_output_larger_than_capacity);
suite_add_tcase(s, tc);
return s;