1
0
Fork 0
mirror of https://github.com/yuzu-emu/mbedtls.git synced 2025-03-31 12:27:02 +00:00
mbedtls/tests/suites/test_suite_rsa.function
Manuel Pégourié-Gonnard 05e464dff7 Merge branch 'development' into iotssl-1381-x509-verify-refactor-restricted
* development: (557 commits)
  Add attribution for  report
  Adapt version_features.c
  Note incompatibility of truncated HMAC extension in ChangeLog
  Add LinkLibraryDependencies to VS2010 app template
  Add ChangeLog entry for PR 
  MD: Make deprecated functions not inline
  Add ChangeLog entry for PR 
  Have Visual Studio handle linking to mbedTLS.lib internally
  Mention in ChangeLog that this fixes 
  Add issue number to ChangeLog
  Note in the changelog that this fixes an interoperability issue.
  Style fix in ChangeLog
  Add ChangeLog entries for PR  and 
  Add ChangeLog entry for PR 
  ctr_drbg: Typo fix in the file description comment.
  dhm: Fix typo in RFC 5114 constants
  tests_suite_pkparse: new PKCS8-v2 keys with PRF != SHA1
  data_files/pkcs8-v2: add keys generated with PRF != SHA1
  tests/pkcs5/pbkdf2_hmac: extend array to accommodate longer results
  tests/pkcs5/pbkdf2_hmac: add unit tests for additional SHA algorithms
  ...
2018-03-05 11:55:38 +01:00

1475 lines
50 KiB
Plaintext

