Merge remote-tracking branch 'origin/pr/2382' into development-psa
diff --git a/crypto b/crypto
index 2169a5e..acdf07c 160000
--- a/crypto
+++ b/crypto
@@ -1 +1 @@
-Subproject commit 2169a5e54ded734f7844af1a16c39b993c2a992c
+Subproject commit acdf07c033bb7ce11f595ddbe0c66d438b46597c
diff --git a/include/mbedtls/psa_util.h b/include/mbedtls/psa_util.h
index a78c1a9..3684e98 100644
--- a/include/mbedtls/psa_util.h
+++ b/include/mbedtls/psa_util.h
@@ -41,6 +41,7 @@
#include "ecp.h"
#include "md.h"
#include "pk.h"
+#include "oid.h"
/* Translations for symmetric crypto. */
@@ -155,6 +156,82 @@
/* Translations for ECC. */
+static inline int mbedtls_psa_get_ecc_oid_from_id(
+ psa_ecc_curve_t curve, char const **oid, size_t *oid_len )
+{
+ switch( curve )
+ {
+#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED)
+ case PSA_ECC_CURVE_SECP192R1:
+ *oid = MBEDTLS_OID_EC_GRP_SECP192R1;
+ *oid_len = MBEDTLS_OID_SIZE( MBEDTLS_OID_EC_GRP_SECP192R1 );
+ return( 0 );
+#endif /* MBEDTLS_ECP_DP_SECP192R1_ENABLED */
+#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED)
+ case PSA_ECC_CURVE_SECP224R1:
+ *oid = MBEDTLS_OID_EC_GRP_SECP224R1;
+ *oid_len = MBEDTLS_OID_SIZE( MBEDTLS_OID_EC_GRP_SECP224R1 );
+ return( 0 );
+#endif /* MBEDTLS_ECP_DP_SECP224R1_ENABLED */
+#if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED)
+ case PSA_ECC_CURVE_SECP256R1:
+ *oid = MBEDTLS_OID_EC_GRP_SECP256R1;
+ *oid_len = MBEDTLS_OID_SIZE( MBEDTLS_OID_EC_GRP_SECP256R1 );
+ return( 0 );
+#endif /* MBEDTLS_ECP_DP_SECP256R1_ENABLED */
+#if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED)
+ case PSA_ECC_CURVE_SECP384R1:
+ *oid = MBEDTLS_OID_EC_GRP_SECP384R1;
+ *oid_len = MBEDTLS_OID_SIZE( MBEDTLS_OID_EC_GRP_SECP384R1 );
+ return( 0 );
+#endif /* MBEDTLS_ECP_DP_SECP384R1_ENABLED */
+#if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED)
+ case PSA_ECC_CURVE_SECP521R1:
+ *oid = MBEDTLS_OID_EC_GRP_SECP521R1;
+ *oid_len = MBEDTLS_OID_SIZE( MBEDTLS_OID_EC_GRP_SECP521R1 );
+ return( 0 );
+#endif /* MBEDTLS_ECP_DP_SECP521R1_ENABLED */
+#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED)
+ case PSA_ECC_CURVE_SECP192K1:
+ *oid = MBEDTLS_OID_EC_GRP_SECP192K1;
+ *oid_len = MBEDTLS_OID_SIZE( MBEDTLS_OID_EC_GRP_SECP192K1 );
+ return( 0 );
+#endif /* MBEDTLS_ECP_DP_SECP192K1_ENABLED */
+#if defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED)
+ case PSA_ECC_CURVE_SECP224K1:
+ *oid = MBEDTLS_OID_EC_GRP_SECP224K1;
+ *oid_len = MBEDTLS_OID_SIZE( MBEDTLS_OID_EC_GRP_SECP224K1 );
+ return( 0 );
+#endif /* MBEDTLS_ECP_DP_SECP224K1_ENABLED */
+#if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED)
+ case PSA_ECC_CURVE_SECP256K1:
+ *oid = MBEDTLS_OID_EC_GRP_SECP256K1;
+ *oid_len = MBEDTLS_OID_SIZE( MBEDTLS_OID_EC_GRP_SECP256K1 );
+ return( 0 );
+#endif /* MBEDTLS_ECP_DP_SECP256K1_ENABLED */
+#if defined(MBEDTLS_ECP_DP_BP256R1_ENABLED)
+ case PSA_ECC_CURVE_BRAINPOOL_P256R1:
+ *oid = MBEDTLS_OID_EC_GRP_BP256R1;
+ *oid_len = MBEDTLS_OID_SIZE( MBEDTLS_OID_EC_GRP_BP256R1 );
+ return( 0 );
+#endif /* MBEDTLS_ECP_DP_BP256R1_ENABLED */
+#if defined(MBEDTLS_ECP_DP_BP384R1_ENABLED)
+ case PSA_ECC_CURVE_BRAINPOOL_P384R1:
+ *oid = MBEDTLS_OID_EC_GRP_BP384R1;
+ *oid_len = MBEDTLS_OID_SIZE( MBEDTLS_OID_EC_GRP_BP384R1 );
+ return( 0 );
+#endif /* MBEDTLS_ECP_DP_BP384R1_ENABLED */
+#if defined(MBEDTLS_ECP_DP_BP512R1_ENABLED)
+ case PSA_ECC_CURVE_BRAINPOOL_P512R1:
+ *oid = MBEDTLS_OID_EC_GRP_BP512R1;
+ *oid_len = MBEDTLS_OID_SIZE( MBEDTLS_OID_EC_GRP_BP512R1 );
+ return( 0 );
+#endif /* MBEDTLS_ECP_DP_BP512R1_ENABLED */
+ }
+
+ return( -1 );
+}
+
static inline psa_ecc_curve_t mbedtls_psa_translate_ecc_group( mbedtls_ecp_group_id grpid )
{
switch( grpid )
diff --git a/library/pk_wrap.c b/library/pk_wrap.c
index 7f8abd4..c7f879a 100644
--- a/library/pk_wrap.c
+++ b/library/pk_wrap.c
@@ -553,7 +553,7 @@
int key_len;
/* see ECP_PUB_DER_MAX_BYTES in pkwrite.c */
unsigned char buf[30 + 2 * MBEDTLS_ECP_MAX_BYTES];
- unsigned char *p = (unsigned char*) sig;
+ unsigned char *p;
mbedtls_pk_info_t pk_info = mbedtls_eckey_info;
psa_algorithm_t psa_sig_md, psa_md;
psa_ecc_curve_t curve = mbedtls_psa_translate_ecc_group(
@@ -563,11 +563,12 @@
if( curve == 0 )
return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
- /* mbedlts_pk_write_pubkey_der() expects a full PK context,
+ /* mbedtls_pk_write_pubkey() expects a full PK context;
* re-construct one to make it happy */
key.pk_info = &pk_info;
key.pk_ctx = ctx;
- key_len = mbedtls_pk_write_pubkey_der( &key, buf, sizeof( buf ) );
+ p = buf + sizeof( buf );
+ key_len = mbedtls_pk_write_pubkey( &p, buf, &key );
if( key_len <= 0 )
return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
@@ -603,6 +604,7 @@
goto cleanup;
}
+ p = (unsigned char*) sig;
if( ( ret = extract_ecdsa_sig( &p, sig + sig_len, buf,
signature_part_size ) ) != 0 )
{
diff --git a/library/pkwrite.c b/library/pkwrite.c
index 11a2a61..ab4f7f5 100644
--- a/library/pkwrite.c
+++ b/library/pkwrite.c
@@ -48,6 +48,7 @@
#if defined(MBEDTLS_USE_PSA_CRYPTO)
#include "psa/crypto.h"
+#include "mbedtls/psa_util.h"
#endif
#if defined(MBEDTLS_PLATFORM_C)
#include "mbedtls/platform.h"
@@ -181,7 +182,8 @@
}
else
{
- memmove( *p - len, start, len );
+ *p -= len;
+ memmove( *p, start, len );
}
}
else
@@ -196,16 +198,13 @@
int ret;
unsigned char *c;
size_t len = 0, par_len = 0, oid_len;
+ mbedtls_pk_type_t pk_type;
const char *oid;
c = buf + size;
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_pk_write_pubkey( &c, buf, key ) );
- if( mbedtls_pk_get_type( key ) == MBEDTLS_PK_OPAQUE )
- {
- return( (int) len );
- }
if( c - buf < 1 )
return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
@@ -220,18 +219,51 @@
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, len ) );
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, buf, MBEDTLS_ASN1_BIT_STRING ) );
- if( ( ret = mbedtls_oid_get_oid_by_pk_alg( mbedtls_pk_get_type( key ),
- &oid, &oid_len ) ) != 0 )
- {
- return( ret );
- }
-
+ pk_type = mbedtls_pk_get_type( key );
#if defined(MBEDTLS_ECP_C)
- if( mbedtls_pk_get_type( key ) == MBEDTLS_PK_ECKEY )
+ if( pk_type == MBEDTLS_PK_ECKEY )
{
MBEDTLS_ASN1_CHK_ADD( par_len, pk_write_ec_param( &c, buf, mbedtls_pk_ec( *key ) ) );
}
#endif
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ if( pk_type == MBEDTLS_PK_OPAQUE )
+ {
+ psa_status_t status;
+ psa_key_type_t key_type;
+ psa_key_handle_t handle;
+ psa_ecc_curve_t curve;
+
+ handle = *((psa_key_handle_t*) key->pk_ctx );
+
+ status = psa_get_key_information( handle, &key_type,
+ NULL /* bitsize not needed */ );
+ if( status != PSA_SUCCESS )
+ return( MBEDTLS_ERR_PK_HW_ACCEL_FAILED );
+
+ curve = PSA_KEY_TYPE_GET_CURVE( key_type );
+ if( curve == 0 )
+ return( MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE );
+
+ ret = mbedtls_psa_get_ecc_oid_from_id( curve, &oid, &oid_len );
+ if( ret != 0 )
+ return( MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE );
+
+ /* Write EC algorithm parameters; that's akin
+ * to pk_write_ec_param() above. */
+ MBEDTLS_ASN1_CHK_ADD( par_len, mbedtls_asn1_write_oid( &c, buf,
+ oid, oid_len ) );
+
+ /* The rest of the function works as for legacy EC contexts. */
+ pk_type = MBEDTLS_PK_ECKEY;
+ }
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
+
+ if( ( ret = mbedtls_oid_get_oid_by_pk_alg( pk_type, &oid,
+ &oid_len ) ) != 0 )
+ {
+ return( ret );
+ }
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_algorithm_identifier( &c, buf, oid, oid_len,
par_len ) );
diff --git a/tests/suites/test_suite_pk.function b/tests/suites/test_suite_pk.function
index 120c171..e469318 100644
--- a/tests/suites/test_suite_pk.function
+++ b/tests/suites/test_suite_pk.function
@@ -778,44 +778,65 @@
void pk_psa_sign( )
{
mbedtls_pk_context pk;
- psa_key_handle_t key;
- unsigned char hash[50], sig[100], pkey[100];
- size_t sig_len, klen = 0;
+ unsigned char hash[50], sig[100], pkey_legacy[100], pkey_psa[100];
+ unsigned char *pkey_legacy_start, *pkey_psa_start;
+ size_t sig_len, klen_legacy, klen_psa;
+ int ret;
+ psa_key_handle_t handle;
/*
* This tests making signatures with a wrapped PSA key:
- * - generate a fresh PSA key
+ * - generate a fresh ECP legacy PK context
* - wrap it in a PK context and make a signature this way
* - extract the public key
* - parse it to a PK context and verify the signature this way
*/
+ /* Create legacy EC public/private key in PK context. */
mbedtls_pk_init( &pk );
+ TEST_ASSERT( mbedtls_pk_setup( &pk,
+ mbedtls_pk_info_from_type( MBEDTLS_PK_ECKEY ) ) == 0 );
+ TEST_ASSERT( mbedtls_ecp_gen_key( MBEDTLS_ECP_DP_SECP256R1,
+ (mbedtls_ecp_keypair*) pk.pk_ctx,
+ rnd_std_rand, NULL ) == 0 );
+
+ /* Export underlying public key for re-importing in a legacy context. */
+ ret = mbedtls_pk_write_pubkey_der( &pk, pkey_legacy,
+ sizeof( pkey_legacy ) );
+ TEST_ASSERT( ret >= 0 );
+ klen_legacy = (size_t) ret;
+ /* mbedtls_pk_write_pubkey_der() writes backwards in the data buffer. */
+ pkey_legacy_start = pkey_legacy + sizeof( pkey_legacy ) - klen_legacy;
+
+ /* Turn PK context into an opaque one. */
+ TEST_ASSERT( psa_allocate_key( &handle ) == PSA_SUCCESS );
+ TEST_ASSERT( mbedtls_pk_wrap_as_opaque( &pk, &handle,
+ PSA_ALG_SHA_256 ) == 0 );
memset( hash, 0x2a, sizeof hash );
memset( sig, 0, sizeof sig );
- memset( pkey, 0, sizeof pkey );
-
- key = pk_psa_genkey();
- TEST_ASSERT( key != 0 );
-
- TEST_ASSERT( mbedtls_pk_setup_opaque( &pk, key ) == 0 );
TEST_ASSERT( mbedtls_pk_sign( &pk, MBEDTLS_MD_SHA256,
hash, sizeof hash, sig, &sig_len,
NULL, NULL ) == 0 );
- mbedtls_pk_free( &pk );
+ /* Export underlying public key for re-importing in a psa context. */
+ ret = mbedtls_pk_write_pubkey_der( &pk, pkey_psa,
+ sizeof( pkey_psa ) );
+ TEST_ASSERT( ret >= 0 );
+ klen_psa = (size_t) ret;
+ /* mbedtls_pk_write_pubkey_der() writes backwards in the data buffer. */
+ pkey_psa_start = pkey_psa + sizeof( pkey_psa ) - klen_psa;
- TEST_ASSERT( PSA_SUCCESS == psa_export_public_key(
- key, pkey, sizeof( pkey ), &klen ) );
- TEST_ASSERT( PSA_SUCCESS == psa_destroy_key( key ) );
+ TEST_ASSERT( klen_psa == klen_legacy );
+ TEST_ASSERT( memcmp( pkey_psa_start, pkey_legacy_start, klen_psa ) == 0 );
+
+ mbedtls_pk_free( &pk );
+ TEST_ASSERT( PSA_SUCCESS == psa_destroy_key( handle ) );
mbedtls_pk_init( &pk );
-
- TEST_ASSERT( mbedtls_pk_parse_public_key( &pk, pkey, klen ) == 0 );
-
-
+ TEST_ASSERT( mbedtls_pk_parse_public_key( &pk, pkey_legacy_start,
+ klen_legacy ) == 0 );
TEST_ASSERT( mbedtls_pk_verify( &pk, MBEDTLS_MD_SHA256,
hash, sizeof hash, sig, sig_len ) == 0 );