Convert load_xxx_representation to take buffers instead of a whole slot
Avoids stack-allocating a key slot during ECDH, and mock-attaching a key to a key slot during key import. Signed-off-by: Steven Cooreman <steven.cooreman@silabs.com>
This commit is contained in:
parent
6d839f05bf
commit
7f39187d6b
1 changed files with 90 additions and 54 deletions
|
@ -518,15 +518,19 @@ static psa_status_t psa_check_rsa_key_byte_aligned(
|
|||
}
|
||||
#endif /* MBEDTLS_PK_PARSE_C */
|
||||
|
||||
/** Load the contents of a key slot into an internal RSA representation
|
||||
/** Load the contents of a key buffer into an internal RSA representation
|
||||
*
|
||||
* \param[in] slot The slot from which to load the representation
|
||||
* \param[in] buffer The buffer from which to load the representation.
|
||||
* \param[in] size The size in bytes of \p buffer.
|
||||
* \param[in] type The type of key contained in the \p buffer.
|
||||
* \param[out] p_rsa Returns a pointer to an RSA context on success.
|
||||
* The caller is responsible for freeing both the
|
||||
* contents of the context and the context itself
|
||||
* when done.
|
||||
*/
|
||||
static psa_status_t psa_load_rsa_representation( const psa_key_slot_t *slot,
|
||||
static psa_status_t psa_load_rsa_representation( const uint8_t *buffer,
|
||||
size_t size,
|
||||
psa_key_type_t type,
|
||||
mbedtls_rsa_context **p_rsa )
|
||||
{
|
||||
#if defined(MBEDTLS_PK_PARSE_C)
|
||||
|
@ -536,12 +540,12 @@ static psa_status_t psa_load_rsa_representation( const psa_key_slot_t *slot,
|
|||
mbedtls_pk_init( &ctx );
|
||||
|
||||
/* Parse the data. */
|
||||
if( PSA_KEY_TYPE_IS_KEY_PAIR( slot->attr.type ) )
|
||||
if( PSA_KEY_TYPE_IS_KEY_PAIR( type ) )
|
||||
status = mbedtls_to_psa_error(
|
||||
mbedtls_pk_parse_key( &ctx, slot->data.key.data, slot->data.key.bytes, NULL, 0 ) );
|
||||
mbedtls_pk_parse_key( &ctx, buffer, size, NULL, 0 ) );
|
||||
else
|
||||
status = mbedtls_to_psa_error(
|
||||
mbedtls_pk_parse_public_key( &ctx, slot->data.key.data, slot->data.key.bytes ) );
|
||||
mbedtls_pk_parse_public_key( &ctx, buffer, size ) );
|
||||
if( status != PSA_SUCCESS )
|
||||
goto exit;
|
||||
|
||||
|
@ -576,7 +580,9 @@ exit:
|
|||
mbedtls_pk_free( &ctx );
|
||||
return( status );
|
||||
#else
|
||||
(void) slot;
|
||||
(void) buffer;
|
||||
(void) size;
|
||||
(void) type;
|
||||
(void) rsa;
|
||||
return( PSA_ERROR_NOT_SUPPORTED );
|
||||
#endif /* MBEDTLS_PK_PARSE_C */
|
||||
|
@ -656,14 +662,11 @@ static psa_status_t psa_import_rsa_key( psa_key_slot_t *slot,
|
|||
uint8_t* output = NULL;
|
||||
mbedtls_rsa_context *rsa = NULL;
|
||||
|
||||
/* Temporarily load input into slot. The cast here is safe since it'll
|
||||
* only be used for load_rsa_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_rsa_representation( slot, &rsa );
|
||||
status = psa_load_rsa_representation( data,
|
||||
data_length,
|
||||
slot->attr.type,
|
||||
&rsa );
|
||||
if( status != PSA_SUCCESS )
|
||||
goto exit;
|
||||
|
||||
|
@ -711,23 +714,27 @@ exit:
|
|||
#endif /* defined(MBEDTLS_RSA_C) */
|
||||
|
||||
#if defined(MBEDTLS_ECP_C)
|
||||
/** Load the contents of a key slot into an internal ECP representation
|
||||
/** Load the contents of a key buffer into an internal ECP representation
|
||||
*
|
||||
* \param[in] slot The slot from which to load the representation
|
||||
* \param[in] buffer The buffer from which to load the representation.
|
||||
* \param[in] size The size in bytes of \p buffer.
|
||||
* \param[in] type The type of key contained in the \p buffer.
|
||||
* \param[out] p_ecp Returns a pointer to an ECP context on success.
|
||||
* The caller is responsible for freeing both the
|
||||
* contents of the context and the context itself
|
||||
* when done.
|
||||
*/
|
||||
static psa_status_t psa_load_ecp_representation( const psa_key_slot_t *slot,
|
||||
static psa_status_t psa_load_ecp_representation( const uint8_t *buffer,
|
||||
size_t size,
|
||||
psa_key_type_t type,
|
||||
mbedtls_ecp_keypair **p_ecp )
|
||||
{
|
||||
mbedtls_ecp_group_id grp_id = MBEDTLS_ECP_DP_NONE;
|
||||
size_t data_length = slot->data.key.bytes;
|
||||
psa_status_t status;
|
||||
mbedtls_ecp_keypair *ecp = NULL;
|
||||
size_t curve_size = size;
|
||||
|
||||
if( PSA_KEY_TYPE_IS_PUBLIC_KEY( slot->attr.type ) )
|
||||
if( PSA_KEY_TYPE_IS_PUBLIC_KEY( type ) )
|
||||
{
|
||||
/* A public key is represented as:
|
||||
* - The byte 0x04;
|
||||
|
@ -735,9 +742,9 @@ static psa_status_t psa_load_ecp_representation( const psa_key_slot_t *slot,
|
|||
* - `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( ( slot->data.key.bytes & 1 ) == 0 )
|
||||
if( ( size & 1 ) == 0 )
|
||||
return( PSA_ERROR_INVALID_ARGUMENT );
|
||||
data_length = slot->data.key.bytes / 2;
|
||||
curve_size = size / 2;
|
||||
}
|
||||
|
||||
/* Allocate and initialize a key representation. */
|
||||
|
@ -747,8 +754,8 @@ static psa_status_t psa_load_ecp_representation( const psa_key_slot_t *slot,
|
|||
mbedtls_ecp_keypair_init( ecp );
|
||||
|
||||
/* Load the group. */
|
||||
grp_id = mbedtls_ecc_group_of_psa( PSA_KEY_TYPE_ECC_GET_FAMILY( slot->attr.type ),
|
||||
data_length );
|
||||
grp_id = mbedtls_ecc_group_of_psa( PSA_KEY_TYPE_ECC_GET_FAMILY( type ),
|
||||
curve_size );
|
||||
if( grp_id == MBEDTLS_ECP_DP_NONE )
|
||||
{
|
||||
status = PSA_ERROR_INVALID_ARGUMENT;
|
||||
|
@ -761,13 +768,13 @@ static psa_status_t psa_load_ecp_representation( const psa_key_slot_t *slot,
|
|||
goto exit;
|
||||
|
||||
/* Load the key material. */
|
||||
if( PSA_KEY_TYPE_IS_PUBLIC_KEY( slot->attr.type ) )
|
||||
if( PSA_KEY_TYPE_IS_PUBLIC_KEY( 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 ) );
|
||||
buffer,
|
||||
size ) );
|
||||
if( status != PSA_SUCCESS )
|
||||
goto exit;
|
||||
|
||||
|
@ -783,8 +790,8 @@ static psa_status_t psa_load_ecp_representation( const psa_key_slot_t *slot,
|
|||
status = mbedtls_to_psa_error(
|
||||
mbedtls_ecp_read_key( ecp->grp.id,
|
||||
ecp,
|
||||
slot->data.key.data,
|
||||
slot->data.key.bytes ) );
|
||||
buffer,
|
||||
size ) );
|
||||
|
||||
if( status != PSA_SUCCESS )
|
||||
goto exit;
|
||||
|
@ -855,14 +862,11 @@ static psa_status_t psa_import_ecp_key( psa_key_slot_t *slot,
|
|||
uint8_t* output = NULL;
|
||||
mbedtls_ecp_keypair *ecp = NULL;
|
||||
|
||||
/* 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 );
|
||||
status = psa_load_ecp_representation( data,
|
||||
data_length,
|
||||
slot->attr.type,
|
||||
&ecp );
|
||||
if( status != PSA_SUCCESS )
|
||||
goto exit;
|
||||
|
||||
|
@ -1440,7 +1444,10 @@ psa_status_t psa_get_key_attributes( psa_key_handle_t handle,
|
|||
{
|
||||
mbedtls_rsa_context *rsa = NULL;
|
||||
|
||||
status = psa_load_rsa_representation( slot, &rsa );
|
||||
status = psa_load_rsa_representation( slot->data.key.data,
|
||||
slot->data.key.bytes,
|
||||
slot->attr.type,
|
||||
&rsa );
|
||||
if( status != PSA_SUCCESS )
|
||||
break;
|
||||
|
||||
|
@ -1552,7 +1559,11 @@ static psa_status_t psa_internal_export_key( const psa_key_slot_t *slot,
|
|||
{
|
||||
#if defined(MBEDTLS_RSA_C)
|
||||
mbedtls_rsa_context *rsa = NULL;
|
||||
psa_status_t status = psa_load_rsa_representation( slot, &rsa );
|
||||
psa_status_t status = psa_load_rsa_representation(
|
||||
slot->data.key.data,
|
||||
slot->data.key.bytes,
|
||||
slot->attr.type,
|
||||
&rsa );
|
||||
if( status != PSA_SUCCESS )
|
||||
return status;
|
||||
|
||||
|
@ -1575,7 +1586,11 @@ static psa_status_t psa_internal_export_key( const psa_key_slot_t *slot,
|
|||
{
|
||||
#if defined(MBEDTLS_ECP_C)
|
||||
mbedtls_ecp_keypair *ecp = NULL;
|
||||
psa_status_t status = psa_load_ecp_representation( slot, &ecp );
|
||||
psa_status_t status = psa_load_ecp_representation(
|
||||
slot->data.key.data,
|
||||
slot->data.key.bytes,
|
||||
slot->attr.type,
|
||||
&ecp );
|
||||
if( status != PSA_SUCCESS )
|
||||
return status;
|
||||
|
||||
|
@ -2003,7 +2018,11 @@ static psa_status_t psa_validate_optional_attributes(
|
|||
mbedtls_mpi actual, required;
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
|
||||
psa_status_t status = psa_load_rsa_representation( slot, &rsa );
|
||||
psa_status_t status = psa_load_rsa_representation(
|
||||
slot->data.key.data,
|
||||
slot->data.key.bytes,
|
||||
slot->attr.type,
|
||||
&rsa );
|
||||
if( status != PSA_SUCCESS )
|
||||
return status;
|
||||
|
||||
|
@ -3659,7 +3678,9 @@ psa_status_t psa_sign_hash( psa_key_handle_t handle,
|
|||
{
|
||||
mbedtls_rsa_context *rsa = NULL;
|
||||
|
||||
status = psa_load_rsa_representation( slot,
|
||||
status = psa_load_rsa_representation( slot->data.key.data,
|
||||
slot->data.key.bytes,
|
||||
slot->attr.type,
|
||||
&rsa );
|
||||
if( status != PSA_SUCCESS )
|
||||
goto exit;
|
||||
|
@ -3688,7 +3709,10 @@ psa_status_t psa_sign_hash( psa_key_handle_t handle,
|
|||
)
|
||||
{
|
||||
mbedtls_ecp_keypair *ecp = NULL;
|
||||
status = psa_load_ecp_representation( slot, &ecp );
|
||||
status = psa_load_ecp_representation( slot->data.key.data,
|
||||
slot->data.key.bytes,
|
||||
slot->attr.type,
|
||||
&ecp );
|
||||
if( status != PSA_SUCCESS )
|
||||
goto exit;
|
||||
status = psa_ecdsa_sign( ecp,
|
||||
|
@ -3763,7 +3787,10 @@ psa_status_t psa_verify_hash( psa_key_handle_t handle,
|
|||
{
|
||||
mbedtls_rsa_context *rsa = NULL;
|
||||
|
||||
status = psa_load_rsa_representation( slot, &rsa );
|
||||
status = psa_load_rsa_representation( slot->data.key.data,
|
||||
slot->data.key.bytes,
|
||||
slot->attr.type,
|
||||
&rsa );
|
||||
if( status != PSA_SUCCESS )
|
||||
return status;
|
||||
|
||||
|
@ -3784,7 +3811,10 @@ psa_status_t psa_verify_hash( psa_key_handle_t handle,
|
|||
if( PSA_ALG_IS_ECDSA( alg ) )
|
||||
{
|
||||
mbedtls_ecp_keypair *ecp = NULL;
|
||||
status = psa_load_ecp_representation( slot, &ecp );
|
||||
status = psa_load_ecp_representation( slot->data.key.data,
|
||||
slot->data.key.bytes,
|
||||
slot->attr.type,
|
||||
&ecp );
|
||||
if( status != PSA_SUCCESS )
|
||||
return status;
|
||||
status = psa_ecdsa_verify( ecp,
|
||||
|
@ -3855,7 +3885,10 @@ psa_status_t psa_asymmetric_encrypt( psa_key_handle_t handle,
|
|||
mbedtls_rsa_context *rsa = NULL;
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
|
||||
status = psa_load_rsa_representation( slot, &rsa );
|
||||
status = psa_load_rsa_representation( slot->data.key.data,
|
||||
slot->data.key.bytes,
|
||||
slot->attr.type,
|
||||
&rsa );
|
||||
if( status != PSA_SUCCESS )
|
||||
return status;
|
||||
|
||||
|
@ -3948,7 +3981,10 @@ psa_status_t psa_asymmetric_decrypt( psa_key_handle_t handle,
|
|||
mbedtls_rsa_context *rsa;
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
|
||||
status = psa_load_rsa_representation( slot, &rsa );
|
||||
status = psa_load_rsa_representation( slot->data.key.data,
|
||||
slot->data.key.bytes,
|
||||
slot->attr.type,
|
||||
&rsa );
|
||||
if( status != PSA_SUCCESS )
|
||||
return status;
|
||||
|
||||
|
@ -5548,20 +5584,16 @@ static psa_status_t psa_key_agreement_ecdh( const uint8_t *peer_key,
|
|||
size_t *shared_secret_length )
|
||||
{
|
||||
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));
|
||||
|
||||
/* 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 );
|
||||
status = psa_load_ecp_representation( peer_key,
|
||||
peer_key_length,
|
||||
PSA_KEY_TYPE_ECC_PUBLIC_KEY(curve),
|
||||
&their_key );
|
||||
if( status != PSA_SUCCESS )
|
||||
goto exit;
|
||||
|
||||
|
@ -5613,7 +5645,11 @@ static psa_status_t psa_key_agreement_raw_internal( psa_algorithm_t alg,
|
|||
if( ! PSA_KEY_TYPE_IS_ECC_KEY_PAIR( private_key->attr.type ) )
|
||||
return( PSA_ERROR_INVALID_ARGUMENT );
|
||||
mbedtls_ecp_keypair *ecp = NULL;
|
||||
psa_status_t status = psa_load_ecp_representation( private_key, &ecp );
|
||||
psa_status_t status = psa_load_ecp_representation(
|
||||
private_key->data.key.data,
|
||||
private_key->data.key.bytes,
|
||||
private_key->attr.type,
|
||||
&ecp );
|
||||
if( status != PSA_SUCCESS )
|
||||
return status;
|
||||
status = psa_key_agreement_ecdh( peer_key, peer_key_length,
|
||||
|
|
Loading…
Reference in a new issue