rsa: add CF testing for PKCS#1 v1.5 decode

Signed-off-by: Manuel Pégourié-Gonnard <[email protected]>
This commit is contained in:
Manuel Pégourié-Gonnard
2026-06-02 11:10:06 +02:00
parent 8f4a4eac98
commit 54682ec425
3 changed files with 81 additions and 30 deletions
+5 -30
View File
@@ -414,37 +414,12 @@ end_of_export:
#if defined(MBEDTLS_PKCS1_V15) && defined(MBEDTLS_RSA_C) && !defined(MBEDTLS_RSA_ALT)
/** This function performs the unpadding part of a PKCS#1 v1.5 decryption
* operation (EME-PKCS1-v1_5 decoding).
*
* \note The return value from this function is a sensitive value
* (this is unusual). #MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE shouldn't happen
* in a well-written application, but 0 vs #MBEDTLS_ERR_RSA_INVALID_PADDING
* is often a situation that an attacker can provoke and leaking which
* one is the result is precisely the information the attacker wants.
*
* \param input The input buffer which is the payload inside PKCS#1v1.5
* encryption padding, called the "encoded message EM"
* by the terminology.
* \param ilen The length of the payload in the \p input buffer.
* \param output The buffer for the payload, called "message M" by the
* PKCS#1 terminology. This must be a writable buffer of
* length \p output_max_len bytes.
* \param olen The address at which to store the length of
* the payload. This must not be \c NULL.
* \param output_max_len The length in bytes of the output buffer \p output.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE
* The output buffer is too small for the unpadded payload.
* \return #MBEDTLS_ERR_RSA_INVALID_PADDING
* The input doesn't contain properly formatted padding.
/*
* EME-PKCS1-v1_5 decoding, see documentation in rsa_internal.h
*/
static int mbedtls_ct_rsaes_pkcs1_v15_unpadding(unsigned char *input,
size_t ilen,
unsigned char *output,
size_t output_max_len,
size_t *olen)
MBEDTLS_STATIC_TESTABLE int mbedtls_ct_rsaes_pkcs1_v15_unpadding(
unsigned char *input, size_t ilen,
unsigned char *output, size_t output_max_len, size_t *olen)
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t i, plaintext_max_size;
+37
View File
@@ -118,4 +118,41 @@ int mbedtls_rsa_rsassa_pss_sign_no_mode_check(mbedtls_rsa_context *ctx,
unsigned char *sig);
#endif /* MBEDTLS_PKCS1_V21 */
/* This would normally be in rsa_invasive.h but it didn't exist before 3.6
* became an LTS, and I'd rather not add files in LTS if it can be avoided. */
#if defined(MBEDTLS_TEST_HOOKS)
#if defined(MBEDTLS_PKCS1_V15) && defined(MBEDTLS_RSA_C) && !defined(MBEDTLS_RSA_ALT)
/** This function performs the unpadding part of a PKCS#1 v1.5 decryption
* operation (EME-PKCS1-v1_5 decoding).
*
* \note The return value from this function is a sensitive value
* (this is unusual). #MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE shouldn't happen
* in a well-written application, but 0 vs #MBEDTLS_ERR_RSA_INVALID_PADDING
* is often a situation that an attacker can provoke and leaking which
* one is the result is precisely the information the attacker wants.
*
* \param input The input buffer which is the payload inside PKCS#1v1.5
* encryption padding, called the "encoded message EM"
* by the terminology.
* \param ilen The length of the payload in the \p input buffer.
* \param output The buffer for the payload, called "message M" by the
* PKCS#1 terminology. This must be a writable buffer of
* length \p output_max_len bytes.
* \param olen The address at which to store the length of
* the payload. This must not be \c NULL.
* \param output_max_len The length in bytes of the output buffer \p output.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE
* The output buffer is too small for the unpadded payload.
* \return #MBEDTLS_ERR_RSA_INVALID_PADDING
* The input doesn't contain properly formatted padding.
*/
MBEDTLS_STATIC_TESTABLE int mbedtls_ct_rsaes_pkcs1_v15_unpadding(
unsigned char *input, size_t ilen,
unsigned char *output, size_t output_max_len, size_t *olen);
#endif /* MBEDTLS_PKCS1_V15 && MBEDTLS_RSA_C && ! MBEDTLS_RSA_ALT */
#endif /* MBEDTLS_TEST_HOOKS */
#endif /* rsa_internal.h */
@@ -1,6 +1,39 @@
/* BEGIN_HEADER */
#include "mbedtls/rsa.h"
#include "mbedtls/md.h"
#include "rsa_internal.h"
#include <test/constant_flow.h>
#if defined(MBEDTLS_TEST_HOOKS) && !defined(MBEDTLS_RSA_ALT)
static void pkcs1_v15_decode_raw(const unsigned char *input,
size_t input_size,
size_t output_size,
int expected_result,
size_t expected_plaintext_length)
{
unsigned char *input_buf = NULL;
unsigned char *output_buf = NULL;
size_t olen = 0;
TEST_CALLOC(output_buf, output_size);
TEST_CALLOC(input_buf, input_size);
memcpy(input_buf, input, input_size);
TEST_CF_SECRET(input_buf, input_size);
TEST_EQUAL(expected_result,
mbedtls_ct_rsaes_pkcs1_v15_unpadding(
input_buf, input_size,
output_buf, output_size, &olen));
if (expected_result == 0) {
TEST_EQUAL(expected_plaintext_length, olen);
}
exit:
mbedtls_free(input_buf);
mbedtls_free(output_buf);
}
#endif /* MBEDTLS_TEST_HOOKS && !MBEDTLS_RSA_ALT */
/* END_HEADER */
/* BEGIN_DEPENDENCIES
@@ -257,6 +290,11 @@ void pkcs1_v15_decode(data_t *input,
TEST_ASSERT(count < 16);
}
#if defined(MBEDTLS_TEST_HOOKS) && !defined(MBEDTLS_RSA_ALT)
pkcs1_v15_decode_raw(original, sizeof(original), output_size,
expected_result, expected_plaintext_length);
#endif
exit:
mbedtls_mpi_free(&Nmpi); mbedtls_mpi_free(&Empi);
mbedtls_mpi_free(&Pmpi); mbedtls_mpi_free(&Qmpi);
@@ -264,6 +302,7 @@ exit:
}
/* END_CASE */
/* BEGIN_CASE */
void pkcs1_rsassa_v15_sign(int mod, char *input_P,
char *input_Q, char *input_N,