5858/* Globals */
5959static uint8_t digest [WOLFBOOT_SHA_DIGEST_SIZE ] XALIGNED (4 );
6060
61+ static int image_CT_compare (const uint8_t * expected , const uint8_t * actual ,
62+ uint32_t len )
63+ {
64+ uint8_t diff = 0 ;
65+ uint32_t i ;
66+
67+ for (i = 0 ; i < len ; i ++ ) {
68+ diff |= expected [i ] ^ actual [i ];
69+ }
70+
71+ return diff == 0 ;
72+ }
73+
6174#if defined(WOLFBOOT_CERT_CHAIN_VERIFY ) && \
6275 (defined(WOLFBOOT_ENABLE_WOLFHSM_CLIENT ) || \
6376 defined(WOLFBOOT_ENABLE_WOLFHSM_SERVER ))
@@ -367,6 +380,9 @@ static void wolfBoot_verify_signature_ecc(uint8_t key_slot,
367380static inline int DecodeAsn1Tag (const uint8_t * input , int inputSz , int * inOutIdx ,
368381 int * tag_len , uint8_t tag )
369382{
383+ if (* inOutIdx < 0 || * inOutIdx >= inputSz || (* inOutIdx + 1 ) >= inputSz ) {
384+ return -1 ;
385+ }
370386 if (input [* inOutIdx ] != tag ) {
371387 return -1 ;
372388 }
@@ -1492,6 +1508,12 @@ int wolfBoot_open_self_address(struct wolfBoot_image* img, uint8_t* hdr,
14921508
14931509 img -> hdr = hdr ;
14941510 img -> fw_size = wolfBoot_image_size (hdr );
1511+ #ifdef WOLFBOOT_FIXED_PARTITIONS
1512+ if (img -> fw_size > (WOLFBOOT_PARTITION_SIZE - IMAGE_HEADER_SIZE )) {
1513+ img -> fw_size = WOLFBOOT_PARTITION_SIZE - IMAGE_HEADER_SIZE ;
1514+ return -1 ;
1515+ }
1516+ #endif
14951517 img -> fw_base = image ;
14961518 img -> part = PART_SELF ;
14971519 img -> hdr_ok = 1 ;
@@ -1518,7 +1540,7 @@ int wolfBoot_verify_integrity(struct wolfBoot_image *img)
15181540 return -1 ;
15191541 if (image_hash (img , digest ) != 0 )
15201542 return -1 ;
1521- if (memcmp (digest , stored_sha , stored_sha_len ) != 0 )
1543+ if (! image_CT_compare (digest , stored_sha , stored_sha_len ))
15221544 return -1 ;
15231545 img -> sha_ok = 1 ;
15241546 img -> sha_hash = stored_sha ;
@@ -2366,6 +2388,21 @@ uint8_t* wolfBoot_peek_image(struct wolfBoot_image *img, uint32_t offset,
23662388
23672389#if !defined(WOLFBOOT_NO_SIGN ) && !defined(WOLFBOOT_RENESAS_SCEPROTECT )
23682390
2391+ /* Compare fixed-size key hints without early exit to avoid leaking hash prefix
2392+ * matches through lookup timing. */
2393+ static int keyslot_CT_hint_matches (const uint8_t * expected ,
2394+ const uint8_t * actual )
2395+ {
2396+ uint8_t diff = 0 ;
2397+ uint32_t i ;
2398+
2399+ for (i = 0 ; i < WOLFBOOT_SHA_DIGEST_SIZE ; i ++ ) {
2400+ diff |= expected [i ] ^ actual [i ];
2401+ }
2402+
2403+ return diff == 0 ;
2404+ }
2405+
23692406/**
23702407 * @brief Get the key slot ID by SHA hash.
23712408 *
@@ -2378,13 +2415,14 @@ uint8_t* wolfBoot_peek_image(struct wolfBoot_image *img, uint32_t offset,
23782415int keyslot_id_by_sha (const uint8_t * hint )
23792416{
23802417 int id ;
2418+ int match_id = -1 ;
23812419
23822420 for (id = 0 ; id < keystore_num_pubkeys (); id ++ ) {
23832421 key_hash (id , digest );
2384- if (memcmp ( digest , hint , WOLFBOOT_SHA_DIGEST_SIZE ) == 0 ) {
2385- return id ;
2422+ if (( match_id < 0 ) && keyslot_CT_hint_matches ( digest , hint ) ) {
2423+ match_id = id ;
23862424 }
23872425 }
2388- return -1 ;
2426+ return match_id ;
23892427}
23902428#endif /* !WOLFBOOT_NO_SIGN && !WOLFBOOT_RENESAS_SCEPROTECT */
0 commit comments