diff --git a/library/pkparse.c b/library/pkparse.c index c2ececb44c..18b40ceb84 100644 --- a/library/pkparse.c +++ b/library/pkparse.c @@ -514,6 +514,9 @@ static int pk_use_ecparams(const mbedtls_asn1_buf *params, mbedtls_pk_context *p #endif } +#if defined(MBEDTLS_PK_USE_PSA_EC_DATA) + ret = pk_update_psa_ecparams(pk, grp_id); +#else /* grp may already be initialized; if so, make sure IDs match */ if (mbedtls_pk_ec_ro(*pk)->grp.id != MBEDTLS_ECP_DP_NONE && mbedtls_pk_ec_ro(*pk)->grp.id != grp_id) { @@ -524,8 +527,6 @@ static int pk_use_ecparams(const mbedtls_asn1_buf *params, mbedtls_pk_context *p grp_id)) != 0) { return ret; } -#if defined(MBEDTLS_PK_USE_PSA_EC_DATA) - ret = pk_update_psa_ecparams(pk, grp_id); #endif /* MBEDTLS_PK_USE_PSA_EC_DATA */ return ret; @@ -539,20 +540,26 @@ static int pk_derive_public_key(mbedtls_pk_context *pk, int (*f_rng)(void *, unsigned char *, size_t), void *p_rng) { int ret; - mbedtls_ecp_keypair *eck = (mbedtls_ecp_keypair *) pk->pk_ctx; #if defined(MBEDTLS_USE_PSA_CRYPTO) - psa_status_t status, destruction_status; + psa_status_t status; + (void) f_rng; + (void) p_rng; +#if defined(MBEDTLS_PK_USE_PSA_EC_DATA) + (void) d; + (void) d_len; + + status = psa_export_public_key(pk->priv_id, pk->pub_raw, sizeof(pk->pub_raw), + &pk->pub_raw_len); + ret = psa_pk_status_to_mbedtls(status); +#else /* MBEDTLS_PK_USE_PSA_EC_DATA */ + mbedtls_ecp_keypair *eck = (mbedtls_ecp_keypair *) pk->pk_ctx; + unsigned char key_buf[MBEDTLS_PSA_MAX_EC_PUBKEY_LENGTH]; + size_t key_len; + mbedtls_svc_key_id_t key_id = MBEDTLS_SVC_KEY_ID_INIT; psa_key_attributes_t key_attr = PSA_KEY_ATTRIBUTES_INIT; size_t curve_bits; psa_ecc_family_t curve = mbedtls_ecc_group_to_psa(eck->grp.id, &curve_bits); -#if !defined(MBEDTLS_PK_USE_PSA_EC_DATA) - unsigned char key_buf[MBEDTLS_PSA_MAX_EC_PUBKEY_LENGTH]; - size_t key_len; -#endif /* !MBEDTLS_PK_USE_PSA_EC_DATA */ - mbedtls_svc_key_id_t key_id = MBEDTLS_SVC_KEY_ID_INIT; - - (void) f_rng; - (void) p_rng; + psa_status_t destruction_status; psa_set_key_type(&key_attr, PSA_KEY_TYPE_ECC_KEY_PAIR(curve)); psa_set_key_usage_flags(&key_attr, PSA_KEY_USAGE_EXPORT); @@ -563,12 +570,7 @@ static int pk_derive_public_key(mbedtls_pk_context *pk, return ret; } -#if defined(MBEDTLS_PK_USE_PSA_EC_DATA) - status = psa_export_public_key(key_id, pk->pub_raw, sizeof(pk->pub_raw), - &pk->pub_raw_len); -#else /* MBEDTLS_PK_USE_PSA_EC_DATA */ status = psa_export_public_key(key_id, key_buf, sizeof(key_buf), &key_len); -#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */ ret = psa_pk_status_to_mbedtls(status); destruction_status = psa_destroy_key(key_id); if (ret != 0) { @@ -576,10 +578,10 @@ static int pk_derive_public_key(mbedtls_pk_context *pk, } else if (destruction_status != PSA_SUCCESS) { return psa_pk_status_to_mbedtls(destruction_status); } -#if !defined(MBEDTLS_PK_USE_PSA_EC_DATA) ret = mbedtls_ecp_point_read_binary(&eck->grp, &eck->Q, key_buf, key_len); -#endif /* !MBEDTLS_PK_USE_PSA_EC_DATA */ +#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */ #else /* MBEDTLS_USE_PSA_CRYPTO */ + mbedtls_ecp_keypair *eck = (mbedtls_ecp_keypair *) pk->pk_ctx; (void) d; (void) d_len; @@ -597,21 +599,21 @@ static int pk_use_ecparams_rfc8410(const mbedtls_asn1_buf *params, mbedtls_ecp_group_id grp_id, mbedtls_pk_context *pk) { - mbedtls_ecp_keypair *ecp = mbedtls_pk_ec_rw(*pk); int ret; if (params->tag != 0 || params->len != 0) { return MBEDTLS_ERR_PK_KEY_INVALID_FORMAT; } +#if defined(MBEDTLS_PK_USE_PSA_EC_DATA) + ret = pk_update_psa_ecparams(pk, grp_id); +#else + mbedtls_ecp_keypair *ecp = mbedtls_pk_ec_rw(*pk); ret = mbedtls_ecp_group_load(&(ecp->grp), grp_id); if (ret != 0) { return ret; } - -#if defined(MBEDTLS_PK_USE_PSA_EC_DATA) - ret = pk_update_psa_ecparams(pk, grp_id); -#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */ +#endif return ret; } @@ -624,7 +626,6 @@ static int pk_parse_key_rfc8410_der(mbedtls_pk_context *pk, unsigned char *key, size_t keylen, const unsigned char *end, int (*f_rng)(void *, unsigned char *, size_t), void *p_rng) { - mbedtls_ecp_keypair *eck = mbedtls_pk_ec_rw(*pk); int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; size_t len; @@ -636,23 +637,54 @@ static int pk_parse_key_rfc8410_der(mbedtls_pk_context *pk, return MBEDTLS_ERR_PK_KEY_INVALID_FORMAT; } +#if defined(MBEDTLS_PK_USE_PSA_EC_DATA) + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_status_t status; + + psa_set_key_type(&attributes, PSA_KEY_TYPE_ECC_KEY_PAIR(pk->ec_family)); + /* Setting largest masks for usage and key algorithms */ + psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_SIGN_HASH | + PSA_KEY_USAGE_SIGN_MESSAGE | + PSA_KEY_USAGE_EXPORT); +#if defined(MBEDTLS_ECDSA_DETERMINISTIC) + psa_set_key_algorithm(&attributes, + PSA_ALG_DETERMINISTIC_ECDSA(PSA_ALG_ANY_HASH)); +#else + psa_set_key_algorithm(&attributes, PSA_ALG_ECDSA(PSA_ALG_ANY_HASH)); +#endif + + status = psa_import_key(&attributes, key, len, &pk->priv_id); + if (status != PSA_SUCCESS) { + ret = psa_pk_status_to_mbedtls(status); + return ret; + } +#else /* MBEDTLS_PK_USE_PSA_EC_DATA */ + mbedtls_ecp_keypair *eck = mbedtls_pk_ec_rw(*pk); + if ((ret = mbedtls_mpi_read_binary_le(&eck->d, key, len)) != 0) { mbedtls_ecp_keypair_free(eck); return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, ret); } +#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */ /* pk_parse_key_pkcs8_unencrypted_der() only supports version 1 PKCS8 keys, * which never contain a public key. As such, derive the public key * unconditionally. */ if ((ret = pk_derive_public_key(pk, key, len, f_rng, p_rng)) != 0) { +#if !defined(MBEDTLS_PK_USE_PSA_EC_DATA) mbedtls_ecp_keypair_free(eck); +#endif /* !MBEDTLS_PK_USE_PSA_EC_DATA */ return ret; } + /* When MBEDTLS_PK_USE_PSA_EC_DATA the key is checked while importing it + * into PSA. */ +#if !defined(MBEDTLS_PK_USE_PSA_EC_DATA) if ((ret = mbedtls_ecp_check_privkey(&eck->grp, &eck->d)) != 0) { mbedtls_ecp_keypair_free(eck); return ret; } +#endif /* !MBEDTLS_PK_USE_PSA_EC_DATA */ return 0; } @@ -926,7 +958,7 @@ int mbedtls_pk_parse_subpubkey(unsigned char **p, const unsigned char *end, #if defined(MBEDTLS_ECP_LIGHT) if (pk_alg == MBEDTLS_PK_ECKEY_DH || pk_alg == MBEDTLS_PK_ECKEY) { #if defined(MBEDTLS_PK_HAVE_RFC8410_CURVES) - if (mbedtls_pk_is_rfc8410_curve(ec_grp_id)) { + if (MBEDTLS_PK_IS_RFC8410_GROUP_ID(ec_grp_id)) { ret = pk_use_ecparams_rfc8410(&alg_params, ec_grp_id, pk); } else #endif @@ -1158,6 +1190,12 @@ static int pk_parse_key_sec1_der(mbedtls_pk_context *pk, unsigned char *end = p + keylen; unsigned char *end2; mbedtls_ecp_keypair *eck = mbedtls_pk_ec_rw(*pk); +#if defined(MBEDTLS_PK_USE_PSA_EC_DATA) + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_status_t status; + uint8_t priv_key_raw[MBEDTLS_PSA_MAX_EC_KEY_PAIR_LENGTH]; + size_t priv_key_len; +#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */ /* * RFC 5915, or SEC1 Appendix C.4 @@ -1190,10 +1228,19 @@ static int pk_parse_key_sec1_der(mbedtls_pk_context *pk, d = p; d_len = len; + +#if defined(MBEDTLS_PK_USE_PSA_EC_DATA) + if (len > MBEDTLS_PSA_MAX_EC_KEY_PAIR_LENGTH) { + return MBEDTLS_ERR_PK_BAD_INPUT_DATA; + } + memcpy(priv_key_raw, p, len); + priv_key_len = len; +#else if ((ret = mbedtls_mpi_read_binary(&eck->d, p, len)) != 0) { mbedtls_ecp_keypair_free(eck); return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, ret); } +#endif p += len; @@ -1252,6 +1299,27 @@ static int pk_parse_key_sec1_der(mbedtls_pk_context *pk, } } +#if defined(MBEDTLS_PK_USE_PSA_EC_DATA) + psa_set_key_type(&attributes, PSA_KEY_TYPE_ECC_KEY_PAIR(pk->ec_family)); + /* Setting largest masks for usage and key algorithms */ + psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_SIGN_HASH | + PSA_KEY_USAGE_SIGN_MESSAGE | + PSA_KEY_USAGE_EXPORT); +#if defined(MBEDTLS_ECDSA_DETERMINISTIC) + psa_set_key_algorithm(&attributes, + PSA_ALG_DETERMINISTIC_ECDSA(PSA_ALG_ANY_HASH)); +#else + psa_set_key_algorithm(&attributes, PSA_ALG_ECDSA(PSA_ALG_ANY_HASH)); +#endif + + status = psa_import_key(&attributes, priv_key_raw, priv_key_len, + &pk->priv_id); + if (status != PSA_SUCCESS) { + ret = psa_pk_status_to_mbedtls(status); + return ret; + } +#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */ + if (!pubkey_done) { if ((ret = pk_derive_public_key(pk, d, d_len, f_rng, p_rng)) != 0) { mbedtls_ecp_keypair_free(eck); @@ -1259,10 +1327,12 @@ static int pk_parse_key_sec1_der(mbedtls_pk_context *pk, } } +#if !defined(MBEDTLS_PK_USE_PSA_EC_DATA) if ((ret = mbedtls_ecp_check_privkey(&eck->grp, &eck->d)) != 0) { mbedtls_ecp_keypair_free(eck); return ret; } +#endif /* !MBEDTLS_PK_USE_PSA_EC_DATA */ return 0; } @@ -1363,7 +1433,7 @@ static int pk_parse_key_pkcs8_unencrypted_der( #if defined(MBEDTLS_ECP_LIGHT) if (pk_alg == MBEDTLS_PK_ECKEY || pk_alg == MBEDTLS_PK_ECKEY_DH) { #if defined(MBEDTLS_PK_HAVE_RFC8410_CURVES) - if (mbedtls_pk_is_rfc8410_curve(ec_grp_id)) { + if (MBEDTLS_PK_IS_RFC8410_GROUP_ID(ec_grp_id)) { if ((ret = pk_use_ecparams_rfc8410(¶ms, ec_grp_id, pk)) != 0 || (ret = diff --git a/library/pkwrite.c b/library/pkwrite.c index e89baaf256..c8a96d9eaa 100644 --- a/library/pkwrite.c +++ b/library/pkwrite.c @@ -185,20 +185,33 @@ static int pk_write_ec_param(unsigned char **p, unsigned char *start, * privateKey OCTET STRING -- always of length ceil(log2(n)/8) */ static int pk_write_ec_private(unsigned char **p, unsigned char *start, - mbedtls_ecp_keypair *ec) + const mbedtls_pk_context *pk) { + size_t byte_length; int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - size_t byte_length = (ec->grp.pbits + 7) / 8; + +#if defined(MBEDTLS_PK_USE_PSA_EC_DATA) + unsigned char tmp[MBEDTLS_PSA_MAX_EC_KEY_PAIR_LENGTH]; + psa_status_t status; + + status = psa_export_key(pk->priv_id, tmp, sizeof(tmp), &byte_length); + if (status != PSA_SUCCESS) { + ret = PSA_PK_ECDSA_TO_MBEDTLS_ERR(status); + goto exit; + } +#else /* MBEDTLS_PK_USE_PSA_EC_DATA */ unsigned char tmp[MBEDTLS_ECP_MAX_BYTES]; + mbedtls_ecp_keypair *ec = mbedtls_pk_ec_rw(*pk); + byte_length = (ec->grp.pbits + 7) / 8; ret = mbedtls_ecp_write_key(ec, tmp, byte_length); if (ret != 0) { goto exit; } +#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */ ret = mbedtls_asn1_write_octet_string(p, start, tmp, byte_length); - exit: - mbedtls_platform_zeroize(tmp, byte_length); + mbedtls_platform_zeroize(tmp, sizeof(tmp)); return ret; } #endif /* MBEDTLS_ECP_LIGHT */ @@ -280,7 +293,11 @@ int mbedtls_pk_write_pubkey_der(const mbedtls_pk_context *key, unsigned char *bu pk_type = mbedtls_pk_get_type(key); #if defined(MBEDTLS_ECP_LIGHT) if (pk_type == MBEDTLS_PK_ECKEY) { +#if defined(MBEDTLS_ECP_C) ec_grp_id = mbedtls_pk_ec_ro(*key)->grp.id; +#else /* MBEDTLS_ECP_C */ + ec_grp_id = mbedtls_ecc_group_of_psa(key->ec_family, key->ec_bits, 0); +#endif /* MBEDTLS_ECP_C */ } #endif /* MBEDTLS_ECP_LIGHT */ #if defined(MBEDTLS_USE_PSA_CRYPTO) @@ -372,7 +389,7 @@ int mbedtls_pk_write_pubkey_der(const mbedtls_pk_context *key, unsigned char *bu * CurvePrivateKey ::= OCTET STRING */ static int pk_write_ec_rfc8410_der(unsigned char **p, unsigned char *buf, - mbedtls_ecp_keypair *ec) + const mbedtls_pk_context *pk) { int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; size_t len = 0; @@ -380,14 +397,23 @@ static int pk_write_ec_rfc8410_der(unsigned char **p, unsigned char *buf, const char *oid; /* privateKey */ - MBEDTLS_ASN1_CHK_ADD(len, pk_write_ec_private(p, buf, ec)); + MBEDTLS_ASN1_CHK_ADD(len, pk_write_ec_private(p, buf, pk)); MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(p, buf, len)); MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(p, buf, MBEDTLS_ASN1_OCTET_STRING)); /* privateKeyAlgorithm */ +#if defined(MBEDTLS_PK_USE_PSA_EC_DATA) + mbedtls_ecp_group_id grp_id = mbedtls_ecc_group_of_psa(pk->ec_family, + pk->ec_bits, 0); + if ((ret = mbedtls_oid_get_oid_by_ec_grp_algid(grp_id, &oid, &oid_len)) != 0) { + return ret; + } +#else /* MBEDTLS_PK_USE_PSA_EC_DATA */ + mbedtls_ecp_keypair *ec = mbedtls_pk_ec_rw(*pk); if ((ret = mbedtls_oid_get_oid_by_ec_grp_algid(ec->grp.id, &oid, &oid_len)) != 0) { return ret; } +#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */ MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_algorithm_identifier_ext(p, buf, oid, oid_len, 0, 0)); @@ -408,6 +434,9 @@ int mbedtls_pk_write_key_der(const mbedtls_pk_context *key, unsigned char *buf, int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; unsigned char *c; size_t len = 0; +#if defined(MBEDTLS_ECP_LIGHT) + mbedtls_ecp_group_id grp_id; +#endif if (size == 0) { return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL; @@ -503,12 +532,11 @@ end_of_export: #endif /* MBEDTLS_RSA_C */ #if defined(MBEDTLS_ECP_LIGHT) if (mbedtls_pk_get_type(key) == MBEDTLS_PK_ECKEY) { - mbedtls_ecp_keypair *ec = mbedtls_pk_ec_rw(*key); size_t pub_len = 0, par_len = 0; #if defined(MBEDTLS_PK_HAVE_RFC8410_CURVES) - if (mbedtls_pk_is_rfc8410_curve(ec->grp.id)) { - return pk_write_ec_rfc8410_der(&c, buf, ec); + if (mbedtls_pk_is_rfc8410(key)) { + return pk_write_ec_rfc8410_der(&c, buf, key); } #endif @@ -542,7 +570,8 @@ end_of_export: len += pub_len; /* parameters */ - MBEDTLS_ASN1_CHK_ADD(par_len, pk_write_ec_param(&c, buf, ec->grp.id)); + grp_id = mbedtls_pk_get_group_id(key); + MBEDTLS_ASN1_CHK_ADD(par_len, pk_write_ec_param(&c, buf, grp_id)); MBEDTLS_ASN1_CHK_ADD(par_len, mbedtls_asn1_write_len(&c, buf, par_len)); MBEDTLS_ASN1_CHK_ADD(par_len, mbedtls_asn1_write_tag(&c, buf, @@ -551,7 +580,7 @@ end_of_export: len += par_len; /* privateKey */ - MBEDTLS_ASN1_CHK_ADD(len, pk_write_ec_private(&c, buf, ec)); + MBEDTLS_ASN1_CHK_ADD(len, pk_write_ec_private(&c, buf, key)); /* version */ MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_int(&c, buf, 1)); @@ -625,7 +654,7 @@ int mbedtls_pk_write_key_pem(const mbedtls_pk_context *key, unsigned char *buf, #if defined(MBEDTLS_ECP_LIGHT) if (mbedtls_pk_get_type(key) == MBEDTLS_PK_ECKEY) { #if defined(MBEDTLS_PK_HAVE_RFC8410_CURVES) - if (mbedtls_pk_is_rfc8410_curve(mbedtls_pk_ec_ro(*key)->grp.id)) { + if (mbedtls_pk_is_rfc8410(key)) { begin = PEM_BEGIN_PRIVATE_KEY_PKCS8; end = PEM_END_PRIVATE_KEY_PKCS8; } else