Fix fTPM NSC bounds handling

pull/756/head
Daniele Lacamera 2026-04-22 12:22:43 +02:00
parent 884352cf08
commit b26d38ed41
4 changed files with 120 additions and 14 deletions

View File

@ -117,28 +117,37 @@ void wcs_ftpm_init(void)
int CSME_NSE_API wcs_ftpm_transmit(const uint8_t *cmd, uint32_t cmdSz,
uint8_t *rsp, uint32_t *rspSz)
{
int rc;
int rspLen;
uint32_t rspCapacity;
uint32_t wireSz;
if (!ftpm_ready) {
return TPM_RC_INITIALIZE;
}
if (cmd == NULL || rsp == NULL || rspSz == NULL || cmdSz == 0U ||
cmdSz > WCS_FTPM_MAX_COMMAND_SIZE || *rspSz == 0U ||
*rspSz > WCS_FTPM_MAX_COMMAND_SIZE) {
cmdSz > WCS_FTPM_MAX_COMMAND_SIZE) {
return BAD_FUNC_ARG;
}
rspLen = (int)*rspSz;
int rc = FWTPM_ProcessCommand(&ftpm_ctx, cmd, (int)cmdSz, rsp, &rspLen, 0);
if (rc >= 0) {
uint32_t wireSz = ftpm_rsp_size(rsp, rspLen);
if (wireSz > 0U && wireSz <= *rspSz) {
rspCapacity = *rspSz;
if (rspCapacity == 0U || rspCapacity > WCS_FTPM_MAX_COMMAND_SIZE) {
return BAD_FUNC_ARG;
}
rspLen = (int)rspCapacity;
rc = FWTPM_ProcessCommand(&ftpm_ctx, cmd, (int)cmdSz, rsp, &rspLen, 0);
if (rc == TPM_RC_SUCCESS) {
wireSz = ftpm_rsp_size(rsp, rspLen);
if (wireSz > 0U && wireSz <= rspCapacity) {
*rspSz = wireSz;
rc = TPM_RC_SUCCESS;
}
else if (rspLen >= 0) {
else if (rspLen >= 0 && (uint32_t)rspLen <= rspCapacity) {
*rspSz = (uint32_t)rspLen;
}
else {
rc = TPM_RC_FAILURE;
}
}
return rc;
}

View File

@ -50,9 +50,15 @@ static struct ftpm_tis_state ftpm_tis = {
FTPM_STS_VALID | FTPM_STS_COMMAND_READY
};
static uint32_t ftpm_reg_offset(uint32_t addr)
static int ftpm_reg_offset(uint32_t addr, uint32_t *off)
{
return (addr - FTPM_TIS_BASE) & 0x0FFFU;
if (off == NULL || addr < FTPM_TIS_BASE ||
addr >= (FTPM_TIS_BASE + 0x1000U)) {
return BAD_FUNC_ARG;
}
*off = addr - FTPM_TIS_BASE;
return TPM_RC_SUCCESS;
}
static void ftpm_store_le(uint8_t *buf, uint16_t size, uint32_t val)
@ -107,11 +113,14 @@ int TPM2_IoCb_FtpmNsc(TPM2_CTX *ctx, INT32 isRead, UINT32 addr,
(void)ctx;
(void)userCtx;
if (buf == NULL || size == 0U || addr < FTPM_TIS_BASE) {
if (buf == NULL || size == 0U) {
return BAD_FUNC_ARG;
}
if (ftpm_reg_offset(addr, &off) != TPM_RC_SUCCESS) {
return BAD_FUNC_ARG;
}
off = ftpm_reg_offset(addr);
burst = FTPM_BURST_COUNT;
if (isRead) {

View File

@ -50,7 +50,7 @@ TESTS:=unit-parser unit-fdt unit-extflash unit-string unit-spi-flash unit-aes128
unit-enc-nvm-flagshome unit-delta unit-update-flash unit-update-flash-delta \
unit-update-flash-self-update \
unit-update-flash-enc unit-update-ram unit-update-ram-nofixed unit-pkcs11_store unit-psa_store unit-disk \
unit-update-disk unit-multiboot unit-boot-x86-fsp unit-loader-tpm-init unit-qspi-flash unit-tpm-rsa-exp \
unit-update-disk unit-multiboot unit-boot-x86-fsp unit-loader-tpm-init unit-qspi-flash unit-ftpm-stub unit-tpm-rsa-exp \
unit-image-nopart unit-image-sha384 unit-image-sha3-384 unit-store-sbrk \
unit-tpm-blob unit-policy-create unit-policy-sign unit-rot-auth unit-sdhci-response-bits \
unit-sdhci-disk-unaligned unit-sign-encrypted-output
@ -168,6 +168,11 @@ unit-tpm-check-rot-auth: ../../include/target.h unit-tpm-check-rot-auth.c ../../
-DWOLFBOOT_HASH_SHA256 \
-ffunction-sections -fdata-sections $(LDFLAGS) -Wl,--gc-sections
unit-ftpm-stub: ../../include/target.h unit-ftpm-stub.c
gcc -o $@ $^ $(CFLAGS) -I$(WOLFBOOT_LIB_WOLFTPM) \
-DWOLFTPM_USER_SETTINGS -ffunction-sections -fdata-sections \
$(LDFLAGS) -Wl,--gc-sections
unit-tpm-blob: ../../include/target.h unit-tpm-blob.c
gcc -o $@ $^ $(CFLAGS) -I$(WOLFBOOT_LIB_WOLFTPM) -DWOLFBOOT_TPM \
-DWOLFTPM_USER_SETTINGS -DWOLFBOOT_TPM_SEAL -DWOLFBOOT_SIGN_RSA2048 \

View File

@ -0,0 +1,83 @@
/* unit-ftpm-stub.c
*
* Unit tests for the fTPM non-secure TIS callback shim.
*/
#include <check.h>
#include <stdint.h>
#define WOLFBOOT_TZ_FTPM
int wcs_ftpm_transmit(const uint8_t *cmd, uint32_t cmdSz, uint8_t *rsp,
uint32_t *rspSz)
{
(void)cmd;
(void)cmdSz;
(void)rsp;
(void)rspSz;
return -1;
}
#include "../../test-app/wcs/ftpm_stub.c"
START_TEST(ftpm_tis_rejects_address_below_window)
{
BYTE buf[4] = {0};
ck_assert_int_eq(TPM2_IoCb_FtpmNsc(NULL, 1, FTPM_TIS_BASE - 1U,
buf, sizeof(buf), NULL), BAD_FUNC_ARG);
}
END_TEST
START_TEST(ftpm_tis_rejects_address_above_window)
{
BYTE buf[4] = {0};
ck_assert_int_eq(TPM2_IoCb_FtpmNsc(NULL, 1, FTPM_TIS_BASE + 0x1000U,
buf, sizeof(buf), NULL), BAD_FUNC_ARG);
}
END_TEST
START_TEST(ftpm_tis_accepts_valid_window_register)
{
BYTE buf[4] = {0};
ck_assert_int_eq(TPM2_IoCb_FtpmNsc(NULL, 1,
FTPM_TIS_BASE + FTPM_TIS_DID_VID, buf, sizeof(buf), NULL),
TPM_RC_SUCCESS);
ck_assert_uint_eq(buf[0], 0x4EU);
ck_assert_uint_eq(buf[1], 0x1BU);
ck_assert_uint_eq(buf[2], 0x01U);
ck_assert_uint_eq(buf[3], 0x00U);
}
END_TEST
static Suite *ftpm_stub_suite(void)
{
Suite *s;
TCase *tc;
s = suite_create("ftpm_stub");
tc = tcase_create("tis_window");
tcase_add_test(tc, ftpm_tis_rejects_address_below_window);
tcase_add_test(tc, ftpm_tis_rejects_address_above_window);
tcase_add_test(tc, ftpm_tis_accepts_valid_window_register);
suite_add_tcase(s, tc);
return s;
}
int main(void)
{
int fails;
Suite *s;
SRunner *sr;
s = ftpm_stub_suite();
sr = srunner_create(s);
srunner_run_all(sr, CK_NORMAL);
fails = srunner_ntests_failed(sr);
srunner_free(sr);
return fails == 0 ? 0 : 1;
}