diff --git a/doc/dox_comments/header_files/signature.h b/doc/dox_comments/header_files/signature.h index 6113887837..cf30d61e3e 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 88f89e54d7..63eb7ae29e 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 cf61e12cbc..85f43c5180 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 c5d4cf0d68..aca522a215 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)) { sig_len = wc_ecc_sig_size((ecc_key*)key); } else { @@ -108,8 +111,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)) { sig_len = wc_RsaEncryptSize((RsaKey*)key); } else {