From 7624a5ae5eade9b6253bca518c576791ed2524d5 Mon Sep 17 00:00:00 2001 From: Neil Armstrong Date: Tue, 12 Apr 2022 10:09:26 +0200 Subject: [PATCH 1/6] Allow RSA PK Opaque keys for RSA-PSS signing Signed-off-by: Neil Armstrong --- library/pk.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/library/pk.c b/library/pk.c index 0f465cdb4..e238911a5 100644 --- a/library/pk.c +++ b/library/pk.c @@ -776,6 +776,8 @@ int mbedtls_pk_wrap_as_opaque( mbedtls_pk_context *pk, psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_SIGN_HASH ); psa_set_key_algorithm( &attributes, PSA_ALG_RSA_PKCS1V15_SIGN( hash_alg ) ); + psa_set_key_enrollment_algorithm( &attributes, + PSA_ALG_RSA_PSS( hash_alg ) ); /* import private key into PSA */ status = psa_import_key( &attributes, From 62d452baac5b3c5c6e999c53983db58a72d2505f Mon Sep 17 00:00:00 2001 From: Neil Armstrong Date: Tue, 12 Apr 2022 15:11:49 +0200 Subject: [PATCH 2/6] Implement PK Opaque RSA PSS signature Signed-off-by: Neil Armstrong --- library/pk.c | 27 +++++++++++++++++++++++++++ library/pk_wrap.c | 3 ++- 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/library/pk.c b/library/pk.c index e238911a5..5f8cbc2a4 100644 --- a/library/pk.c +++ b/library/pk.c @@ -545,6 +545,33 @@ int mbedtls_pk_sign_ext( mbedtls_pk_type_t pk_type, if( ! mbedtls_pk_can_do( ctx, pk_type ) ) return( MBEDTLS_ERR_PK_TYPE_MISMATCH ); + if( pk_type == MBEDTLS_PK_RSASSA_PSS && + mbedtls_pk_get_type( ctx ) == MBEDTLS_PK_OPAQUE ) + { +#if defined(MBEDTLS_RSA_C) + const mbedtls_svc_key_id_t *key = (const mbedtls_svc_key_id_t *) ctx->pk_ctx; + psa_status_t status; + + /* PSA has its own RNG */ + (void) f_rng; + (void) p_rng; + + psa_md_alg = mbedtls_psa_translate_md( md_alg ); + if( psa_md_alg == 0 ) + return( MBEDTLS_ERR_PK_BAD_INPUT_DATA ); + + status = psa_sign_hash( *key, PSA_ALG_RSA_PSS( psa_md_alg ), + hash, hash_len, + sig, sig_size, sig_len ); + if( status != PSA_SUCCESS ) + return( mbedtls_pk_error_from_psa_rsa( status ) ); + + return 0; +#else + return( MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE ); +#endif /* MBEDTLS_RSA_C */ + } + if( pk_type != MBEDTLS_PK_RSASSA_PSS ) { return( mbedtls_pk_sign( ctx, md_alg, hash, hash_len, diff --git a/library/pk_wrap.c b/library/pk_wrap.c index a9c3c718b..852c46ef6 100644 --- a/library/pk_wrap.c +++ b/library/pk_wrap.c @@ -1501,7 +1501,8 @@ static int pk_opaque_ecdsa_can_do( mbedtls_pk_type_t type ) static int pk_opaque_rsa_can_do( mbedtls_pk_type_t type ) { - return( type == MBEDTLS_PK_RSA ); + return( type == MBEDTLS_PK_RSA || + type == MBEDTLS_PK_RSASSA_PSS ); } static int pk_opaque_sign_wrap( void *ctx, mbedtls_md_type_t md_alg, From 999930e4478da1161c45043eeb3c78073885d746 Mon Sep 17 00:00:00 2001 From: Neil Armstrong Date: Tue, 12 Apr 2022 15:12:43 +0200 Subject: [PATCH 3/6] Add RSA PK Wrapped Sign ext tests Signed-off-by: Neil Armstrong --- tests/suites/test_suite_pk.data | 23 ++++++++++ tests/suites/test_suite_pk.function | 68 +++++++++++++++++++++++++++++ 2 files changed, 91 insertions(+) diff --git a/tests/suites/test_suite_pk.data b/tests/suites/test_suite_pk.data index 323efc2c4..306cfd730 100644 --- a/tests/suites/test_suite_pk.data +++ b/tests/suites/test_suite_pk.data @@ -386,3 +386,26 @@ PK Sign ext:SECP521R1,PK_ECDSA,MD_SHA512 depends_on:MBEDTLS_ECDSA_C:MBEDTLS_ECP_DP_SECP521R1_ENABLED:MBEDTLS_SHA512_C pk_psa_sign_ext:MBEDTLS_PK_ECDSA:MBEDTLS_ECP_DP_SECP521R1:MBEDTLS_PK_ECDSA:MBEDTLS_MD_SHA512 +PK wrapped Sign ext:RSA2048,PK_RSA,MD_SHA256 +depends_on:MBEDTLS_PKCS1_V15:MBEDTLS_SHA256_C:MBEDTLS_RSA_C +pk_psa_wrap_sign_ext:MBEDTLS_PK_RSA:2048:MBEDTLS_PK_RSA:MBEDTLS_MD_SHA256 + +PK wrapped Sign ext:RSA2048,PK_RSASSA_PSS,MD_SHA256 +depends_on:MBEDTLS_PKCS1_V21:MBEDTLS_SHA256_C:MBEDTLS_RSA_C +pk_psa_wrap_sign_ext:MBEDTLS_PK_RSA:2048:MBEDTLS_PK_RSASSA_PSS:MBEDTLS_MD_SHA256 + +PK wrapped Sign ext:RSA2048,PK_RSA,MD_SHA384 +depends_on:MBEDTLS_PKCS1_V15:MBEDTLS_SHA384_C:MBEDTLS_RSA_C +pk_psa_wrap_sign_ext:MBEDTLS_PK_RSA:2048:MBEDTLS_PK_RSA:MBEDTLS_MD_SHA384 + +PK wrapped Sign ext:RSA2048,PK_RSASSA_PSS,MD_SHA384 +depends_on:MBEDTLS_PKCS1_V21:MBEDTLS_SHA384_C:MBEDTLS_RSA_C +pk_psa_wrap_sign_ext:MBEDTLS_PK_RSA:2048:MBEDTLS_PK_RSASSA_PSS:MBEDTLS_MD_SHA384 + +PK wrapped Sign ext:RSA2048,PK_RSA,MD_SHA512 +depends_on:MBEDTLS_PKCS1_V15:MBEDTLS_SHA512_C:MBEDTLS_RSA_C +pk_psa_wrap_sign_ext:MBEDTLS_PK_RSA:2048:MBEDTLS_PK_RSA:MBEDTLS_MD_SHA512 + +PK wrapped Sign ext:RSA2048,PK_RSASSA_PSS,MD_SHA512 +depends_on:MBEDTLS_PKCS1_V21:MBEDTLS_SHA512_C:MBEDTLS_RSA_C +pk_psa_wrap_sign_ext:MBEDTLS_PK_RSA:2048:MBEDTLS_PK_RSASSA_PSS:MBEDTLS_MD_SHA512 diff --git a/tests/suites/test_suite_pk.function b/tests/suites/test_suite_pk.function index 6c4f9e44d..fed1427cd 100644 --- a/tests/suites/test_suite_pk.function +++ b/tests/suites/test_suite_pk.function @@ -1208,3 +1208,71 @@ exit: } /* END_CASE */ +/* BEGIN_CASE depends_on:MBEDTLS_RSA_C:MBEDTLS_GENPRIME:MBEDTLS_USE_PSA_CRYPTO */ +void pk_psa_wrap_sign_ext( int pk_type, int parameter, int key_pk_type, int md_alg ) +{ + /* See the description of mbedtls_rsa_gen_key() for the description of the `parameter` argument. */ + mbedtls_pk_context pk; + size_t sig_len, pkey_len; + mbedtls_svc_key_id_t key_id; + unsigned char sig[MBEDTLS_PK_SIGNATURE_MAX_SIZE]; + unsigned char pkey[400]; + unsigned char *pkey_start; + unsigned char hash[MBEDTLS_MD_MAX_SIZE]; + psa_algorithm_t psa_md_alg = mbedtls_psa_translate_md( md_alg ); + size_t hash_len = PSA_HASH_LENGTH( psa_md_alg ); + const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type( md_alg ); + void const *options = NULL; + mbedtls_pk_rsassa_pss_options rsassa_pss_options; + int ret; + + mbedtls_pk_init( &pk ); + PSA_INIT(); + + /* Create legacy RSA public/private key in PK context. */ + mbedtls_pk_init( &pk ); + TEST_EQUAL( mbedtls_pk_setup( &pk, + mbedtls_pk_info_from_type( pk_type ) ), 0 ); + TEST_EQUAL( mbedtls_rsa_gen_key( mbedtls_pk_rsa( pk ), + mbedtls_test_rnd_std_rand, NULL, + parameter, 3 ), 0 ); + + /* Export underlying public key for re-importing in a legacy context. */ + ret = mbedtls_pk_write_pubkey_der( &pk, pkey, sizeof( pkey ) ); + TEST_ASSERT( ret >= 0 ); + + pkey_len = (size_t) ret; + /* mbedtls_pk_write_pubkey_der() writes backwards in the data buffer. */ + pkey_start = pkey + sizeof( pkey ) - pkey_len; + + /* Turn PK context into an opaque one. */ + TEST_EQUAL( mbedtls_pk_wrap_as_opaque( &pk, &key_id, psa_md_alg ), 0 ); + + memset( hash, 0x2a, sizeof( hash ) ); + memset( sig, 0, sizeof( sig ) ); + + TEST_EQUAL( mbedtls_pk_sign_ext( key_pk_type, &pk, md_alg, hash, hash_len, + sig, sizeof( sig ), &sig_len, + mbedtls_test_rnd_std_rand, NULL ), 0 ); + + mbedtls_pk_free( &pk ); + TEST_EQUAL( PSA_SUCCESS, psa_destroy_key( key_id ) ); + + mbedtls_pk_init( &pk ); + TEST_EQUAL( mbedtls_pk_parse_public_key( &pk, pkey_start, pkey_len ), 0 ); + + if( key_pk_type == MBEDTLS_PK_RSASSA_PSS ) + { + rsassa_pss_options.mgf1_hash_id = md_alg; + TEST_ASSERT( md_info != NULL ); + rsassa_pss_options.expected_salt_len = mbedtls_md_get_size( md_info ); + options = (const void*) &rsassa_pss_options; + } + TEST_EQUAL( mbedtls_pk_verify_ext( key_pk_type, options, &pk, md_alg, + hash, hash_len, sig, sig_len ), 0 ); + +exit: + mbedtls_pk_free( &pk ); + PSA_DONE( ); +} +/* END_CASE */ From 23143dca2ab16a72822fdcfb66c468df6aea4481 Mon Sep 17 00:00:00 2001 From: Neil Armstrong Date: Thu, 21 Apr 2022 11:33:54 +0200 Subject: [PATCH 4/6] Update mbedtls_pk_wrap_as_opaque() public documentation for RSA & RSA-PSS Signed-off-by: Neil Armstrong --- include/mbedtls/pk.h | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/include/mbedtls/pk.h b/include/mbedtls/pk.h index 7e056dbe3..dc808e837 100644 --- a/include/mbedtls/pk.h +++ b/include/mbedtls/pk.h @@ -917,16 +917,20 @@ int mbedtls_pk_load_file( const char *path, unsigned char **buf, size_t *n ); #if defined(MBEDTLS_USE_PSA_CRYPTO) /** - * \brief Turn an EC key into an opaque one. + * \brief Turn an EC or RSA key into an opaque one. * * \warning This is a temporary utility function for tests. It might * change or be removed at any time without notice. * - * \note Only ECDSA keys are supported so far. Signing with the - * specified hash & ECDH key agreement derivation operation - * are the only allowed use of that key. + * \note ECDSA & RSA keys are supported. + * For both key types, signing with the specified hash + * is the only allowed use of that key with PK API. + * The RSA key supports RSA-PSS signing with the specified + * hash with the PK EXT API. + * In addition, the ECDSA key is also allowed for ECDH key + * agreement derivation operation using the PSA API. * - * \param pk Input: the EC key to import to a PSA key. + * \param pk Input: the EC or RSA key to import to a PSA key. * Output: a PK context wrapping that PSA key. * \param key Output: a PSA key identifier. * It's the caller's responsibility to call From 13e76be02bf41869165b550e20d9d590e13c2323 Mon Sep 17 00:00:00 2001 From: Neil Armstrong Date: Thu, 21 Apr 2022 12:08:52 +0200 Subject: [PATCH 5/6] Reorganize & simplify mbedtls_pk_sign_ext() handling of wrapped RSA-PSS Signed-off-by: Neil Armstrong --- library/pk.c | 40 +++++++++++++--------------------------- 1 file changed, 13 insertions(+), 27 deletions(-) diff --git a/library/pk.c b/library/pk.c index 5f8cbc2a4..bba2ef7c5 100644 --- a/library/pk.c +++ b/library/pk.c @@ -545,42 +545,28 @@ int mbedtls_pk_sign_ext( mbedtls_pk_type_t pk_type, if( ! mbedtls_pk_can_do( ctx, pk_type ) ) return( MBEDTLS_ERR_PK_TYPE_MISMATCH ); - if( pk_type == MBEDTLS_PK_RSASSA_PSS && - mbedtls_pk_get_type( ctx ) == MBEDTLS_PK_OPAQUE ) - { -#if defined(MBEDTLS_RSA_C) - const mbedtls_svc_key_id_t *key = (const mbedtls_svc_key_id_t *) ctx->pk_ctx; - psa_status_t status; - - /* PSA has its own RNG */ - (void) f_rng; - (void) p_rng; - - psa_md_alg = mbedtls_psa_translate_md( md_alg ); - if( psa_md_alg == 0 ) - return( MBEDTLS_ERR_PK_BAD_INPUT_DATA ); - - status = psa_sign_hash( *key, PSA_ALG_RSA_PSS( psa_md_alg ), - hash, hash_len, - sig, sig_size, sig_len ); - if( status != PSA_SUCCESS ) - return( mbedtls_pk_error_from_psa_rsa( status ) ); - - return 0; -#else - return( MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE ); -#endif /* MBEDTLS_RSA_C */ - } - if( pk_type != MBEDTLS_PK_RSASSA_PSS ) { return( mbedtls_pk_sign( ctx, md_alg, hash, hash_len, sig, sig_size, sig_len, f_rng, p_rng ) ); } + #if defined(MBEDTLS_RSA_C) psa_md_alg = mbedtls_psa_translate_md( md_alg ); if( psa_md_alg == 0 ) return( MBEDTLS_ERR_PK_BAD_INPUT_DATA ); + + if( mbedtls_pk_get_type( ctx ) == MBEDTLS_PK_OPAQUE ) + { + const mbedtls_svc_key_id_t *key = (const mbedtls_svc_key_id_t *) ctx->pk_ctx; + psa_status_t status; + + status = psa_sign_hash( *key, PSA_ALG_RSA_PSS( psa_md_alg ), + hash, hash_len, + sig, sig_size, sig_len ); + return( mbedtls_pk_error_from_psa_rsa( status ) ); + } + return( mbedtls_pk_psa_rsa_sign_ext( PSA_ALG_RSA_PSS( psa_md_alg ), ctx->pk_ctx, hash, hash_len, sig, sig_size, sig_len ) ); From 843795ad2f79e2f78b9588cdfd9604b328c90b4a Mon Sep 17 00:00:00 2001 From: Neil Armstrong Date: Thu, 21 Apr 2022 12:23:28 +0200 Subject: [PATCH 6/6] Use macro for public key buffer size in pk_psa_wrap_sign_ext() Signed-off-by: Neil Armstrong --- tests/suites/test_suite_pk.function | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/suites/test_suite_pk.function b/tests/suites/test_suite_pk.function index fed1427cd..8fd536729 100644 --- a/tests/suites/test_suite_pk.function +++ b/tests/suites/test_suite_pk.function @@ -1216,7 +1216,7 @@ void pk_psa_wrap_sign_ext( int pk_type, int parameter, int key_pk_type, int md_a size_t sig_len, pkey_len; mbedtls_svc_key_id_t key_id; unsigned char sig[MBEDTLS_PK_SIGNATURE_MAX_SIZE]; - unsigned char pkey[400]; + unsigned char pkey[PSA_EXPORT_PUBLIC_KEY_MAX_SIZE]; unsigned char *pkey_start; unsigned char hash[MBEDTLS_MD_MAX_SIZE]; psa_algorithm_t psa_md_alg = mbedtls_psa_translate_md( md_alg );