mirror of
https://github.com/yuzu-emu/mbedtls.git
synced 2024-12-23 00:05:35 +00:00
Remove ECP internal representation from key slot
Change to on-demand loading of the internal representation when required in order to call an mbed TLS cryptography API. Signed-off-by: Steven Cooreman <steven.cooreman@silabs.com>
This commit is contained in:
parent
a01795d609
commit
acda8346bf
|
@ -713,18 +713,17 @@ exit:
|
|||
#endif /* defined(MBEDTLS_RSA_C) */
|
||||
|
||||
#if defined(MBEDTLS_ECP_C)
|
||||
static psa_status_t psa_prepare_import_ec_key( psa_ecc_family_t curve,
|
||||
size_t data_length,
|
||||
int is_public,
|
||||
mbedtls_ecp_keypair **p_ecp )
|
||||
/* Load the key slot contents into an mbedTLS internal representation object.
|
||||
* Note: caller is responsible for freeing the object properly */
|
||||
static psa_status_t psa_load_ecp_representation( const psa_key_slot_t *slot,
|
||||
mbedtls_ecp_keypair *ecp )
|
||||
{
|
||||
mbedtls_ecp_group_id grp_id = MBEDTLS_ECP_DP_NONE;
|
||||
*p_ecp = mbedtls_calloc( 1, sizeof( mbedtls_ecp_keypair ) );
|
||||
if( *p_ecp == NULL )
|
||||
return( PSA_ERROR_INSUFFICIENT_MEMORY );
|
||||
mbedtls_ecp_keypair_init( *p_ecp );
|
||||
size_t data_length = slot->data.key.bytes;
|
||||
psa_status_t status;
|
||||
mbedtls_ecp_keypair_init( ecp );
|
||||
|
||||
if( is_public )
|
||||
if( PSA_KEY_TYPE_IS_PUBLIC_KEY( slot->attr.type ) )
|
||||
{
|
||||
/* A public key is represented as:
|
||||
* - The byte 0x04;
|
||||
|
@ -732,99 +731,169 @@ static psa_status_t psa_prepare_import_ec_key( psa_ecc_family_t curve,
|
|||
* - `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 )
|
||||
if( ( slot->data.key.bytes & 1 ) == 0 )
|
||||
return( PSA_ERROR_INVALID_ARGUMENT );
|
||||
data_length = data_length / 2;
|
||||
data_length = slot->data.key.bytes / 2;
|
||||
}
|
||||
|
||||
/* Load the group. */
|
||||
grp_id = mbedtls_ecc_group_of_psa( curve, data_length );
|
||||
grp_id = mbedtls_ecc_group_of_psa( PSA_KEY_TYPE_ECC_GET_FAMILY( slot->attr.type),
|
||||
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 ) ) );
|
||||
status = mbedtls_to_psa_error(
|
||||
mbedtls_ecp_group_load( &ecp->grp, grp_id ) );
|
||||
if( status != PSA_SUCCESS )
|
||||
return( status );
|
||||
|
||||
/* Load the key material */
|
||||
if( PSA_KEY_TYPE_IS_PUBLIC_KEY( slot->attr.type ) )
|
||||
{
|
||||
/* Load the public value. */
|
||||
status = mbedtls_to_psa_error(
|
||||
mbedtls_ecp_point_read_binary( &ecp->grp, &ecp->Q,
|
||||
slot->data.key.data,
|
||||
slot->data.key.bytes ) );
|
||||
if( status != PSA_SUCCESS )
|
||||
goto exit;
|
||||
|
||||
/* Check that the point is on the curve. */
|
||||
status = mbedtls_to_psa_error(
|
||||
mbedtls_ecp_check_pubkey( &ecp->grp, &ecp->Q ) );
|
||||
if( status != PSA_SUCCESS )
|
||||
goto exit;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Load the secret value. */
|
||||
status = mbedtls_to_psa_error(
|
||||
mbedtls_ecp_read_key( ecp->grp.id,
|
||||
ecp,
|
||||
slot->data.key.data,
|
||||
slot->data.key.bytes ) );
|
||||
|
||||
if( status != PSA_SUCCESS )
|
||||
goto exit;
|
||||
/* Validate the private key. */
|
||||
status = mbedtls_to_psa_error(
|
||||
mbedtls_ecp_check_privkey( &ecp->grp, &ecp->d ) );
|
||||
if( status != PSA_SUCCESS )
|
||||
goto exit;
|
||||
}
|
||||
exit:
|
||||
if( status != PSA_SUCCESS )
|
||||
mbedtls_ecp_keypair_free( ecp );
|
||||
return status;
|
||||
}
|
||||
|
||||
/* Import a public key given as the uncompressed representation defined by SEC1
|
||||
* 2.3.3 as the content of an ECPoint. */
|
||||
static psa_status_t psa_import_ec_public_key( psa_ecc_family_t curve,
|
||||
const uint8_t *data,
|
||||
size_t data_length,
|
||||
mbedtls_ecp_keypair **p_ecp )
|
||||
static psa_status_t psa_export_ecp_key( psa_key_type_t type,
|
||||
mbedtls_ecp_keypair *ecp,
|
||||
uint8_t *data,
|
||||
size_t data_size,
|
||||
size_t *data_length )
|
||||
{
|
||||
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
|
||||
mbedtls_ecp_keypair *ecp = NULL;
|
||||
psa_status_t status;
|
||||
|
||||
status = psa_prepare_import_ec_key( curve, data_length, 1, &ecp );
|
||||
if( status != PSA_SUCCESS )
|
||||
goto exit;
|
||||
|
||||
/* Load the public value. */
|
||||
status = mbedtls_to_psa_error(
|
||||
mbedtls_ecp_point_read_binary( &ecp->grp, &ecp->Q,
|
||||
data, data_length ) );
|
||||
if( status != PSA_SUCCESS )
|
||||
goto exit;
|
||||
|
||||
/* Check that the point is on the curve. */
|
||||
status = mbedtls_to_psa_error(
|
||||
mbedtls_ecp_check_pubkey( &ecp->grp, &ecp->Q ) );
|
||||
if( status != PSA_SUCCESS )
|
||||
goto exit;
|
||||
|
||||
*p_ecp = ecp;
|
||||
return( PSA_SUCCESS );
|
||||
|
||||
exit:
|
||||
if( ecp != NULL )
|
||||
if( PSA_KEY_TYPE_IS_PUBLIC_KEY( type ) )
|
||||
{
|
||||
mbedtls_ecp_keypair_free( ecp );
|
||||
mbedtls_free( ecp );
|
||||
/* Check whether the public part is loaded */
|
||||
if( mbedtls_ecp_is_zero( &ecp->Q ) )
|
||||
{
|
||||
/* Calculate the public key */
|
||||
status = mbedtls_to_psa_error(
|
||||
mbedtls_ecp_mul( &ecp->grp, &ecp->Q, &ecp->d, &ecp->grp.G,
|
||||
mbedtls_ctr_drbg_random, &global_data.ctr_drbg ) );
|
||||
if( status != PSA_SUCCESS )
|
||||
return status;
|
||||
}
|
||||
|
||||
return( mbedtls_to_psa_error(
|
||||
mbedtls_ecp_point_write_binary( &ecp->grp, &ecp->Q,
|
||||
MBEDTLS_ECP_PF_UNCOMPRESSED,
|
||||
data_length,
|
||||
data,
|
||||
data_size ) ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
if( data_size < PSA_BITS_TO_BYTES(ecp->grp.nbits) )
|
||||
return( PSA_ERROR_BUFFER_TOO_SMALL );
|
||||
|
||||
status = mbedtls_to_psa_error(
|
||||
mbedtls_ecp_write_key( ecp,
|
||||
data,
|
||||
PSA_BITS_TO_BYTES(ecp->grp.nbits) ) );
|
||||
if( status == PSA_SUCCESS )
|
||||
{
|
||||
*data_length = PSA_BITS_TO_BYTES(ecp->grp.nbits);
|
||||
}
|
||||
|
||||
return( status );
|
||||
}
|
||||
return( status );
|
||||
}
|
||||
|
||||
/* Import a private key given as a byte string which is the private value
|
||||
* in big-endian order. */
|
||||
static psa_status_t psa_import_ec_private_key( psa_ecc_family_t curve,
|
||||
const uint8_t *data,
|
||||
size_t data_length,
|
||||
mbedtls_ecp_keypair **p_ecp )
|
||||
static psa_status_t psa_import_ecp_key( psa_key_slot_t *slot,
|
||||
const uint8_t *data,
|
||||
size_t data_length )
|
||||
{
|
||||
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
|
||||
mbedtls_ecp_keypair *ecp = NULL;
|
||||
psa_status_t status;
|
||||
uint8_t* output = NULL;
|
||||
mbedtls_ecp_keypair ecp;
|
||||
|
||||
status = psa_prepare_import_ec_key( curve, data_length, 0, &ecp );
|
||||
/* Temporarily load input into slot. The cast here is safe since it'll
|
||||
* only be used for load_ecp_representation, which doesn't modify the
|
||||
* buffer. */
|
||||
slot->data.key.data = (uint8_t *)data;
|
||||
slot->data.key.bytes = data_length;
|
||||
|
||||
/* Parse input */
|
||||
status = psa_load_ecp_representation( slot, &ecp );
|
||||
if( status != PSA_SUCCESS )
|
||||
goto exit;
|
||||
|
||||
/* Load and validate the secret key */
|
||||
status = mbedtls_to_psa_error(
|
||||
mbedtls_ecp_read_key( ecp->grp.id, ecp, data, data_length ) );
|
||||
if( status != PSA_SUCCESS )
|
||||
goto exit;
|
||||
if( PSA_KEY_TYPE_ECC_GET_FAMILY( slot->attr.type ) == PSA_ECC_FAMILY_MONTGOMERY)
|
||||
slot->attr.bits = (psa_key_bits_t) ecp.grp.nbits + 1;
|
||||
else
|
||||
slot->attr.bits = (psa_key_bits_t) ecp.grp.nbits;
|
||||
|
||||
/* 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,
|
||||
mbedtls_ctr_drbg_random, &global_data.ctr_drbg ) );
|
||||
if( status != PSA_SUCCESS )
|
||||
goto exit;
|
||||
/* Re-export the data to PSA export format. There is currently no support
|
||||
* for other input formats then the export format, so this is a 1-1
|
||||
* copy operation. */
|
||||
output = mbedtls_calloc( 1, data_length );
|
||||
|
||||
*p_ecp = ecp;
|
||||
return( PSA_SUCCESS );
|
||||
if( output == NULL )
|
||||
{
|
||||
status = PSA_ERROR_INSUFFICIENT_MEMORY;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
status = psa_export_ecp_key( slot->attr.type,
|
||||
&ecp,
|
||||
output,
|
||||
data_length,
|
||||
&data_length);
|
||||
|
||||
exit:
|
||||
if( ecp != NULL )
|
||||
/* Always free the PK object (will also free contained RSA context) */
|
||||
mbedtls_ecp_keypair_free( &ecp );
|
||||
|
||||
/* Free the allocated buffer only on error. */
|
||||
if( status != PSA_SUCCESS )
|
||||
{
|
||||
mbedtls_ecp_keypair_free( ecp );
|
||||
mbedtls_free( ecp );
|
||||
mbedtls_free( output );
|
||||
slot->data.key.data = NULL;
|
||||
slot->data.key.bytes = 0;
|
||||
return( status );
|
||||
}
|
||||
return( status );
|
||||
|
||||
/* On success, store the allocated export-formatted key. */
|
||||
slot->data.key.data = output;
|
||||
slot->data.key.bytes = data_length;
|
||||
|
||||
return( PSA_SUCCESS );
|
||||
}
|
||||
#endif /* defined(MBEDTLS_ECP_C) */
|
||||
|
||||
|
||||
/** Return the size of the key in the given slot, in bits.
|
||||
*
|
||||
* \param[in] slot A key slot.
|
||||
|
@ -848,10 +917,6 @@ static psa_key_bits_t psa_calculate_key_bits( const psa_key_slot_t *slot )
|
|||
|
||||
if( key_type_is_raw_bytes( slot->attr.type ) )
|
||||
bits = PSA_BYTES_TO_BITS( slot->data.key.bytes );
|
||||
#if defined(MBEDTLS_ECP_C)
|
||||
else if( PSA_KEY_TYPE_IS_ECC( slot->attr.type ) )
|
||||
bits = slot->data.ecp->grp.pbits;
|
||||
#endif /* defined(MBEDTLS_ECP_C) */
|
||||
|
||||
/* We know that the size fits in psa_key_bits_t thanks to checks
|
||||
* when the key was created. */
|
||||
|
@ -906,18 +971,9 @@ psa_status_t psa_import_key_into_slot( psa_key_slot_t *slot,
|
|||
}
|
||||
else
|
||||
#if defined(MBEDTLS_ECP_C)
|
||||
if( PSA_KEY_TYPE_IS_ECC_KEY_PAIR( slot->attr.type ) )
|
||||
if( PSA_KEY_TYPE_IS_ECC( slot->attr.type ) )
|
||||
{
|
||||
status = psa_import_ec_private_key( PSA_KEY_TYPE_ECC_GET_FAMILY( slot->attr.type ),
|
||||
data, data_length,
|
||||
&slot->data.ecp );
|
||||
}
|
||||
else if( PSA_KEY_TYPE_IS_ECC_PUBLIC_KEY( slot->attr.type ) )
|
||||
{
|
||||
status = psa_import_ec_public_key(
|
||||
PSA_KEY_TYPE_ECC_GET_FAMILY( slot->attr.type ),
|
||||
data, data_length,
|
||||
&slot->data.ecp );
|
||||
status = psa_import_ecp_key( slot, data, data_length );
|
||||
}
|
||||
else
|
||||
#endif /* MBEDTLS_ECP_C */
|
||||
|
@ -934,7 +990,8 @@ psa_status_t psa_import_key_into_slot( psa_key_slot_t *slot,
|
|||
|
||||
if( status == PSA_SUCCESS )
|
||||
{
|
||||
if( !PSA_KEY_TYPE_IS_RSA( slot->attr.type ) )
|
||||
if( !PSA_KEY_TYPE_IS_RSA( slot->attr.type ) &&
|
||||
!PSA_KEY_TYPE_IS_ECC( slot->attr.type ) )
|
||||
{
|
||||
/* Write the actual key size to the slot.
|
||||
* psa_start_key_creation() wrote the size declared by the
|
||||
|
@ -1126,8 +1183,9 @@ static psa_status_t psa_remove_key_data_from_memory( psa_key_slot_t *slot )
|
|||
#if defined(MBEDTLS_ECP_C)
|
||||
if( PSA_KEY_TYPE_IS_ECC( slot->attr.type ) )
|
||||
{
|
||||
mbedtls_ecp_keypair_free( slot->data.ecp );
|
||||
mbedtls_free( slot->data.ecp );
|
||||
mbedtls_free( slot->data.key.data );
|
||||
slot->data.key.data = NULL;
|
||||
slot->data.key.bytes = 0;
|
||||
}
|
||||
else
|
||||
#endif /* defined(MBEDTLS_ECP_C) */
|
||||
|
@ -1409,22 +1467,6 @@ psa_status_t psa_get_key_slot_number(
|
|||
}
|
||||
#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
|
||||
|
||||
#if defined(MBEDTLS_RSA_C) || defined(MBEDTLS_ECP_C)
|
||||
static int pk_write_pubkey_simple( mbedtls_pk_context *key,
|
||||
unsigned char *buf, size_t size )
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
unsigned char *c;
|
||||
size_t len = 0;
|
||||
|
||||
c = buf + size;
|
||||
|
||||
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_pk_write_pubkey( &c, buf, key ) );
|
||||
|
||||
return( (int) len );
|
||||
}
|
||||
#endif /* defined(MBEDTLS_RSA_C) || defined(MBEDTLS_ECP_C) */
|
||||
|
||||
static psa_status_t psa_internal_export_key_buffer( const psa_key_slot_t *slot,
|
||||
uint8_t *data,
|
||||
size_t data_size,
|
||||
|
@ -1491,29 +1533,15 @@ static psa_status_t psa_internal_export_key( const psa_key_slot_t *slot,
|
|||
#if defined(MBEDTLS_ECP_C)
|
||||
if( PSA_KEY_TYPE_IS_ECC_KEY_PAIR( slot->attr.type ) && !export_public_key )
|
||||
{
|
||||
psa_status_t status;
|
||||
|
||||
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_ecp_write_key( slot->data.ecp,
|
||||
data, bytes ) );
|
||||
if( status != PSA_SUCCESS )
|
||||
return( status );
|
||||
memset( data + bytes, 0, data_size - bytes );
|
||||
*data_length = bytes;
|
||||
return( PSA_SUCCESS );
|
||||
/* Exporting private -> private */
|
||||
return( psa_internal_export_key_buffer( slot, data, data_size, data_length ) );
|
||||
}
|
||||
#endif
|
||||
else
|
||||
{
|
||||
#if defined(MBEDTLS_PK_WRITE_C)
|
||||
if( PSA_KEY_TYPE_IS_RSA( slot->attr.type ) ||
|
||||
PSA_KEY_TYPE_IS_ECC( slot->attr.type ) )
|
||||
{
|
||||
mbedtls_pk_context pk;
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
if( PSA_KEY_TYPE_IS_RSA( slot->attr.type ) )
|
||||
{
|
||||
#if defined(MBEDTLS_RSA_C)
|
||||
|
@ -1553,44 +1581,28 @@ static psa_status_t psa_internal_export_key( const psa_key_slot_t *slot,
|
|||
else
|
||||
{
|
||||
#if defined(MBEDTLS_ECP_C)
|
||||
mbedtls_pk_init( &pk );
|
||||
pk.pk_info = &mbedtls_eckey_info;
|
||||
pk.pk_ctx = slot->data.ecp;
|
||||
mbedtls_ecp_keypair ecp;
|
||||
psa_status_t status = psa_load_ecp_representation( slot, &ecp );
|
||||
if( status != PSA_SUCCESS )
|
||||
return status;
|
||||
|
||||
status = psa_export_ecp_key( PSA_KEY_TYPE_ECC_PUBLIC_KEY(
|
||||
PSA_KEY_TYPE_ECC_GET_FAMILY(
|
||||
slot->attr.type ) ),
|
||||
&ecp,
|
||||
data,
|
||||
data_size,
|
||||
data_length );
|
||||
|
||||
mbedtls_ecp_keypair_free( &ecp );
|
||||
return( status );
|
||||
#else
|
||||
/* We don't know how to convert a private ECC key to public. */
|
||||
return( PSA_ERROR_NOT_SUPPORTED );
|
||||
#endif
|
||||
#endif /* defined(MBEDTLS_ECP_C) */
|
||||
}
|
||||
if( export_public_key || PSA_KEY_TYPE_IS_PUBLIC_KEY( slot->attr.type ) )
|
||||
{
|
||||
ret = pk_write_pubkey_simple( &pk, data, data_size );
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = mbedtls_pk_write_key_der( &pk, data, data_size );
|
||||
}
|
||||
if( ret < 0 )
|
||||
{
|
||||
memset( data, 0, data_size );
|
||||
return( mbedtls_to_psa_error( ret ) );
|
||||
}
|
||||
/* The mbedtls_pk_xxx functions write to the end of the buffer.
|
||||
* Move the data to the beginning and erase remaining data
|
||||
* at the original location. */
|
||||
if( 2 * (size_t) ret <= data_size )
|
||||
{
|
||||
memcpy( data, data + data_size - ret, ret );
|
||||
memset( data + data_size - ret, 0, ret );
|
||||
}
|
||||
else if( (size_t) ret < data_size )
|
||||
{
|
||||
memmove( data, data + data_size - ret, ret );
|
||||
memset( data + ret, 0, data_size - ret );
|
||||
}
|
||||
*data_length = ret;
|
||||
return( PSA_SUCCESS );
|
||||
}
|
||||
else
|
||||
#endif /* defined(MBEDTLS_PK_WRITE_C) */
|
||||
{
|
||||
/* This shouldn't happen in the reference implementation, but
|
||||
it is valid for a special-purpose implementation to omit
|
||||
|
@ -3580,6 +3592,14 @@ static psa_status_t psa_ecdsa_verify( mbedtls_ecp_keypair *ecp,
|
|||
signature + curve_bytes,
|
||||
curve_bytes ) );
|
||||
|
||||
/* Check whether the public part is loaded. If not, load it. */
|
||||
if( mbedtls_ecp_is_zero( &ecp->Q ) )
|
||||
{
|
||||
MBEDTLS_MPI_CHK(
|
||||
mbedtls_ecp_mul( &ecp->grp, &ecp->Q, &ecp->d, &ecp->grp.G,
|
||||
mbedtls_ctr_drbg_random, &global_data.ctr_drbg ) );
|
||||
}
|
||||
|
||||
ret = mbedtls_ecdsa_verify( &ecp->grp, hash, hash_length,
|
||||
&ecp->Q, &r, &s );
|
||||
|
||||
|
@ -3672,11 +3692,18 @@ psa_status_t psa_sign_hash( psa_key_handle_t handle,
|
|||
PSA_ALG_IS_RANDOMIZED_ECDSA( alg )
|
||||
#endif
|
||||
)
|
||||
status = psa_ecdsa_sign( slot->data.ecp,
|
||||
{
|
||||
mbedtls_ecp_keypair ecp;
|
||||
status = psa_load_ecp_representation( slot, &ecp );
|
||||
if( status != PSA_SUCCESS )
|
||||
goto exit;
|
||||
status = psa_ecdsa_sign( &ecp,
|
||||
alg,
|
||||
hash, hash_length,
|
||||
signature, signature_size,
|
||||
signature_length );
|
||||
mbedtls_ecp_keypair_free( &ecp );
|
||||
}
|
||||
else
|
||||
#endif /* defined(MBEDTLS_ECDSA_C) */
|
||||
{
|
||||
|
@ -3760,9 +3787,17 @@ psa_status_t psa_verify_hash( psa_key_handle_t handle,
|
|||
{
|
||||
#if defined(MBEDTLS_ECDSA_C)
|
||||
if( PSA_ALG_IS_ECDSA( alg ) )
|
||||
return( psa_ecdsa_verify( slot->data.ecp,
|
||||
hash, hash_length,
|
||||
signature, signature_length ) );
|
||||
{
|
||||
mbedtls_ecp_keypair ecp;
|
||||
status = psa_load_ecp_representation( slot, &ecp );
|
||||
if( status != PSA_SUCCESS )
|
||||
return status;
|
||||
status = psa_ecdsa_verify( &ecp,
|
||||
hash, hash_length,
|
||||
signature, signature_length );
|
||||
mbedtls_ecp_keypair_free( &ecp );
|
||||
return status;
|
||||
}
|
||||
else
|
||||
#endif /* defined(MBEDTLS_ECDSA_C) */
|
||||
{
|
||||
|
@ -5511,21 +5546,26 @@ static psa_status_t psa_key_agreement_ecdh( const uint8_t *peer_key,
|
|||
size_t shared_secret_size,
|
||||
size_t *shared_secret_length )
|
||||
{
|
||||
mbedtls_ecp_keypair *their_key = NULL;
|
||||
mbedtls_ecp_keypair their_key;
|
||||
psa_key_slot_t their_key_slot;
|
||||
mbedtls_ecdh_context ecdh;
|
||||
psa_status_t status;
|
||||
size_t bits = 0;
|
||||
psa_ecc_family_t curve = mbedtls_ecc_group_to_psa( our_key->grp.id, &bits );
|
||||
mbedtls_ecdh_init( &ecdh );
|
||||
memset(&their_key_slot, 0, sizeof(their_key_slot));
|
||||
|
||||
status = psa_import_ec_public_key( curve,
|
||||
peer_key, peer_key_length,
|
||||
&their_key );
|
||||
/* Creating ephemeral key slot for import purposes */
|
||||
their_key_slot.attr.type = PSA_KEY_TYPE_ECC_PUBLIC_KEY(curve);
|
||||
their_key_slot.data.key.data = (uint8_t*) peer_key;
|
||||
their_key_slot.data.key.bytes = peer_key_length;
|
||||
|
||||
status = psa_load_ecp_representation( &their_key_slot, &their_key );
|
||||
if( status != PSA_SUCCESS )
|
||||
goto exit;
|
||||
|
||||
status = mbedtls_to_psa_error(
|
||||
mbedtls_ecdh_get_params( &ecdh, their_key, MBEDTLS_ECDH_THEIRS ) );
|
||||
mbedtls_ecdh_get_params( &ecdh, &their_key, MBEDTLS_ECDH_THEIRS ) );
|
||||
if( status != PSA_SUCCESS )
|
||||
goto exit;
|
||||
status = mbedtls_to_psa_error(
|
||||
|
@ -5548,8 +5588,7 @@ exit:
|
|||
if( status != PSA_SUCCESS )
|
||||
mbedtls_platform_zeroize( shared_secret, shared_secret_size );
|
||||
mbedtls_ecdh_free( &ecdh );
|
||||
mbedtls_ecp_keypair_free( their_key );
|
||||
mbedtls_free( their_key );
|
||||
mbedtls_ecp_keypair_free( &their_key );
|
||||
return( status );
|
||||
}
|
||||
#endif /* MBEDTLS_ECDH_C */
|
||||
|
@ -5570,10 +5609,16 @@ static psa_status_t psa_key_agreement_raw_internal( psa_algorithm_t alg,
|
|||
case PSA_ALG_ECDH:
|
||||
if( ! PSA_KEY_TYPE_IS_ECC_KEY_PAIR( private_key->attr.type ) )
|
||||
return( PSA_ERROR_INVALID_ARGUMENT );
|
||||
return( psa_key_agreement_ecdh( peer_key, peer_key_length,
|
||||
private_key->data.ecp,
|
||||
shared_secret, shared_secret_size,
|
||||
shared_secret_length ) );
|
||||
mbedtls_ecp_keypair ecp;
|
||||
psa_status_t status = psa_load_ecp_representation( private_key, &ecp );
|
||||
if( status != PSA_SUCCESS )
|
||||
return status;
|
||||
status = psa_key_agreement_ecdh( peer_key, peer_key_length,
|
||||
&ecp,
|
||||
shared_secret, shared_secret_size,
|
||||
shared_secret_length );
|
||||
mbedtls_ecp_keypair_free( &ecp );
|
||||
return status;
|
||||
#endif /* MBEDTLS_ECDH_C */
|
||||
default:
|
||||
(void) private_key;
|
||||
|
@ -5860,7 +5905,7 @@ static psa_status_t psa_generate_key_internal(
|
|||
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;
|
||||
mbedtls_ecp_keypair ecp;
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
if( domain_parameters_size != 0 )
|
||||
return( PSA_ERROR_NOT_SUPPORTED );
|
||||
|
@ -5868,20 +5913,36 @@ static psa_status_t psa_generate_key_internal(
|
|||
return( PSA_ERROR_NOT_SUPPORTED );
|
||||
if( curve_info->bit_size != bits )
|
||||
return( PSA_ERROR_INVALID_ARGUMENT );
|
||||
ecp = mbedtls_calloc( 1, sizeof( *ecp ) );
|
||||
if( ecp == NULL )
|
||||
return( PSA_ERROR_INSUFFICIENT_MEMORY );
|
||||
mbedtls_ecp_keypair_init( ecp );
|
||||
ret = mbedtls_ecp_gen_key( grp_id, ecp,
|
||||
mbedtls_ecp_keypair_init( &ecp );
|
||||
ret = mbedtls_ecp_gen_key( grp_id, &ecp,
|
||||
mbedtls_ctr_drbg_random,
|
||||
&global_data.ctr_drbg );
|
||||
if( ret != 0 )
|
||||
{
|
||||
mbedtls_ecp_keypair_free( ecp );
|
||||
mbedtls_free( ecp );
|
||||
mbedtls_ecp_keypair_free( &ecp );
|
||||
return( mbedtls_to_psa_error( ret ) );
|
||||
}
|
||||
slot->data.ecp = ecp;
|
||||
|
||||
|
||||
/* Make sure to always have an export representation available */
|
||||
size_t bytes = PSA_BITS_TO_BYTES( bits );
|
||||
slot->data.key.data = mbedtls_calloc( 1, bytes );
|
||||
if( slot->data.key.data == NULL )
|
||||
{
|
||||
mbedtls_ecp_keypair_free( &ecp );
|
||||
return( PSA_ERROR_INSUFFICIENT_MEMORY );
|
||||
}
|
||||
slot->data.key.bytes = bytes;
|
||||
psa_status_t status = mbedtls_to_psa_error(
|
||||
mbedtls_ecp_write_key( &ecp, slot->data.key.data, bytes ) );
|
||||
|
||||
mbedtls_ecp_keypair_free( &ecp );
|
||||
if( status != PSA_SUCCESS )
|
||||
{
|
||||
psa_remove_key_data_from_memory( slot );
|
||||
return( status );
|
||||
}
|
||||
return( PSA_SUCCESS );
|
||||
}
|
||||
else
|
||||
#endif /* MBEDTLS_ECP_C */
|
||||
|
|
|
@ -32,8 +32,6 @@
|
|||
#include "psa/crypto.h"
|
||||
#include "psa/crypto_se_driver.h"
|
||||
|
||||
#include "mbedtls/ecp.h"
|
||||
|
||||
/** The data structure representing a key slot, containing key material
|
||||
* and metadata for one key.
|
||||
*/
|
||||
|
@ -49,10 +47,6 @@ typedef struct
|
|||
uint8_t *data;
|
||||
size_t bytes;
|
||||
} key;
|
||||
#if defined(MBEDTLS_ECP_C)
|
||||
/* EC public key or key pair */
|
||||
mbedtls_ecp_keypair *ecp;
|
||||
#endif /* MBEDTLS_ECP_C */
|
||||
#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
|
||||
/* Any key type in a secure element */
|
||||
struct se
|
||||
|
|
Loading…
Reference in a new issue