mbedtls/tests/suites/test_suite_pk.function
Andrzej Kurek e735310551 Declare mbedtls_pk_info_t through macro
New macro MBEDTLS_PK_OPAQUE_INFO_1 to initialize mbedtls_pk_info_t structures.
Document that this macro must be used in engine implementations for forward
compatibility. Use this macro rather than accessing the structure directly
in tests and in the sample engine to set a good example.
2018-01-22 07:52:58 -05:00

1000 lines
35 KiB
Plaintext

/* BEGIN_HEADER */
#include <string.h>
#include "mbedtls/pk.h"
#include "mbedtls/pk_info.h"
/* For error codes */
#include "mbedtls/ecp.h"
#include "mbedtls/rsa.h"
/* For detecting 64-bit compilation */
#include "mbedtls/bignum.h"
static int rnd_std_rand( void *rng_state, unsigned char *output, size_t len );
#define RSA_KEY_SIZE 512
#define RSA_KEY_LEN 64
static int pk_genkey( mbedtls_pk_context *pk )
{
((void) pk);
#if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_GENPRIME)
if( mbedtls_pk_get_type( pk ) == MBEDTLS_PK_RSA )
return mbedtls_rsa_gen_key( mbedtls_pk_rsa( *pk ), rnd_std_rand, NULL, RSA_KEY_SIZE, 3 );
#endif
#if defined(MBEDTLS_ECP_C)
if( mbedtls_pk_get_type( pk ) == MBEDTLS_PK_ECKEY ||
mbedtls_pk_get_type( pk ) == MBEDTLS_PK_ECKEY_DH ||
mbedtls_pk_get_type( pk ) == MBEDTLS_PK_ECDSA )
{
int ret;
if( ( ret = mbedtls_ecp_group_load( &mbedtls_pk_ec( *pk )->grp,
MBEDTLS_ECP_DP_SECP192R1 ) ) != 0 )
return( ret );
return mbedtls_ecp_gen_keypair( &mbedtls_pk_ec( *pk )->grp, &mbedtls_pk_ec( *pk )->d,
&mbedtls_pk_ec( *pk )->Q, rnd_std_rand, NULL );
}
#endif
return( -1 );
}
#if defined(MBEDTLS_RSA_C)
static int mbedtls_rsa_decrypt_func( void *ctx, int mode, size_t *olen,
const unsigned char *input, unsigned char *output,
size_t output_max_len )
{
return( mbedtls_rsa_pkcs1_decrypt( (mbedtls_rsa_context *) ctx, NULL, NULL, mode, olen,
input, output, output_max_len ) );
}
static int mbedtls_rsa_sign_func( void *ctx,
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng,
int mode, mbedtls_md_type_t md_alg, unsigned int hashlen,
const unsigned char *hash, unsigned char *sig )
{
return( mbedtls_rsa_pkcs1_sign( (mbedtls_rsa_context *) ctx, f_rng, p_rng, mode,
md_alg, hashlen, hash, sig ) );
}
static size_t mbedtls_rsa_key_len_func( void *ctx )
{
return( ((const mbedtls_rsa_context *) ctx)->len );
}
/* Prepare a raw RSA context with a small random key. */
static void pk_rsa_prepare( mbedtls_rsa_context *raw )
{
mbedtls_rsa_init( raw, MBEDTLS_RSA_PKCS_V15, MBEDTLS_MD_NONE );
mbedtls_rsa_gen_key( raw, rnd_std_rand, NULL, RSA_KEY_SIZE, 3 );
}
/* Test the RSA context tested_ctx by comparing its operation with a
generic RSA context which is initialized with the key in raw. */
static void pk_rsa_match( mbedtls_rsa_context *raw,
mbedtls_pk_context *tested_ctx,
int sign_ret, int verify_ret,
int encrypt_ret, int decrypt_ret,
int debug_ret )
{
mbedtls_pk_context basic_ctx;
mbedtls_pk_debug_item dbg_items[10];
unsigned char hash[50], sig[1000];
unsigned char msg[50], ciph[1000], test[1000];
size_t sig_len, ciph_len, test_len;
memset( hash, 0x2a, sizeof hash );
memset( sig, 0, sizeof sig );
memset( msg, 0x2a, sizeof msg );
memset( ciph, 0, sizeof ciph );
memset( test, 0, sizeof test );
/* Initiliaze basic PK RSA context with raw key */
mbedtls_pk_init( &basic_ctx );
TEST_ASSERT( mbedtls_pk_setup( &basic_ctx,
mbedtls_pk_info_from_type( MBEDTLS_PK_RSA ) ) == 0 );
TEST_ASSERT( mbedtls_rsa_copy( mbedtls_pk_rsa( basic_ctx ), raw ) == 0 );
/* Test administrative functions */
TEST_ASSERT( mbedtls_pk_can_do( tested_ctx, MBEDTLS_PK_RSA ) );
TEST_ASSERT( mbedtls_pk_get_bitlen( tested_ctx ) == RSA_KEY_SIZE );
TEST_ASSERT( mbedtls_pk_get_len( tested_ctx ) == RSA_KEY_LEN );
TEST_ASSERT( mbedtls_pk_signature_size( tested_ctx ) == RSA_KEY_LEN );
/* Test signature */
TEST_ASSERT( mbedtls_pk_sign( tested_ctx, MBEDTLS_MD_NONE, hash, sizeof hash,
sig, &sig_len, rnd_std_rand, NULL ) == sign_ret );
if( sign_ret == 0 )
{
#if defined(MBEDTLS_HAVE_INT64)
TEST_ASSERT( mbedtls_pk_sign( tested_ctx, MBEDTLS_MD_NONE, hash, (size_t)-1,
NULL, NULL, rnd_std_rand, NULL ) ==
MBEDTLS_ERR_PK_BAD_INPUT_DATA );
#endif /* MBEDTLS_HAVE_INT64 */
TEST_ASSERT( sig_len == RSA_KEY_LEN );
TEST_ASSERT( mbedtls_pk_verify( &basic_ctx, MBEDTLS_MD_NONE,
hash, sizeof hash, sig, sig_len ) == 0 );
}
/* Test verification */
TEST_ASSERT( mbedtls_pk_sign( &basic_ctx, MBEDTLS_MD_NONE, hash, sizeof hash,
sig, &sig_len, rnd_std_rand, NULL ) == 0 );
TEST_ASSERT( mbedtls_pk_verify( tested_ctx, MBEDTLS_MD_NONE,
hash, sizeof hash, sig, sig_len ) == verify_ret );
if( verify_ret == 0 )
{
TEST_ASSERT( mbedtls_pk_verify( tested_ctx, MBEDTLS_MD_NONE,
hash, sizeof hash, sig, sig_len - 1 ) == MBEDTLS_ERR_RSA_VERIFY_FAILED );
sig[sig_len-1] ^= 1;
TEST_ASSERT( mbedtls_pk_verify( tested_ctx, MBEDTLS_MD_NONE,
hash, sizeof hash, sig, sig_len ) == MBEDTLS_ERR_RSA_INVALID_PADDING );
}
/* Test encryption */
TEST_ASSERT( mbedtls_pk_encrypt( tested_ctx, msg, sizeof msg,
ciph, &ciph_len, sizeof ciph,
rnd_std_rand, NULL ) == encrypt_ret );
if( encrypt_ret == 0 )
{
TEST_ASSERT( mbedtls_pk_decrypt( &basic_ctx, ciph, ciph_len,
test, &test_len, sizeof test,
rnd_std_rand, NULL ) == 0 );
TEST_ASSERT( test_len == sizeof msg );
TEST_ASSERT( memcmp( test, msg, test_len ) == 0 );
}
/* Test decryption */
TEST_ASSERT( mbedtls_pk_encrypt( &basic_ctx, msg, sizeof msg,
ciph, &ciph_len, sizeof ciph,
rnd_std_rand, NULL ) == 0 );
TEST_ASSERT( mbedtls_pk_decrypt( tested_ctx, ciph, ciph_len,
test, &test_len, sizeof test,
rnd_std_rand, NULL ) == decrypt_ret );
if( decrypt_ret == 0 )
{
TEST_ASSERT( test_len == sizeof msg );
TEST_ASSERT( memcmp( test, msg, test_len ) == 0 );
}
/* Test debug */
TEST_ASSERT( mbedtls_pk_debug( tested_ctx, dbg_items ) == debug_ret );
exit:
mbedtls_pk_free( &basic_ctx );
}
#define OPAQUE_MOCK_CAN_DO MBEDTLS_PK_RSA
#define OPAQUE_MOCK_BITLEN 'b'
#define OPAQUE_MOCK_MD_ALG MBEDTLS_MD_SHA256
#define OPAQUE_MOCK_SIGNATURE_SIZE 4
#define OPAQUE_MOCK_GOOD_SIGNATURE "good"
static const unsigned char opaque_mock_hash[8] = "HASHhash";
static const unsigned char opaque_mock_reference_input[10] = "INPUTinput";
static const unsigned char opaque_mock_input[10] = "INPUTinput";
static const unsigned char opaque_mock_reference_encrypted[12] = "C:JOQVUjoqvu";
static const unsigned char opaque_mock_reference_decrypted[12] = "P:HMOTShmots";
static char opaque_mock_fake_ctx = 'c';
static mbedtls_pk_debug_item opaque_mock_pk_debug_item;
static int opaque_mock_debug_called_correctly = 0;
static int opaque_mock_free_called_correctly = 0;
static size_t opaque_mock_get_bitlen( const void *ctx )
{
TEST_ASSERT( ctx == &opaque_mock_fake_ctx );
return( OPAQUE_MOCK_BITLEN );
exit:
return( INT_MIN );
}
static int opaque_mock_can_do( const void *ctx,
mbedtls_pk_type_t type )
{
TEST_ASSERT( ctx == &opaque_mock_fake_ctx );
return( type == OPAQUE_MOCK_CAN_DO );
exit:
return( INT_MIN );
}
static int opaque_mock_verify_func( void *ctx, mbedtls_md_type_t md_alg,
const unsigned char *hash, size_t hash_len,
const unsigned char *sig, size_t sig_len )
{
TEST_ASSERT( ctx == &opaque_mock_fake_ctx );
TEST_ASSERT( md_alg == OPAQUE_MOCK_MD_ALG );
TEST_ASSERT( hash_len == sizeof( opaque_mock_hash ) );
TEST_ASSERT( hash == opaque_mock_hash );
if( sig_len != OPAQUE_MOCK_SIGNATURE_SIZE )
return( MBEDTLS_ERR_PK_SIG_LEN_MISMATCH );
if( memcmp( sig, OPAQUE_MOCK_GOOD_SIGNATURE, OPAQUE_MOCK_SIGNATURE_SIZE ) )
return( MBEDTLS_ERR_PK_INVALID_SIGNATURE );
return( 0 );
exit:
return( INT_MIN );
}
static int opaque_mock_sign_func( void *ctx, mbedtls_md_type_t md_alg,
const unsigned char *hash, size_t hash_len,
unsigned char *sig, size_t *sig_len,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng )
{
TEST_ASSERT( ctx == &opaque_mock_fake_ctx );
TEST_ASSERT( md_alg == OPAQUE_MOCK_MD_ALG );
TEST_ASSERT( hash_len == sizeof( opaque_mock_hash ) );
TEST_ASSERT( hash == opaque_mock_hash );
memcpy( sig, OPAQUE_MOCK_GOOD_SIGNATURE, OPAQUE_MOCK_SIGNATURE_SIZE );
*sig_len = OPAQUE_MOCK_SIGNATURE_SIZE;
(void) f_rng;
(void) p_rng;
return( 0 );
exit:
return( INT_MIN );
}
static int opaque_mock_decrypt_func( void *ctx, const unsigned char *input, size_t ilen,
unsigned char *output, size_t *olen, size_t osize,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng )
{
TEST_ASSERT( ctx == &opaque_mock_fake_ctx );
TEST_ASSERT( ilen == sizeof( opaque_mock_reference_input ) );
TEST_ASSERT( !memcmp( input, opaque_mock_reference_input,
sizeof( opaque_mock_reference_input ) ) );
if( osize < sizeof( opaque_mock_reference_decrypted ) )
return( MBEDTLS_ERR_PK_BUFFER_TOO_SMALL );
*olen = sizeof( opaque_mock_reference_decrypted );
memcpy( output, opaque_mock_reference_decrypted, sizeof( opaque_mock_reference_decrypted ) );
(void) f_rng;
(void) p_rng;
return( 0 );
exit:
return( INT_MIN );
}
static int opaque_mock_encrypt_func( void *ctx, const unsigned char *input, size_t ilen,
unsigned char *output, size_t *olen, size_t osize,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng )
{
TEST_ASSERT( ctx == &opaque_mock_fake_ctx );
TEST_ASSERT( ilen == sizeof( opaque_mock_reference_input ) );
TEST_ASSERT( !memcmp( input, opaque_mock_reference_input,
sizeof( opaque_mock_reference_input ) ) );
if( osize < sizeof( opaque_mock_reference_encrypted ) )
return( MBEDTLS_ERR_PK_BUFFER_TOO_SMALL );
*olen = sizeof( opaque_mock_reference_encrypted );
memcpy( output, opaque_mock_reference_encrypted, sizeof( opaque_mock_reference_encrypted ) );
(void) f_rng;
(void) p_rng;
return( 0 );
exit:
return( INT_MIN );
}
static int opaque_mock_check_pair_func( const mbedtls_pk_context *pub,
const void *prv )
{
TEST_ASSERT( prv == &opaque_mock_fake_ctx );
if( mbedtls_pk_get_type( pub ) != MBEDTLS_PK_RSA )
return( MBEDTLS_ERR_PK_TYPE_MISMATCH );
return( 0 );
exit:
return( INT_MIN );
}
static void *opaque_mock_ctx_alloc_func( void )
{
return( &opaque_mock_fake_ctx );
}
static void *opaque_mock_ctx_alloc_fail( void )
{
return( NULL );
}
static void opaque_mock_ctx_free_func( void *ctx )
{
TEST_ASSERT( ctx == &opaque_mock_fake_ctx );
opaque_mock_free_called_correctly = 1;
exit:
return;
}
static void opaque_mock_debug_func( const void *ctx,
mbedtls_pk_debug_item *items )
{
TEST_ASSERT( ctx == &opaque_mock_fake_ctx );
TEST_ASSERT( items == &opaque_mock_pk_debug_item );
opaque_mock_debug_called_correctly = 1;
exit:
return;
}
static size_t opaque_mock_signature_size_func( const void *ctx )
{
TEST_ASSERT( ctx == &opaque_mock_fake_ctx );
return( OPAQUE_MOCK_SIGNATURE_SIZE );
exit:
return( -1 );
}
#endif /* MBEDTLS_RSA_C */
/* END_HEADER */
/* BEGIN_DEPENDENCIES
* depends_on:MBEDTLS_PK_C
* END_DEPENDENCIES
*/
/* BEGIN_CASE */
void pk_utils( int type, int size, int len, char *name )
{
mbedtls_pk_context pk;
mbedtls_pk_init( &pk );
TEST_ASSERT( mbedtls_pk_setup( &pk, mbedtls_pk_info_from_type( type ) ) == 0 );
TEST_ASSERT( pk_genkey( &pk ) == 0 );
TEST_ASSERT( (int) mbedtls_pk_get_type( &pk ) == type );
TEST_ASSERT( mbedtls_pk_can_do( &pk, type ) );
TEST_ASSERT( mbedtls_pk_get_bitlen( &pk ) == (unsigned) size );
TEST_ASSERT( mbedtls_pk_get_len( &pk ) == (unsigned) len );
TEST_ASSERT( strcmp( mbedtls_pk_get_name( &pk), name ) == 0 );
exit:
mbedtls_pk_free( &pk );
}
/* END_CASE */
/* BEGIN_CASE depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_FS_IO */
void mbedtls_pk_check_pair( char *pub_file, char *prv_file, int ret )
{
mbedtls_pk_context pub, prv, alt;
mbedtls_pk_init( &pub );
mbedtls_pk_init( &prv );
mbedtls_pk_init( &alt );
TEST_ASSERT( mbedtls_pk_parse_public_keyfile( &pub, pub_file ) == 0 );
TEST_ASSERT( mbedtls_pk_parse_keyfile( &prv, prv_file, NULL ) == 0 );
TEST_ASSERT( mbedtls_pk_check_pair( &pub, &prv ) == ret );
#if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_PK_RSA_ALT_SUPPORT)
if( mbedtls_pk_get_type( &prv ) == MBEDTLS_PK_RSA )
{
TEST_ASSERT( mbedtls_pk_setup_rsa_alt( &alt, mbedtls_pk_rsa( prv ),
mbedtls_rsa_decrypt_func, mbedtls_rsa_sign_func, mbedtls_rsa_key_len_func ) == 0 );
TEST_ASSERT( mbedtls_pk_check_pair( &pub, &alt ) == ret );
}
#endif
mbedtls_pk_free( &pub );
mbedtls_pk_free( &prv );
mbedtls_pk_free( &alt );
}
/* END_CASE */
/* BEGIN_CASE depends_on:MBEDTLS_RSA_C */
void pk_rsa_verify_test_vec( char *message_hex_string, 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 *rsa;
mbedtls_pk_context pk;
int msg_len;
mbedtls_pk_init( &pk );
memset( message_str, 0x00, 1000 );
memset( hash_result, 0x00, 1000 );
memset( result_str, 0x00, 1000 );
TEST_ASSERT( mbedtls_pk_setup( &pk, mbedtls_pk_info_from_type( MBEDTLS_PK_RSA ) ) == 0 );
rsa = mbedtls_pk_rsa( pk );
rsa->len = mod / 8;
TEST_ASSERT( mbedtls_mpi_read_string( &rsa->N, radix_N, input_N ) == 0 );
TEST_ASSERT( mbedtls_mpi_read_string( &rsa->E, radix_E, input_E ) == 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_pk_verify( &pk, digest, hash_result, 0,
result_str, mbedtls_pk_get_len( &pk ) ) == result );
exit:
mbedtls_pk_free( &pk );
}
/* END_CASE */
/* BEGIN_CASE depends_on:MBEDTLS_RSA_C */
void pk_rsa_verify_ext_test_vec( char *message_hex_string, int digest,
int mod, int radix_N, char *input_N, int radix_E,
char *input_E, char *result_hex_str,
int pk_type, int mgf1_hash_id, int salt_len,
int result )
{
unsigned char message_str[1000];
unsigned char hash_result[1000];
unsigned char result_str[1000];
mbedtls_rsa_context *rsa;
mbedtls_pk_context pk;
mbedtls_pk_rsassa_pss_options pss_opts;
void *options;
int msg_len;
size_t hash_len;
mbedtls_pk_init( &pk );
memset( message_str, 0x00, 1000 );
memset( hash_result, 0x00, 1000 );
memset( result_str, 0x00, 1000 );
TEST_ASSERT( mbedtls_pk_setup( &pk, mbedtls_pk_info_from_type( MBEDTLS_PK_RSA ) ) == 0 );
rsa = mbedtls_pk_rsa( pk );
rsa->len = mod / 8;
TEST_ASSERT( mbedtls_mpi_read_string( &rsa->N, radix_N, input_N ) == 0 );
TEST_ASSERT( mbedtls_mpi_read_string( &rsa->E, radix_E, input_E ) == 0 );
msg_len = unhexify( message_str, message_hex_string );
unhexify( result_str, result_hex_str );
if( digest != MBEDTLS_MD_NONE )
{
TEST_ASSERT( mbedtls_md( mbedtls_md_info_from_type( digest ),
message_str, msg_len, hash_result ) == 0 );
hash_len = 0;
}
else
{
memcpy( hash_result, message_str, msg_len );
hash_len = msg_len;
}
if( mgf1_hash_id < 0 )
{
options = NULL;
}
else
{
options = &pss_opts;
pss_opts.mgf1_hash_id = mgf1_hash_id;
pss_opts.expected_salt_len = salt_len;
}
TEST_ASSERT( mbedtls_pk_verify_ext( pk_type, options, &pk,
digest, hash_result, hash_len,
result_str, mbedtls_pk_get_len( &pk ) ) == result );
exit:
mbedtls_pk_free( &pk );
}
/* END_CASE */
/* BEGIN_CASE depends_on:MBEDTLS_ECDSA_C */
void pk_ec_test_vec( int type, int id, char *key_str,
char *hash_str, char * sig_str, int ret )
{
mbedtls_pk_context pk;
mbedtls_ecp_keypair *eckey;
unsigned char hash[100], sig[500], key[500];
size_t hash_len, sig_len, key_len;
mbedtls_pk_init( &pk );
memset( hash, 0, sizeof( hash ) ); hash_len = unhexify(hash, hash_str);
memset( sig, 0, sizeof( sig ) ); sig_len = unhexify(sig, sig_str);
memset( key, 0, sizeof( key ) ); key_len = unhexify(key, key_str);
TEST_ASSERT( mbedtls_pk_setup( &pk, mbedtls_pk_info_from_type( type ) ) == 0 );
TEST_ASSERT( mbedtls_pk_can_do( &pk, MBEDTLS_PK_ECDSA ) );
eckey = mbedtls_pk_ec( pk );
TEST_ASSERT( mbedtls_ecp_group_load( &eckey->grp, id ) == 0 );
TEST_ASSERT( mbedtls_ecp_point_read_binary( &eckey->grp, &eckey->Q,
key, key_len ) == 0 );
TEST_ASSERT( mbedtls_pk_verify( &pk, MBEDTLS_MD_NONE,
hash, hash_len, sig, sig_len ) == ret );
exit:
mbedtls_pk_free( &pk );
}
/* END_CASE */
/* BEGIN_CASE depends_on:MBEDTLS_SHA256_C */
void pk_sign_verify( int type, int sign_ret, int verify_ret )
{
mbedtls_pk_context pk;
unsigned char hash[50], sig[5000];
size_t sig_len;
mbedtls_pk_init( &pk );
memset( hash, 0x2a, sizeof hash );
memset( sig, 0, sizeof sig );
TEST_ASSERT( mbedtls_pk_setup( &pk, mbedtls_pk_info_from_type( type ) ) == 0 );
TEST_ASSERT( pk_genkey( &pk ) == 0 );
TEST_ASSERT( mbedtls_pk_sign( &pk, MBEDTLS_MD_SHA256, hash, sizeof hash,
sig, &sig_len, rnd_std_rand, NULL ) == sign_ret );
if( sign_ret == 0 )
TEST_ASSERT( sig_len <= mbedtls_pk_signature_size( &pk ) );
TEST_ASSERT( mbedtls_pk_verify( &pk, MBEDTLS_MD_SHA256,
hash, sizeof hash, sig, sig_len ) == verify_ret );
exit:
mbedtls_pk_free( &pk );
}
/* END_CASE */
/* BEGIN_CASE depends_on:MBEDTLS_RSA_C */
void pk_rsa_encrypt_test_vec( char *message_hex, int mod,
int radix_N, char *input_N,
int radix_E, char *input_E,
char *result_hex, int ret )
{
unsigned char message[1000];
unsigned char output[1000];
unsigned char result[1000];
size_t msg_len, olen, res_len;
rnd_pseudo_info rnd_info;
mbedtls_rsa_context *rsa;
mbedtls_pk_context pk;
memset( &rnd_info, 0, sizeof( rnd_pseudo_info ) );
memset( message, 0, sizeof( message ) );
memset( output, 0, sizeof( output ) );
memset( result, 0, sizeof( result ) );
msg_len = unhexify( message, message_hex );
res_len = unhexify( result, result_hex );
mbedtls_pk_init( &pk );
TEST_ASSERT( mbedtls_pk_setup( &pk, mbedtls_pk_info_from_type( MBEDTLS_PK_RSA ) ) == 0 );
rsa = mbedtls_pk_rsa( pk );
rsa->len = mod / 8;
TEST_ASSERT( mbedtls_mpi_read_string( &rsa->N, radix_N, input_N ) == 0 );
TEST_ASSERT( mbedtls_mpi_read_string( &rsa->E, radix_E, input_E ) == 0 );
TEST_ASSERT( mbedtls_pk_encrypt( &pk, message, msg_len,
output, &olen, sizeof( output ),
rnd_pseudo_rand, &rnd_info ) == ret );
TEST_ASSERT( olen == res_len );
TEST_ASSERT( memcmp( output, result, olen ) == 0 );
exit:
mbedtls_pk_free( &pk );
}
/* END_CASE */
/* BEGIN_CASE depends_on:MBEDTLS_RSA_C */
void pk_rsa_decrypt_test_vec( char *cipher_hex, 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 *clear_hex, int ret )
{
unsigned char clear[1000];
unsigned char output[1000];
unsigned char cipher[1000];
size_t clear_len, olen, cipher_len;
rnd_pseudo_info rnd_info;
mbedtls_mpi N, P, Q, E;
mbedtls_rsa_context *rsa;
mbedtls_pk_context pk;
mbedtls_pk_init( &pk );
mbedtls_mpi_init( &N ); mbedtls_mpi_init( &P );
mbedtls_mpi_init( &Q ); mbedtls_mpi_init( &E );
memset( &rnd_info, 0, sizeof( rnd_pseudo_info ) );
memset( clear, 0, sizeof( clear ) );
memset( cipher, 0, sizeof( cipher ) );
clear_len = unhexify( clear, clear_hex );
cipher_len = unhexify( cipher, cipher_hex );
/* init pk-rsa context */
TEST_ASSERT( mbedtls_pk_setup( &pk, mbedtls_pk_info_from_type( MBEDTLS_PK_RSA ) ) == 0 );
rsa = mbedtls_pk_rsa( pk );
/* load public key */
TEST_ASSERT( mbedtls_mpi_read_string( &N, radix_N, input_N ) == 0 );
TEST_ASSERT( mbedtls_mpi_read_string( &E, radix_E, input_E ) == 0 );
/* load private key */
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_rsa_import( rsa, &N, &P, &Q, NULL, &E ) == 0 );
TEST_ASSERT( mbedtls_rsa_get_len( rsa ) == (size_t) ( mod / 8 ) );
TEST_ASSERT( mbedtls_rsa_complete( rsa ) == 0 );
/* decryption test */
memset( output, 0, sizeof( output ) );
olen = 0;
TEST_ASSERT( mbedtls_pk_decrypt( &pk, cipher, cipher_len,
output, &olen, sizeof( output ),
rnd_pseudo_rand, &rnd_info ) == ret );
if( ret == 0 )
{
TEST_ASSERT( olen == clear_len );
TEST_ASSERT( memcmp( output, clear, olen ) == 0 );
}
exit:
mbedtls_mpi_free( &N ); mbedtls_mpi_free( &P );
mbedtls_mpi_free( &Q ); mbedtls_mpi_free( &E );
mbedtls_pk_free( &pk );
}
/* END_CASE */
/* BEGIN_CASE */
void pk_ec_nocrypt( int type )
{
mbedtls_pk_context pk;
unsigned char output[100];
unsigned char input[100];
rnd_pseudo_info rnd_info;
size_t olen = 0;
int ret = MBEDTLS_ERR_PK_TYPE_MISMATCH;
mbedtls_pk_init( &pk );
memset( &rnd_info, 0, sizeof( rnd_pseudo_info ) );
memset( output, 0, sizeof( output ) );
memset( input, 0, sizeof( input ) );
TEST_ASSERT( mbedtls_pk_setup( &pk, mbedtls_pk_info_from_type( type ) ) == 0 );
TEST_ASSERT( mbedtls_pk_encrypt( &pk, input, sizeof( input ),
output, &olen, sizeof( output ),
rnd_pseudo_rand, &rnd_info ) == ret );
TEST_ASSERT( mbedtls_pk_decrypt( &pk, input, sizeof( input ),
output, &olen, sizeof( output ),
rnd_pseudo_rand, &rnd_info ) == ret );
exit:
mbedtls_pk_free( &pk );
}
/* END_CASE */
/* BEGIN_CASE depends_on:MBEDTLS_RSA_C:MBEDTLS_HAVE_INT64 */
void pk_rsa_overflow( )
{
mbedtls_pk_context pk;
size_t hash_len = (size_t)-1;
mbedtls_pk_init( &pk );
TEST_ASSERT( mbedtls_pk_setup( &pk,
mbedtls_pk_info_from_type( MBEDTLS_PK_RSA ) ) == 0 );
#if defined(MBEDTLS_PKCS1_V21)
TEST_ASSERT( mbedtls_pk_verify_ext( MBEDTLS_PK_RSASSA_PSS, NULL, &pk,
MBEDTLS_MD_NONE, NULL, hash_len, NULL, 0 ) ==
MBEDTLS_ERR_PK_BAD_INPUT_DATA );
#endif /* MBEDTLS_PKCS1_V21 */
TEST_ASSERT( mbedtls_pk_verify( &pk, MBEDTLS_MD_NONE, NULL, hash_len,
NULL, 0 ) == MBEDTLS_ERR_PK_BAD_INPUT_DATA );
TEST_ASSERT( mbedtls_pk_sign( &pk, MBEDTLS_MD_NONE, NULL, hash_len, NULL, 0,
rnd_std_rand, NULL ) == MBEDTLS_ERR_PK_BAD_INPUT_DATA );
exit:
mbedtls_pk_free( &pk );
}
/* END_CASE */
/* BEGIN_CASE depends_on:MBEDTLS_RSA_C:MBEDTLS_PK_RSA_ALT_SUPPORT */
void pk_rsa_alt( )
{
/*
* An rsa_alt context can only do private operations (decrypt, sign).
* Test it against the public operations (encrypt, verify) of a
* corresponding rsa context.
*/
mbedtls_pk_context alt;
mbedtls_rsa_context raw;
/* Generate an RSA key to use in both contexts */
pk_rsa_prepare( &raw );
/* Set up the alt context with the generated key */
mbedtls_pk_init( &alt );
TEST_ASSERT( mbedtls_pk_setup_rsa_alt( &alt, (void *) &raw,
mbedtls_rsa_decrypt_func,
mbedtls_rsa_sign_func,
mbedtls_rsa_key_len_func ) == 0 );
/* Check the metadata in the alt context */
TEST_ASSERT( mbedtls_pk_get_type( &alt ) == MBEDTLS_PK_RSA_ALT );
TEST_ASSERT( strcmp( mbedtls_pk_get_name( &alt ), "RSA-alt" ) == 0 );
/* Exercise the alt context */
pk_rsa_match( &raw, &alt,
0, MBEDTLS_ERR_PK_TYPE_MISMATCH,
MBEDTLS_ERR_PK_TYPE_MISMATCH, 0,
MBEDTLS_ERR_PK_TYPE_MISMATCH );
exit:
mbedtls_rsa_free( &raw );
mbedtls_pk_free( &alt );
}
/* END_CASE */
/* BEGIN_CASE */
void pk_opaque_mock( )
{
mbedtls_pk_info_t info =
MBEDTLS_PK_OPAQUE_INFO_1(
"mock"
, opaque_mock_get_bitlen
, opaque_mock_can_do
, opaque_mock_signature_size_func
, opaque_mock_verify_func
, opaque_mock_sign_func
, opaque_mock_decrypt_func
, opaque_mock_encrypt_func
, opaque_mock_check_pair_func
, opaque_mock_ctx_alloc_func
, opaque_mock_ctx_free_func
, opaque_mock_debug_func
);
mbedtls_pk_context ctx;
unsigned char sig[OPAQUE_MOCK_SIGNATURE_SIZE] = OPAQUE_MOCK_GOOD_SIGNATURE;
unsigned char input[sizeof( opaque_mock_reference_input )];
unsigned char output[sizeof( opaque_mock_reference_decrypted )] = "garbage";
size_t len;
mbedtls_pk_init( &ctx );
TEST_ASSERT( mbedtls_pk_setup( &ctx, &info ) == 0 );
TEST_ASSERT( mbedtls_pk_get_type( &ctx ) == MBEDTLS_PK_OPAQUE );
TEST_ASSERT( mbedtls_pk_get_name( &ctx ) == info.name );
TEST_ASSERT( mbedtls_pk_get_bitlen( &ctx ) == OPAQUE_MOCK_BITLEN );
TEST_ASSERT( mbedtls_pk_can_do( &ctx, OPAQUE_MOCK_CAN_DO ) == 1 );
TEST_ASSERT( mbedtls_pk_can_do( &ctx, OPAQUE_MOCK_CAN_DO ^ 1 ) == 0 );
TEST_ASSERT( mbedtls_pk_signature_size( &ctx ) == OPAQUE_MOCK_SIGNATURE_SIZE );
TEST_ASSERT( mbedtls_pk_verify( &ctx, OPAQUE_MOCK_MD_ALG,
opaque_mock_hash, sizeof( opaque_mock_hash ),
sig, OPAQUE_MOCK_SIGNATURE_SIZE ) == 0 );
TEST_ASSERT( mbedtls_pk_verify( &ctx, OPAQUE_MOCK_MD_ALG,
opaque_mock_hash, sizeof( opaque_mock_hash ),
sig, OPAQUE_MOCK_SIGNATURE_SIZE - 1 ) ==
MBEDTLS_ERR_PK_SIG_LEN_MISMATCH );
sig[0] ^= 1;
TEST_ASSERT( mbedtls_pk_verify( &ctx, OPAQUE_MOCK_MD_ALG,
opaque_mock_hash, sizeof( opaque_mock_hash ),
sig, OPAQUE_MOCK_SIGNATURE_SIZE ) ==
MBEDTLS_ERR_PK_INVALID_SIGNATURE );
len = -42;
TEST_ASSERT( mbedtls_pk_sign( &ctx, OPAQUE_MOCK_MD_ALG,
opaque_mock_hash, sizeof( opaque_mock_hash ),
sig, &len, NULL, NULL ) == 0 );
TEST_ASSERT( len == OPAQUE_MOCK_SIGNATURE_SIZE );
memcpy( input, opaque_mock_reference_input,
sizeof( opaque_mock_reference_input ) );
len = -42;
TEST_ASSERT( mbedtls_pk_encrypt( &ctx, input, sizeof( input ),
output, &len,
sizeof( opaque_mock_reference_encrypted ),
NULL, NULL ) == 0);
TEST_ASSERT( memcmp( input, opaque_mock_reference_input,
sizeof( opaque_mock_reference_input ) ) == 0 );
TEST_ASSERT( len == sizeof( opaque_mock_reference_encrypted ) );
TEST_ASSERT( memcmp( output, opaque_mock_reference_encrypted,
sizeof( opaque_mock_reference_encrypted ) ) == 0 );
len = -42;
TEST_ASSERT( mbedtls_pk_decrypt( &ctx, input, sizeof( input ),
output, &len,
sizeof( opaque_mock_reference_decrypted ),
NULL, NULL ) == 0);
TEST_ASSERT( memcmp( input, opaque_mock_reference_input,
sizeof( opaque_mock_reference_input ) ) == 0 );
TEST_ASSERT( len == sizeof( opaque_mock_reference_decrypted ) );
TEST_ASSERT( memcmp( output, opaque_mock_reference_decrypted,
sizeof( opaque_mock_reference_decrypted ) ) == 0 );
TEST_ASSERT( mbedtls_pk_check_pair( NULL, &ctx ) ==
MBEDTLS_ERR_PK_BAD_INPUT_DATA );
TEST_ASSERT( mbedtls_pk_check_pair( &ctx, &ctx ) == 0 );
{
mbedtls_pk_context pub;
mbedtls_pk_init( &pub );
TEST_ASSERT( mbedtls_pk_check_pair( &pub, &ctx ) ==
MBEDTLS_ERR_PK_BAD_INPUT_DATA );
TEST_ASSERT( mbedtls_pk_setup( &pub,
mbedtls_pk_info_from_type( MBEDTLS_PK_RSA ) ) == 0 );
TEST_ASSERT( mbedtls_pk_check_pair( &pub, &ctx ) == 0 );
mbedtls_pk_free( &pub );
TEST_ASSERT( mbedtls_pk_setup( &pub,
mbedtls_pk_info_from_type( MBEDTLS_PK_ECDSA ) ) == 0 );
TEST_ASSERT( mbedtls_pk_check_pair( &pub, &ctx ) ==
MBEDTLS_ERR_PK_TYPE_MISMATCH );
mbedtls_pk_free( &pub );
}
opaque_mock_debug_called_correctly = 0;
TEST_ASSERT( mbedtls_pk_debug( &ctx, &opaque_mock_pk_debug_item ) == 0 );
TEST_ASSERT( opaque_mock_debug_called_correctly );
opaque_mock_free_called_correctly = 0;
mbedtls_pk_free( &ctx );
TEST_ASSERT( opaque_mock_free_called_correctly );
return;
exit:
mbedtls_pk_free( &ctx );
}
/* END_CASE */
/* BEGIN_CASE */
void pk_opaque_minimal( )
{
mbedtls_pk_info_t info =
MBEDTLS_PK_OPAQUE_INFO_1(
"mock"
, opaque_mock_get_bitlen
, opaque_mock_can_do
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, opaque_mock_ctx_free_func
, NULL
);
mbedtls_pk_context ctx;
mbedtls_pk_init( &ctx );
TEST_ASSERT( mbedtls_pk_setup( &ctx, &info ) == 0 );
ctx.pk_ctx = &opaque_mock_fake_ctx;
TEST_ASSERT( mbedtls_pk_get_type( &ctx ) == MBEDTLS_PK_OPAQUE );
TEST_ASSERT( mbedtls_pk_get_name( &ctx ) == info.name );
TEST_ASSERT( mbedtls_pk_get_bitlen( &ctx ) == OPAQUE_MOCK_BITLEN );
TEST_ASSERT( mbedtls_pk_can_do( &ctx, OPAQUE_MOCK_CAN_DO ) == 1 );
TEST_ASSERT( mbedtls_pk_can_do( &ctx, OPAQUE_MOCK_CAN_DO ^ 1 ) == 0 );
TEST_ASSERT( mbedtls_pk_signature_size( &ctx ) == 0 );
TEST_ASSERT( mbedtls_pk_verify( &ctx, OPAQUE_MOCK_MD_ALG,
NULL, 0, NULL, 0 ) ==
MBEDTLS_ERR_PK_TYPE_MISMATCH );
TEST_ASSERT( mbedtls_pk_sign( &ctx, OPAQUE_MOCK_MD_ALG, NULL, 0,
NULL, NULL, NULL, NULL ) ==
MBEDTLS_ERR_PK_TYPE_MISMATCH );
TEST_ASSERT( mbedtls_pk_encrypt( &ctx, NULL, 0,
NULL, NULL, 0, NULL, NULL ) ==
MBEDTLS_ERR_PK_TYPE_MISMATCH);
TEST_ASSERT( mbedtls_pk_decrypt( &ctx, NULL, 0,
NULL, NULL, 0, NULL, NULL ) ==
MBEDTLS_ERR_PK_TYPE_MISMATCH);
TEST_ASSERT( mbedtls_pk_check_pair( NULL, &ctx ) ==
MBEDTLS_ERR_PK_BAD_INPUT_DATA );
TEST_ASSERT( mbedtls_pk_check_pair( &ctx, &ctx ) == 0 );
{
mbedtls_pk_context pub;
mbedtls_pk_init( &pub );
TEST_ASSERT( mbedtls_pk_setup( &pub,
mbedtls_pk_info_from_type( MBEDTLS_PK_RSA ) ) == 0 );
TEST_ASSERT( mbedtls_pk_check_pair( &pub, &ctx ) ==
MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE );
mbedtls_pk_free( &pub );
}
TEST_ASSERT( mbedtls_pk_debug( &ctx, &opaque_mock_pk_debug_item ) ==
MBEDTLS_ERR_PK_TYPE_MISMATCH );
opaque_mock_free_called_correctly = 0;
mbedtls_pk_free( &ctx );
TEST_ASSERT( opaque_mock_free_called_correctly );
return;
exit:
mbedtls_pk_free( &ctx );
}
/* END_CASE */
/* BEGIN_CASE */
void pk_opaque_fail_allocation( )
{
mbedtls_pk_info_t info =
MBEDTLS_PK_OPAQUE_INFO_1(
"mock"
, opaque_mock_get_bitlen
, opaque_mock_can_do
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, opaque_mock_ctx_alloc_fail
, NULL
, NULL
);
mbedtls_pk_context ctx;
mbedtls_pk_init( &ctx );
TEST_ASSERT( mbedtls_pk_setup( &ctx, &info ) ==
MBEDTLS_ERR_PK_ALLOC_FAILED );
TEST_ASSERT( ctx.pk_info == NULL );
TEST_ASSERT( ctx.pk_ctx == NULL );
exit:
mbedtls_pk_free( &ctx );
}
/* END_CASE */
/* BEGIN_CASE depends_on:MBEDTLS_RSA_C:MBEDTLS_PK_RSA_ALT_SUPPORT */
void pk_opaque_wrapper( )
{
/* Test an opaque context that's a wrapper around the usual RSA
implementation against an independent raw RSA context. */
mbedtls_pk_context opaque;
mbedtls_rsa_context raw;
const mbedtls_pk_info_t *mbedtls_rsa_info =
mbedtls_pk_info_from_type( MBEDTLS_PK_RSA );
mbedtls_pk_info_t pk_rsa_opaque_info =
MBEDTLS_PK_OPAQUE_INFO_1(
"RSA-opaque-wrapper"
, mbedtls_rsa_info->get_bitlen
, mbedtls_rsa_info->can_do
, mbedtls_rsa_info->signature_size_func
, mbedtls_rsa_info->verify_func
, mbedtls_rsa_info->sign_func
, mbedtls_rsa_info->decrypt_func
, mbedtls_rsa_info->encrypt_func
, NULL // we don't test check_pair here
, mbedtls_rsa_info->ctx_alloc_func
, mbedtls_rsa_info->ctx_free_func
, mbedtls_rsa_info->debug_func
);
/* Generate an RSA key to use in both contexts */
pk_rsa_prepare( &raw );
/* Set up the opaque context with the generated key */
mbedtls_pk_init( &opaque );
TEST_ASSERT( mbedtls_pk_setup( &opaque, &pk_rsa_opaque_info ) == 0 );
mbedtls_rsa_copy( opaque.pk_ctx, &raw );
/* Check the metadata in the opaque context */
TEST_ASSERT( mbedtls_pk_get_type( &opaque ) == MBEDTLS_PK_OPAQUE );
TEST_ASSERT( strcmp( mbedtls_pk_get_name( &opaque ),
"RSA-opaque-wrapper" ) == 0 );
/* Exercise the opaque context */
pk_rsa_match( &raw, &opaque, 0, 0, 0, 0, 0 );
exit:
mbedtls_rsa_free( &raw );
mbedtls_pk_free( &opaque );
}
/* END_CASE */