From 9afe8a5e9a4a2c051a07e1ae87e95bb47bdbce5f Mon Sep 17 00:00:00 2001 From: Daniele Lacamera Date: Mon, 9 Mar 2026 11:49:14 +0100 Subject: [PATCH] Do not rely on alignment when loading RSA exponent F/369 --- src/tpm.c | 13 ++- tools/unit-tests/Makefile | 7 +- tools/unit-tests/unit-tpm-rsa-exp.c | 133 ++++++++++++++++++++++++++++ 3 files changed, 151 insertions(+), 2 deletions(-) create mode 100644 tools/unit-tests/unit-tpm-rsa-exp.c diff --git a/src/tpm.c b/src/tpm.c index a99bd927..f63bc53b 100644 --- a/src/tpm.c +++ b/src/tpm.c @@ -382,6 +382,8 @@ int wolfBoot_load_pubkey(const uint8_t* pubkey_hint, WOLFTPM2_KEY* pubKey, defined(WOLFBOOT_SIGN_RSA3072) || \ defined(WOLFBOOT_SIGN_RSA4096) uint32_t inOutIdx = 0; + uint32_t exponent = 0; + uint32_t j; const uint8_t*n = NULL, *e = NULL; uint32_t nSz = 0, eSz = 0; if (key_type != AUTH_KEY_RSA2048 && key_type != AUTH_KEY_RSA3072 && @@ -395,10 +397,19 @@ int wolfBoot_load_pubkey(const uint8_t* pubkey_hint, WOLFTPM2_KEY* pubKey, &e, &eSz /* exponent */ ); } + if (rc == 0) { + if (eSz == 0 || eSz > sizeof(exponent)) + rc = -1; + } + if (rc == 0) { + for (j = 0; j < eSz; j++) { + exponent = (exponent << 8) | e[j]; + } + } if (rc == 0) { /* Load public key into TPM */ rc = wolfTPM2_LoadRsaPublicKey_ex(&wolftpm_dev, pubKey, - n, nSz, *((uint32_t*)e), + n, nSz, exponent, TPM_ALG_NULL, WOLFBOOT_TPM_HASH_ALG); } #else diff --git a/tools/unit-tests/Makefile b/tools/unit-tests/Makefile index 4fe9f553..5f72ed7d 100644 --- a/tools/unit-tests/Makefile +++ b/tools/unit-tests/Makefile @@ -38,7 +38,7 @@ TESTS:=unit-parser unit-extflash unit-string unit-spi-flash unit-aes128 \ unit-image unit-image-rsa unit-nvm unit-nvm-flagshome unit-enc-nvm \ unit-enc-nvm-flagshome unit-delta unit-update-flash \ unit-update-flash-enc unit-update-ram unit-pkcs11_store unit-psa_store unit-disk \ - unit-multiboot unit-boot-x86-fsp unit-qspi-flash + unit-multiboot unit-boot-x86-fsp unit-qspi-flash unit-tpm-rsa-exp all: $(TESTS) @@ -109,6 +109,11 @@ unit-spi-flash: ../../include/target.h unit-spi-flash.c unit-qspi-flash: ../../include/target.h unit-qspi-flash.c gcc -o $@ $^ $(CFLAGS) $(LDFLAGS) +unit-tpm-rsa-exp: ../../include/target.h unit-tpm-rsa-exp.c + gcc -o $@ $^ $(CFLAGS) -I../../lib/wolfTPM -DWOLFBOOT_TPM \ + -DWOLFBOOT_TPM_VERIFY -DWOLFBOOT_SIGN_RSA2048 -DWOLFBOOT_HASH_SHA256 \ + -ffunction-sections -fdata-sections $(LDFLAGS) -Wl,--gc-sections + unit-string: ../../include/target.h unit-string.c gcc -o $@ $^ $(CFLAGS) -DDEBUG_UART -DPRINTF_ENABLED $(LDFLAGS) diff --git a/tools/unit-tests/unit-tpm-rsa-exp.c b/tools/unit-tests/unit-tpm-rsa-exp.c new file mode 100644 index 00000000..18b21d70 --- /dev/null +++ b/tools/unit-tests/unit-tpm-rsa-exp.c @@ -0,0 +1,133 @@ +/* unit-tpm-rsa-exp.c + * + * Unit tests for TPM RSA public-key loading. + */ + +#include +#include +#include + +#ifndef SPI_CS_TPM +#define SPI_CS_TPM 1 +#endif +#ifndef WOLFBOOT_SHA_DIGEST_SIZE +#define WOLFBOOT_SHA_DIGEST_SIZE 32 +#endif +#ifndef WOLFBOOT_TPM_HASH_ALG +#define WOLFBOOT_TPM_HASH_ALG TPM_ALG_SHA256 +#endif + +#include "wolfboot/wolfboot.h" +#include "keystore.h" +#include "tpm.h" + +static uint8_t test_hdr[16]; +static uint8_t test_modulus[256]; +static uint8_t test_exponent_der[] = { 0xAA, 0x01, 0x00, 0x01, 0x7B }; +static uint32_t captured_exponent; + +int keyslot_id_by_sha(const uint8_t* pubkey_hint) +{ + (void)pubkey_hint; + return 0; +} + +uint32_t keystore_get_key_type(int id) +{ + ck_assert_int_eq(id, 0); + return AUTH_KEY_RSA2048; +} + +uint8_t *keystore_get_buffer(int id) +{ + ck_assert_int_eq(id, 0); + return test_hdr; +} + +int keystore_get_size(int id) +{ + ck_assert_int_eq(id, 0); + return (int)sizeof(test_hdr); +} + +int wc_RsaPublicKeyDecode_ex(const byte* input, word32* inOutIdx, word32 inSz, + const byte** n, word32* nSz, const byte** e, word32* eSz) +{ + (void)input; + (void)inSz; + + *inOutIdx = 0; + *n = test_modulus; + *nSz = sizeof(test_modulus); + *e = &test_exponent_der[1]; + *eSz = 3; + return 0; +} + +int wolfTPM2_LoadRsaPublicKey_ex(WOLFTPM2_DEV* dev, WOLFTPM2_KEY* key, + const byte* rsaPub, word32 rsaPubSz, word32 exponent, + TPM_ALG_ID scheme, TPMI_ALG_HASH hashAlg) +{ + (void)dev; + (void)key; + (void)rsaPub; + (void)rsaPubSz; + (void)scheme; + (void)hashAlg; + + captured_exponent = exponent; + return 0; +} + +#include "../../src/tpm.c" + +static void setup(void) +{ + memset(test_hdr, 0x42, sizeof(test_hdr)); + memset(test_modulus, 0x5A, sizeof(test_modulus)); + captured_exponent = 0; +} + +START_TEST(test_wolfBoot_load_pubkey_decodes_der_exponent_bytes) +{ + 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)); + + rc = wolfBoot_load_pubkey(hint, &key, &alg); + + ck_assert_int_eq(rc, 0); + ck_assert_int_eq(alg, TPM_ALG_RSA); + ck_assert_uint_eq(captured_exponent, 65537U); +} +END_TEST + +static Suite *tpm_suite(void) +{ + Suite *s; + TCase *tc; + + s = suite_create("TPM RSA"); + 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); + suite_add_tcase(s, tc); + return s; +} + +int main(void) +{ + Suite *s; + SRunner *sr; + int failed; + + s = tpm_suite(); + sr = srunner_create(s); + srunner_run_all(sr, CK_NORMAL); + failed = srunner_ntests_failed(sr); + srunner_free(sr); + return failed == 0 ? 0 : 1; +}