From e3fd4cc24d100dde6b6c7247875e91e823b57e91 Mon Sep 17 00:00:00 2001 From: Hideki Miyazaki Date: Thu, 2 Apr 2026 09:50:34 +0900 Subject: [PATCH 1/3] fix f-1370 key_len size check for void* in wc_SignatureGetSize --- doc/dox_comments/header_files/signature.h | 65 ++++++++++++++++------- tests/api/test_signature.c | 14 +++++ tests/api/test_signature.h | 2 +- wolfcrypt/src/signature.c | 13 +++-- 4 files changed, 70 insertions(+), 24 deletions(-) diff --git a/doc/dox_comments/header_files/signature.h b/doc/dox_comments/header_files/signature.h index 5ab04f2cdff..3c4caf91d8f 100644 --- a/doc/dox_comments/header_files/signature.h +++ b/doc/dox_comments/header_files/signature.h @@ -4,13 +4,22 @@ \brief This function returns the maximum size of the resulting signature. \return Returns SIG_TYPE_E if sig_type is not supported. Returns - BAD_FUNC_ARG if sig_type was invalid. A positive return value indicates + BAD_FUNC_ARG if sig_type was invalid or key_len does not exactly match + the size of the expected key structure. A positive return value indicates the maximum size of a signature. \param sig_type A signature type enum value such as WC_SIGNATURE_TYPE_ECC or WC_SIGNATURE_TYPE_RSA. - \param key Pointer to a key structure such as ecc_key or RsaKey. - \param key_len Size of the key structure. + \param key Pointer to the key structure corresponding to sig_type: + pass an ecc_key* (cast to const void*) for + WC_SIGNATURE_TYPE_ECC, or a RsaKey* for + WC_SIGNATURE_TYPE_RSA / WC_SIGNATURE_TYPE_RSA_W_ENC. + The caller is responsible for ensuring the pointer refers to the correct + type; this function cannot verify the actual runtime type of the object. + \param key_len Must be exactly sizeof(ecc_key) or + sizeof(RsaKey) matching the sig_type. Passing any other value + causes the function to return BAD_FUNC_ARG without dereferencing key. + The conventional idiom is to pass sizeof(*key) at the call site. _Example_ \code @@ -43,16 +52,19 @@ int wc_SignatureGetSize(enum wc_SignatureType sig_type, \return BAD_FUNC_ARG -173, bad function argument provided \return BUFFER_E -132, output buffer too small or input too large. - \param hash_type A hash type from the “enum wc_HashType” such as - “WC_HASH_TYPE_SHA256”. + \param hash_type A hash type from the "enum wc_HashType" such as + "WC_HASH_TYPE_SHA256". \param sig_type A signature type enum value such as WC_SIGNATURE_TYPE_ECC or WC_SIGNATURE_TYPE_RSA. \param data Pointer to buffer containing the data to hash. \param data_len Length of the data buffer. \param sig Pointer to buffer to output signature. \param sig_len Length of the signature output buffer. - \param key Pointer to a key structure such as ecc_key or RsaKey. - \param key_len Size of the key structure. + \param key Pointer to the key structure corresponding to sig_type. + See wc_SignatureGetSize() for the type-safety constraints that apply + to this parameter. + \param key_len Must be exactly sizeof(ecc_key) or + sizeof(RsaKey) matching sig_type. See wc_SignatureGetSize(). _Example_ \code @@ -93,16 +105,19 @@ int wc_SignatureVerify( \return BAD_FUNC_ARG -173, bad function argument provided \return BUFFER_E -132, output buffer too small or input too large. - \param hash_type A hash type from the “enum wc_HashType” - such as “WC_HASH_TYPE_SHA256”. + \param hash_type A hash type from the "enum wc_HashType" + such as "WC_HASH_TYPE_SHA256". \param sig_type A signature type enum value such as WC_SIGNATURE_TYPE_ECC or WC_SIGNATURE_TYPE_RSA. \param data Pointer to buffer containing the data to hash. \param data_len Length of the data buffer. \param sig Pointer to buffer to output signature. \param sig_len Length of the signature output buffer. - \param key Pointer to a key structure such as ecc_key or RsaKey. - \param key_len Size of the key structure. + \param key Pointer to the key structure corresponding to sig_type. + See wc_SignatureGetSize() for the type-safety constraints that apply + to this parameter. + \param key_len Must be exactly sizeof(ecc_key) or + sizeof(RsaKey) matching sig_type. See wc_SignatureGetSize(). \param rng Pointer to an initialized RNG structure. _Example_ @@ -166,8 +181,11 @@ int wc_SignatureGenerate( \param hash_len Length of the hash buffer \param sig Pointer to buffer containing the signature \param sig_len Length of the signature buffer - \param key Pointer to a key structure such as ecc_key or RsaKey - \param key_len Size of the key structure + \param key Pointer to the key structure corresponding to sig_type. + See wc_SignatureGetSize() for the type-safety constraints that apply + to this parameter. + \param key_len Must be exactly sizeof(ecc_key) or + sizeof(RsaKey) matching sig_type. See wc_SignatureGetSize(). _Example_ \code @@ -216,8 +234,11 @@ int wc_SignatureVerifyHash(enum wc_HashType hash_type, \param hash_len Length of the hash buffer \param sig Pointer to buffer to output signature \param sig_len Pointer to length of signature output buffer - \param key Pointer to a key structure such as ecc_key or RsaKey - \param key_len Size of the key structure + \param key Pointer to the key structure corresponding to sig_type. + See wc_SignatureGetSize() for the type-safety constraints that apply + to this parameter. + \param key_len Must be exactly sizeof(ecc_key) or + sizeof(RsaKey) matching sig_type. See wc_SignatureGetSize(). \param rng Pointer to an initialized RNG structure _Example_ @@ -266,8 +287,11 @@ int wc_SignatureGenerateHash(enum wc_HashType hash_type, \param hash_len Length of the hash buffer \param sig Pointer to buffer to output signature \param sig_len Pointer to length of signature output buffer - \param key Pointer to a key structure such as ecc_key or RsaKey - \param key_len Size of the key structure + \param key Pointer to the key structure corresponding to sig_type. + See wc_SignatureGetSize() for the type-safety constraints that apply + to this parameter. + \param key_len Must be exactly sizeof(ecc_key) or + sizeof(RsaKey) matching sig_type. See wc_SignatureGetSize(). \param rng Pointer to an initialized RNG structure \param verify If non-zero, verify the signature after generation @@ -317,8 +341,11 @@ int wc_SignatureGenerateHash_ex(enum wc_HashType hash_type, \param data_len Length of the data buffer \param sig Pointer to buffer to output signature \param sig_len Pointer to length of signature output buffer - \param key Pointer to a key structure such as ecc_key or RsaKey - \param key_len Size of the key structure + \param key Pointer to the key structure corresponding to sig_type. + See wc_SignatureGetSize() for the type-safety constraints that apply + to this parameter. + \param key_len Must be exactly sizeof(ecc_key) or + sizeof(RsaKey) matching sig_type. See wc_SignatureGetSize(). \param rng Pointer to an initialized RNG structure \param verify If non-zero, verify the signature after generation diff --git a/tests/api/test_signature.c b/tests/api/test_signature.c index 88f89e54d75..63eb7ae29e0 100644 --- a/tests/api/test_signature.c +++ b/tests/api/test_signature.c @@ -68,6 +68,13 @@ int test_wc_SignatureGetSize_ecc(void) sig_type = WC_SIGNATURE_TYPE_ECC; ExpectIntEQ(wc_SignatureGetSize(sig_type, NULL, key_len), 0); key_len = (word32)0; + ExpectIntEQ(wc_SignatureGetSize(sig_type, &ecc, key_len), + WC_NO_ERR_TRACE(BAD_FUNC_ARG)); + /* key_len must be exactly sizeof(ecc_key): one less or one more is invalid */ + key_len = (word32)(sizeof(ecc_key) - 1); + ExpectIntEQ(wc_SignatureGetSize(sig_type, &ecc, key_len), + WC_NO_ERR_TRACE(BAD_FUNC_ARG)); + key_len = (word32)(sizeof(ecc_key) + 1); ExpectIntEQ(wc_SignatureGetSize(sig_type, &ecc, key_len), WC_NO_ERR_TRACE(BAD_FUNC_ARG)); @@ -138,6 +145,13 @@ int test_wc_SignatureGetSize_rsa(void) ExpectIntEQ(wc_SignatureGetSize(sig_type, NULL, key_len), WC_NO_ERR_TRACE(BAD_FUNC_ARG)); key_len = (word32)0; + ExpectIntEQ(wc_SignatureGetSize(sig_type, &rsa_key, key_len), + WC_NO_ERR_TRACE(BAD_FUNC_ARG)); + /* key_len must be exactly sizeof(RsaKey): one less or one more is invalid */ + key_len = (word32)(sizeof(RsaKey) - 1); + ExpectIntEQ(wc_SignatureGetSize(sig_type, &rsa_key, key_len), + WC_NO_ERR_TRACE(BAD_FUNC_ARG)); + key_len = (word32)(sizeof(RsaKey) + 1); ExpectIntEQ(wc_SignatureGetSize(sig_type, &rsa_key, key_len), WC_NO_ERR_TRACE(BAD_FUNC_ARG)); diff --git a/tests/api/test_signature.h b/tests/api/test_signature.h index cf61e12cbc0..85f43c51808 100644 --- a/tests/api/test_signature.h +++ b/tests/api/test_signature.h @@ -29,6 +29,6 @@ int test_wc_SignatureGetSize_rsa(void); #define TEST_SIGNATURE_DECLS \ TEST_DECL_GROUP("signature", test_wc_SignatureGetSize_ecc), \ - TEST_DECL_GROUP("signature", test_wc_SignatureGetSize_ecc) + TEST_DECL_GROUP("signature", test_wc_SignatureGetSize_rsa) #endif /* WOLFCRYPT_TEST_SIGNATURE_H */ diff --git a/wolfcrypt/src/signature.c b/wolfcrypt/src/signature.c index b26620e5da6..fbd09ed78da 100644 --- a/wolfcrypt/src/signature.c +++ b/wolfcrypt/src/signature.c @@ -93,8 +93,11 @@ int wc_SignatureGetSize(enum wc_SignatureType sig_type, switch(sig_type) { case WC_SIGNATURE_TYPE_ECC: #ifdef HAVE_ECC - /* Sanity check that void* key is at least ecc_key in size */ - if (key_len >= sizeof(ecc_key)) { + /* Verify that key_len matches exactly sizeof(ecc_key). + * This is a necessary but not sufficient type check: the void* + * API cannot verify the actual runtime type of the pointed-to + * object. Callers must pass a valid ecc_key* cast to void*. */ + if (key_len == sizeof(ecc_key)) { #if defined(HAVE_SELFTEST) || (defined(HAVE_FIPS) && FIPS_VERSION3_LT(5,0,0)) sig_len = wc_ecc_sig_size((ecc_key*)(wc_ptr_t)key); #else @@ -112,8 +115,10 @@ int wc_SignatureGetSize(enum wc_SignatureType sig_type, case WC_SIGNATURE_TYPE_RSA_W_ENC: case WC_SIGNATURE_TYPE_RSA: #ifndef NO_RSA - /* Sanity check that void* key is at least RsaKey in size */ - if (key_len >= sizeof(RsaKey)) { + /* Verify that key_len matches exactly sizeof(RsaKey). + * Same caveat as the ECC case above: size equality is necessary + * but not sufficient; the caller must pass a valid RsaKey*. */ + if (key_len == sizeof(RsaKey)) { #if defined(HAVE_SELFTEST) || (defined(HAVE_FIPS) && FIPS_VERSION3_LT(5,0,0)) sig_len = wc_RsaEncryptSize((RsaKey*)(wc_ptr_t)key); #else From 0e14849c31ce3d858da146e919c80819d18e1b4d Mon Sep 17 00:00:00 2001 From: Hideki Miyazaki Date: Wed, 8 Apr 2026 17:24:11 +0900 Subject: [PATCH 2/3] addressed Copilot review comments --- doc/dox_comments/header_files/signature.h | 7 +++---- wolfcrypt/src/signature.c | 7 ++++--- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/doc/dox_comments/header_files/signature.h b/doc/dox_comments/header_files/signature.h index 3c4caf91d8f..f3f2f7d2795 100644 --- a/doc/dox_comments/header_files/signature.h +++ b/doc/dox_comments/header_files/signature.h @@ -11,13 +11,12 @@ \param sig_type A signature type enum value such as WC_SIGNATURE_TYPE_ECC or WC_SIGNATURE_TYPE_RSA. \param key Pointer to the key structure corresponding to sig_type: - pass an ecc_key* (cast to const void*) for - WC_SIGNATURE_TYPE_ECC, or a RsaKey* for + pass an ecc_key* for WC_SIGNATURE_TYPE_ECC, or a RsaKey* for WC_SIGNATURE_TYPE_RSA / WC_SIGNATURE_TYPE_RSA_W_ENC. The caller is responsible for ensuring the pointer refers to the correct type; this function cannot verify the actual runtime type of the object. - \param key_len Must be exactly sizeof(ecc_key) or - sizeof(RsaKey) matching the sig_type. Passing any other value + \param key_len If key is non-NULL, key_len Must be exactly sizeof(ecc_key) + or sizeof(RsaKey) matching the sig_type. Passing any other value causes the function to return BAD_FUNC_ARG without dereferencing key. The conventional idiom is to pass sizeof(*key) at the call site. diff --git a/wolfcrypt/src/signature.c b/wolfcrypt/src/signature.c index fbd09ed78da..ea40b047b49 100644 --- a/wolfcrypt/src/signature.c +++ b/wolfcrypt/src/signature.c @@ -94,9 +94,10 @@ int wc_SignatureGetSize(enum wc_SignatureType sig_type, case WC_SIGNATURE_TYPE_ECC: #ifdef HAVE_ECC /* Verify that key_len matches exactly sizeof(ecc_key). - * This is a necessary but not sufficient type check: the void* - * API cannot verify the actual runtime type of the pointed-to - * object. Callers must pass a valid ecc_key* cast to void*. */ + * This is a necessary but not sufficient type check: + * the const void* API cannot verify the actual runtime + * type of the pointed-to object. + * Callers must pass a valid ecc_key* cast to const void*. */ if (key_len == sizeof(ecc_key)) { #if defined(HAVE_SELFTEST) || (defined(HAVE_FIPS) && FIPS_VERSION3_LT(5,0,0)) sig_len = wc_ecc_sig_size((ecc_key*)(wc_ptr_t)key); From e04fe0c347202026e7754da38fb2c80f5a7df468 Mon Sep 17 00:00:00 2001 From: Hideki Miyazaki Date: Fri, 10 Apr 2026 06:15:11 +0900 Subject: [PATCH 3/3] fix typo --- doc/dox_comments/header_files/signature.h | 7 +++++-- wolfcrypt/src/signature.c | 4 ++-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/doc/dox_comments/header_files/signature.h b/doc/dox_comments/header_files/signature.h index f3f2f7d2795..f4355b384ea 100644 --- a/doc/dox_comments/header_files/signature.h +++ b/doc/dox_comments/header_files/signature.h @@ -15,10 +15,13 @@ WC_SIGNATURE_TYPE_RSA / WC_SIGNATURE_TYPE_RSA_W_ENC. The caller is responsible for ensuring the pointer refers to the correct type; this function cannot verify the actual runtime type of the object. - \param key_len If key is non-NULL, key_len Must be exactly sizeof(ecc_key) + \param key_len If key is non-NULL, key_len must be exactly sizeof(ecc_key) or sizeof(RsaKey) matching the sig_type. Passing any other value causes the function to return BAD_FUNC_ARG without dereferencing key. - The conventional idiom is to pass sizeof(*key) at the call site. + Always pass the size of the concrete key type at the call site: if you + have a typed pointer (e.g., ecc_key* k), use sizeof(*k); otherwise use + sizeof(ecc_key) or sizeof(RsaKey) directly. Do not use sizeof(*key) + on the const void* parameter itself, as dereferencing void is invalid. _Example_ \code diff --git a/wolfcrypt/src/signature.c b/wolfcrypt/src/signature.c index ea40b047b49..5218760b796 100644 --- a/wolfcrypt/src/signature.c +++ b/wolfcrypt/src/signature.c @@ -98,7 +98,7 @@ int wc_SignatureGetSize(enum wc_SignatureType sig_type, * the const void* API cannot verify the actual runtime * type of the pointed-to object. * Callers must pass a valid ecc_key* cast to const void*. */ - if (key_len == sizeof(ecc_key)) { + if ((size_t)key_len == sizeof(ecc_key)) { #if defined(HAVE_SELFTEST) || (defined(HAVE_FIPS) && FIPS_VERSION3_LT(5,0,0)) sig_len = wc_ecc_sig_size((ecc_key*)(wc_ptr_t)key); #else @@ -119,7 +119,7 @@ int wc_SignatureGetSize(enum wc_SignatureType sig_type, /* Verify that key_len matches exactly sizeof(RsaKey). * Same caveat as the ECC case above: size equality is necessary * but not sufficient; the caller must pass a valid RsaKey*. */ - if (key_len == sizeof(RsaKey)) { + if ((size_t)key_len == sizeof(RsaKey)) { #if defined(HAVE_SELFTEST) || (defined(HAVE_FIPS) && FIPS_VERSION3_LT(5,0,0)) sig_len = wc_RsaEncryptSize((RsaKey*)(wc_ptr_t)key); #else