From 4295e8b9c557e7545de0300368e584c59c9ea858 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Mon, 2 Dec 2019 21:39:10 +0100 Subject: [PATCH] Rework PSA curve to mbedlts group id conversion Don't rely on the bit size encoded in the PSA curve identifier, in preparation for removing that. For some inputs, the error code on EC key creation changes from PSA_ERROR_INVALID_ARGUMENT to PSA_ERROR_NOT_SUPPORTED or vice versa. There will be further such changes in subsequent commits. --- library/psa_crypto.c | 30 ++++++++++++++++++++----- tests/suites/test_suite_psa_crypto.data | 6 +---- 2 files changed, 26 insertions(+), 10 deletions(-) diff --git a/library/psa_crypto.c b/library/psa_crypto.c index f031654a6..8fc021a92 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -424,8 +424,10 @@ static psa_ecc_curve_t mbedtls_ecc_group_to_psa( mbedtls_ecp_group_id grpid, } } -static mbedtls_ecp_group_id mbedtls_ecc_group_of_psa( psa_ecc_curve_t curve ) +static mbedtls_ecp_group_id mbedtls_ecc_group_of_psa( psa_ecc_curve_t curve, + size_t byte_length ) { + (void) byte_length; switch( curve ) { case PSA_ECC_CURVE_SECP192R1: @@ -602,6 +604,8 @@ exit: #if defined(MBEDTLS_ECP_C) static psa_status_t psa_prepare_import_ec_key( psa_ecc_curve_t curve, + size_t data_length, + int is_public, mbedtls_ecp_keypair **p_ecp ) { mbedtls_ecp_group_id grp_id = MBEDTLS_ECP_DP_NONE; @@ -610,8 +614,23 @@ static psa_status_t psa_prepare_import_ec_key( psa_ecc_curve_t curve, return( PSA_ERROR_INSUFFICIENT_MEMORY ); mbedtls_ecp_keypair_init( *p_ecp ); + if( is_public ) + { + /* A public key is represented as: + * - The byte 0x04; + * - `x_P` as a `ceiling(m/8)`-byte string, big-endian; + * - `y_P` as a `ceiling(m/8)`-byte string, big-endian. + * So its data length is 2m+1 where n is the key size in bits. + */ + if( ( data_length & 1 ) == 0 ) + return( PSA_ERROR_INVALID_ARGUMENT ); + data_length = data_length / 2; + } + /* Load the group. */ - grp_id = mbedtls_ecc_group_of_psa( curve ); + grp_id = mbedtls_ecc_group_of_psa( curve, data_length ); + if( grp_id == MBEDTLS_ECP_DP_NONE ) + return( PSA_ERROR_INVALID_ARGUMENT ); return( mbedtls_to_psa_error( mbedtls_ecp_group_load( &( *p_ecp )->grp, grp_id ) ) ); } @@ -626,7 +645,7 @@ static psa_status_t psa_import_ec_public_key( psa_ecc_curve_t curve, psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; mbedtls_ecp_keypair *ecp = NULL; - status = psa_prepare_import_ec_key( curve, &ecp ); + status = psa_prepare_import_ec_key( curve, data_length, 1, &ecp ); if( status != PSA_SUCCESS ) goto exit; @@ -668,7 +687,7 @@ static psa_status_t psa_import_ec_private_key( psa_ecc_curve_t curve, if( PSA_BITS_TO_BYTES( PSA_ECC_CURVE_BITS( curve ) ) != data_length ) return( PSA_ERROR_INVALID_ARGUMENT ); - status = psa_prepare_import_ec_key( curve, &ecp ); + status = psa_prepare_import_ec_key( curve, data_length, 0, &ecp ); if( status != PSA_SUCCESS ) goto exit; @@ -5578,7 +5597,8 @@ static psa_status_t psa_generate_key_internal( if ( PSA_KEY_TYPE_IS_ECC( type ) && PSA_KEY_TYPE_IS_KEY_PAIR( type ) ) { psa_ecc_curve_t curve = PSA_KEY_TYPE_GET_CURVE( type ); - mbedtls_ecp_group_id grp_id = mbedtls_ecc_group_of_psa( curve ); + mbedtls_ecp_group_id grp_id = + mbedtls_ecc_group_of_psa( curve, PSA_BITS_TO_BYTES( bits ) ); const mbedtls_ecp_curve_info *curve_info = mbedtls_ecp_curve_info_from_grp_id( grp_id ); mbedtls_ecp_keypair *ecp; diff --git a/tests/suites/test_suite_psa_crypto.data b/tests/suites/test_suite_psa_crypto.data index b70fc638f..0205eea2b 100644 --- a/tests/suites/test_suite_psa_crypto.data +++ b/tests/suites/test_suite_psa_crypto.data @@ -304,11 +304,7 @@ import_with_data:"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325 PSA import EC public key: key pair depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_ECP_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED -# For consistency with ECpub as ECpair, RSApub as RSApair and RSApair as RSApub, -# one would expect the status to be PSA_ERROR_INVALID_ARGUMENT. But the -# Mbed TLS pkparse module returns MBEDTLS_ERR_PK_INVALID_ALG, I think because -# it's looking for an OID where there is no OID. -import_with_data:"3078020101042100ab45435712649cb30bbddac49197eebf2740ffc7f874d9244c3460f54f322d3aa00a06082a8648ce3d030107a14403420004dea5e45d0ea37fc566232a508f4ad20ea13d47e4bf5fa4d54a57a0ba012042087097496efc583fed8b24a5b9be9a51de063f5a00a8b698a16fd7f29b5485f320":PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_CURVE_SECP256R1):0:PSA_ERROR_NOT_SUPPORTED +import_with_data:"3078020101042100ab45435712649cb30bbddac49197eebf2740ffc7f874d9244c3460f54f322d3aa00a06082a8648ce3d030107a14403420004dea5e45d0ea37fc566232a508f4ad20ea13d47e4bf5fa4d54a57a0ba012042087097496efc583fed8b24a5b9be9a51de063f5a00a8b698a16fd7f29b5485f320":PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_CURVE_SECP256R1):0:PSA_ERROR_INVALID_ARGUMENT PSA import EC keypair: valid key but RSA depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_ECP_C:MBEDTLS_ECP_DP_BP512R1_ENABLED:MBEDTLS_RSA_C