diff --git a/ChangeLog b/ChangeLog index 01c9c876b..e4147bd06 100644 --- a/ChangeLog +++ b/ChangeLog @@ -22,6 +22,8 @@ Bugfix * oid_get_numeric_string() used to truncate the output without returning an error if the output buffer was just 1 byte too small. * dhm_parse_dhm() (hence dhm_parse_dhmfile()) did not set dhm->len. + * Calling pk_debug() on an RSA-alt key would segfault. + * pk_get_size() and pk_get_len() were off by a factor 8 for RSA-alt keys. = PolarSSL 1.3.5 released on 2014-03-26 Features diff --git a/include/polarssl/pk.h b/include/polarssl/pk.h index 6f21dab52..b764d5554 100644 --- a/include/polarssl/pk.h +++ b/include/polarssl/pk.h @@ -234,7 +234,7 @@ int pk_init_ctx( pk_context *ctx, const pk_info_t *info ); * \param key RSA key pointer * \param decrypt_func Decryption function * \param sign_func Signing function - * \param key_len_func Function returning key length + * \param key_len_func Function returning key length in bytes * * \return 0 on success, or POLARSSL_ERR_PK_BAD_INPUT_DATA if the * context wasn't already initialized as RSA_ALT. diff --git a/library/pk.c b/library/pk.c index 80eccc911..cfde265bf 100644 --- a/library/pk.c +++ b/library/pk.c @@ -258,6 +258,9 @@ int pk_debug( const pk_context *ctx, pk_debug_item *items ) if( ctx == NULL || ctx->pk_info == NULL ) return( POLARSSL_ERR_PK_BAD_INPUT_DATA ); + if( ctx->pk_info->debug_func == NULL ) + return( POLARSSL_ERR_PK_TYPE_MISMATCH ); + ctx->pk_info->debug_func( ctx->pk_ctx, items ); return( 0 ); } diff --git a/library/pk_wrap.c b/library/pk_wrap.c index 99535d613..96695d462 100644 --- a/library/pk_wrap.c +++ b/library/pk_wrap.c @@ -357,7 +357,7 @@ static size_t rsa_alt_get_size( const void *ctx ) { const rsa_alt_context *rsa_alt = (const rsa_alt_context *) ctx; - return( rsa_alt->key_len_func( rsa_alt->key ) ); + return( 8 * rsa_alt->key_len_func( rsa_alt->key ) ); } static int rsa_alt_sign_wrap( void *ctx, md_type_t md_alg, diff --git a/tests/suites/test_suite_pk.data b/tests/suites/test_suite_pk.data index e07495a41..974748c6b 100644 --- a/tests/suites/test_suite_pk.data +++ b/tests/suites/test_suite_pk.data @@ -77,3 +77,7 @@ pk_ec_nocrypt:POLARSSL_PK_ECKEY_DH ECDSA nocrypt depends_on:POLARSSL_ECDSA_C pk_ec_nocrypt:POLARSSL_PK_ECDSA + +RSA_ALT consistency +depends_on:POLARSSL_RSA_C:POLARSSL_PKCS1_V15:POLARSSL_GENPRIME +pk_rsa_alt: diff --git a/tests/suites/test_suite_pk.function b/tests/suites/test_suite_pk.function index 85cdb7498..f82ed6748 100644 --- a/tests/suites/test_suite_pk.function +++ b/tests/suites/test_suite_pk.function @@ -3,13 +3,16 @@ 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( pk_context *pk ) { ((void) pk); #if defined(POLARSSL_RSA_C) && defined(POLARSSL_GENPRIME) if( pk_get_type( pk ) == POLARSSL_PK_RSA ) - return rsa_gen_key( pk_rsa( *pk ), rnd_std_rand, NULL, 512, 3 ); + return rsa_gen_key( pk_rsa( *pk ), rnd_std_rand, NULL, RSA_KEY_SIZE, 3 ); #endif #if defined(POLARSSL_ECP_C) if( pk_get_type( pk ) == POLARSSL_PK_ECKEY || @@ -27,6 +30,28 @@ static int pk_genkey( pk_context *pk ) #endif return( -1 ); } + +#if defined(POLARSSL_RSA_C) +int rsa_decrypt_func( void *ctx, int mode, size_t *olen, + const unsigned char *input, unsigned char *output, + size_t output_max_len ) +{ + return( rsa_pkcs1_decrypt( (rsa_context *) ctx, NULL, NULL, mode, olen, + input, output, output_max_len ) ); +} +int rsa_sign_func( void *ctx, + int (*f_rng)(void *, unsigned char *, size_t), void *p_rng, + int mode, md_type_t md_alg, unsigned int hashlen, + const unsigned char *hash, unsigned char *sig ) +{ + return( rsa_pkcs1_sign( (rsa_context *) ctx, f_rng, p_rng, mode, + md_alg, hashlen, hash, sig ) ); +} +size_t rsa_key_len_func( void *ctx ) +{ + return( ((const rsa_context *) ctx)->len ); +} +#endif /* POLARSSL_RSA_C */ /* END_HEADER */ /* BEGIN_DEPENDENCIES @@ -282,3 +307,77 @@ void pk_ec_nocrypt( int type ) pk_free( &pk ); } /* END_CASE */ + +/* BEGIN_CASE depends_on:POLARSSL_RSA_C */ +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. + */ + rsa_context raw; + pk_context rsa, alt; + 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; + int ret = POLARSSL_ERR_PK_TYPE_MISMATCH; + + rsa_init( &raw, RSA_PKCS_V15, POLARSSL_MD_NONE ); + pk_init( &rsa ); pk_init( &alt ); + + 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 PK RSA context with random key */ + TEST_ASSERT( pk_init_ctx( &rsa, + pk_info_from_type( POLARSSL_PK_RSA ) ) == 0 ); + TEST_ASSERT( pk_genkey( &rsa ) == 0 ); + + /* Extract key to the raw rsa context */ + TEST_ASSERT( rsa_copy( &raw, pk_rsa( rsa ) ) == 0 ); + + /* Initialize PK RSA_ALT context */ + TEST_ASSERT( pk_init_ctx_rsa_alt( &alt, (void *) &raw, + rsa_decrypt_func, rsa_sign_func, rsa_key_len_func ) == 0 ); + + /* Test administrative functions */ + TEST_ASSERT( pk_can_do( &alt, POLARSSL_PK_RSA ) ); + TEST_ASSERT( pk_get_size( &alt ) == RSA_KEY_SIZE ); + TEST_ASSERT( pk_get_len( &alt ) == RSA_KEY_LEN ); + TEST_ASSERT( pk_get_type( &alt ) == POLARSSL_PK_RSA_ALT ); + TEST_ASSERT( strcmp( pk_get_name( &alt ), "RSA-alt" ) == 0 ); + + /* Test signature */ + TEST_ASSERT( pk_sign( &alt, POLARSSL_MD_NONE, hash, sizeof hash, + sig, &sig_len, rnd_std_rand, NULL ) == 0 ); + TEST_ASSERT( sig_len == RSA_KEY_LEN ); + TEST_ASSERT( pk_verify( &rsa, POLARSSL_MD_NONE, + hash, sizeof hash, sig, sig_len ) == 0 ); + + /* Test decrypt */ + TEST_ASSERT( pk_encrypt( &rsa, msg, sizeof msg, + ciph, &ciph_len, sizeof ciph, + rnd_std_rand, NULL ) == 0 ); + TEST_ASSERT( pk_decrypt( &alt, 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 forbidden operations */ + TEST_ASSERT( pk_encrypt( &alt, msg, sizeof msg, + ciph, &ciph_len, sizeof ciph, + rnd_std_rand, NULL ) == ret ); + TEST_ASSERT( pk_verify( &alt, POLARSSL_MD_NONE, + hash, sizeof hash, sig, sig_len ) == ret ); + TEST_ASSERT( pk_debug( &alt, dbg_items ) == ret ); + + rsa_free( &raw ); + pk_free( &rsa ); pk_free( &alt ); +} +/* END_CASE */