From e3fd39289ea15787064b00e8c29d9e9a63d2ff5d Mon Sep 17 00:00:00 2001 From: Steven Cooreman Date: Thu, 11 Jun 2020 16:50:36 +0200 Subject: [PATCH] Fix endianness and masking for Curve25519 keys handled by PSA Changed PSA core (and PKWrite) from reaching into MPI to using the proper ecp function to fetch a private key. Added changelog. Signed-off-by: Steven Cooreman --- ChangeLog.d/psa_curve25519_key_support.txt | 10 ++++++++++ library/pkwrite.c | 3 ++- library/psa_crypto.c | 14 ++++++-------- 3 files changed, 18 insertions(+), 9 deletions(-) create mode 100644 ChangeLog.d/psa_curve25519_key_support.txt diff --git a/ChangeLog.d/psa_curve25519_key_support.txt b/ChangeLog.d/psa_curve25519_key_support.txt new file mode 100644 index 0000000000..f0d19aa73c --- /dev/null +++ b/ChangeLog.d/psa_curve25519_key_support.txt @@ -0,0 +1,10 @@ +Requirement changes + * Clarify and test the import/export behaviour of PSA key management APIs to + adhere to the to-be-introduced clarification. Montgomery keys + (such as Curve25519) should be imported/exported in masked form. + +Bugfix + * Update and test the PSA key management against Montgomery keys, since + these need to be imported/exported in little-endian form. Added mirror + function of mbedtls_ecp_read_key called mbedtls_ecp_write_key to retrieve + a private key in the correct form. diff --git a/library/pkwrite.c b/library/pkwrite.c index b1b5f4685a..914b33ff46 100644 --- a/library/pkwrite.c +++ b/library/pkwrite.c @@ -166,9 +166,10 @@ static int pk_write_ec_private( unsigned char **p, unsigned char *start, { int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; size_t byte_length = ( ec->grp.pbits + 7 ) / 8; + size_t output_length; unsigned char tmp[MBEDTLS_ECP_MAX_BYTES]; - ret = mbedtls_mpi_write_binary( &ec->d, tmp, byte_length ); + ret = mbedtls_ecp_write_key( ec->grp.id, ec, &output_length, tmp, byte_length ); if( ret != 0 ) goto exit; ret = mbedtls_asn1_write_octet_string( p, start, tmp, byte_length ); diff --git a/library/psa_crypto.c b/library/psa_crypto.c index 69323184d0..1151d17f73 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -670,16 +670,12 @@ static psa_status_t psa_import_ec_private_key( psa_ecc_curve_t curve, if( status != PSA_SUCCESS ) goto exit; - /* Load the secret value. */ + /* Load and validate the secret key */ status = mbedtls_to_psa_error( - mbedtls_mpi_read_binary( &ecp->d, data, data_length ) ); - if( status != PSA_SUCCESS ) - goto exit; - /* Validate the private key. */ - status = mbedtls_to_psa_error( - mbedtls_ecp_check_privkey( &ecp->grp, &ecp->d ) ); + mbedtls_ecp_read_key( ecp->grp.id, ecp, data, data_length ) ); if( status != PSA_SUCCESS ) goto exit; + /* Calculate the public key from the private key. */ status = mbedtls_to_psa_error( mbedtls_ecp_mul( &ecp->grp, &ecp->Q, &ecp->d, &ecp->grp.G, @@ -1325,12 +1321,14 @@ static psa_status_t psa_internal_export_key( const psa_key_slot_t *slot, if( PSA_KEY_TYPE_IS_ECC_KEY_PAIR( slot->attr.type ) && !export_public_key ) { psa_status_t status; + size_t actual_data_size; size_t bytes = PSA_BITS_TO_BYTES( slot->attr.bits ); if( bytes > data_size ) return( PSA_ERROR_BUFFER_TOO_SMALL ); status = mbedtls_to_psa_error( - mbedtls_mpi_write_binary( &slot->data.ecp->d, data, bytes ) ); + mbedtls_ecp_write_key(slot->data.ecp->grp.id, slot->data.ecp, + &actual_data_size, data, bytes) ); if( status != PSA_SUCCESS ) return( status ); memset( data + bytes, 0, data_size - bytes );