Skip to content

Commit c544365

Browse files
committed
TPM: RoT comparison made Constant time
F/448
1 parent 120b284 commit c544365

2 files changed

Lines changed: 105 additions & 1 deletion

File tree

src/tpm.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
#include "spi_drv.h"
3333
#include "tpm.h"
3434
#include "wolftpm/tpm2_tis.h" /* for TIS header size and wait state */
35+
#include <wolfssl/wolfcrypt/misc.h>
3536

3637
WOLFTPM2_DEV wolftpm_dev;
3738
#if defined(WOLFBOOT_TPM_KEYSTORE) || defined(WOLFBOOT_TPM_SEAL)
@@ -1515,7 +1516,8 @@ int wolfBoot_check_rot(int key_slot, uint8_t* pubkey_hint)
15151516
if (rc == 0) {
15161517
/* verify the hint (hash) matches */
15171518
if (digestSz == WOLFBOOT_SHA_DIGEST_SIZE &&
1518-
memcmp(digest, pubkey_hint, WOLFBOOT_SHA_DIGEST_SIZE) == 0) {
1519+
ConstantCompare(digest, pubkey_hint,
1520+
WOLFBOOT_SHA_DIGEST_SIZE) == 0) {
15191521
wolfBoot_printf("TPM Root of Trust valid (id %d)\n", key_slot);
15201522
}
15211523
else {

tools/unit-tests/unit-tpm-rsa-exp.c

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
#include <check.h>
77
#include <stdint.h>
8+
#include <stdio.h>
89
#include <string.h>
910

1011
#ifndef SPI_CS_TPM
@@ -16,6 +17,7 @@
1617
#ifndef WOLFBOOT_TPM_HASH_ALG
1718
#define WOLFBOOT_TPM_HASH_ALG TPM_ALG_SHA256
1819
#endif
20+
#define WOLFBOOT_TPM_KEYSTORE
1921

2022
#include "wolfboot/wolfboot.h"
2123
#include "keystore.h"
@@ -24,7 +26,9 @@
2426
static uint8_t test_hdr[16];
2527
static uint8_t test_modulus[256];
2628
static uint8_t test_exponent_der[] = { 0xAA, 0x01, 0x00, 0x01, 0x7B };
29+
static uint8_t test_nv_digest[WOLFBOOT_SHA_DIGEST_SIZE];
2730
static uint32_t captured_exponent;
31+
static int forbidden_memcmp_calls;
2832

2933
int keyslot_id_by_sha(const uint8_t* pubkey_hint)
3034
{
@@ -79,13 +83,96 @@ int wolfTPM2_LoadRsaPublicKey_ex(WOLFTPM2_DEV* dev, WOLFTPM2_KEY* key,
7983
return 0;
8084
}
8185

86+
int wolfTPM2_SetAuthHandle(WOLFTPM2_DEV* dev, int index,
87+
const WOLFTPM2_HANDLE* handle)
88+
{
89+
(void)dev;
90+
(void)index;
91+
(void)handle;
92+
return 0;
93+
}
94+
95+
int wolfTPM2_SetAuthSession(WOLFTPM2_DEV* dev, int index,
96+
WOLFTPM2_SESSION* tpmSession, TPMA_SESSION sessionAttributes)
97+
{
98+
(void)dev;
99+
(void)index;
100+
(void)tpmSession;
101+
(void)sessionAttributes;
102+
return 0;
103+
}
104+
105+
int wolfTPM2_UnsetAuth(WOLFTPM2_DEV* dev, int index)
106+
{
107+
(void)dev;
108+
(void)index;
109+
return 0;
110+
}
111+
112+
int wolfTPM2_UnsetAuthSession(WOLFTPM2_DEV* dev, int index,
113+
WOLFTPM2_SESSION* tpmSession)
114+
{
115+
(void)dev;
116+
(void)index;
117+
(void)tpmSession;
118+
return 0;
119+
}
120+
121+
int wolfTPM2_NVReadAuth(WOLFTPM2_DEV* dev, WOLFTPM2_NV* nv,
122+
word32 nvIndex, byte* dataBuf, word32* pDataSz, word32 offset)
123+
{
124+
(void)dev;
125+
(void)nv;
126+
(void)nvIndex;
127+
(void)offset;
128+
ck_assert_uint_eq(*pDataSz, WOLFBOOT_SHA_DIGEST_SIZE);
129+
memcpy(dataBuf, test_nv_digest, WOLFBOOT_SHA_DIGEST_SIZE);
130+
*pDataSz = WOLFBOOT_SHA_DIGEST_SIZE;
131+
return 0;
132+
}
133+
134+
const char* wolfTPM2_GetRCString(int rc)
135+
{
136+
(void)rc;
137+
return "mock";
138+
}
139+
140+
int ConstantCompare(const byte* a, const byte* b, int length)
141+
{
142+
int diff = 0;
143+
int i;
144+
145+
for (i = 0; i < length; i++) {
146+
diff |= a[i] ^ b[i];
147+
}
148+
return diff;
149+
}
150+
151+
static int forbidden_memcmp(const void *a, const void *b, size_t n)
152+
{
153+
const uint8_t *lhs = (const uint8_t *)a;
154+
const uint8_t *rhs = (const uint8_t *)b;
155+
size_t i;
156+
157+
forbidden_memcmp_calls++;
158+
for (i = 0; i < n; i++) {
159+
if (lhs[i] != rhs[i])
160+
return (int)lhs[i] - (int)rhs[i];
161+
}
162+
return 0;
163+
}
164+
165+
#define memcmp forbidden_memcmp
82166
#include "../../src/tpm.c"
167+
#undef memcmp
83168

84169
static void setup(void)
85170
{
86171
memset(test_hdr, 0x42, sizeof(test_hdr));
87172
memset(test_modulus, 0x5A, sizeof(test_modulus));
173+
memset(test_nv_digest, 0x7C, sizeof(test_nv_digest));
88174
captured_exponent = 0;
175+
forbidden_memcmp_calls = 0;
89176
}
90177

91178
START_TEST(test_wolfBoot_load_pubkey_decodes_der_exponent_bytes)
@@ -105,6 +192,20 @@ START_TEST(test_wolfBoot_load_pubkey_decodes_der_exponent_bytes)
105192
}
106193
END_TEST
107194

195+
START_TEST(test_wolfBoot_check_rot_avoids_memcmp_on_digest_compare)
196+
{
197+
uint8_t hint[WOLFBOOT_SHA_DIGEST_SIZE];
198+
int rc;
199+
200+
memcpy(hint, test_nv_digest, sizeof(hint));
201+
202+
rc = wolfBoot_check_rot(0, hint);
203+
204+
ck_assert_int_eq(rc, 0);
205+
ck_assert_int_eq(forbidden_memcmp_calls, 0);
206+
}
207+
END_TEST
208+
108209
static Suite *tpm_suite(void)
109210
{
110211
Suite *s;
@@ -114,6 +215,7 @@ static Suite *tpm_suite(void)
114215
tc = tcase_create("wolfBoot_load_pubkey");
115216
tcase_add_checked_fixture(tc, setup, NULL);
116217
tcase_add_test(tc, test_wolfBoot_load_pubkey_decodes_der_exponent_bytes);
218+
tcase_add_test(tc, test_wolfBoot_check_rot_avoids_memcmp_on_digest_compare);
117219
suite_add_tcase(s, tc);
118220
return s;
119221
}

0 commit comments

Comments
 (0)