/* BEGIN_HEADER */
#include "mbedtls/rsa.h"
#include "mbedtls/rsa_internal.h"
#include "mbedtls/md2.h"
#include "mbedtls/md4.h"
#include "mbedtls/md5.h"
#include "mbedtls/sha1.h"
#include "mbedtls/sha256.h"
#include "mbedtls/sha512.h"
#include "mbedtls/entropy.h"
#include "mbedtls/ctr_drbg.h"
/* END_HEADER */
/* BEGIN_DEPENDENCIES
* depends_on:MBEDTLS_RSA_C:MBEDTLS_BIGNUM_C:MBEDTLS_GENPRIME
* END_DEPENDENCIES
*/
/* BEGIN_CASE */
void mbedtls_rsa_pkcs1_sign( char *message_hex_string, int padding_mode, int digest,
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, char *result_hex_str, int result )
{
unsigned char message_str[1000];
unsigned char hash_result[1000];
unsigned char output[1000];
unsigned char output_str[1000];
mbedtls_rsa_context ctx;
mbedtls_mpi N, P, Q, E;
int msg_len;
rnd_pseudo_info rnd_info;
mbedtls_mpi_init( &N ); mbedtls_mpi_init( &P );
mbedtls_mpi_init( &Q ); mbedtls_mpi_init( &E );
mbedtls_rsa_init( &ctx, padding_mode, 0 );
memset( message_str, 0x00, 1000 );
memset( hash_result, 0x00, 1000 );
memset( output, 0x00, 1000 );
memset( output_str, 0x00, 1000 );
memset( &rnd_info, 0, sizeof( rnd_pseudo_info ) );
TEST_ASSERT( mbedtls_mpi_read_string( &P, radix_P, input_P ) == 0 );
TEST_ASSERT( mbedtls_mpi_read_string( &Q, radix_Q, input_Q ) == 0 );
TEST_ASSERT( mbedtls_mpi_read_string( &N, radix_N, input_N ) == 0 );
TEST_ASSERT( mbedtls_mpi_read_string( &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 / 8 ) );
TEST_ASSERT( mbedtls_rsa_complete( &ctx ) == 0 );
TEST_ASSERT( mbedtls_rsa_check_privkey( &ctx ) == 0 );
msg_len = unhexify( message_str, message_hex_string );
if( mbedtls_md_info_from_type( digest ) != NULL )
TEST_ASSERT( mbedtls_md( mbedtls_md_info_from_type( digest ),
message_str, msg_len, hash_result ) == 0 );
TEST_ASSERT( mbedtls_rsa_pkcs1_sign( &ctx, &rnd_pseudo_rand, &rnd_info,
MBEDTLS_RSA_PRIVATE, digest, 0,
hash_result, output ) == result );
if( result == 0 )
{
hexify( output_str, output, ctx.len );
TEST_ASSERT( strcasecmp( (char *) output_str, result_hex_str ) == 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 mbedtls_rsa_pkcs1_verify( char *message_hex_string, int padding_mode, int digest,
int mod, int radix_N, char *input_N, int radix_E,
char *input_E, char *result_hex_str, int result )
{
unsigned char message_str[1000];
unsigned char hash_result[1000];
unsigned char result_str[1000];
mbedtls_rsa_context ctx;
int msg_len;
mbedtls_mpi N, E;
mbedtls_mpi_init( &N ); mbedtls_mpi_init( &E );
mbedtls_rsa_init( &ctx, padding_mode, 0 );
memset( message_str, 0x00, 1000 );
memset( hash_result, 0x00, 1000 );
memset( result_str, 0x00, 1000 );
TEST_ASSERT( mbedtls_mpi_read_string( &N, radix_N, input_N ) == 0 );
TEST_ASSERT( mbedtls_mpi_read_string( &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 / 8 ) );
TEST_ASSERT( mbedtls_rsa_check_pubkey( &ctx ) == 0 );
msg_len = unhexify( message_str, message_hex_string );
unhexify( result_str, result_hex_str );
if( mbedtls_md_info_from_type( digest ) != NULL )
TEST_ASSERT( mbedtls_md( mbedtls_md_info_from_type( digest ), message_str, msg_len, hash_result ) == 0 );
TEST_ASSERT( mbedtls_rsa_pkcs1_verify( &ctx, NULL, NULL, MBEDTLS_RSA_PUBLIC, digest, 0, hash_result, result_str ) == result );
exit:
mbedtls_mpi_free( &N ); mbedtls_mpi_free( &E );
mbedtls_rsa_free( &ctx );
}
/* END_CASE */
/* BEGIN_CASE */
void rsa_pkcs1_sign_raw( char *message_hex_string, char *hash_result_string,
int padding_mode, 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,
char *result_hex_str )
{
int res;
unsigned char message_str[1000];
unsigned char hash_result[1000];
unsigned char output[1000];
unsigned char output_str[1000];
mbedtls_rsa_context ctx;
mbedtls_mpi N, P, Q, E;
int hash_len;
rnd_pseudo_info rnd_info;
mbedtls_rsa_init( &ctx, padding_mode, 0 );
mbedtls_mpi_init( &N ); mbedtls_mpi_init( &P );
mbedtls_mpi_init( &Q ); mbedtls_mpi_init( &E );
memset( message_str, 0x00, 1000 );
memset( hash_result, 0x00, 1000 );
memset( output, 0x00, 1000 );
memset( output_str, 0x00, 1000 );
memset( &rnd_info, 0, sizeof( rnd_pseudo_info ) );
TEST_ASSERT( mbedtls_mpi_read_string( &P, radix_P, input_P ) == 0 );
TEST_ASSERT( mbedtls_mpi_read_string( &Q, radix_Q, input_Q ) == 0 );
TEST_ASSERT( mbedtls_mpi_read_string( &N, radix_N, input_N ) == 0 );
TEST_ASSERT( mbedtls_mpi_read_string( &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 / 8 ) );
TEST_ASSERT( mbedtls_rsa_complete( &ctx ) == 0 );
TEST_ASSERT( mbedtls_rsa_check_privkey( &ctx ) == 0 );
unhexify( message_str, message_hex_string );
hash_len = unhexify( hash_result, hash_result_string );
TEST_ASSERT( mbedtls_rsa_pkcs1_sign( &ctx, &rnd_pseudo_rand, &rnd_info,
MBEDTLS_RSA_PRIVATE, MBEDTLS_MD_NONE,
hash_len, hash_result, output ) == 0 );
hexify( output_str, output, ctx.len );
TEST_ASSERT( strcasecmp( (char *) output_str, result_hex_str ) == 0 );
#if defined(MBEDTLS_PKCS1_V15)
/* For PKCS#1 v1.5, there is an alternative way to generate signatures */
if( padding_mode == MBEDTLS_RSA_PKCS_V15 )
{
memset( output, 0x00, 1000 );
memset( output_str, 0x00, 1000 );
res = mbedtls_rsa_rsaes_pkcs1_v15_encrypt( &ctx,
&rnd_pseudo_rand, &rnd_info, MBEDTLS_RSA_PRIVATE,
hash_len, hash_result, output );
#if !defined(MBEDTLS_RSA_ALT)
TEST_ASSERT( res == 0 );
#else
TEST_ASSERT( ( res == 0 ) ||
( res == MBEDTLS_ERR_RSA_UNSUPPORTED_OPERATION ) );
#endif
if( res == 0 )
{
hexify( output_str, output, ctx.len );
TEST_ASSERT( strcasecmp( (char *) output_str, result_hex_str ) == 0 );
}
}
#endif /* MBEDTLS_PKCS1_V15 */
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 rsa_pkcs1_verify_raw( char *message_hex_string, char *hash_result_string,
int padding_mode, int mod, int radix_N,
char *input_N, int radix_E, char *input_E,
char *result_hex_str, int correct )
{
int res;
unsigned char message_str[1000];
unsigned char hash_result[1000];
unsigned char result_str[1000];
unsigned char output[1000];
mbedtls_rsa_context ctx;
size_t hash_len;
mbedtls_mpi N, E;
mbedtls_mpi_init( &N ); mbedtls_mpi_init( &E );
mbedtls_rsa_init( &ctx, padding_mode, 0 );
memset( message_str, 0x00, 1000 );
memset( hash_result, 0x00, 1000 );
memset( result_str, 0x00, 1000 );
memset( output, 0x00, sizeof( output ) );
TEST_ASSERT( mbedtls_mpi_read_string( &N, radix_N, input_N ) == 0 );
TEST_ASSERT( mbedtls_mpi_read_string( &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 / 8 ) );
TEST_ASSERT( mbedtls_rsa_check_pubkey( &ctx ) == 0 );
unhexify( message_str, message_hex_string );
hash_len = unhexify( hash_result, hash_result_string );
unhexify( result_str, result_hex_str );
TEST_ASSERT( mbedtls_rsa_pkcs1_verify( &ctx, NULL, NULL,
MBEDTLS_RSA_PUBLIC, MBEDTLS_MD_NONE,
hash_len, hash_result,
result_str ) == correct );
#if defined(MBEDTLS_PKCS1_V15)
/* For PKCS#1 v1.5, there is an alternative way to verify signatures */
if( padding_mode == MBEDTLS_RSA_PKCS_V15 )
{
int ok;
size_t olen;
res = mbedtls_rsa_rsaes_pkcs1_v15_decrypt( &ctx,
NULL, NULL, MBEDTLS_RSA_PUBLIC,
&olen, result_str, output, sizeof( output ) );
#if !defined(MBEDTLS_RSA_ALT)
TEST_ASSERT( res == 0 );
#else
TEST_ASSERT( ( res == 0 ) ||
( res == MBEDTLS_ERR_RSA_UNSUPPORTED_OPERATION ) );
#endif
if( res == 0 )
{
ok = olen == hash_len && memcmp( output, hash_result, olen ) == 0;
if( correct == 0 )
TEST_ASSERT( ok == 1 );
else
TEST_ASSERT( ok == 0 );
}
}
#endif /* MBEDTLS_PKCS1_V15 */
exit:
mbedtls_mpi_free( &N ); mbedtls_mpi_free( &E );
mbedtls_rsa_free( &ctx );
}
/* END_CASE */
/* BEGIN_CASE */
void mbedtls_rsa_pkcs1_encrypt( char *message_hex_string, int padding_mode, int mod,
int radix_N, char *input_N, int radix_E, char *input_E,
char *result_hex_str, int result )
{
unsigned char message_str[1000];
unsigned char output[1000];
unsigned char output_str[1000];
mbedtls_rsa_context ctx;
size_t msg_len;
rnd_pseudo_info rnd_info;
mbedtls_mpi N, E;
mbedtls_mpi_init( &N ); mbedtls_mpi_init( &E );
memset( &rnd_info, 0, sizeof( rnd_pseudo_info ) );
mbedtls_rsa_init( &ctx, padding_mode, 0 );
memset( message_str, 0x00, 1000 );
memset( output, 0x00, 1000 );
memset( output_str, 0x00, 1000 );
TEST_ASSERT( mbedtls_mpi_read_string( &N, radix_N, input_N ) == 0 );
TEST_ASSERT( mbedtls_mpi_read_string( &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 / 8 ) );
TEST_ASSERT( mbedtls_rsa_check_pubkey( &ctx ) == 0 );
msg_len = unhexify( message_str, message_hex_string );
TEST_ASSERT( mbedtls_rsa_pkcs1_encrypt( &ctx, &rnd_pseudo_rand, &rnd_info,
MBEDTLS_RSA_PUBLIC, msg_len,
message_str, output ) == result );
if( result == 0 )
{
hexify( output_str, output, ctx.len );
TEST_ASSERT( strcasecmp( (char *) output_str, result_hex_str ) == 0 );
}
exit:
mbedtls_mpi_free( &N ); mbedtls_mpi_free( &E );
mbedtls_rsa_free( &ctx );
}
/* END_CASE */
/* BEGIN_CASE */
void rsa_pkcs1_encrypt_bad_rng( char *message_hex_string, int padding_mode,
int mod, int radix_N, char *input_N,
int radix_E, char *input_E,
char *result_hex_str, int result )
{
unsigned char message_str[1000];
unsigned char output[1000];
unsigned char output_str[1000];
mbedtls_rsa_context ctx;
size_t msg_len;
mbedtls_mpi N, E;
mbedtls_mpi_init( &N ); mbedtls_mpi_init( &E );
mbedtls_rsa_init( &ctx, padding_mode, 0 );
memset( message_str, 0x00, 1000 );
memset( output, 0x00, 1000 );
memset( output_str, 0x00, 1000 );
TEST_ASSERT( mbedtls_mpi_read_string( &N, radix_N, input_N ) == 0 );
TEST_ASSERT( mbedtls_mpi_read_string( &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 / 8 ) );
TEST_ASSERT( mbedtls_rsa_check_pubkey( &ctx ) == 0 );
msg_len = unhexify( message_str, message_hex_string );
TEST_ASSERT( mbedtls_rsa_pkcs1_encrypt( &ctx, &rnd_zero_rand, NULL,
MBEDTLS_RSA_PUBLIC, msg_len,
message_str, output ) == result );
if( result == 0 )
{
hexify( output_str, output, ctx.len );
TEST_ASSERT( strcasecmp( (char *) output_str, result_hex_str ) == 0 );
}
exit:
mbedtls_mpi_free( &N ); mbedtls_mpi_free( &E );
mbedtls_rsa_free( &ctx );
}
/* END_CASE */
/* BEGIN_CASE */
void mbedtls_rsa_pkcs1_decrypt( char *message_hex_string, int padding_mode, 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 max_output, char *result_hex_str, int result )
{
unsigned char message_str[1000];
unsigned char output[1000];
unsigned char output_str[1000];
mbedtls_rsa_context ctx;
size_t output_len;
rnd_pseudo_info rnd_info;
mbedtls_mpi N, P, Q, E;
mbedtls_mpi_init( &N ); mbedtls_mpi_init( &P );
mbedtls_mpi_init( &Q ); mbedtls_mpi_init( &E );
mbedtls_rsa_init( &ctx, padding_mode, 0 );
memset( message_str, 0x00, 1000 );
memset( output, 0x00, 1000 );
memset( output_str, 0x00, 1000 );
memset( &rnd_info, 0, sizeof( rnd_pseudo_info ) );
TEST_ASSERT( mbedtls_mpi_read_string( &P, radix_P, input_P ) == 0 );
TEST_ASSERT( mbedtls_mpi_read_string( &Q, radix_Q, input_Q ) == 0 );
TEST_ASSERT( mbedtls_mpi_read_string( &N, radix_N, input_N ) == 0 );
TEST_ASSERT( mbedtls_mpi_read_string( &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 / 8 ) );
TEST_ASSERT( mbedtls_rsa_complete( &ctx ) == 0 );
TEST_ASSERT( mbedtls_rsa_check_privkey( &ctx ) == 0 );
unhexify( message_str, message_hex_string );
output_len = 0;
TEST_ASSERT( mbedtls_rsa_pkcs1_decrypt( &ctx, rnd_pseudo_rand, &rnd_info, MBEDTLS_RSA_PRIVATE, &output_len, message_str, output, max_output ) == result );
if( result == 0 )
{
hexify( output_str, output, ctx.len );
TEST_ASSERT( strncasecmp( (char *) output_str, result_hex_str, strlen( result_hex_str ) ) == 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 mbedtls_rsa_public( char *message_hex_string, int mod, int radix_N, char *input_N,
int radix_E, char *input_E, char *result_hex_str, int result )
{
unsigned char message_str[1000];
unsigned char output[1000];
unsigned char output_str[1000];
mbedtls_rsa_context ctx, ctx2; /* Also test mbedtls_rsa_copy() while at it */
mbedtls_mpi N, E;
mbedtls_mpi_init( &N ); mbedtls_mpi_init( &E );
mbedtls_rsa_init( &ctx, MBEDTLS_RSA_PKCS_V15, 0 );
mbedtls_rsa_init( &ctx2, MBEDTLS_RSA_PKCS_V15, 0 );
memset( message_str, 0x00, 1000 );
memset( output, 0x00, 1000 );
memset( output_str, 0x00, 1000 );
TEST_ASSERT( mbedtls_mpi_read_string( &N, radix_N, input_N ) == 0 );
TEST_ASSERT( mbedtls_mpi_read_string( &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 / 8 ) );
TEST_ASSERT( mbedtls_rsa_check_pubkey( &ctx ) == 0 );
unhexify( message_str, message_hex_string );
TEST_ASSERT( mbedtls_rsa_public( &ctx, message_str, output ) == result );
if( result == 0 )
{
hexify( output_str, output, ctx.len );
TEST_ASSERT( strcasecmp( (char *) output_str, result_hex_str ) == 0 );
}
/* And now with the copy */
TEST_ASSERT( mbedtls_rsa_copy( &ctx2, &ctx ) == 0 );
/* clear the original to be sure */
mbedtls_rsa_free( &ctx );
TEST_ASSERT( mbedtls_rsa_check_pubkey( &ctx2 ) == 0 );
memset( output, 0x00, 1000 );
memset( output_str, 0x00, 1000 );
TEST_ASSERT( mbedtls_rsa_public( &ctx2, message_str, output ) == result );
if( result == 0 )
{
hexify( output_str, output, ctx2.len );
TEST_ASSERT( strcasecmp( (char *) output_str, result_hex_str ) == 0 );
}
exit:
mbedtls_mpi_free( &N ); mbedtls_mpi_free( &E );
mbedtls_rsa_free( &ctx );
mbedtls_rsa_free( &ctx2 );
}
/* END_CASE */
/* BEGIN_CASE */
void mbedtls_rsa_private( char *message_hex_string, 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, char *result_hex_str, int result )
{
unsigned char message_str[1000];
unsigned char output[1000];
unsigned char output_str[1000];
mbedtls_rsa_context ctx, ctx2; /* Also test mbedtls_rsa_copy() while at it */
mbedtls_mpi N, P, Q, E;
rnd_pseudo_info rnd_info;
int i;
mbedtls_mpi_init( &N ); mbedtls_mpi_init( &P );
mbedtls_mpi_init( &Q ); mbedtls_mpi_init( &E );
mbedtls_rsa_init( &ctx, MBEDTLS_RSA_PKCS_V15, 0 );
mbedtls_rsa_init( &ctx2, MBEDTLS_RSA_PKCS_V15, 0 );
memset( message_str, 0x00, 1000 );
memset( &rnd_info, 0, sizeof( rnd_pseudo_info ) );
TEST_ASSERT( mbedtls_mpi_read_string( &P, radix_P, input_P ) == 0 );
TEST_ASSERT( mbedtls_mpi_read_string( &Q, radix_Q, input_Q ) == 0 );
TEST_ASSERT( mbedtls_mpi_read_string( &N, radix_N, input_N ) == 0 );
TEST_ASSERT( mbedtls_mpi_read_string( &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 / 8 ) );
TEST_ASSERT( mbedtls_rsa_complete( &ctx ) == 0 );
TEST_ASSERT( mbedtls_rsa_check_privkey( &ctx ) == 0 );
unhexify( message_str, message_hex_string );
/* repeat three times to test updating of blinding values */
for( i = 0; i < 3; i++ )
{
memset( output, 0x00, 1000 );
memset( output_str, 0x00, 1000 );
TEST_ASSERT( mbedtls_rsa_private( &ctx, rnd_pseudo_rand, &rnd_info,
message_str, output ) == result );
if( result == 0 )
{
hexify( output_str, output, ctx.len );
TEST_ASSERT( strcasecmp( (char *) output_str,
result_hex_str ) == 0 );
}
}
/* And now one more time with the copy */
TEST_ASSERT( mbedtls_rsa_copy( &ctx2, &ctx ) == 0 );
/* clear the original to be sure */
mbedtls_rsa_free( &ctx );
TEST_ASSERT( mbedtls_rsa_check_privkey( &ctx2 ) == 0 );
memset( output, 0x00, 1000 );
memset( output_str, 0x00, 1000 );
TEST_ASSERT( mbedtls_rsa_private( &ctx2, rnd_pseudo_rand, &rnd_info,
message_str, output ) == result );
if( result == 0 )
{
hexify( output_str, output, ctx2.len );
TEST_ASSERT( strcasecmp( (char *) output_str,
result_hex_str ) == 0 );
}
exit:
mbedtls_mpi_free( &N ); mbedtls_mpi_free( &P );
mbedtls_mpi_free( &Q ); mbedtls_mpi_free( &E );
mbedtls_rsa_free( &ctx ); mbedtls_rsa_free( &ctx2 );
}
/* END_CASE */
/* BEGIN_CASE */
void rsa_check_privkey_null()
{
mbedtls_rsa_context ctx;
memset( &ctx, 0x00, sizeof( mbedtls_rsa_context ) );
TEST_ASSERT( mbedtls_rsa_check_privkey( &ctx ) == MBEDTLS_ERR_RSA_KEY_CHECK_FAILED );
}
/* END_CASE */
/* BEGIN_CASE */
void mbedtls_rsa_check_pubkey( int radix_N, char *input_N, int radix_E, char *input_E,
int result )
{
mbedtls_rsa_context ctx;
mbedtls_mpi N, E;
mbedtls_mpi_init( &N ); mbedtls_mpi_init( &E );
mbedtls_rsa_init( &ctx, MBEDTLS_RSA_PKCS_V15, 0 );
if( strlen( input_N ) )
{
TEST_ASSERT( mbedtls_mpi_read_string( &N, radix_N, input_N ) == 0 );
}
if( strlen( input_E ) )
{
TEST_ASSERT( mbedtls_mpi_read_string( &E, radix_E, input_E ) == 0 );
}
TEST_ASSERT( mbedtls_rsa_import( &ctx, &N, NULL, NULL, NULL, &E ) == 0 );
TEST_ASSERT( mbedtls_rsa_check_pubkey( &ctx ) == result );
exit:
mbedtls_mpi_free( &N ); mbedtls_mpi_free( &E );
mbedtls_rsa_free( &ctx );
}
/* END_CASE */
/* BEGIN_CASE */
void mbedtls_rsa_check_privkey( 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 radix_D, char *input_D,
int radix_DP, char *input_DP, int radix_DQ,
char *input_DQ, int radix_QP, char *input_QP,
int result )
{
mbedtls_rsa_context ctx;
mbedtls_rsa_init( &ctx, MBEDTLS_RSA_PKCS_V15, 0 );
ctx.len = mod / 8;
if( strlen( input_P ) )
{
TEST_ASSERT( mbedtls_mpi_read_string( &ctx.P, radix_P, input_P ) == 0 );
}
if( strlen( input_Q ) )
{
TEST_ASSERT( mbedtls_mpi_read_string( &ctx.Q, radix_Q, input_Q ) == 0 );
}
if( strlen( input_N ) )
{
TEST_ASSERT( mbedtls_mpi_read_string( &ctx.N, radix_N, input_N ) == 0 );
}
if( strlen( input_E ) )
{
TEST_ASSERT( mbedtls_mpi_read_string( &ctx.E, radix_E, input_E ) == 0 );
}
if( strlen( input_D ) )
{
TEST_ASSERT( mbedtls_mpi_read_string( &ctx.D, radix_D, input_D ) == 0 );
}
#if !defined(MBEDTLS_RSA_NO_CRT)
if( strlen( input_DP ) )
{
TEST_ASSERT( mbedtls_mpi_read_string( &ctx.DP, radix_DP, input_DP ) == 0 );
}
if( strlen( input_DQ ) )
{
TEST_ASSERT( mbedtls_mpi_read_string( &ctx.DQ, radix_DQ, input_DQ ) == 0 );
}
if( strlen( input_QP ) )
{
TEST_ASSERT( mbedtls_mpi_read_string( &ctx.QP, radix_QP, input_QP ) == 0 );
}
#else
((void) radix_DP); ((void) input_DP);
((void) radix_DQ); ((void) input_DQ);
((void) radix_QP); ((void) input_QP);
#endif
TEST_ASSERT( mbedtls_rsa_check_privkey( &ctx ) == result );
exit:
mbedtls_rsa_free( &ctx );
}
/* END_CASE */
/* BEGIN_CASE */
void rsa_check_pubpriv( int mod, int radix_Npub, char *input_Npub,
int radix_Epub, char *input_Epub,
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 radix_D, char *input_D,
int radix_DP, char *input_DP, int radix_DQ,
char *input_DQ, int radix_QP, char *input_QP,
int result )
{
mbedtls_rsa_context pub, prv;
mbedtls_rsa_init( &pub, MBEDTLS_RSA_PKCS_V15, 0 );
mbedtls_rsa_init( &prv, MBEDTLS_RSA_PKCS_V15, 0 );
pub.len = mod / 8;
prv.len = mod / 8;
if( strlen( input_Npub ) )
{
TEST_ASSERT( mbedtls_mpi_read_string( &pub.N, radix_Npub, input_Npub ) == 0 );
}
if( strlen( input_Epub ) )
{
TEST_ASSERT( mbedtls_mpi_read_string( &pub.E, radix_Epub, input_Epub ) == 0 );
}
if( strlen( input_P ) )
{
TEST_ASSERT( mbedtls_mpi_read_string( &prv.P, radix_P, input_P ) == 0 );
}
if( strlen( input_Q ) )
{
TEST_ASSERT( mbedtls_mpi_read_string( &prv.Q, radix_Q, input_Q ) == 0 );
}
if( strlen( input_N ) )
{
TEST_ASSERT( mbedtls_mpi_read_string( &prv.N, radix_N, input_N ) == 0 );
}
if( strlen( input_E ) )
{
TEST_ASSERT( mbedtls_mpi_read_string( &prv.E, radix_E, input_E ) == 0 );
}
if( strlen( input_D ) )
{
TEST_ASSERT( mbedtls_mpi_read_string( &prv.D, radix_D, input_D ) == 0 );
}
#if !defined(MBEDTLS_RSA_NO_CRT)
if( strlen( input_DP ) )
{
TEST_ASSERT( mbedtls_mpi_read_string( &prv.DP, radix_DP, input_DP ) == 0 );
}
if( strlen( input_DQ ) )
{
TEST_ASSERT( mbedtls_mpi_read_string( &prv.DQ, radix_DQ, input_DQ ) == 0 );
}
if( strlen( input_QP ) )
{
TEST_ASSERT( mbedtls_mpi_read_string( &prv.QP, radix_QP, input_QP ) == 0 );
}
#else
((void) radix_DP); ((void) input_DP);
((void) radix_DQ); ((void) input_DQ);
((void) radix_QP); ((void) input_QP);
#endif
TEST_ASSERT( mbedtls_rsa_check_pub_priv( &pub, &prv ) == result );
exit:
mbedtls_rsa_free( &pub );
mbedtls_rsa_free( &prv );
}
/* END_CASE */
/* BEGIN_CASE depends_on:MBEDTLS_CTR_DRBG_C:MBEDTLS_ENTROPY_C:ENTROPY_HAVE_STRONG */
void mbedtls_rsa_gen_key( int nrbits, int exponent, int result)
{
mbedtls_rsa_context ctx;
mbedtls_entropy_context entropy;
mbedtls_ctr_drbg_context ctr_drbg;
const char *pers = "test_suite_rsa";
mbedtls_ctr_drbg_init( &ctr_drbg );
mbedtls_entropy_init( &entropy );
mbedtls_rsa_init ( &ctx, 0, 0 );
TEST_ASSERT( mbedtls_ctr_drbg_seed( &ctr_drbg, mbedtls_entropy_func,
&entropy, (const unsigned char *) pers,
strlen( pers ) ) == 0 );
TEST_ASSERT( mbedtls_rsa_gen_key( &ctx, mbedtls_ctr_drbg_random, &ctr_drbg, nrbits, exponent ) == result );
if( result == 0 )
{
TEST_ASSERT( mbedtls_rsa_check_privkey( &ctx ) == 0 );
TEST_ASSERT( mbedtls_mpi_cmp_mpi( &ctx.P, &ctx.Q ) > 0 );
}
exit:
mbedtls_rsa_free( &ctx );
mbedtls_ctr_drbg_free( &ctr_drbg );
mbedtls_entropy_free( &entropy );
}
/* END_CASE */
/* BEGIN_CASE depends_on:MBEDTLS_CTR_DRBG_C:MBEDTLS_ENTROPY_C */
void mbedtls_rsa_deduce_primes( int radix_N, char *input_N,
int radix_D, char *input_D,
int radix_E, char *input_E,
int radix_P, char *output_P,
int radix_Q, char *output_Q,
int corrupt, int result )
{
mbedtls_mpi N, P, Pp, Q, Qp, D, E;
mbedtls_mpi_init( &N );
mbedtls_mpi_init( &P ); mbedtls_mpi_init( &Q );
mbedtls_mpi_init( &Pp ); mbedtls_mpi_init( &Qp );
mbedtls_mpi_init( &D ); mbedtls_mpi_init( &E );
TEST_ASSERT( mbedtls_mpi_read_string( &N, radix_N, input_N ) == 0 );
TEST_ASSERT( mbedtls_mpi_read_string( &D, radix_D, input_D ) == 0 );
TEST_ASSERT( mbedtls_mpi_read_string( &E, radix_E, input_E ) == 0 );
TEST_ASSERT( mbedtls_mpi_read_string( &Qp, radix_P, output_P ) == 0 );
TEST_ASSERT( mbedtls_mpi_read_string( &Pp, radix_Q, output_Q ) == 0 );
if( corrupt )
TEST_ASSERT( mbedtls_mpi_add_int( &D, &D, 2 ) == 0 );
/* Try to deduce P, Q from N, D, E only. */
TEST_ASSERT( mbedtls_rsa_deduce_primes( &N, &D, &E, &P, &Q ) == result );
if( !corrupt )
{
/* Check if (P,Q) = (Pp, Qp) or (P,Q) = (Qp, Pp) */
TEST_ASSERT( ( mbedtls_mpi_cmp_mpi( &P, &Pp ) == 0 && mbedtls_mpi_cmp_mpi( &Q, &Qp ) == 0 ) ||
( mbedtls_mpi_cmp_mpi( &P, &Qp ) == 0 && mbedtls_mpi_cmp_mpi( &Q, &Pp ) == 0 ) );
}
exit:
mbedtls_mpi_free( &N );
mbedtls_mpi_free( &P ); mbedtls_mpi_free( &Q );
mbedtls_mpi_free( &Pp ); mbedtls_mpi_free( &Qp );
mbedtls_mpi_free( &D ); mbedtls_mpi_free( &E );
}
/* END_CASE */
/* BEGIN_CASE */
void mbedtls_rsa_deduce_private_exponent( int radix_P, char *input_P,
int radix_Q, char *input_Q,
int radix_E, char *input_E,
int radix_D, char *output_D,
int corrupt, int result )
{
mbedtls_mpi P, Q, D, Dp, E, R, Rp;
mbedtls_mpi_init( &P ); mbedtls_mpi_init( &Q );
mbedtls_mpi_init( &D ); mbedtls_mpi_init( &Dp );
mbedtls_mpi_init( &E );
mbedtls_mpi_init( &R ); mbedtls_mpi_init( &Rp );
TEST_ASSERT( mbedtls_mpi_read_string( &P, radix_P, input_P ) == 0 );
TEST_ASSERT( mbedtls_mpi_read_string( &Q, radix_Q, input_Q ) == 0 );
TEST_ASSERT( mbedtls_mpi_read_string( &E, radix_E, input_E ) == 0 );
TEST_ASSERT( mbedtls_mpi_read_string( &Dp, radix_D, output_D ) == 0 );
if( corrupt )
{
/* Make E even */
TEST_ASSERT( mbedtls_mpi_set_bit( &E, 0, 0 ) == 0 );
}
/* Try to deduce D from N, P, Q, E. */
TEST_ASSERT( mbedtls_rsa_deduce_private_exponent( &P, &Q,
&E, &D ) == result );
if( !corrupt )
{
/*
* Check that D and Dp agree modulo LCM(P-1, Q-1).
*/
/* Replace P,Q by P-1, Q-1 */
TEST_ASSERT( mbedtls_mpi_sub_int( &P, &P, 1 ) == 0 );
TEST_ASSERT( mbedtls_mpi_sub_int( &Q, &Q, 1 ) == 0 );
/* Check D == Dp modulo P-1 */
TEST_ASSERT( mbedtls_mpi_mod_mpi( &R, &D, &P ) == 0 );
TEST_ASSERT( mbedtls_mpi_mod_mpi( &Rp, &Dp, &P ) == 0 );
TEST_ASSERT( mbedtls_mpi_cmp_mpi( &R, &Rp ) == 0 );
/* Check D == Dp modulo Q-1 */
TEST_ASSERT( mbedtls_mpi_mod_mpi( &R, &D, &Q ) == 0 );
TEST_ASSERT( mbedtls_mpi_mod_mpi( &Rp, &Dp, &Q ) == 0 );
TEST_ASSERT( mbedtls_mpi_cmp_mpi( &R, &Rp ) == 0 );
}
exit:
mbedtls_mpi_free( &P ); mbedtls_mpi_free( &Q );
mbedtls_mpi_free( &D ); mbedtls_mpi_free( &Dp );
mbedtls_mpi_free( &E );
mbedtls_mpi_free( &R ); mbedtls_mpi_free( &Rp );
}
/* END_CASE */
/* BEGIN_CASE depends_on:MBEDTLS_CTR_DRBG_C:MBEDTLS_ENTROPY_C:ENTROPY_HAVE_STRONG */
void mbedtls_rsa_import( int radix_N, char *input_N,
int radix_P, char *input_P,
int radix_Q, char *input_Q,
int radix_D, char *input_D,
int radix_E, char *input_E,
int successive,
int is_priv,
int res_check,
int res_complete )
{
mbedtls_mpi N, P, Q, D, E;
mbedtls_rsa_context ctx;
/* Buffers used for encryption-decryption test */
unsigned char *buf_orig = NULL;
unsigned char *buf_enc = NULL;
unsigned char *buf_dec = NULL;
mbedtls_entropy_context entropy;
mbedtls_ctr_drbg_context ctr_drbg;
const char *pers = "test_suite_rsa";
const int have_N = ( strlen( input_N ) > 0 );
const int have_P = ( strlen( input_P ) > 0 );
const int have_Q = ( strlen( input_Q ) > 0 );
const int have_D = ( strlen( input_D ) > 0 );
const int have_E = ( strlen( input_E ) > 0 );
mbedtls_ctr_drbg_init( &ctr_drbg );
mbedtls_entropy_init( &entropy );
mbedtls_rsa_init( &ctx, 0, 0 );
mbedtls_mpi_init( &N );
mbedtls_mpi_init( &P ); mbedtls_mpi_init( &Q );
mbedtls_mpi_init( &D ); mbedtls_mpi_init( &E );
TEST_ASSERT( mbedtls_ctr_drbg_seed( &ctr_drbg, mbedtls_entropy_func, &entropy,
(const unsigned char *) pers, strlen( pers ) ) == 0 );
if( have_N )
TEST_ASSERT( mbedtls_mpi_read_string( &N, radix_N, input_N ) == 0 );
if( have_P )
TEST_ASSERT( mbedtls_mpi_read_string( &P, radix_P, input_P ) == 0 );
if( have_Q )
TEST_ASSERT( mbedtls_mpi_read_string( &Q, radix_Q, input_Q ) == 0 );
if( have_D )
TEST_ASSERT( mbedtls_mpi_read_string( &D, radix_D, input_D ) == 0 );
if( have_E )
TEST_ASSERT( mbedtls_mpi_read_string( &E, radix_E, input_E ) == 0 );
if( !successive )
{
TEST_ASSERT( mbedtls_rsa_import( &ctx,
have_N ? &N : NULL,
have_P ? &P : NULL,
have_Q ? &Q : NULL,
have_D ? &D : NULL,
have_E ? &E : NULL ) == 0 );
}
else
{
/* Import N, P, Q, D, E separately.
* This should make no functional difference. */
TEST_ASSERT( mbedtls_rsa_import( &ctx,
have_N ? &N : NULL,
NULL, NULL, NULL, NULL ) == 0 );
TEST_ASSERT( mbedtls_rsa_import( &ctx,
NULL,
have_P ? &P : NULL,
NULL, NULL, NULL ) == 0 );
TEST_ASSERT( mbedtls_rsa_import( &ctx,
NULL, NULL,
have_Q ? &Q : NULL,
NULL, NULL ) == 0 );
TEST_ASSERT( mbedtls_rsa_import( &ctx,
NULL, NULL, NULL,
have_D ? &D : NULL,
NULL ) == 0 );
TEST_ASSERT( mbedtls_rsa_import( &ctx,
NULL, NULL, NULL, NULL,
have_E ? &E : NULL ) == 0 );
}
TEST_ASSERT( mbedtls_rsa_complete( &ctx ) == res_complete );
/* On expected success, perform some public and private
* key operations to check if the key is working properly. */
if( res_complete == 0 )
{
if( is_priv )
TEST_ASSERT( mbedtls_rsa_check_privkey( &ctx ) == res_check );
else
TEST_ASSERT( mbedtls_rsa_check_pubkey( &ctx ) == res_check );
if( res_check != 0 )
goto exit;
buf_orig = mbedtls_calloc( 1, mbedtls_rsa_get_len( &ctx ) );
buf_enc = mbedtls_calloc( 1, mbedtls_rsa_get_len( &ctx ) );
buf_dec = mbedtls_calloc( 1, mbedtls_rsa_get_len( &ctx ) );
if( buf_orig == NULL || buf_enc == NULL || buf_dec == NULL )
goto exit;
TEST_ASSERT( mbedtls_ctr_drbg_random( &ctr_drbg,
buf_orig, mbedtls_rsa_get_len( &ctx ) ) == 0 );
/* Make sure the number we're generating is smaller than the modulus */
buf_orig[0] = 0x00;
TEST_ASSERT( mbedtls_rsa_public( &ctx, buf_orig, buf_enc ) == 0 );
if( is_priv )
{
TEST_ASSERT( mbedtls_rsa_private( &ctx, mbedtls_ctr_drbg_random,
&ctr_drbg, buf_enc,
buf_dec ) == 0 );
TEST_ASSERT( memcmp( buf_orig, buf_dec,
mbedtls_rsa_get_len( &ctx ) ) == 0 );
}
}
exit:
mbedtls_free( buf_orig );
mbedtls_free( buf_enc );
mbedtls_free( buf_dec );
mbedtls_rsa_free( &ctx );
mbedtls_ctr_drbg_free( &ctr_drbg );
mbedtls_entropy_free( &entropy );
mbedtls_mpi_free( &N );
mbedtls_mpi_free( &P ); mbedtls_mpi_free( &Q );
mbedtls_mpi_free( &D ); mbedtls_mpi_free( &E );
}
/* END_CASE */
/* BEGIN_CASE */
void mbedtls_rsa_export( int radix_N, char *input_N,
int radix_P, char *input_P,
int radix_Q, char *input_Q,
int radix_D, char *input_D,
int radix_E, char *input_E,
int is_priv,
int successive )
{
/* Original MPI's with which we set up the RSA context */
mbedtls_mpi N, P, Q, D, E;
/* Exported MPI's */
mbedtls_mpi Ne, Pe, Qe, De, Ee;
const int have_N = ( strlen( input_N ) > 0 );
const int have_P = ( strlen( input_P ) > 0 );
const int have_Q = ( strlen( input_Q ) > 0 );
const int have_D = ( strlen( input_D ) > 0 );
const int have_E = ( strlen( input_E ) > 0 );
mbedtls_rsa_context ctx;
mbedtls_rsa_init( &ctx, 0, 0 );
mbedtls_mpi_init( &N );
mbedtls_mpi_init( &P ); mbedtls_mpi_init( &Q );
mbedtls_mpi_init( &D ); mbedtls_mpi_init( &E );
mbedtls_mpi_init( &Ne );
mbedtls_mpi_init( &Pe ); mbedtls_mpi_init( &Qe );
mbedtls_mpi_init( &De ); mbedtls_mpi_init( &Ee );
/* Setup RSA context */
if( have_N )
TEST_ASSERT( mbedtls_mpi_read_string( &N, radix_N, input_N ) == 0 );
if( have_P )
TEST_ASSERT( mbedtls_mpi_read_string( &P, radix_P, input_P ) == 0 );
if( have_Q )
TEST_ASSERT( mbedtls_mpi_read_string( &Q, radix_Q, input_Q ) == 0 );
if( have_D )
TEST_ASSERT( mbedtls_mpi_read_string( &D, radix_D, input_D ) == 0 );
if( have_E )
TEST_ASSERT( mbedtls_mpi_read_string( &E, radix_E, input_E ) == 0 );
TEST_ASSERT( mbedtls_rsa_import( &ctx,
strlen( input_N ) ? &N : NULL,
strlen( input_P ) ? &P : NULL,
strlen( input_Q ) ? &Q : NULL,
strlen( input_D ) ? &D : NULL,
strlen( input_E ) ? &E : NULL ) == 0 );
TEST_ASSERT( mbedtls_rsa_complete( &ctx ) == 0 );
/*
* Export parameters and compare to original ones.
*/
/* N and E must always be present. */
if( !successive )
{
TEST_ASSERT( mbedtls_rsa_export( &ctx, &Ne, NULL, NULL, NULL, &Ee ) == 0 );
}
else
{
TEST_ASSERT( mbedtls_rsa_export( &ctx, &Ne, NULL, NULL, NULL, NULL ) == 0 );
TEST_ASSERT( mbedtls_rsa_export( &ctx, NULL, NULL, NULL, NULL, &Ee ) == 0 );
}
TEST_ASSERT( mbedtls_mpi_cmp_mpi( &N, &Ne ) == 0 );
TEST_ASSERT( mbedtls_mpi_cmp_mpi( &E, &Ee ) == 0 );
/* If we were providing enough information to setup a complete private context,
* we expect to be able to export all core parameters. */
if( is_priv )
{
if( !successive )
{
TEST_ASSERT( mbedtls_rsa_export( &ctx, NULL, &Pe, &Qe,
&De, NULL ) == 0 );
}
else
{
TEST_ASSERT( mbedtls_rsa_export( &ctx, NULL, &Pe, NULL,
NULL, NULL ) == 0 );
TEST_ASSERT( mbedtls_rsa_export( &ctx, NULL, NULL, &Qe,
NULL, NULL ) == 0 );
TEST_ASSERT( mbedtls_rsa_export( &ctx, NULL, NULL, NULL,
&De, NULL ) == 0 );
}
if( have_P )
TEST_ASSERT( mbedtls_mpi_cmp_mpi( &P, &Pe ) == 0 );
if( have_Q )
TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Q, &Qe ) == 0 );
if( have_D )
TEST_ASSERT( mbedtls_mpi_cmp_mpi( &D, &De ) == 0 );
/* While at it, perform a sanity check */
TEST_ASSERT( mbedtls_rsa_validate_params( &Ne, &Pe, &Qe, &De, &Ee,
NULL, NULL ) == 0 );
}
exit:
mbedtls_rsa_free( &ctx );
mbedtls_mpi_free( &N );
mbedtls_mpi_free( &P ); mbedtls_mpi_free( &Q );
mbedtls_mpi_free( &D ); mbedtls_mpi_free( &E );
mbedtls_mpi_free( &Ne );
mbedtls_mpi_free( &Pe ); mbedtls_mpi_free( &Qe );
mbedtls_mpi_free( &De ); mbedtls_mpi_free( &Ee );
}
/* END_CASE */
/* BEGIN_CASE depends_on:MBEDTLS_ENTROPY_C:ENTROPY_HAVE_STRONG */
void mbedtls_rsa_validate_params( int radix_N, char *input_N,
int radix_P, char *input_P,
int radix_Q, char *input_Q,
int radix_D, char *input_D,
int radix_E, char *input_E,
int prng, int result )
{
/* Original MPI's with which we set up the RSA context */
mbedtls_mpi N, P, Q, D, E;
const int have_N = ( strlen( input_N ) > 0 );
const int have_P = ( strlen( input_P ) > 0 );
const int have_Q = ( strlen( input_Q ) > 0 );
const int have_D = ( strlen( input_D ) > 0 );
const int have_E = ( strlen( input_E ) > 0 );
mbedtls_entropy_context entropy;
mbedtls_ctr_drbg_context ctr_drbg;
const char *pers = "test_suite_rsa";
mbedtls_mpi_init( &N );
mbedtls_mpi_init( &P ); mbedtls_mpi_init( &Q );
mbedtls_mpi_init( &D ); mbedtls_mpi_init( &E );
mbedtls_ctr_drbg_init( &ctr_drbg );
mbedtls_entropy_init( &entropy );
TEST_ASSERT( mbedtls_ctr_drbg_seed( &ctr_drbg, mbedtls_entropy_func,
&entropy, (const unsigned char *) pers,
strlen( pers ) ) == 0 );
if( have_N )
TEST_ASSERT( mbedtls_mpi_read_string( &N, radix_N, input_N ) == 0 );
if( have_P )
TEST_ASSERT( mbedtls_mpi_read_string( &P, radix_P, input_P ) == 0 );
if( have_Q )
TEST_ASSERT( mbedtls_mpi_read_string( &Q, radix_Q, input_Q ) == 0 );
if( have_D )
TEST_ASSERT( mbedtls_mpi_read_string( &D, radix_D, input_D ) == 0 );
if( have_E )
TEST_ASSERT( mbedtls_mpi_read_string( &E, radix_E, input_E ) == 0 );
TEST_ASSERT( mbedtls_rsa_validate_params( have_N ? &N : NULL,
have_P ? &P : NULL,
have_Q ? &Q : NULL,
have_D ? &D : NULL,
have_E ? &E : NULL,
prng ? mbedtls_ctr_drbg_random : NULL,
prng ? &ctr_drbg : NULL ) == result );
exit:
mbedtls_ctr_drbg_free( &ctr_drbg );
mbedtls_entropy_free( &entropy );
mbedtls_mpi_free( &N );
mbedtls_mpi_free( &P ); mbedtls_mpi_free( &Q );
mbedtls_mpi_free( &D ); mbedtls_mpi_free( &E );
}
/* END_CASE */
/* BEGIN_CASE depends_on:MBEDTLS_CTR_DRBG_C:MBEDTLS_ENTROPY_C */
void mbedtls_rsa_export_raw( char *input_N, char *input_P,
char *input_Q, char *input_D,
char *input_E, int is_priv,
int successive )
{
/* Original raw buffers with which we set up the RSA context */
unsigned char bufN[1000];
unsigned char bufP[1000];
unsigned char bufQ[1000];
unsigned char bufD[1000];
unsigned char bufE[1000];
size_t lenN = 0;
size_t lenP = 0;
size_t lenQ = 0;
size_t lenD = 0;
size_t lenE = 0;
/* Exported buffers */
unsigned char bufNe[ sizeof( bufN ) ];
unsigned char bufPe[ sizeof( bufP ) ];
unsigned char bufQe[ sizeof( bufQ ) ];
unsigned char bufDe[ sizeof( bufD ) ];
unsigned char bufEe[ sizeof( bufE ) ];
const int have_N = ( strlen( input_N ) > 0 );
const int have_P = ( strlen( input_P ) > 0 );
const int have_Q = ( strlen( input_Q ) > 0 );
const int have_D = ( strlen( input_D ) > 0 );
const int have_E = ( strlen( input_E ) > 0 );
mbedtls_rsa_context ctx;
mbedtls_rsa_init( &ctx, 0, 0 );
/* Setup RSA context */
if( have_N )
lenN = unhexify( bufN, input_N );
if( have_P )
lenP = unhexify( bufP, input_P );
if( have_Q )
lenQ = unhexify( bufQ, input_Q );
if( have_D )
lenD = unhexify( bufD, input_D );
if( have_E )
lenE = unhexify( bufE, input_E );
TEST_ASSERT( mbedtls_rsa_import_raw( &ctx,
have_N ? bufN : NULL, lenN,
have_P ? bufP : NULL, lenP,
have_Q ? bufQ : NULL, lenQ,
have_D ? bufD : NULL, lenD,
have_E ? bufE : NULL, lenE ) == 0 );
TEST_ASSERT( mbedtls_rsa_complete( &ctx ) == 0 );
/*
* Export parameters and compare to original ones.
*/
/* N and E must always be present. */
if( !successive )
{
TEST_ASSERT( mbedtls_rsa_export_raw( &ctx, bufNe, lenN,
NULL, 0, NULL, 0, NULL, 0,
bufEe, lenE ) == 0 );
}
else
{
TEST_ASSERT( mbedtls_rsa_export_raw( &ctx, bufNe, lenN,
NULL, 0, NULL, 0, NULL, 0,
NULL, 0 ) == 0 );
TEST_ASSERT( mbedtls_rsa_export_raw( &ctx, NULL, 0,
NULL, 0, NULL, 0, NULL, 0,
bufEe, lenE ) == 0 );
}
TEST_ASSERT( memcmp( bufN, bufNe, lenN ) == 0 );
TEST_ASSERT( memcmp( bufE, bufEe, lenE ) == 0 );
/* If we were providing enough information to setup a complete private context,
* we expect to be able to export all core parameters. */
if( is_priv )
{
if( !successive )
{
TEST_ASSERT( mbedtls_rsa_export_raw( &ctx, NULL, 0,
bufPe, lenP ? lenP : sizeof( bufPe ),
bufQe, lenQ ? lenQ : sizeof( bufQe ),
bufDe, lenD ? lenD : sizeof( bufDe ),
NULL, 0 ) == 0 );
}
else
{
TEST_ASSERT( mbedtls_rsa_export_raw( &ctx, NULL, 0,
bufPe, lenP ? lenP : sizeof( bufPe ),
NULL, 0, NULL, 0,
NULL, 0 ) == 0 );
TEST_ASSERT( mbedtls_rsa_export_raw( &ctx, NULL, 0, NULL, 0,
bufQe, lenQ ? lenQ : sizeof( bufQe ),
NULL, 0, NULL, 0 ) == 0 );
TEST_ASSERT( mbedtls_rsa_export_raw( &ctx, NULL, 0, NULL, 0,
NULL, 0, bufDe, lenD ? lenD : sizeof( bufDe ),
NULL, 0 ) == 0 );
}
if( have_P )
TEST_ASSERT( memcmp( bufP, bufPe, lenP ) == 0 );
if( have_Q )
TEST_ASSERT( memcmp( bufQ, bufQe, lenQ ) == 0 );
if( have_D )
TEST_ASSERT( memcmp( bufD, bufDe, lenD ) == 0 );
}
exit:
mbedtls_rsa_free( &ctx );
}
/* END_CASE */
/* BEGIN_CASE depends_on:MBEDTLS_CTR_DRBG_C:MBEDTLS_ENTROPY_C:ENTROPY_HAVE_STRONG */
void mbedtls_rsa_import_raw( char *input_N,
char *input_P, char *input_Q,
char *input_D, char *input_E,
int successive,
int is_priv,
int res_check,
int res_complete )
{
unsigned char bufN[1000];
unsigned char bufP[1000];
unsigned char bufQ[1000];
unsigned char bufD[1000];
unsigned char bufE[1000];
/* Buffers used for encryption-decryption test */
unsigned char *buf_orig = NULL;
unsigned char *buf_enc = NULL;
unsigned char *buf_dec = NULL;
size_t lenN = 0;
size_t lenP = 0;
size_t lenQ = 0;
size_t lenD = 0;
size_t lenE = 0;
mbedtls_rsa_context ctx;
mbedtls_entropy_context entropy;
mbedtls_ctr_drbg_context ctr_drbg;
const char *pers = "test_suite_rsa";
mbedtls_ctr_drbg_init( &ctr_drbg );
mbedtls_entropy_init( &entropy );
mbedtls_rsa_init( &ctx, 0, 0 );
TEST_ASSERT( mbedtls_ctr_drbg_seed( &ctr_drbg, mbedtls_entropy_func,
&entropy, (const unsigned char *) pers,
strlen( pers ) ) == 0 );
if( strlen( input_N ) )
lenN = unhexify( bufN, input_N );
if( strlen( input_P ) )
lenP = unhexify( bufP, input_P );
if( strlen( input_Q ) )
lenQ = unhexify( bufQ, input_Q );
if( strlen( input_D ) )
lenD = unhexify( bufD, input_D );
if( strlen( input_E ) )
lenE = unhexify( bufE, input_E );
if( !successive )
{
TEST_ASSERT( mbedtls_rsa_import_raw( &ctx,
( lenN > 0 ) ? bufN : NULL, lenN,
( lenP > 0 ) ? bufP : NULL, lenP,
( lenQ > 0 ) ? bufQ : NULL, lenQ,
( lenD > 0 ) ? bufD : NULL, lenD,
( lenE > 0 ) ? bufE : NULL, lenE ) == 0 );
}
else
{
/* Import N, P, Q, D, E separately.
* This should make no functional difference. */
TEST_ASSERT( mbedtls_rsa_import_raw( &ctx,
( lenN > 0 ) ? bufN : NULL, lenN,
NULL, 0, NULL, 0, NULL, 0, NULL, 0 ) == 0 );
TEST_ASSERT( mbedtls_rsa_import_raw( &ctx,
NULL, 0,
( lenP > 0 ) ? bufP : NULL, lenP,
NULL, 0, NULL, 0, NULL, 0 ) == 0 );
TEST_ASSERT( mbedtls_rsa_import_raw( &ctx,
NULL, 0, NULL, 0,
( lenQ > 0 ) ? bufQ : NULL, lenQ,
NULL, 0, NULL, 0 ) == 0 );
TEST_ASSERT( mbedtls_rsa_import_raw( &ctx,
NULL, 0, NULL, 0, NULL, 0,
( lenD > 0 ) ? bufD : NULL, lenD,
NULL, 0 ) == 0 );
TEST_ASSERT( mbedtls_rsa_import_raw( &ctx,
NULL, 0, NULL, 0, NULL, 0, NULL, 0,
( lenE > 0 ) ? bufE : NULL, lenE ) == 0 );
}
TEST_ASSERT( mbedtls_rsa_complete( &ctx ) == res_complete );
/* On expected success, perform some public and private
* key operations to check if the key is working properly. */
if( res_complete == 0 )
{
if( is_priv )
TEST_ASSERT( mbedtls_rsa_check_privkey( &ctx ) == res_check );
else
TEST_ASSERT( mbedtls_rsa_check_pubkey( &ctx ) == res_check );
if( res_check != 0 )
goto exit;
buf_orig = mbedtls_calloc( 1, mbedtls_rsa_get_len( &ctx ) );
buf_enc = mbedtls_calloc( 1, mbedtls_rsa_get_len( &ctx ) );
buf_dec = mbedtls_calloc( 1, mbedtls_rsa_get_len( &ctx ) );
if( buf_orig == NULL || buf_enc == NULL || buf_dec == NULL )
goto exit;
TEST_ASSERT( mbedtls_ctr_drbg_random( &ctr_drbg,
buf_orig, mbedtls_rsa_get_len( &ctx ) ) == 0 );
/* Make sure the number we're generating is smaller than the modulus */
buf_orig[0] = 0x00;
TEST_ASSERT( mbedtls_rsa_public( &ctx, buf_orig, buf_enc ) == 0 );
if( is_priv )
{
TEST_ASSERT( mbedtls_rsa_private( &ctx, mbedtls_ctr_drbg_random,
&ctr_drbg, buf_enc,
buf_dec ) == 0 );
TEST_ASSERT( memcmp( buf_orig, buf_dec,
mbedtls_rsa_get_len( &ctx ) ) == 0 );
}
}
exit:
mbedtls_free( buf_orig );
mbedtls_free( buf_enc );
mbedtls_free( buf_dec );
mbedtls_rsa_free( &ctx );
mbedtls_ctr_drbg_free( &ctr_drbg );
mbedtls_entropy_free( &entropy );
}
/* END_CASE */
/* BEGIN_CASE depends_on:MBEDTLS_SELF_TEST */
void rsa_selftest()
{
TEST_ASSERT( mbedtls_rsa_self_test( 1 ) == 0 );
}
/* END_CASE */