Skip to content

Commit 990d025

Browse files
committed
psa: Simplify EC public key format
Remove front matter from our EC key format, to make it just ECPoint as defined by SEC1 section 2.3.3. As a consequence of the simplification, remove the restriction on not being able to use an ECDH key with ECDSA. There is no longer any OID specified when importing a key, so we can't reject importing of an ECDH key for the purpose of ECDSA based on the OID.
1 parent 4215198 commit 990d025

File tree

4 files changed

+117
-133
lines changed

4 files changed

+117
-133
lines changed

include/psa/crypto.h

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -503,27 +503,16 @@ psa_status_t psa_export_key(psa_key_handle_t handle,
503503
* ```
504504
* - For elliptic curve public keys (key types for which
505505
* #PSA_KEY_TYPE_IS_ECC_PUBLIC_KEY is true),
506-
* the `subjectPublicKey` format is defined by RFC 3279 §2.3.5 as
506+
* the format is defined by RFC 3279 §2.3.5 as
507507
* `ECPoint`, which contains the uncompressed
508508
* representation defined by SEC1 §2.3.3.
509-
* The OID is `id-ecPublicKey`,
510-
* and the parameters must be given as a `namedCurve` OID as specified in
511-
* RFC 5480 §2.1.1.1 or other applicable standards.
512509
* ```
513-
* ansi-X9-62 OBJECT IDENTIFIER ::=
514-
* { iso(1) member-body(2) us(840) 10045 }
515-
* id-public-key-type OBJECT IDENTIFIER ::= { ansi-X9.62 2 }
516-
* id-ecPublicKey OBJECT IDENTIFIER ::= { id-publicKeyType 1 }
517-
*
518510
* ECPoint ::= ...
519511
* -- first 8 bits: 0x04;
520512
* -- then x_P as a `ceiling(m/8)`-byte string, big endian;
521513
* -- then y_P as a `ceiling(m/8)`-byte string, big endian;
522514
* -- where `m` is the bit size associated with the curve,
523515
* -- i.e. the bit size of `q` for a curve over `F_q`.
524-
*
525-
* EcpkParameters ::= CHOICE { -- other choices are not allowed
526-
* namedCurve OBJECT IDENTIFIER }
527516
* ```
528517
*
529518
* \param handle Handle to the key to export.
@@ -2152,7 +2141,9 @@ psa_status_t psa_key_derivation(psa_crypto_generator_t *generator,
21522141
* in the same format that psa_import_key()
21532142
* accepts. The standard formats for public
21542143
* keys are documented in the documentation
2155-
* of psa_export_public_key().
2144+
* of psa_export_public_key(). For EC keys, it
2145+
* must also be of the same group as the private
2146+
* key. XXX check this with crypto know-hower
21562147
* \param peer_key_length Size of \p peer_key in bytes.
21572148
* \param alg The key agreement algorithm to compute
21582149
* (\c PSA_ALG_XXX value such that

library/psa_crypto.c

Lines changed: 78 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -537,25 +537,53 @@ static psa_status_t psa_import_rsa_key( mbedtls_pk_context *pk,
537537
}
538538
#endif /* defined(MBEDTLS_RSA_C) && defined(MBEDTLS_PK_PARSE_C) */
539539

540-
#if defined(MBEDTLS_ECP_C) && defined(MBEDTLS_PK_PARSE_C)
541-
/* Import an elliptic curve parsed by the mbedtls pk module. */
542-
static psa_status_t psa_import_ecp_key( psa_ecc_curve_t expected_curve,
543-
mbedtls_pk_context *pk,
544-
mbedtls_ecp_keypair **p_ecp )
540+
#if defined(MBEDTLS_ECP_C)
541+
/* Import a public key given as a byte string which is a SEC1 2.3.3 ECPoint. */
542+
static psa_status_t psa_import_ec_public_key( psa_ecc_curve_t curve,
543+
const uint8_t *data,
544+
size_t data_length,
545+
mbedtls_ecp_keypair **p_ecp )
545546
{
546-
if( mbedtls_pk_get_type( pk ) != MBEDTLS_PK_ECKEY )
547-
return( PSA_ERROR_INVALID_ARGUMENT );
548-
else
547+
psa_status_t status = PSA_ERROR_TAMPERING_DETECTED;
548+
mbedtls_ecp_keypair *ecp = NULL;
549+
mbedtls_ecp_group_id grp_id = mbedtls_ecc_group_of_psa( curve );
550+
551+
*p_ecp = NULL;
552+
ecp = mbedtls_calloc( 1, sizeof( *ecp ) );
553+
if( ecp == NULL )
554+
return( PSA_ERROR_INSUFFICIENT_MEMORY );
555+
mbedtls_ecp_keypair_init( ecp );
556+
557+
/* Load the group. */
558+
status = mbedtls_to_psa_error(
559+
mbedtls_ecp_group_load( &ecp->grp, grp_id ) );
560+
if( status != PSA_SUCCESS )
561+
goto exit;
562+
/* Load the public value. */
563+
status = mbedtls_to_psa_error(
564+
mbedtls_ecp_point_read_binary( &ecp->grp, &ecp->Q,
565+
data, data_length ) );
566+
if( status != PSA_SUCCESS )
567+
goto exit;
568+
569+
/* Check that the point belongs to the group. */
570+
status = mbedtls_to_psa_error(
571+
mbedtls_ecp_check_pubkey( &ecp->grp, &ecp->Q ) );
572+
if( status != PSA_SUCCESS )
573+
goto exit;
574+
575+
*p_ecp = ecp;
576+
return( PSA_SUCCESS );
577+
578+
exit:
579+
if( ecp != NULL )
549580
{
550-
mbedtls_ecp_keypair *ecp = mbedtls_pk_ec( *pk );
551-
psa_ecc_curve_t actual_curve = mbedtls_ecc_group_to_psa( ecp->grp.id );
552-
if( actual_curve != expected_curve )
553-
return( PSA_ERROR_INVALID_ARGUMENT );
554-
*p_ecp = ecp;
555-
return( PSA_SUCCESS );
581+
mbedtls_ecp_keypair_free( ecp );
582+
mbedtls_free( ecp );
556583
}
584+
return( status );
557585
}
558-
#endif /* defined(MBEDTLS_ECP_C) && defined(MBEDTLS_PK_PARSE_C) */
586+
#endif /* defined(MBEDTLS_ECP_C) */
559587

560588
#if defined(MBEDTLS_ECP_C)
561589
/* Import a private key given as a byte string which is the private value
@@ -644,9 +672,8 @@ psa_status_t psa_import_key_into_slot( psa_key_slot_t *slot,
644672
}
645673
else
646674
#endif /* MBEDTLS_ECP_C */
647-
#if defined(MBEDTLS_PK_PARSE_C)
648-
if( PSA_KEY_TYPE_IS_RSA( slot->type ) ||
649-
PSA_KEY_TYPE_IS_ECC( slot->type ) )
675+
#if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_PK_PARSE_C)
676+
if( PSA_KEY_TYPE_IS_RSA( slot->type ) )
650677
{
651678
int ret;
652679
mbedtls_pk_context pk;
@@ -663,20 +690,7 @@ psa_status_t psa_import_key_into_slot( psa_key_slot_t *slot,
663690
/* We have something that the pkparse module recognizes.
664691
* If it has the expected type and passes any type-specific
665692
* checks, store it. */
666-
#if defined(MBEDTLS_RSA_C)
667-
if( PSA_KEY_TYPE_IS_RSA( slot->type ) )
668-
status = psa_import_rsa_key( &pk, &slot->data.rsa );
669-
else
670-
#endif /* MBEDTLS_RSA_C */
671-
#if defined(MBEDTLS_ECP_C)
672-
if( PSA_KEY_TYPE_IS_ECC( slot->type ) )
673-
status = psa_import_ecp_key( PSA_KEY_TYPE_GET_CURVE( slot->type ),
674-
&pk, &slot->data.ecp );
675-
else
676-
#endif /* MBEDTLS_ECP_C */
677-
{
678-
status = PSA_ERROR_NOT_SUPPORTED;
679-
}
693+
status = psa_import_rsa_key( &pk, &slot->data.rsa );
680694

681695
/* Free the content of the pk object only on error. On success,
682696
* the content of the object has been stored in the slot. */
@@ -687,7 +701,20 @@ psa_status_t psa_import_key_into_slot( psa_key_slot_t *slot,
687701
}
688702
}
689703
else
690-
#endif /* defined(MBEDTLS_PK_PARSE_C) */
704+
#endif /* defined(MBEDTLS_RSA_C) && defined(MBEDTLS_PK_PARSE_C) */
705+
#if defined(MBEDTLS_ECP_C)
706+
if( PSA_KEY_TYPE_IS_ECC( slot->type ) )
707+
{
708+
status = psa_import_ec_public_key(
709+
PSA_KEY_TYPE_GET_CURVE( slot->type ),
710+
data, data_length,
711+
&slot->data.ecp );
712+
713+
if( status != PSA_SUCCESS )
714+
return( status );
715+
}
716+
else
717+
#endif /* MBEDTLS_ECP_C */
691718
{
692719
return( PSA_ERROR_NOT_SUPPORTED );
693720
}
@@ -915,6 +942,19 @@ static int pk_write_pubkey_rsa( mbedtls_pk_context *key, unsigned char *buf, siz
915942
return( (int) len );
916943
}
917944

945+
static int pk_write_pubkey_ecp( mbedtls_pk_context *key, unsigned char *buf, size_t size )
946+
{
947+
int ret;
948+
unsigned char *c;
949+
size_t len = 0;
950+
951+
c = buf + size;
952+
953+
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_pk_write_pubkey( &c, buf, key ) );
954+
955+
return( (int) len );
956+
}
957+
918958
static psa_status_t psa_internal_export_key( psa_key_slot_t *slot,
919959
uint8_t *data,
920960
size_t data_size,
@@ -992,7 +1032,7 @@ static psa_status_t psa_internal_export_key( psa_key_slot_t *slot,
9921032
}
9931033
else
9941034
{
995-
ret = mbedtls_pk_write_pubkey_der( &pk, data, data_size );
1035+
ret = pk_write_pubkey_ecp( &pk, data, data_size );
9961036
}
9971037
}
9981038
else
@@ -4040,32 +4080,17 @@ static psa_status_t psa_key_agreement_ecdh( const uint8_t *peer_key,
40404080
size_t shared_secret_size,
40414081
size_t *shared_secret_length )
40424082
{
4043-
mbedtls_pk_context pk;
40444083
mbedtls_ecp_keypair *their_key = NULL;
40454084
mbedtls_ecdh_context ecdh;
40464085
psa_status_t status;
40474086
mbedtls_ecdh_init( &ecdh );
4048-
mbedtls_pk_init( &pk );
40494087

4050-
status = mbedtls_to_psa_error(
4051-
mbedtls_pk_parse_public_key( &pk, peer_key, peer_key_length ) );
4088+
status = psa_import_ec_public_key(
4089+
mbedtls_ecc_group_to_psa( our_key->grp.id ),
4090+
peer_key, peer_key_length,
4091+
&their_key );
40524092
if( status != PSA_SUCCESS )
40534093
goto exit;
4054-
switch( mbedtls_pk_get_type( &pk ) )
4055-
{
4056-
case MBEDTLS_PK_ECKEY:
4057-
case MBEDTLS_PK_ECKEY_DH:
4058-
break;
4059-
default:
4060-
status = PSA_ERROR_INVALID_ARGUMENT;
4061-
goto exit;
4062-
}
4063-
their_key = mbedtls_pk_ec( pk );
4064-
if( their_key->grp.id != our_key->grp.id )
4065-
{
4066-
status = PSA_ERROR_INVALID_ARGUMENT;
4067-
goto exit;
4068-
}
40694094

40704095
status = mbedtls_to_psa_error(
40714096
mbedtls_ecdh_get_params( &ecdh, their_key, MBEDTLS_ECDH_THEIRS ) );
@@ -4083,7 +4108,6 @@ static psa_status_t psa_key_agreement_ecdh( const uint8_t *peer_key,
40834108
&global_data.ctr_drbg ) );
40844109

40854110
exit:
4086-
mbedtls_pk_free( &pk );
40874111
mbedtls_ecdh_free( &ecdh );
40884112
return( status );
40894113
}

0 commit comments

Comments
 (0)