e496c6273e
When MD is only used to compute a size, use md_internal.h instead. When it's actually used to compute a hash, mark the test function as depending on it. This is probably suboptimal in the long run, and we might want to either adapt the code so that it can use PSA Crypto instead, or just pre-compute the hash in the test data. Signed-off-by: Manuel Pégourié-Gonnard <manuel.pegourie-gonnard@arm.com>
357 lines
15 KiB
Text
357 lines
15 KiB
Text
/* BEGIN_HEADER */
|
|
#include "mbedtls/rsa.h"
|
|
#include "mbedtls/md.h"
|
|
/* END_HEADER */
|
|
|
|
/* BEGIN_DEPENDENCIES
|
|
* depends_on:MBEDTLS_PKCS1_V15:MBEDTLS_RSA_C:MBEDTLS_SHA1_C
|
|
* END_DEPENDENCIES
|
|
*/
|
|
|
|
/* BEGIN_CASE */
|
|
void pkcs1_rsaes_v15_encrypt( int mod, int radix_N, char * input_N,
|
|
int radix_E, char * input_E, int hash,
|
|
data_t * message_str, data_t * rnd_buf,
|
|
data_t * result_str, int result )
|
|
{
|
|
unsigned char output[128];
|
|
mbedtls_rsa_context ctx;
|
|
mbedtls_test_rnd_buf_info info;
|
|
mbedtls_mpi N, E;
|
|
|
|
info.fallback_f_rng = mbedtls_test_rnd_std_rand;
|
|
info.fallback_p_rng = NULL;
|
|
info.buf = rnd_buf->x;
|
|
info.length = rnd_buf->len;
|
|
|
|
mbedtls_mpi_init( &N ); mbedtls_mpi_init( &E );
|
|
mbedtls_rsa_init( &ctx );
|
|
TEST_ASSERT( mbedtls_rsa_set_padding( &ctx,
|
|
MBEDTLS_RSA_PKCS_V15, hash ) == 0 );
|
|
memset( output, 0x00, sizeof( output ) );
|
|
|
|
TEST_ASSERT( mbedtls_test_read_mpi( &N, radix_N, input_N ) == 0 );
|
|
TEST_ASSERT( mbedtls_test_read_mpi( &E, radix_E, input_E ) == 0 );
|
|
TEST_ASSERT( mbedtls_rsa_import( &ctx, &N, NULL, NULL, NULL, &E ) == 0 );
|
|
TEST_ASSERT( mbedtls_rsa_get_len( &ctx ) == (size_t) ( ( mod + 7 ) / 8 ) );
|
|
TEST_ASSERT( mbedtls_rsa_check_pubkey( &ctx ) == 0 );
|
|
|
|
if( message_str->len == 0 )
|
|
message_str->x = NULL;
|
|
TEST_ASSERT( mbedtls_rsa_pkcs1_encrypt( &ctx,
|
|
&mbedtls_test_rnd_buffer_rand,
|
|
&info, message_str->len,
|
|
message_str->x,
|
|
output ) == result );
|
|
|
|
if( result == 0 )
|
|
{
|
|
TEST_ASSERT( mbedtls_test_hexcmp( output, result_str->x,
|
|
ctx.len, result_str->len ) == 0 );
|
|
}
|
|
|
|
exit:
|
|
mbedtls_mpi_free( &N ); mbedtls_mpi_free( &E );
|
|
mbedtls_rsa_free( &ctx );
|
|
}
|
|
/* END_CASE */
|
|
|
|
/* BEGIN_CASE */
|
|
void pkcs1_rsaes_v15_decrypt( int mod, int radix_P, char * input_P,
|
|
int radix_Q, char * input_Q, int radix_N,
|
|
char * input_N, int radix_E, char * input_E,
|
|
int hash, data_t * result_str,
|
|
char * seed, data_t * message_str,
|
|
int result )
|
|
{
|
|
unsigned char output[128];
|
|
mbedtls_rsa_context ctx;
|
|
size_t output_len;
|
|
mbedtls_test_rnd_pseudo_info rnd_info;
|
|
mbedtls_mpi N, P, Q, E;
|
|
((void) seed);
|
|
|
|
mbedtls_mpi_init( &N ); mbedtls_mpi_init( &P );
|
|
mbedtls_mpi_init( &Q ); mbedtls_mpi_init( &E );
|
|
mbedtls_rsa_init( &ctx );
|
|
TEST_ASSERT( mbedtls_rsa_set_padding( &ctx,
|
|
MBEDTLS_RSA_PKCS_V15, hash ) == 0 );
|
|
|
|
memset( output, 0x00, sizeof( output ) );
|
|
memset( &rnd_info, 0, sizeof( mbedtls_test_rnd_pseudo_info ) );
|
|
|
|
TEST_ASSERT( mbedtls_test_read_mpi( &P, radix_P, input_P ) == 0 );
|
|
TEST_ASSERT( mbedtls_test_read_mpi( &Q, radix_Q, input_Q ) == 0 );
|
|
TEST_ASSERT( mbedtls_test_read_mpi( &N, radix_N, input_N ) == 0 );
|
|
TEST_ASSERT( mbedtls_test_read_mpi( &E, radix_E, input_E ) == 0 );
|
|
|
|
TEST_ASSERT( mbedtls_rsa_import( &ctx, &N, &P, &Q, NULL, &E ) == 0 );
|
|
TEST_ASSERT( mbedtls_rsa_get_len( &ctx ) == (size_t) ( ( mod + 7 ) / 8 ) );
|
|
TEST_ASSERT( mbedtls_rsa_complete( &ctx ) == 0 );
|
|
TEST_ASSERT( mbedtls_rsa_check_privkey( &ctx ) == 0 );
|
|
|
|
if( result_str->len == 0 )
|
|
{
|
|
TEST_ASSERT( mbedtls_rsa_pkcs1_decrypt( &ctx,
|
|
&mbedtls_test_rnd_pseudo_rand,
|
|
&rnd_info,
|
|
&output_len, message_str->x,
|
|
NULL, 0 ) == result );
|
|
}
|
|
else
|
|
{
|
|
TEST_ASSERT( mbedtls_rsa_pkcs1_decrypt( &ctx,
|
|
&mbedtls_test_rnd_pseudo_rand,
|
|
&rnd_info,
|
|
&output_len, message_str->x,
|
|
output, 1000 ) == result );
|
|
if( result == 0 )
|
|
{
|
|
TEST_ASSERT( mbedtls_test_hexcmp( output, result_str->x,
|
|
output_len,
|
|
result_str->len) == 0 );
|
|
}
|
|
}
|
|
|
|
exit:
|
|
mbedtls_mpi_free( &N ); mbedtls_mpi_free( &P );
|
|
mbedtls_mpi_free( &Q ); mbedtls_mpi_free( &E );
|
|
mbedtls_rsa_free( &ctx );
|
|
}
|
|
/* END_CASE */
|
|
|
|
/* BEGIN_CASE */
|
|
void pkcs1_v15_decode( data_t *input,
|
|
int expected_plaintext_length_arg,
|
|
int output_size_arg,
|
|
int expected_result )
|
|
{
|
|
size_t expected_plaintext_length = expected_plaintext_length_arg;
|
|
size_t output_size = output_size_arg;
|
|
mbedtls_test_rnd_pseudo_info rnd_info;
|
|
mbedtls_mpi Nmpi, Empi, Pmpi, Qmpi;
|
|
mbedtls_rsa_context ctx;
|
|
static unsigned char N[128] = {
|
|
0xc4, 0x79, 0x4c, 0x6d, 0xb2, 0xe9, 0xdf, 0xc5,
|
|
0xe5, 0xd7, 0x55, 0x4b, 0xfb, 0x6c, 0x2e, 0xec,
|
|
0x84, 0xd0, 0x88, 0x12, 0xaf, 0xbf, 0xb4, 0xf5,
|
|
0x47, 0x3c, 0x7e, 0x92, 0x4c, 0x58, 0xc8, 0x73,
|
|
0xfe, 0x8f, 0x2b, 0x8f, 0x8e, 0xc8, 0x5c, 0xf5,
|
|
0x05, 0xeb, 0xfb, 0x0d, 0x7b, 0x2a, 0x93, 0xde,
|
|
0x15, 0x0d, 0xc8, 0x13, 0xcf, 0xd2, 0x6f, 0x0d,
|
|
0x9d, 0xad, 0x30, 0xe5, 0x70, 0x20, 0x92, 0x9e,
|
|
0xb3, 0x6b, 0xba, 0x5c, 0x50, 0x0f, 0xc3, 0xb2,
|
|
0x7e, 0x64, 0x07, 0x94, 0x7e, 0xc9, 0x4e, 0xc1,
|
|
0x65, 0x04, 0xaf, 0xb3, 0x9f, 0xde, 0xa8, 0x46,
|
|
0xfa, 0x6c, 0xf3, 0x03, 0xaf, 0x1c, 0x1b, 0xec,
|
|
0x75, 0x44, 0x66, 0x77, 0xc9, 0xde, 0x51, 0x33,
|
|
0x64, 0x27, 0xb0, 0xd4, 0x8d, 0x31, 0x6a, 0x11,
|
|
0x27, 0x3c, 0x99, 0xd4, 0x22, 0xc0, 0x9d, 0x12,
|
|
0x01, 0xc7, 0x4a, 0x73, 0xac, 0xbf, 0xc2, 0xbb
|
|
};
|
|
static unsigned char E[1] = { 0x03 };
|
|
static unsigned char P[64] = {
|
|
0xe5, 0x53, 0x1f, 0x88, 0x51, 0xee, 0x59, 0xf8,
|
|
0xc1, 0xe4, 0xcc, 0x5b, 0xb3, 0x75, 0x8d, 0xc8,
|
|
0xe8, 0x95, 0x2f, 0xd0, 0xef, 0x37, 0xb4, 0xcd,
|
|
0xd3, 0x9e, 0x48, 0x8b, 0x81, 0x58, 0x60, 0xb9,
|
|
0x27, 0x1d, 0xb6, 0x28, 0x92, 0x64, 0xa3, 0xa5,
|
|
0x64, 0xbd, 0xcc, 0x53, 0x68, 0xdd, 0x3e, 0x55,
|
|
0xea, 0x9d, 0x5e, 0xcd, 0x1f, 0x96, 0x87, 0xf1,
|
|
0x29, 0x75, 0x92, 0x70, 0x8f, 0x28, 0xfb, 0x2b
|
|
};
|
|
static unsigned char Q[64] = {
|
|
0xdb, 0x53, 0xef, 0x74, 0x61, 0xb4, 0x20, 0x3b,
|
|
0x3b, 0x87, 0x76, 0x75, 0x81, 0x56, 0x11, 0x03,
|
|
0x59, 0x31, 0xe3, 0x38, 0x4b, 0x8c, 0x7a, 0x9c,
|
|
0x05, 0xd6, 0x7f, 0x1e, 0x5e, 0x60, 0xf0, 0x4e,
|
|
0x0b, 0xdc, 0x34, 0x54, 0x1c, 0x2e, 0x90, 0x83,
|
|
0x14, 0xef, 0xc0, 0x96, 0x5c, 0x30, 0x10, 0xcc,
|
|
0xc1, 0xba, 0xa0, 0x54, 0x3f, 0x96, 0x24, 0xca,
|
|
0xa3, 0xfb, 0x55, 0xbc, 0x71, 0x29, 0x4e, 0xb1
|
|
};
|
|
unsigned char original[128];
|
|
unsigned char intermediate[128];
|
|
static unsigned char default_content[128] = {
|
|
/* A randomly generated pattern. */
|
|
0x4c, 0x27, 0x54, 0xa0, 0xce, 0x0d, 0x09, 0x4a,
|
|
0x1c, 0x38, 0x8e, 0x2d, 0xa3, 0xc4, 0xe0, 0x19,
|
|
0x4c, 0x99, 0xb2, 0xbf, 0xe6, 0x65, 0x7e, 0x58,
|
|
0xd7, 0xb6, 0x8a, 0x05, 0x2f, 0xa5, 0xec, 0xa4,
|
|
0x35, 0xad, 0x10, 0x36, 0xff, 0x0d, 0x08, 0x50,
|
|
0x74, 0x47, 0xc9, 0x9c, 0x4a, 0xe7, 0xfd, 0xfa,
|
|
0x83, 0x5f, 0x14, 0x5a, 0x1e, 0xe7, 0x35, 0x08,
|
|
0xad, 0xf7, 0x0d, 0x86, 0xdf, 0xb8, 0xd4, 0xcf,
|
|
0x32, 0xb9, 0x5c, 0xbe, 0xa3, 0xd2, 0x89, 0x70,
|
|
0x7b, 0xc6, 0x48, 0x7e, 0x58, 0x4d, 0xf3, 0xef,
|
|
0x34, 0xb7, 0x57, 0x54, 0x79, 0xc5, 0x8e, 0x0a,
|
|
0xa3, 0xbf, 0x6d, 0x42, 0x83, 0x25, 0x13, 0xa2,
|
|
0x95, 0xc0, 0x0d, 0x32, 0xec, 0x77, 0x91, 0x2b,
|
|
0x68, 0xb6, 0x8c, 0x79, 0x15, 0xfb, 0x94, 0xde,
|
|
0xb9, 0x2b, 0x94, 0xb3, 0x28, 0x23, 0x86, 0x3d,
|
|
0x37, 0x00, 0xe6, 0xf1, 0x1f, 0x4e, 0xd4, 0x42
|
|
};
|
|
unsigned char final[128];
|
|
size_t output_length = 0x7EA0;
|
|
|
|
memset( &rnd_info, 0, sizeof( mbedtls_test_rnd_pseudo_info ) );
|
|
mbedtls_mpi_init( &Nmpi ); mbedtls_mpi_init( &Empi );
|
|
mbedtls_mpi_init( &Pmpi ); mbedtls_mpi_init( &Qmpi );
|
|
mbedtls_rsa_init( &ctx );
|
|
|
|
TEST_ASSERT( mbedtls_mpi_read_binary( &Nmpi, N, sizeof( N ) ) == 0 );
|
|
TEST_ASSERT( mbedtls_mpi_read_binary( &Empi, E, sizeof( E ) ) == 0 );
|
|
TEST_ASSERT( mbedtls_mpi_read_binary( &Pmpi, P, sizeof( P ) ) == 0 );
|
|
TEST_ASSERT( mbedtls_mpi_read_binary( &Qmpi, Q, sizeof( Q ) ) == 0 );
|
|
|
|
TEST_ASSERT( mbedtls_rsa_import( &ctx, &Nmpi, &Pmpi, &Qmpi,
|
|
NULL, &Empi ) == 0 );
|
|
TEST_ASSERT( mbedtls_rsa_complete( &ctx ) == 0 );
|
|
|
|
TEST_ASSERT( input->len <= sizeof( N ) );
|
|
memcpy( original, input->x, input->len );
|
|
memset( original + input->len, 'd', sizeof( original ) - input->len );
|
|
TEST_ASSERT( mbedtls_rsa_public( &ctx, original, intermediate ) == 0 );
|
|
|
|
memcpy( final, default_content, sizeof( final ) );
|
|
TEST_ASSERT( mbedtls_rsa_pkcs1_decrypt( &ctx,
|
|
&mbedtls_test_rnd_pseudo_rand,
|
|
&rnd_info, &output_length,
|
|
intermediate, final,
|
|
output_size ) == expected_result );
|
|
if( expected_result == 0 )
|
|
{
|
|
TEST_ASSERT( output_length == expected_plaintext_length );
|
|
TEST_ASSERT( memcmp( original + sizeof( N ) - output_length,
|
|
final,
|
|
output_length ) == 0 );
|
|
}
|
|
else if( expected_result == MBEDTLS_ERR_RSA_INVALID_PADDING ||
|
|
expected_result == MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE )
|
|
{
|
|
size_t max_payload_length =
|
|
output_size > sizeof( N ) - 11 ? sizeof( N ) - 11 : output_size;
|
|
size_t i;
|
|
size_t count = 0;
|
|
|
|
#if !defined(MBEDTLS_RSA_ALT)
|
|
/* Check that the output in invalid cases is what the default
|
|
* implementation currently does. Alternative implementations
|
|
* may produce different output, so we only perform these precise
|
|
* checks when using the default implementation. */
|
|
TEST_ASSERT( output_length == max_payload_length );
|
|
for( i = 0; i < max_payload_length; i++ )
|
|
TEST_ASSERT( final[i] == 0 );
|
|
#endif
|
|
/* Even in alternative implementations, the outputs must have
|
|
* changed, otherwise it indicates at least a timing vulnerability
|
|
* because no write to the outputs is performed in the bad case. */
|
|
TEST_ASSERT( output_length != 0x7EA0 );
|
|
for( i = 0; i < max_payload_length; i++ )
|
|
count += ( final[i] == default_content[i] );
|
|
/* If more than 16 bytes are unchanged in final, that's evidence
|
|
* that final wasn't overwritten. */
|
|
TEST_ASSERT( count < 16 );
|
|
}
|
|
|
|
exit:
|
|
mbedtls_mpi_free( &Nmpi ); mbedtls_mpi_free( &Empi );
|
|
mbedtls_mpi_free( &Pmpi ); mbedtls_mpi_free( &Qmpi );
|
|
mbedtls_rsa_free( &ctx );
|
|
}
|
|
/* END_CASE */
|
|
|
|
/* BEGIN_CASE depends_on:MBEDTLS_MD_C */
|
|
void pkcs1_rsassa_v15_sign( int mod, int radix_P, char * input_P, int radix_Q,
|
|
char * input_Q, int radix_N, char * input_N,
|
|
int radix_E, char * input_E, int digest, int hash,
|
|
data_t * message_str, data_t * rnd_buf,
|
|
data_t * result_str, int result )
|
|
{
|
|
unsigned char hash_result[MBEDTLS_MD_MAX_SIZE];
|
|
const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type( digest );
|
|
unsigned char output[128];
|
|
mbedtls_rsa_context ctx;
|
|
mbedtls_mpi N, P, Q, E;
|
|
mbedtls_test_rnd_buf_info info;
|
|
|
|
info.fallback_f_rng = mbedtls_test_rnd_std_rand;
|
|
info.fallback_p_rng = NULL;
|
|
info.buf = rnd_buf->x;
|
|
info.length = rnd_buf->len;
|
|
|
|
mbedtls_mpi_init( &N ); mbedtls_mpi_init( &P );
|
|
mbedtls_mpi_init( &Q ); mbedtls_mpi_init( &E );
|
|
mbedtls_rsa_init( &ctx );
|
|
TEST_ASSERT( mbedtls_rsa_set_padding( &ctx,
|
|
MBEDTLS_RSA_PKCS_V15, hash ) == 0 );
|
|
|
|
memset( hash_result, 0x00, sizeof( hash_result ) );
|
|
memset( output, 0x00, sizeof( output ) );
|
|
|
|
TEST_ASSERT( mbedtls_test_read_mpi( &P, radix_P, input_P ) == 0 );
|
|
TEST_ASSERT( mbedtls_test_read_mpi( &Q, radix_Q, input_Q ) == 0 );
|
|
TEST_ASSERT( mbedtls_test_read_mpi( &N, radix_N, input_N ) == 0 );
|
|
TEST_ASSERT( mbedtls_test_read_mpi( &E, radix_E, input_E ) == 0 );
|
|
|
|
TEST_ASSERT( mbedtls_rsa_import( &ctx, &N, &P, &Q, NULL, &E ) == 0 );
|
|
TEST_ASSERT( mbedtls_rsa_get_len( &ctx ) == (size_t) ( ( mod + 7 ) / 8 ) );
|
|
TEST_ASSERT( mbedtls_rsa_complete( &ctx ) == 0 );
|
|
TEST_ASSERT( mbedtls_rsa_check_privkey( &ctx ) == 0 );
|
|
|
|
if( md_info != NULL )
|
|
TEST_ASSERT( mbedtls_md( md_info, message_str->x, message_str->len, hash_result ) == 0 );
|
|
|
|
TEST_ASSERT( mbedtls_rsa_pkcs1_sign(
|
|
&ctx, &mbedtls_test_rnd_buffer_rand, &info,
|
|
digest, mbedtls_md_get_size( md_info ), hash_result,
|
|
output ) == result );
|
|
if( result == 0 )
|
|
{
|
|
|
|
TEST_ASSERT( mbedtls_test_hexcmp( output, result_str->x,
|
|
ctx.len, result_str->len ) == 0 );
|
|
}
|
|
|
|
exit:
|
|
mbedtls_mpi_free( &N ); mbedtls_mpi_free( &P );
|
|
mbedtls_mpi_free( &Q ); mbedtls_mpi_free( &E );
|
|
mbedtls_rsa_free( &ctx );
|
|
}
|
|
/* END_CASE */
|
|
|
|
/* BEGIN_CASE depends_on:MBEDTLS_MD_C */
|
|
void pkcs1_rsassa_v15_verify( int mod, int radix_N, char * input_N,
|
|
int radix_E, char * input_E, int digest,
|
|
int hash, data_t * message_str, char * salt,
|
|
data_t * result_str, int result )
|
|
{
|
|
unsigned char hash_result[MBEDTLS_MD_MAX_SIZE];
|
|
const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type( digest );
|
|
mbedtls_rsa_context ctx;
|
|
mbedtls_mpi N, E;
|
|
((void) salt);
|
|
|
|
mbedtls_mpi_init( &N ); mbedtls_mpi_init( &E );
|
|
mbedtls_rsa_init( &ctx );
|
|
TEST_ASSERT( mbedtls_rsa_set_padding( &ctx,
|
|
MBEDTLS_RSA_PKCS_V15, hash ) == 0 );
|
|
memset( hash_result, 0x00, sizeof( hash_result ) );
|
|
|
|
TEST_ASSERT( mbedtls_test_read_mpi( &N, radix_N, input_N ) == 0 );
|
|
TEST_ASSERT( mbedtls_test_read_mpi( &E, radix_E, input_E ) == 0 );
|
|
TEST_ASSERT( mbedtls_rsa_import( &ctx, &N, NULL, NULL, NULL, &E ) == 0 );
|
|
TEST_ASSERT( mbedtls_rsa_get_len( &ctx ) == (size_t) ( ( mod + 7 ) / 8 ) );
|
|
TEST_ASSERT( mbedtls_rsa_check_pubkey( &ctx ) == 0 );
|
|
|
|
|
|
if( md_info != NULL )
|
|
TEST_ASSERT( mbedtls_md( md_info, message_str->x, message_str->len, hash_result ) == 0 );
|
|
|
|
TEST_ASSERT( mbedtls_rsa_pkcs1_verify( &ctx, digest, mbedtls_md_get_size( md_info ), hash_result, result_str->x ) == result );
|
|
|
|
exit:
|
|
mbedtls_mpi_free( &N ); mbedtls_mpi_free( &E );
|
|
mbedtls_rsa_free( &ctx );
|
|
}
|
|
/* END_CASE */
|