From 70aa3dc5b18b23f5502d8e3aa45deed16ac204bd Mon Sep 17 00:00:00 2001 From: Daniel Pouzzner Date: Fri, 20 Feb 2026 11:08:11 -0600 Subject: [PATCH] 20260204-linuxkm-fips-hash: more fixes+improvements from peer and AI review: linuxkm/linuxkm_memory.c: * fix straddle check in wc_reloc_normalize_text(); * fix seg_map bounds checks in wc_fips_generate_hash(); linuxkm/linuxkm_memory.h: fix initializer for wc_reloc_table_segments.bss_end; wolfssl/wolfcrypt/settings.h: add WC_BITS_TO_BYTES() and WC_BITS_FULL_BYTES() and deploy opportunistically to wolfssl/internal.h, wolfssl/wolfcrypt/{asn.h,dh.h,rsa.h,types.h}, wolfcrypt/src/sakke.c, and wolfcrypt/test/test.c. --- linuxkm/linuxkm_memory.c | 47 +++++++++++++++++++++++------------- linuxkm/linuxkm_memory.h | 4 +-- wolfcrypt/src/sakke.c | 8 +++--- wolfcrypt/test/test.c | 10 ++++---- wolfssl/internal.h | 2 +- wolfssl/wolfcrypt/asn.h | 2 +- wolfssl/wolfcrypt/dh.h | 2 +- wolfssl/wolfcrypt/rsa.h | 2 +- wolfssl/wolfcrypt/settings.h | 5 +++- wolfssl/wolfcrypt/types.h | 2 +- 10 files changed, 50 insertions(+), 34 deletions(-) diff --git a/linuxkm/linuxkm_memory.c b/linuxkm/linuxkm_memory.c index 2e16f19cca..ecda60f590 100644 --- a/linuxkm/linuxkm_memory.c +++ b/linuxkm/linuxkm_memory.c @@ -237,7 +237,9 @@ ssize_t wc_reloc_normalize_text( break; } - if (next_reloc_rel > text_in_len - layout->width) { + if ((text_in_len < WC_BITS_TO_BYTES(layout->width)) || + (next_reloc_rel > text_in_len - WC_BITS_TO_BYTES(layout->width))) + { /* relocation straddles buffer at end -- caller will try again with * that relocation at the start. */ @@ -586,29 +588,40 @@ int wc_fips_generate_hash( return BAD_FUNC_ARG; } - if (seg_map->end > 0) { + if (seg_map->start > 0) { if ((seg_map->fips_text_start < seg_map->start) || - (seg_map->fips_text_end >= seg_map->end) || (seg_map->fips_rodata_start < seg_map->start) || + (seg_map->verifyCore_start < seg_map->start) +#if defined(WC_SYM_RELOC_TABLES) || defined(WC_SYM_RELOC_TABLES_SUPPORT) + || + (seg_map->reloc_tab_start < seg_map->start) || + (seg_map->reloc_tab_len_start < seg_map->start) || + (seg_map->text_start < seg_map->start) || + (seg_map->rodata_start < seg_map->start) || + (seg_map->data_start < seg_map->start) || + (seg_map->bss_start < seg_map->start) +#endif + ) + { + RELOC_DEBUG_PRINTF("assert failed.\n"); + return BUFFER_E; + } + } + + if (seg_map->end > 0) { + if ((seg_map->fips_text_end > seg_map->end) || (seg_map->fips_rodata_end > seg_map->end) || - (seg_map->verifyCore_start < seg_map->start) || - (seg_map->verifyCore_end >= seg_map->end) + (seg_map->verifyCore_end > seg_map->end) #if defined(WC_SYM_RELOC_TABLES) || defined(WC_SYM_RELOC_TABLES_SUPPORT) || ((seg_map->reloc_tab_end != 0) && - ((seg_map->reloc_tab_start < seg_map->start) || - (seg_map->reloc_tab_end >= seg_map->end))) || + (seg_map->reloc_tab_end > seg_map->end)) || ((seg_map->reloc_tab_len_end != 0) && - ((seg_map->reloc_tab_len_start < seg_map->start) || - (seg_map->reloc_tab_len_end >= seg_map->end))) || - (seg_map->text_start < seg_map->start) || - (seg_map->text_end >= seg_map->end) || - (seg_map->rodata_start < seg_map->start) || - (seg_map->rodata_end >= seg_map->end) || - (seg_map->data_start < seg_map->start) || - (seg_map->data_end >= seg_map->end) || - (seg_map->bss_start < seg_map->start) || - (seg_map->bss_end >= seg_map->end) + (seg_map->reloc_tab_len_end > seg_map->end)) || + (seg_map->text_end > seg_map->end) || + (seg_map->rodata_end > seg_map->end) || + (seg_map->data_end > seg_map->end) || + (seg_map->bss_end > seg_map->end) #endif ) { diff --git a/linuxkm/linuxkm_memory.h b/linuxkm/linuxkm_memory.h index 054b454e7c..011b2ee457 100644 --- a/linuxkm/linuxkm_memory.h +++ b/linuxkm/linuxkm_memory.h @@ -130,7 +130,7 @@ struct wc_reloc_table_segments { .data_start = ~0UL, \ .data_end = ~0UL, \ .bss_start = ~0UL, \ - .bss_end = 0, \ + .bss_end = ~0UL, \ .text_is_live = 0 \ } @@ -150,7 +150,7 @@ struct wc_reloc_table_segments { .data_start = ~0UL, \ .data_end = ~0UL, \ .bss_start = ~0UL, \ - .bss_end = 0, \ + .bss_end = ~0UL, \ .text_is_live = 0 \ } diff --git a/wolfcrypt/src/sakke.c b/wolfcrypt/src/sakke.c index 8797764615..e59943506b 100644 --- a/wolfcrypt/src/sakke.c +++ b/wolfcrypt/src/sakke.c @@ -2510,7 +2510,7 @@ int wc_GetSakkeAuthSize(SakkeKey* key, word16* authSz) err = sakke_load_params(key); } if (err == 0) { - word16 n = (word16)((mp_count_bits(&key->params.prime) + 7) / 8); + word16 n = (word16)WC_BITS_TO_BYTES(mp_count_bits(&key->params.prime)); *authSz = (word16)(1 + 2 * n); } @@ -6709,7 +6709,7 @@ int wc_MakeSakkeEncapsulatedSSV(SakkeKey* key, enum wc_HashType hashType, err = sakke_load_params(key); } if (err == 0) { - n = (word16)((mp_count_bits(&key->params.prime) + 7) / 8); + n = (word16)WC_BITS_TO_BYTES(mp_count_bits(&key->params.prime)); /* Uncompressed point */ outSz = (word16)(1 + 2 * n); @@ -6807,7 +6807,7 @@ int wc_GenerateSakkeSSV(SakkeKey* key, WC_RNG* rng, byte* ssv, word16* ssvSz) err = sakke_load_params(key); } if (err == 0) { - n = (word16)((mp_count_bits(&key->params.prime) + 7) / 8); + n = (word16)WC_BITS_TO_BYTES(mp_count_bits(&key->params.prime)); if ((ssv != NULL) && (*ssvSz > n)) { err = BAD_FUNC_ARG; @@ -6886,7 +6886,7 @@ int wc_DeriveSakkeSSV(SakkeKey* key, enum wc_HashType hashType, byte* ssv, err = sakke_load_params(key); } if (err == 0) { - n = (word16)((mp_count_bits(&key->params.prime) + 7) / 8); + n = (word16)WC_BITS_TO_BYTES(mp_count_bits(&key->params.prime)); if (authSz != 2 * n + 1) { err = BAD_FUNC_ARG; diff --git a/wolfcrypt/test/test.c b/wolfcrypt/test/test.c index fa49d76bca..a98e826af2 100644 --- a/wolfcrypt/test/test.c +++ b/wolfcrypt/test/test.c @@ -60083,7 +60083,7 @@ static wc_test_ret_t mp_test_shbd(mp_int* a, mp_int* b, WC_RNG* rng) #ifndef WOLFSSL_SP_MATH for (i = 0; i < 10; i++) { - for (j = 1; j < (DIGIT_BIT + 7) / 8 * 3; j++) { + for (j = 1; j < WC_BITS_TO_BYTES(DIGIT_BIT) * 3; j++) { ret = randNum(a, j, rng, NULL); if (ret != MP_OKAY) return WC_TEST_RET_ENC_EC(ret); @@ -60104,7 +60104,7 @@ static wc_test_ret_t mp_test_shbd(mp_int* a, mp_int* b, WC_RNG* rng) #endif for (i = 0; i < 10; i++) { - for (j = 1; j < (DIGIT_BIT + 7) / 8 * 3; j++) { + for (j = 1; j < WC_BITS_TO_BYTES(DIGIT_BIT) * 3; j++) { ret = randNum(a, j, rng, NULL); if (ret != MP_OKAY) return WC_TEST_RET_ENC_EC(ret); @@ -60182,11 +60182,11 @@ static wc_test_ret_t mp_test_div(mp_int* a, mp_int* d, mp_int* r, mp_int* rem, return WC_TEST_RET_ENC_EC(ret); for (i = 0; i < 100; i++) { - for (j = 1; j < (DIGIT_BIT + 7) / 8 * 2; j++) { + for (j = 1; j < WC_BITS_TO_BYTES(DIGIT_BIT) * 2; j++) { ret = randNum(d, j, rng, NULL); if (ret != MP_OKAY) return WC_TEST_RET_ENC_EC(ret); - for (k = 1; k < (DIGIT_BIT + 7) / 8 * 2 + 1; k++) { + for (k = 1; k < WC_BITS_TO_BYTES(DIGIT_BIT) * 2 + 1; k++) { ret = randNum(a, k, rng, NULL); if (ret != MP_OKAY) return WC_TEST_RET_ENC_EC(ret); @@ -60210,7 +60210,7 @@ static wc_test_ret_t mp_test_div(mp_int* a, mp_int* d, mp_int* r, mp_int* rem, } } - ret = randNum(d, (DIGIT_BIT + 7) / 8 * 2, rng, NULL); + ret = randNum(d, WC_BITS_TO_BYTES(DIGIT_BIT) * 2, rng, NULL); if (ret != MP_OKAY) return WC_TEST_RET_ENC_EC(ret); mp_add(d, d, a); diff --git a/wolfssl/internal.h b/wolfssl/internal.h index 294c69be41..7ebe3d7b6c 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -1260,7 +1260,7 @@ enum { #elif (defined(WOLFSSL_SP_MATH_ALL) || defined(WOLFSSL_SP_MATH)) && \ defined(SP_INT_BITS) /* SP implementation supports numbers of SP_INT_BITS bits. */ - #define WOLFSSL_MAX_DHKEY_BITS (((SP_INT_BITS + 7) / 8) * 8) + #define WOLFSSL_MAX_DHKEY_BITS WC_BITS_FULL_BYTES(SP_INT_BITS) #else #define WOLFSSL_MAX_DHKEY_BITS 4096 #endif diff --git a/wolfssl/wolfcrypt/asn.h b/wolfssl/wolfcrypt/asn.h index 4af6481205..69e8f04bae 100644 --- a/wolfssl/wolfcrypt/asn.h +++ b/wolfssl/wolfcrypt/asn.h @@ -855,7 +855,7 @@ extern const WOLFSSL_ObjectInfo wolfssl_object_info[]; #define WC_MAX_RSA_BITS (FP_MAX_BITS / 2) #elif defined(WOLFSSL_SP_MATH_ALL) || defined(WOLFSSL_SP_MATH) /* SP implementation supports numbers of SP_INT_BITS bits. */ - #define WC_MAX_RSA_BITS (((SP_INT_BITS + 7) / 8) * 8) + #define WC_MAX_RSA_BITS WC_BITS_FULL_BYTES(SP_INT_BITS) #else /* Integer maths is dynamic but we only go up to 4096 bits. */ #define WC_MAX_RSA_BITS 4096 diff --git a/wolfssl/wolfcrypt/dh.h b/wolfssl/wolfcrypt/dh.h index 31ec83ecf5..f61025d36d 100644 --- a/wolfssl/wolfcrypt/dh.h +++ b/wolfssl/wolfcrypt/dh.h @@ -104,7 +104,7 @@ enum { #endif #elif defined(WOLFSSL_SP_MATH_ALL) || defined(WOLFSSL_SP_MATH) /* SP implementation supports numbers of SP_INT_BITS bits. */ - #define DH_MAX_SIZE (((SP_INT_BITS + 7) / 8) * 8) + #define DH_MAX_SIZE WC_BITS_FULL_BYTES(SP_INT_BITS) #if defined(WOLFSSL_MYSQL_COMPATIBLE) && DH_MAX_SIZE < 8192 #error "MySQL needs SP_INT_BITS at least at 8192" #endif diff --git a/wolfssl/wolfcrypt/rsa.h b/wolfssl/wolfcrypt/rsa.h index 19f963a181..77911fc954 100644 --- a/wolfssl/wolfcrypt/rsa.h +++ b/wolfssl/wolfcrypt/rsa.h @@ -119,7 +119,7 @@ RSA keys can be used to encrypt, decrypt, sign and verify data. #endif #elif defined(WOLFSSL_SP_MATH_ALL) || defined(WOLFSSL_SP_MATH) /* SP implementation supports numbers of SP_INT_BITS bits. */ - #define RSA_MAX_SIZE (((SP_INT_BITS + 7) / 8) * 8) + #define RSA_MAX_SIZE WC_BITS_FULL_BYTES(SP_INT_BITS) #if defined(WOLFSSL_MYSQL_COMPATIBLE) && RSA_MAX_SIZE < 8192 #error "MySQL needs SP_INT_BITS at least at 8192" #endif diff --git a/wolfssl/wolfcrypt/settings.h b/wolfssl/wolfcrypt/settings.h index f5186c802e..503fade1d9 100644 --- a/wolfssl/wolfcrypt/settings.h +++ b/wolfssl/wolfcrypt/settings.h @@ -63,6 +63,9 @@ #include #endif +#define WC_BITS_TO_BYTES(x) (((x) + 7) >> 3) +#define WC_BITS_FULL_BYTES(x) (WC_BITS_TO_BYTES(x) << 3) + /* Uncomment next line if using IPHONE */ /* #define IPHONE */ @@ -4391,7 +4394,7 @@ extern void uITRON4_free(void *p) ; #endif #elif defined(WOLFSSL_SP_MATH_ALL) || defined(WOLFSSL_SP_MATH) /* SP implementation supports numbers of SP_INT_BITS bits. */ - #define DH_MAX_SIZE (((SP_INT_BITS + 7) / 8) * 8) + #define DH_MAX_SIZE WC_BITS_FULL_BYTES(SP_INT_BITS) #if defined(WOLFSSL_MYSQL_COMPATIBLE) && DH_MAX_SIZE < 8192 #error "MySQL needs SP_INT_BITS at least at 8192" #endif diff --git a/wolfssl/wolfcrypt/types.h b/wolfssl/wolfcrypt/types.h index c0cd8bd847..28bb12fc17 100644 --- a/wolfssl/wolfcrypt/types.h +++ b/wolfssl/wolfcrypt/types.h @@ -2300,7 +2300,7 @@ enum Max_ASN { MAX_ENCODED_SIG_SZ = FP_MAX_BITS / 8, #elif (defined(WOLFSSL_SP_MATH_ALL) || defined(WOLFSSL_SP_MATH)) && \ defined(SP_INT_BITS) - MAX_ENCODED_SIG_SZ = (SP_INT_BITS + 7) / 8, + MAX_ENCODED_SIG_SZ = WC_BITS_TO_BYTES(SP_INT_BITS), #elif defined(WOLFSSL_HAPROXY) MAX_ENCODED_SIG_SZ = 1024, /* Supports 8192 bit keys */ #else