F-12105: tpm: keep keystore size as int in load_pubkey

keystore_get_size() returns -1 on invalid or oversized OTP slot
data; storing it in uint16_t made -1 become 65535, which passed the
hdrSz <= 0 check and was fed to the ECC/RSA parser as a 65535-byte
read from the keystore buffer. Keep it as int and reject values
<= 0 or above KEYSTORE_PUBKEY_SIZE.
pull/882/head
Daniele Lacamera 2026-09-04 14:06:33 +02:00
parent b5ab88a50a
commit b9068ce162
2 changed files with 29 additions and 3 deletions

View File

@ -393,7 +393,7 @@ int wolfBoot_load_pubkey(const uint8_t* pubkey_hint, WOLFTPM2_KEY* pubKey,
uint32_t key_type;
int key_slot = -1;
uint8_t *hdr;
uint16_t hdrSz;
int hdrSz;
*pAlg = TPM_ALG_NULL;
@ -406,7 +406,7 @@ int wolfBoot_load_pubkey(const uint8_t* pubkey_hint, WOLFTPM2_KEY* pubKey,
key_type = keystore_get_key_type(key_slot);
hdr = keystore_get_buffer(key_slot);
hdrSz = keystore_get_size(key_slot);
if (hdr == NULL || hdrSz <= 0)
if (hdr == NULL || hdrSz <= 0 || hdrSz > KEYSTORE_PUBKEY_SIZE)
rc = -1;
}
/* Parse public key to TPM public key. Note: this loads as temp handle,

View File

@ -30,6 +30,8 @@ static uint8_t test_nv_digest[WOLFBOOT_SHA_DIGEST_SIZE];
static uint32_t captured_exponent;
static int forbidden_memcmp_calls;
static uint32_t mock_nv_digest_sz;
static int mock_keystore_size;
static int decode_calls;
int keyslot_id_by_sha(const uint8_t* pubkey_hint)
{
@ -52,7 +54,7 @@ uint8_t *keystore_get_buffer(int id)
int keystore_get_size(int id)
{
ck_assert_int_eq(id, 0);
return (int)sizeof(test_hdr);
return mock_keystore_size;
}
int wc_RsaPublicKeyDecode_ex(const byte* input, word32* inOutIdx, word32 inSz,
@ -61,6 +63,7 @@ int wc_RsaPublicKeyDecode_ex(const byte* input, word32* inOutIdx, word32 inSz,
(void)input;
(void)inSz;
decode_calls++;
*inOutIdx = 0;
*n = test_modulus;
*nSz = sizeof(test_modulus);
@ -175,6 +178,8 @@ static void setup(void)
captured_exponent = 0;
forbidden_memcmp_calls = 0;
mock_nv_digest_sz = WOLFBOOT_SHA_DIGEST_SIZE;
mock_keystore_size = (int)sizeof(test_hdr);
decode_calls = 0;
}
START_TEST(test_wolfBoot_load_pubkey_decodes_der_exponent_bytes)
@ -194,6 +199,26 @@ START_TEST(test_wolfBoot_load_pubkey_decodes_der_exponent_bytes)
}
END_TEST
/* A failed keystore_get_size() (-1: invalid or oversized OTP slot) must be
* rejected, not narrowed to uint16_t (65535) and fed to the key parser. */
START_TEST(test_wolfBoot_load_pubkey_rejects_failed_keystore_size)
{
uint8_t hint[WOLFBOOT_SHA_DIGEST_SIZE] = { 0 };
WOLFTPM2_KEY key;
TPM_ALG_ID alg = TPM_ALG_NULL;
int rc;
memset(&key, 0, sizeof(key));
mock_keystore_size = -1;
rc = wolfBoot_load_pubkey(hint, &key, &alg);
ck_assert_int_eq(rc, -1);
ck_assert_uint_eq(decode_calls, 0);
ck_assert_int_eq(alg, TPM_ALG_NULL);
}
END_TEST
START_TEST(test_wolfBoot_check_rot_avoids_memcmp_on_digest_compare)
{
uint8_t hint[WOLFBOOT_SHA_DIGEST_SIZE];
@ -245,6 +270,7 @@ static Suite *tpm_suite(void)
tc = tcase_create("wolfBoot_load_pubkey");
tcase_add_checked_fixture(tc, setup, NULL);
tcase_add_test(tc, test_wolfBoot_load_pubkey_decodes_der_exponent_bytes);
tcase_add_test(tc, test_wolfBoot_load_pubkey_rejects_failed_keystore_size);
tcase_add_test(tc, test_wolfBoot_check_rot_avoids_memcmp_on_digest_compare);
tcase_add_test(tc, test_wolfBoot_check_rot_rejects_mismatched_digest);
tcase_add_test(tc, test_wolfBoot_check_rot_rejects_wrong_digest_size);