diff --git a/components/wpa_supplicant/esp_supplicant/src/crypto/crypto_mbedtls-ec.c b/components/wpa_supplicant/esp_supplicant/src/crypto/crypto_mbedtls-ec.c index b7c9fab697..9e9d7a6b19 100644 --- a/components/wpa_supplicant/esp_supplicant/src/crypto/crypto_mbedtls-ec.c +++ b/components/wpa_supplicant/esp_supplicant/src/crypto/crypto_mbedtls-ec.c @@ -25,6 +25,11 @@ #include "mbedtls/error.h" #include "mbedtls/oid.h" +#include +#include "psa/crypto.h" + +#include "esp_heap_caps.h" + #define ECP_PRV_DER_MAX_BYTES ( 29 + 3 * MBEDTLS_ECP_MAX_BYTES ) #define ECP_PUB_DER_MAX_BYTES ( 30 + 2 * MBEDTLS_ECP_MAX_BYTES ) @@ -36,6 +41,7 @@ #ifdef CONFIG_ECC +// NOTE: Used with mpi, no PSA equivalent struct crypto_ec *crypto_ec_init(int group) { mbedtls_ecp_group *e; @@ -80,6 +86,7 @@ void crypto_ec_deinit(struct crypto_ec *e) os_free(e); } +// NOTE: Used with mpi, no PSA equivalent struct crypto_ec_point *crypto_ec_point_init(struct crypto_ec *e) { mbedtls_ecp_point *pt; @@ -293,9 +300,8 @@ int crypto_ec_point_mul(struct crypto_ec *e, const struct crypto_ec_point *p, (mbedtls_ecp_point *) res, (const mbedtls_mpi *)b, (const mbedtls_ecp_point *)p, - mbedtls_esp_random, - NULL)); - + mbedtls_psa_get_random, + MBEDTLS_PSA_RANDOM_STATE)); cleanup: return ret ? -1 : 0; } @@ -476,10 +482,27 @@ int crypto_ec_point_cmp(const struct crypto_ec *e, int crypto_ec_key_compare(struct crypto_ec_key *key1, struct crypto_ec_key *key2) { - if (mbedtls_pk_check_pair((mbedtls_pk_context *)key1, (mbedtls_pk_context *)key2, mbedtls_esp_random, NULL) < 0) { + psa_status_t status = psa_crypto_init(); + if (status != PSA_SUCCESS) { return 0; } - return 1; + + psa_key_id_t *key1_id = (psa_key_id_t *)key1; + psa_key_id_t *key2_id = (psa_key_id_t *)key2; + + unsigned char pub1[PSA_EXPORT_PUBLIC_KEY_MAX_SIZE]; + unsigned char pub2[PSA_EXPORT_PUBLIC_KEY_MAX_SIZE]; + + size_t key1_len, key2_len; + + psa_export_public_key(*key1_id, pub1, sizeof(pub1), &key1_len); + psa_export_public_key(*key2_id, pub2, sizeof(pub2), &key2_len); + + if ((key1_len == key2_len) && (os_memcmp(pub1, pub2, key1_len) == 0)) { + return 1; + } + + return 0; } void crypto_debug_print_point(const char *title, struct crypto_ec *e, @@ -498,6 +521,11 @@ void crypto_debug_print_point(const char *title, struct crypto_ec *e, static struct crypto_ec_key *crypto_alloc_key(void) { + /* + * Not moving this to PSA as there is no direct replacement + * for mbedtls_pk_context in PSA. Once all the other functions + * are moved to PSA, this can be removed. + */ mbedtls_pk_context *key = os_malloc(sizeof(*key)); if (!key) { @@ -512,64 +540,113 @@ static struct crypto_ec_key *crypto_alloc_key(void) struct crypto_ec_key * crypto_ec_key_set_pub(const struct crypto_ec_group *group, const u8 *buf, size_t len) { - mbedtls_ecp_point *point = NULL; - struct crypto_ec_key *pkey = NULL; - int ret; - mbedtls_pk_context *key = (mbedtls_pk_context *)crypto_alloc_key(); - mbedtls_ecp_group *ecp_grp = (mbedtls_ecp_group *)group; - - if (!key) { - wpa_printf(MSG_ERROR, "%s: memory allocation failed", __func__); + psa_status_t status = psa_crypto_init(); + if (status != PSA_SUCCESS) { return NULL; } - point = (mbedtls_ecp_point *)crypto_ec_point_from_bin((struct crypto_ec *)group, buf); - if (!point) { - wpa_printf(MSG_ERROR, "%s: Point initialization failed", __func__); - goto fail; - } - if (crypto_ec_point_is_at_infinity((struct crypto_ec *)group, (struct crypto_ec_point *)point)) { - wpa_printf(MSG_ERROR, "Point is at infinity"); - goto fail; - } - if (!crypto_ec_point_is_on_curve((struct crypto_ec *)group, (struct crypto_ec_point *)point)) { - wpa_printf(MSG_ERROR, "Point not on curve"); - goto fail; + mbedtls_ecp_group *ecp_grp = (mbedtls_ecp_group *)group; + mbedtls_ecp_group_id grp_id = ecp_grp->id; + + size_t key_bits = 0; + psa_ecc_family_t ecc_family = mbedtls_ecc_group_to_psa(grp_id, &key_bits); + + if (ecc_family == 0) { + wpa_printf(MSG_ERROR, "Unsupported ECC group"); } - if (mbedtls_ecp_check_pubkey(ecp_grp, point) < 0) { - // ideally should have failed in upper condition, duplicate code?? - wpa_printf(MSG_ERROR, "Invalid key"); - goto fail; - } - /* Assign values */ - if ((ret = mbedtls_pk_setup(key, - mbedtls_pk_info_from_type(MBEDTLS_PK_ECKEY))) != 0) { - goto fail; + psa_key_id_t *key_id = os_calloc(1, sizeof(psa_key_id_t)); + psa_key_attributes_t key_attributes = PSA_KEY_ATTRIBUTES_INIT; + + u8* key_buf = NULL; + size_t key_len = 0; + if (PSA_KEY_TYPE_ECC_GET_FAMILY(ecc_family) != PSA_ECC_FAMILY_MONTGOMERY) { + /* + * For non-Montgomery curves, the public key is represented as an + * uncompressed point (0x04 || X || Y). + * Check if the buffer starts with 0x04 to indicate an uncompressed + * point. + */ + + if (((len & 1) == 0) && (buf[0] != 0x04)) { + // Key doesn't start with 0x04. + key_buf = os_calloc(1, len + 1); + if (!key_buf) { + wpa_printf(MSG_ERROR, "memory allocation failed"); + return NULL; + } + + key_buf[0] = 0x04; + os_memcpy(key_buf + 1, buf, len); + key_len = len + 1; + } else { + key_buf = os_calloc(1, len); + if (!key_buf) { + wpa_printf(MSG_ERROR, "memory allocation failed"); + return NULL; + } + + os_memcpy(key_buf, buf, len); + key_len = len; + } } - mbedtls_ecp_copy(&mbedtls_pk_ec(*key)->MBEDTLS_PRIVATE(Q), point); - mbedtls_ecp_group_load(&mbedtls_pk_ec(*key)->MBEDTLS_PRIVATE(grp), ecp_grp->id); + psa_set_key_usage_flags(&key_attributes, PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_EXPORT); + psa_set_key_algorithm(&key_attributes, PSA_ALG_ECDSA(PSA_ALG_SHA_256)); + psa_set_key_type(&key_attributes, PSA_KEY_TYPE_ECC_PUBLIC_KEY(ecc_family)); - pkey = (struct crypto_ec_key *)key; - crypto_ec_point_deinit((struct crypto_ec_point *)point, 0); - return pkey; -fail: - if (point) { - crypto_ec_point_deinit((struct crypto_ec_point *)point, 0); + status = psa_import_key(&key_attributes, key_buf, key_len, key_id); + if (status != PSA_SUCCESS) { + wpa_printf(MSG_ERROR, "Failed to import key, %d", status); + return NULL; } - if (key) { - mbedtls_pk_free(key); + + if (key_buf) { + os_free(key_buf); } - pkey = NULL; - return pkey; + + return (struct crypto_ec_key *)key_id; } struct crypto_ec_point *crypto_ec_key_get_public_key(struct crypto_ec_key *key) { - mbedtls_pk_context *pkey = (mbedtls_pk_context *)key; + psa_key_id_t *pkey = (psa_key_id_t *)key; - return (struct crypto_ec_point *)&mbedtls_pk_ec(*pkey)->MBEDTLS_PRIVATE(Q); + mbedtls_pk_context *pkey_ctx = os_calloc(1, sizeof(mbedtls_pk_context)); + if (!pkey_ctx) { + return NULL; + } + mbedtls_pk_init(pkey_ctx); + + int ret = mbedtls_pk_copy_from_psa(*pkey, pkey_ctx); + if (ret != 0) { + wpa_printf(MSG_ERROR, "Failed to copy key from PSA"); + os_free(pkey_ctx); + return NULL; + } + + mbedtls_ecp_point *point = os_calloc(1, sizeof(mbedtls_ecp_point)); + if (!point) { + mbedtls_pk_free(pkey_ctx); + os_free(pkey_ctx); + return NULL; + } + + mbedtls_ecp_point_init(point); + + ret = mbedtls_ecp_copy(point, &mbedtls_pk_ec(*pkey_ctx)->MBEDTLS_PRIVATE(Q)); + if (ret != 0) { + wpa_printf(MSG_ERROR, "Failed to copy point"); + mbedtls_ecp_point_free(point); + os_free(point); + mbedtls_pk_free(pkey_ctx); + os_free(pkey_ctx); + return NULL; + } + + mbedtls_pk_free(pkey_ctx); + os_free(pkey_ctx); + return (struct crypto_ec_point *)point; } int crypto_ec_get_priv_key_der(struct crypto_ec_key *key, unsigned char **key_data, int *key_len) @@ -602,63 +679,199 @@ int crypto_ec_get_priv_key_der(struct crypto_ec_key *key, unsigned char **key_da struct crypto_ec_group *crypto_ec_get_group_from_key(struct crypto_ec_key *key) { - mbedtls_pk_context *pkey = (mbedtls_pk_context *)key; + // mbedtls_pk_context *pkey = (mbedtls_pk_context *)key; - return (struct crypto_ec_group *) & (mbedtls_pk_ec(*pkey)->MBEDTLS_PRIVATE(grp)); + // return (struct crypto_ec_group *) & (mbedtls_pk_ec(*pkey)->MBEDTLS_PRIVATE(grp)); + psa_key_id_t *pkey = (psa_key_id_t *)key; + + psa_key_attributes_t key_attributes = PSA_KEY_ATTRIBUTES_INIT; + + psa_status_t status = psa_get_key_attributes(*pkey, &key_attributes); + if (status != PSA_SUCCESS) { + return NULL; + } + + psa_ecc_family_t ecc_family = psa_get_key_type(&key_attributes); + size_t bits = psa_get_key_bits(&key_attributes); + int ret = mbedtls_ecc_group_from_psa(ecc_family, bits); + if (ret == 0) { + wpa_printf(MSG_ERROR, "Unsupported ECC group"); + } + + mbedtls_ecp_group *e = os_zalloc(sizeof(*e)); + if (!e) { + return NULL; + } + + mbedtls_ecp_group_init(e); + + if (mbedtls_ecp_group_load(e, ret)) { + mbedtls_ecp_group_free(e); + os_free(e); + e = NULL; + } + + return (struct crypto_ec_group *)e; } int crypto_ec_key_group(struct crypto_ec_key *key) { - mbedtls_pk_context *pkey = (mbedtls_pk_context *)key; + // mbedtls_pk_context *pkey = (mbedtls_pk_context *)key; - int iana_group = (int)crypto_ec_get_mbedtls_to_nist_group_id(mbedtls_pk_ec(*pkey)->MBEDTLS_PRIVATE(grp).id); + // int iana_group = (int)crypto_ec_get_mbedtls_to_nist_group_id(mbedtls_pk_ec(*pkey)->MBEDTLS_PRIVATE(grp).id); + // return iana_group; + psa_key_id_t *pkey = (psa_key_id_t *)key; + + psa_key_attributes_t key_attributes = PSA_KEY_ATTRIBUTES_INIT; + + psa_status_t status = psa_get_key_attributes(*pkey, &key_attributes); + if (status != PSA_SUCCESS) { + return -1; + } + + psa_ecc_family_t ecc_family = psa_get_key_type(&key_attributes); + size_t bits = psa_get_key_bits(&key_attributes); + int ret = mbedtls_ecc_group_from_psa(ecc_family, bits); + if (ret == 0) { + wpa_printf(MSG_ERROR, "Unsupported ECC group"); + } + + int iana_group = (int)crypto_ec_get_mbedtls_to_nist_group_id(ret); return iana_group; } struct crypto_bignum *crypto_ec_key_get_private_key(struct crypto_ec_key *key) { - mbedtls_pk_context *pkey = (mbedtls_pk_context *)key; + // mbedtls_pk_context *pkey = (mbedtls_pk_context *)key; - return ((struct crypto_bignum *) & (mbedtls_pk_ec(*pkey)->MBEDTLS_PRIVATE(d))); + // return ((struct crypto_bignum *) & (mbedtls_pk_ec(*pkey)->MBEDTLS_PRIVATE(d))); + psa_status_t status = psa_crypto_init(); + if (status != PSA_SUCCESS) { + return NULL; + } + + psa_key_id_t *pkey = (psa_key_id_t *)key; + + mbedtls_pk_context *pkey_ctx = os_calloc(1, sizeof(mbedtls_pk_context)); + if (!pkey_ctx) { + return NULL; + } + + mbedtls_pk_init(pkey_ctx); + + int ret = mbedtls_pk_copy_from_psa(*pkey, pkey_ctx); + if (ret != 0) { + wpa_printf(MSG_ERROR, "Failed to copy key from PSA"); + os_free(pkey_ctx); + return NULL; + } + + mbedtls_mpi *d = os_calloc(1, sizeof(mbedtls_mpi)); + if (!d) { + mbedtls_pk_free(pkey_ctx); + os_free(pkey_ctx); + return NULL; + } + + mbedtls_mpi_init(d); + ret = mbedtls_mpi_copy(d, &mbedtls_pk_ec(*pkey_ctx)->MBEDTLS_PRIVATE(d)); + if (ret != 0) { + wpa_printf(MSG_ERROR, "Failed to copy private key"); + mbedtls_mpi_free(d); + os_free(d); + mbedtls_pk_free(pkey_ctx); + os_free(pkey_ctx); + return NULL; + } + + mbedtls_pk_free(pkey_ctx); + os_free(pkey_ctx); + + return (struct crypto_bignum *)d; } int crypto_ec_get_publickey_buf(struct crypto_ec_key *key, u8 *key_buf, int len) { - mbedtls_pk_context *pkey = (mbedtls_pk_context *)key; - unsigned char buf[MBEDTLS_MPI_MAX_SIZE + 10]; /* tag, length + MPI */ - unsigned char *c = buf + sizeof(buf); - int pk_len = 0; - memset(buf, 0, sizeof(buf)); - pk_len = mbedtls_pk_write_pubkey(&c, buf, pkey); + psa_key_id_t *pkey = (psa_key_id_t *)key; + psa_status_t status = PSA_SUCCESS; - if (pk_len < 0) { + if (key_buf == NULL && len == 0) { + // This is a call to determine the buffer length + // needed for the public key + + psa_key_attributes_t key_attributes = PSA_KEY_ATTRIBUTES_INIT; + + status = psa_get_key_attributes(*pkey, &key_attributes); + if (status != PSA_SUCCESS) { + printf("psa_get_key_attributes failed with %d\n", status); + return -1; + } + + size_t key_bits = psa_get_key_bits(&key_attributes); + if (key_bits == 0) { + printf("psa_get_key_bits failed with %d\n", -1); + return -1; + } + + psa_key_type_t key_type = psa_get_key_type(&key_attributes); + + psa_reset_key_attributes(&key_attributes); + return PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(key_type, key_bits); + } + + size_t key_len = 0; + status = psa_export_public_key(*pkey, key_buf, len, &key_len); + if (status != PSA_SUCCESS) { + printf("psa_export_public_key failed with %d\n", status); return -1; } - if (len == 0) { - return pk_len; - } - - os_memcpy(key_buf, buf + MBEDTLS_MPI_MAX_SIZE + 10 - pk_len, pk_len); - - return pk_len; + return key_len; } int crypto_write_pubkey_der(struct crypto_ec_key *key, unsigned char **key_buf) { - unsigned char *buf = os_malloc(ECP_PUB_DER_MAX_BYTES); + psa_status_t status = psa_crypto_init(); + if (status != PSA_SUCCESS) { + return -1; + } + unsigned char *buf = os_malloc(ECP_PUB_DER_MAX_BYTES); if (!buf) { wpa_printf(MSG_ERROR, "memory allocation failed"); return -1; } - int len = mbedtls_pk_write_pubkey_der((mbedtls_pk_context *)key, buf, ECP_PUB_DER_MAX_BYTES); - if (len <= 0) { + + psa_key_id_t *pkey = (psa_key_id_t *)key; + mbedtls_pk_context *pkey_ctx = os_calloc(1, sizeof(mbedtls_pk_context)); + if (!pkey_ctx) { os_free(buf); return -1; } + mbedtls_pk_init(pkey_ctx); + + int ret = mbedtls_pk_copy_from_psa(*pkey, pkey_ctx); + if (ret != 0) { + wpa_printf(MSG_ERROR, "Failed to copy key from PSA. ret: %d", ret); + os_free(buf); + mbedtls_pk_free(pkey_ctx); + os_free(pkey_ctx); + return -1; + } + + int len = mbedtls_pk_write_pubkey_der(pkey_ctx, buf, ECP_PUB_DER_MAX_BYTES); + if (len <= 0) { + os_free(buf); + mbedtls_pk_free(pkey_ctx); + os_free(pkey_ctx); + return -1; + } + + mbedtls_pk_free(pkey_ctx); + os_free(pkey_ctx); + *key_buf = os_malloc(len); if (!*key_buf) { os_free(buf); @@ -672,25 +885,57 @@ int crypto_write_pubkey_der(struct crypto_ec_key *key, unsigned char **key_buf) struct crypto_ec_key *crypto_ec_key_parse_priv(const u8 *privkey, size_t privkey_len) { + /* + * As of PSA API v1.0, there is no way to import a private key with PSA APIs without + * knowing the metadata (such as type, size, etc.) of the key. So, we need to use + * mbedtls_pk_parse_key() to parse the private key and then import it into PSA. + */ + + psa_status_t status = psa_crypto_init(); + if (status != PSA_SUCCESS) { + return NULL; + } + int ret; mbedtls_pk_context *kctx = (mbedtls_pk_context *)crypto_alloc_key(); + psa_key_id_t *key_id = os_calloc(1, sizeof(psa_key_id_t)); if (!kctx) { wpa_printf(MSG_ERROR, "memory allocation failed"); return NULL; } - ret = mbedtls_pk_parse_key(kctx, privkey, privkey_len, NULL, 0, mbedtls_esp_random, NULL); + ret = mbedtls_pk_parse_key(kctx, privkey, privkey_len, NULL, 0, mbedtls_psa_get_random, MBEDTLS_PSA_RANDOM_STATE); if (ret < 0) { //crypto_print_error_string(ret); goto fail; } - return (struct crypto_ec_key *)kctx; + psa_key_attributes_t key_attributes = PSA_KEY_ATTRIBUTES_INIT; + ret = mbedtls_pk_get_psa_attributes(kctx, PSA_KEY_USAGE_DERIVE, &key_attributes); + if (ret != 0) { + wpa_printf(MSG_ERROR, "mbedtls_pk_get_psa_attributes failed with %d", ret); + goto fail; + } + + ret = mbedtls_pk_import_into_psa(kctx, &key_attributes, key_id); + if (ret != 0) { + wpa_printf(MSG_ERROR, "mbedtls_pk_import_into_psa failed with %d", ret); + goto fail; + } + + mbedtls_pk_free(kctx); + os_free(kctx); + + return (struct crypto_ec_key *)key_id; fail: mbedtls_pk_free(kctx); os_free(kctx); + if (key_id) { + psa_destroy_key(*key_id); + os_free(key_id); + } return NULL; } @@ -732,90 +977,90 @@ int crypto_ec_get_curve_id(const struct crypto_ec_group *group) int crypto_ecdh(struct crypto_ec_key *key_own, struct crypto_ec_key *key_peer, u8 *secret, size_t *secret_len) { - mbedtls_ecdh_context *ctx = NULL; - mbedtls_pk_context *own = (mbedtls_pk_context *)key_own; - mbedtls_pk_context *peer = (mbedtls_pk_context *)key_peer; - int ret = -1; + int ret = 0; + psa_status_t status = psa_crypto_init(); + if (status != PSA_SUCCESS) { + return -1; + } + + psa_key_id_t *peer = (psa_key_id_t *)key_peer; + psa_key_id_t *own = (psa_key_id_t *)key_own; + + unsigned char *peer_key_buf = os_calloc(PSA_EXPORT_PUBLIC_KEY_MAX_SIZE, sizeof(uint8_t)); + if (!peer_key_buf) { + wpa_printf(MSG_ERROR, "memory allocation failed"); + ret = -1; + goto fail; + } + + size_t peer_key_len = 0; + status = psa_export_public_key(*peer, peer_key_buf, PSA_EXPORT_PUBLIC_KEY_MAX_SIZE, &peer_key_len); + if (status != PSA_SUCCESS) { + wpa_printf(MSG_ERROR, "psa_export_public_key failed with %d", status); + ret = -1; + goto fail; + } + + psa_key_attributes_t peer_key_attributes = PSA_KEY_ATTRIBUTES_INIT; + status = psa_get_key_attributes(*peer, &peer_key_attributes); + if (status != PSA_SUCCESS) { + wpa_printf(MSG_ERROR, "psa_get_key_attributes failed with %d", status); + ret = -1; + goto fail; + } + + // psa_algorithm_t alg = psa_get_key_algorithm(&peer_key_attributes); *secret_len = 0; - ctx = os_malloc(sizeof(*ctx)); - if (!ctx) { - wpa_printf(MSG_ERROR, "DPP: EVP_PKEY_CTX_new failed: %s", - __func__); + size_t secret_length = 0; + status = psa_raw_key_agreement(PSA_ALG_ECDH, *own, peer_key_buf, peer_key_len, secret, 66, &secret_length); + if (status != PSA_SUCCESS) { + wpa_printf(MSG_ERROR, "psa_raw_key_agreement failed with %d", status); + printf("psa_raw_key_agreement failed with %d\n", status); + ret = -1; goto fail; } - mbedtls_ecdh_init(ctx); - /* No need to setup, done through mbedtls_ecdh_get_params */ - - /* set params from our key */ - if (mbedtls_ecdh_get_params(ctx, mbedtls_pk_ec(*own), MBEDTLS_ECDH_OURS) < 0) { - wpa_printf(MSG_ERROR, "failed to set our ecdh params"); - goto fail; - } - -#ifndef DPP_MAX_SHARED_SECRET_LEN -#define DPP_MAX_SHARED_SECRET_LEN 66 -#endif - /* set params from peers key */ - if (mbedtls_ecdh_get_params(ctx, mbedtls_pk_ec(*peer), MBEDTLS_ECDH_THEIRS) < 0) { - wpa_printf(MSG_ERROR, "failed to set peer's ecdh params"); - goto fail; - } - - if (mbedtls_ecdh_calc_secret(ctx, secret_len, secret, DPP_MAX_SHARED_SECRET_LEN, - mbedtls_esp_random, NULL) < 0) { - wpa_printf(MSG_ERROR, "failed to calculate secret"); - goto fail; - } - - if (*secret_len > DPP_MAX_SHARED_SECRET_LEN) { - wpa_printf(MSG_ERROR, "secret len=%d is too big", *secret_len); - goto fail; - } - - ret = 0; + *secret_len = secret_length; fail: - if (ctx) { - mbedtls_ecdh_free(ctx); - os_free(ctx); + if (peer_key_buf) { + os_free(peer_key_buf); } + return ret; } int crypto_ecdsa_get_sign(unsigned char *hash, const struct crypto_bignum *r, const struct crypto_bignum *s, struct crypto_ec_key *csign, int hash_len) { - int ret = -1; - mbedtls_pk_context *pkey = (mbedtls_pk_context *)csign; + psa_key_id_t *pkey = (psa_key_id_t *)csign; - mbedtls_ecdsa_context *ctx = os_malloc(sizeof(*ctx)); - if (!ctx) { - wpa_printf(MSG_ERROR, "failed to allcate memory"); + (void)r; + (void)s; + + psa_status_t status = psa_crypto_init(); + if (status != PSA_SUCCESS) { return -1; } - mbedtls_ecdsa_init(ctx); - if (mbedtls_ecdsa_from_keypair(ctx, mbedtls_pk_ec(*pkey)) < 0) { - goto fail; + size_t signature_length = 0; + status = psa_sign_hash(*pkey, PSA_ALG_DETERMINISTIC_ECDSA(PSA_ALG_SHA_256), hash, hash_len, hash, hash_len, &signature_length); + if (status != PSA_SUCCESS) { + printf("psa_sign_hash failed with %d\n", status); + return -1; } - ret = mbedtls_ecdsa_sign(&ctx->MBEDTLS_PRIVATE(grp), (mbedtls_mpi *)r, (mbedtls_mpi *)s, - &ctx->MBEDTLS_PRIVATE(d), hash, SHA256_MAC_LEN, mbedtls_esp_random, NULL); -fail: - mbedtls_ecdsa_free(ctx); - os_free(ctx); - - return ret; + return 0; } +// TODO: Add a test case for this function and then migrate to PSA int crypto_ec_key_verify_signature_r_s(struct crypto_ec_key *csign, const unsigned char *hash, int hlen, const u8 *r, size_t r_len, const u8 *s, size_t s_len) { - /* (mbedtls_ecdsa_context *) */ + printf("crypto_ec_key_verify_signature_r_s\n"); mbedtls_ecp_keypair *ecp_kp = mbedtls_pk_ec(*(mbedtls_pk_context *)csign); if (!ecp_kp) { return -1; @@ -841,26 +1086,26 @@ int crypto_ec_key_verify_signature_r_s(struct crypto_ec_key *csign, void crypto_ec_key_debug_print(struct crypto_ec_key *key, const char *title) { -#if defined(CONFIG_LOG_DEFAULT_LEVEL_DEBUG) || defined(CONFIG_LOG_DEFAULT_LEVEL_VERBOSE) -#if defined(DEBUG_PRINT) - mbedtls_pk_context *pkey = (mbedtls_pk_context *)key; - mbedtls_ecp_keypair *ecp = mbedtls_pk_ec(*pkey); - u8 x[32], y[32], d[32]; - wpa_printf(MSG_EXCESSIVE, "curve: %s", - mbedtls_ecp_curve_info_from_grp_id(ecp->MBEDTLS_PRIVATE(grp).id)->name); - int len = mbedtls_mpi_size((mbedtls_mpi *)crypto_ec_get_prime((struct crypto_ec *)crypto_ec_get_group_from_key(key))); +#ifdef DEBUG_PRINT + // mbedtls_pk_context *pkey = (mbedtls_pk_context *)key; + // mbedtls_ecp_keypair *ecp = mbedtls_pk_ec(*pkey); + // u8 x[32], y[32], d[32]; + // wpa_printf(MSG_INFO, "curve: %s", + // mbedtls_ecp_curve_info_from_grp_id(ecp->MBEDTLS_PRIVATE(grp).id)->name); + // int len = mbedtls_mpi_size((mbedtls_mpi *)crypto_ec_get_prime((struct crypto_ec *)crypto_ec_get_group_from_key(key))); - wpa_printf(MSG_EXCESSIVE, "prime len is %d", len); - crypto_ec_point_to_bin((struct crypto_ec *)crypto_ec_get_group_from_key(key), crypto_ec_key_get_public_key(key), x, y); - crypto_bignum_to_bin(crypto_ec_key_get_private_key(key), - d, len, len); - wpa_hexdump(MSG_EXCESSIVE, "Q_x:", x, 32); - wpa_hexdump(MSG_EXCESSIVE, "Q_y:", y, 32); - wpa_hexdump(MSG_EXCESSIVE, "d: ", d, 32); -#endif + // wpa_printf(MSG_INFO, "prime len is %d", len); + // crypto_ec_point_to_bin((struct crypto_ec *)crypto_ec_get_group_from_key(key), crypto_ec_key_get_public_key(key), x, y); + // crypto_bignum_to_bin(crypto_ec_key_get_private_key(key), + // d, len, len); + // wpa_hexdump(MSG_INFO, "Q_x:", x, 32); + // wpa_hexdump(MSG_INFO, "Q_y:", y, 32); + // wpa_hexdump(MSG_INFO, "d: ", d, 32); #endif } +// NOTE: PSA doesn't have replacements for mbedtls_asn1_* functions +// so this function is not migrated to PSA struct crypto_ec_key *crypto_ec_parse_subpub_key(const unsigned char *p, size_t len) { int ret; @@ -879,6 +1124,7 @@ struct crypto_ec_key *crypto_ec_parse_subpub_key(const unsigned char *p, size_t return NULL; } +// TODO: Migrate this to PSA along with crypto_ec_parse_subpub_key int crypto_is_ec_key(struct crypto_ec_key *key) { int ret = mbedtls_pk_can_do((mbedtls_pk_context *)key, MBEDTLS_PK_ECKEY); @@ -887,26 +1133,34 @@ int crypto_is_ec_key(struct crypto_ec_key *key) struct crypto_ec_key * crypto_ec_key_gen(u16 ike_group) { - mbedtls_pk_context *kctx = (mbedtls_pk_context *)crypto_alloc_key(); - - if (!kctx) { - wpa_printf(MSG_ERROR, "%s: memory allocation failed", __func__); + psa_status_t status = psa_crypto_init(); + if (status != PSA_SUCCESS) { return NULL; } - if (mbedtls_pk_setup(kctx, - mbedtls_pk_info_from_type(MBEDTLS_PK_ECKEY)) != 0) { - goto fail; + size_t key_bit_length = 0; + psa_ecc_family_t ecc_family = mbedtls_ecc_group_to_psa(ike_group, &key_bit_length); + if (ecc_family == 0) { + printf("mbedtls_ecc_group_to_psa failed\n"); + return NULL; } - mbedtls_ecp_gen_key(MBEDTLS_ECP_DP_SECP256R1, mbedtls_pk_ec(*kctx), //get this from argument - mbedtls_esp_random, NULL); + psa_key_attributes_t key_attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_set_key_usage_flags(&key_attributes, PSA_KEY_USAGE_DERIVE | PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE); + psa_set_key_algorithm(&key_attributes, PSA_ALG_DETERMINISTIC_ECDSA(PSA_ALG_ANY_HASH)); + psa_set_key_type(&key_attributes, PSA_KEY_TYPE_ECC_KEY_PAIR(ecc_family)); + psa_set_key_bits(&key_attributes, key_bit_length); - return (struct crypto_ec_key *)kctx; -fail: - mbedtls_pk_free(kctx); - os_free(kctx); - return NULL; + psa_key_id_t *key_id = os_calloc(1, sizeof(psa_key_id_t)); + + status = psa_generate_key(&key_attributes, key_id); + if (status != PSA_SUCCESS) { + return NULL; + } + + psa_reset_key_attributes(&key_attributes); + + return (struct crypto_ec_key *)key_id; } /* @@ -1025,12 +1279,26 @@ int crypto_pk_write_formatted_pubkey_der(mbedtls_pk_context *key, unsigned char int crypto_ec_write_pub_key(struct crypto_ec_key *key, unsigned char **key_buf) { + + psa_key_id_t *pkey = (psa_key_id_t *)key; + + mbedtls_pk_context *pk = os_malloc(sizeof(mbedtls_pk_context)); + mbedtls_pk_init(pk); + + int ret = mbedtls_pk_copy_public_from_psa(*pkey, pk); + if (ret != 0) { + wpa_printf(MSG_ERROR, "Failed to copy public key from psa key"); + return 0; + } unsigned char output_buf[1600] = {0}; - int len = crypto_pk_write_formatted_pubkey_der((mbedtls_pk_context *)key, output_buf, 1600, 1); + int len = crypto_pk_write_formatted_pubkey_der(pk, output_buf, 1600, 1); if (len <= 0) { return 0; } + mbedtls_pk_free(pk); + os_free(pk); + *key_buf = os_malloc(len); if (!*key_buf) { wpa_printf(MSG_ERROR, "%s: memory allocation failed", __func__); @@ -1051,6 +1319,8 @@ struct wpabuf * crypto_ec_key_get_subject_public_key(struct crypto_ec_key *key) if (!der) { wpa_printf(MSG_ERROR, "failed to get der for bootstrapping key\n"); return NULL; + } else { + wpa_printf(MSG_DEBUG, "der_len: %d\n", der_len); } ret = wpabuf_alloc_copy(der, der_len); @@ -1074,167 +1344,81 @@ int crypto_mbedtls_get_grp_id(int group) void crypto_ecdh_deinit(struct crypto_ecdh *ecdh) { - mbedtls_ecdh_context *ctx = (mbedtls_ecdh_context *)ecdh; - if (!ctx) { - return; - } - mbedtls_ecdh_free(ctx); - os_free(ctx); - ctx = NULL; + psa_key_id_t *key_id = (psa_key_id_t *)ecdh; + psa_destroy_key(*key_id); + os_free(key_id); } struct crypto_ecdh * crypto_ecdh_init(int group) { - mbedtls_ecdh_context *ctx; - - ctx = os_zalloc(sizeof(*ctx)); - if (!ctx) { - wpa_printf(MSG_ERROR, "Memory allocation failed for ecdh context"); - goto fail; - } - mbedtls_ecdh_init(ctx); -#ifndef CONFIG_MBEDTLS_ECDH_LEGACY_CONTEXT - ctx->MBEDTLS_PRIVATE(var) = MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0; -#endif - - if ((mbedtls_ecp_group_load(ACCESS_ECDH(&ctx, grp), crypto_mbedtls_get_grp_id(group))) != 0) { - wpa_printf(MSG_ERROR, "Failed to set up ECDH context with group info"); - goto fail; + psa_status_t status = psa_crypto_init(); + if (status != PSA_SUCCESS) { + return NULL; } - /* Generates ECDH keypair on elliptic curve */ - if (mbedtls_ecdh_gen_public(ACCESS_ECDH(&ctx, grp), ACCESS_ECDH(&ctx, d), ACCESS_ECDH(&ctx, Q), mbedtls_esp_random, NULL) != 0) { - wpa_printf(MSG_ERROR, "ECDH keypair on curve failed"); - goto fail; + psa_key_attributes_t key_attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_key_id_t key_id; + size_t key_size = 0; + + psa_ecc_family_t ecc_family = mbedtls_ecc_group_to_psa(crypto_mbedtls_get_grp_id(group), &key_size); + + psa_set_key_type(&key_attributes, PSA_KEY_TYPE_ECC_KEY_PAIR(ecc_family)); + psa_set_key_bits(&key_attributes, key_size); + psa_set_key_usage_flags(&key_attributes, PSA_KEY_USAGE_DERIVE); + psa_set_key_algorithm(&key_attributes, PSA_ALG_ECDH); + + status = psa_generate_key(&key_attributes, &key_id); + if (status != PSA_SUCCESS) { + return NULL; } - return (struct crypto_ecdh *)ctx; -fail: - if (ctx) { - mbedtls_ecdh_free(ctx); - os_free(ctx); - ctx = NULL; - } - return NULL; + return (struct crypto_ecdh *)key_id; } struct wpabuf * crypto_ecdh_get_pubkey(struct crypto_ecdh *ecdh, int y) { struct wpabuf *public_key = NULL; - uint8_t *buf = NULL; - int ret; - mbedtls_ecdh_context *ctx = (mbedtls_ecdh_context *)ecdh; - size_t prime_len = ACCESS_ECDH(ctx, grp).pbits / 8; + psa_key_id_t *key_id = (psa_key_id_t *)ecdh; - buf = os_zalloc(y ? prime_len : 2 * prime_len); - if (!buf) { - wpa_printf(MSG_ERROR, "Memory allocation failed"); + size_t key_size = 0; + + psa_status_t status = psa_crypto_init(); + if (status != PSA_SUCCESS) { return NULL; } - /* Export an MPI into unsigned big endian binary data of fixed size */ - ret = mbedtls_mpi_write_binary(ACCESS_ECDH(&ctx, Q).MBEDTLS_PRIVATE(X), buf, prime_len); - if (ret) { - goto cleanup; + status = psa_export_public_key(*key_id, raw_key, sizeof(raw_key), &key_size); + if (status != PSA_SUCCESS) { + return NULL; } - public_key = wpabuf_alloc_copy(buf, 32); -cleanup: - os_free(buf); + public_key = wpabuf_alloc_copy(raw_key, key_size); return public_key; } struct wpabuf * crypto_ecdh_set_peerkey(struct crypto_ecdh *ecdh, int inc_y, const u8 *key, size_t len) { - uint8_t *secret = 0; - size_t olen = 0, len_prime = 0; - struct crypto_bignum *bn_x = NULL; - struct crypto_ec_point *ec_pt = NULL; - uint8_t *px = NULL, *py = NULL, *buf = NULL; - struct crypto_ec_key *pkey = NULL; - struct wpabuf *sh_secret = NULL; - int secret_key = 0; - - mbedtls_ecdh_context *ctx = (mbedtls_ecdh_context *)ecdh; - if (!ctx) { - wpa_printf(MSG_ERROR, "ECDH Context is NULL"); - return 0; + psa_status_t status = psa_crypto_init(); + if (status != PSA_SUCCESS) { + return NULL; } - len_prime = ACCESS_ECDH(ctx, grp).pbits / 8; - bn_x = crypto_bignum_init_set(key, len); + psa_key_id_t *key_id = (psa_key_id_t *)ecdh; - /* Initialize data for EC point */ - ec_pt = crypto_ec_point_init((struct crypto_ec*)ACCESS_ECDH(&ctx, grp)); - if (!ec_pt) { - wpa_printf(MSG_ERROR, "Initializing for EC point failed"); - goto cleanup; + size_t secret_len = inc_y ? 2 * len : len; + uint8_t *secret = os_zalloc(secret_len); + size_t secret_length = 0; + + status = psa_raw_key_agreement(PSA_ALG_ECDH, *key_id, key, len, secret, secret_len, &secret_length); + if (status != PSA_SUCCESS) { + return NULL; } - if (crypto_ec_point_solve_y_coord((struct crypto_ec *)ACCESS_ECDH(&ctx, grp), ec_pt, bn_x, inc_y) != 0) { - wpa_printf(MSG_ERROR, "Failed to solve for y coordinate"); - goto cleanup; - } - px = os_zalloc(len); - py = os_zalloc(len); - buf = os_zalloc(2 * len); + struct wpabuf *sh_secret = wpabuf_alloc_copy(secret, secret_len); - if (!px || !py || !buf) { - wpa_printf(MSG_ERROR, "Memory allocation failed"); - goto cleanup; - } - if (crypto_ec_point_to_bin((struct crypto_ec *)ACCESS_ECDH(&ctx, grp), ec_pt, px, py) != 0) { - wpa_printf(MSG_ERROR, "Failed to write EC point value as binary data"); - goto cleanup; - } - - os_memcpy(buf, px, len); - os_memcpy(buf + len, py, len); - - pkey = crypto_ec_key_set_pub((struct crypto_ec_group*)ACCESS_ECDH(&ctx, grp), buf, len); - if (!pkey) { - wpa_printf(MSG_ERROR, "Failed to set point for peer's public key"); - goto cleanup; - } - - mbedtls_pk_context *peer = (mbedtls_pk_context*)pkey; - - /* Setup ECDH context from EC key */ - /* Call to mbedtls_ecdh_get_params() will initialize the context when not LEGACY context */ - if (peer != NULL) { - mbedtls_ecp_copy(ACCESS_ECDH(&ctx, Qp), &(mbedtls_pk_ec(*peer))->MBEDTLS_PRIVATE(Q)); -#ifndef CONFIG_MBEDTLS_ECDH_LEGACY_CONTEXT - ctx->MBEDTLS_PRIVATE(var) = MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0; -#endif - } else { - wpa_printf(MSG_ERROR, "Failed to set peer's ECDH context"); - goto cleanup; - } - int len_secret = inc_y ? 2 * len : len; - secret = os_zalloc(len_secret); - if (!secret) { - wpa_printf(MSG_ERROR, "Allocation failed for secret"); - goto cleanup; - } - - /* Calculate secret - z = F(DH(x,Y)) */ - secret_key = mbedtls_ecdh_calc_secret(ctx, &olen, secret, len_prime, mbedtls_esp_random, NULL); - if (secret_key != 0) { - wpa_printf(MSG_ERROR, "Calculation of secret failed"); - goto cleanup; - } - sh_secret = wpabuf_alloc_copy(secret, len_secret); - -cleanup: - os_free(px); - os_free(py); - os_free(buf); os_free(secret); - crypto_ec_key_deinit(pkey); - crypto_bignum_deinit(bn_x, 1); - crypto_ec_point_deinit(ec_pt, 1); + return sh_secret; } @@ -1260,44 +1444,31 @@ struct crypto_ec_key *crypto_ec_key_parse_pub(const u8 *der, size_t der_len) void crypto_ec_key_deinit(struct crypto_ec_key *key) { - mbedtls_pk_free((mbedtls_pk_context *)key); + psa_key_id_t *key_id = (psa_key_id_t *)key; + if (key_id == NULL) { + return; + } + if (*key_id != 0) { + psa_destroy_key(*key_id); + } os_free(key); } int crypto_ec_key_verify_signature(struct crypto_ec_key *key, const u8 *data, size_t len, const u8 *sig, size_t sig_len) { - int ret = 0; - - mbedtls_ecdsa_context *ctx_verify = os_malloc(sizeof(mbedtls_ecdsa_context)); - if (!ctx_verify) { + psa_status_t status = psa_crypto_init(); + if (status != PSA_SUCCESS) { return -1; } - mbedtls_ecdsa_init(ctx_verify); - - mbedtls_ecp_keypair *ec_key = mbedtls_pk_ec(*((mbedtls_pk_context *)key)); - mbedtls_ecp_group *grp = &ec_key->MBEDTLS_PRIVATE(grp); - - if ((ret = mbedtls_ecp_group_copy(&ctx_verify->MBEDTLS_PRIVATE(grp), grp)) != 0) { - goto cleanup; + psa_key_id_t *key_id = (psa_key_id_t *)key; + status = psa_verify_hash(*key_id, PSA_ALG_DETERMINISTIC_ECDSA(PSA_ALG_SHA_256), data, len, sig, sig_len); + if (status != PSA_SUCCESS) { + return -1; } - if ((ret = mbedtls_ecp_copy(&ctx_verify->MBEDTLS_PRIVATE(Q), &ec_key->MBEDTLS_PRIVATE(Q))) != 0) { - goto cleanup; - } - - if ((ret = mbedtls_ecdsa_read_signature(ctx_verify, - data, len, - sig, sig_len)) != 0) { - goto cleanup; - } - ret = 1; - -cleanup: - mbedtls_ecdsa_free(ctx_verify); - os_free(ctx_verify); - return ret; + return 0; } #endif /* CONFIG_ECC */ diff --git a/components/wpa_supplicant/esp_supplicant/src/crypto/crypto_mbedtls-rsa.c b/components/wpa_supplicant/esp_supplicant/src/crypto/crypto_mbedtls-rsa.c index 649e860a3c..ceecb76422 100644 --- a/components/wpa_supplicant/esp_supplicant/src/crypto/crypto_mbedtls-rsa.c +++ b/components/wpa_supplicant/esp_supplicant/src/crypto/crypto_mbedtls-rsa.c @@ -20,6 +20,9 @@ #include #include +#include "psa/crypto.h" +#include + /* Dummy structures; these are just typecast to struct crypto_rsa_key */ struct crypto_public_key; struct crypto_private_key; @@ -181,23 +184,55 @@ int crypto_public_key_encrypt_pkcs1_v15(struct crypto_public_key *key, const u8 *in, size_t inlen, u8 *out, size_t *outlen) { - int ret; + int ret = 0; mbedtls_pk_context *pkey = (mbedtls_pk_context *)key; + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_key_id_t key_id = 0; if (!pkey) { - return -1; - } - - ret = mbedtls_rsa_pkcs1_encrypt(mbedtls_pk_rsa(*pkey), mbedtls_esp_random, - NULL, inlen, in, out); - - if (ret != 0) { - wpa_printf(MSG_ERROR, " failed ! mbedtls_rsa_pkcs1_encrypt returned -0x%04x", -ret); + wpa_printf(MSG_ERROR, "failed to allocate memory"); + ret = -1; goto cleanup; } - *outlen = mbedtls_rsa_get_len(mbedtls_pk_rsa(*pkey)); + + psa_status_t status = psa_crypto_init(); + if (status != PSA_SUCCESS) { + wpa_printf(MSG_ERROR, "Failed to initialize PSA crypto, returned %d", (int) status); + ret = -1; + goto cleanup; + } + + ret = mbedtls_pk_get_psa_attributes(pkey, PSA_KEY_USAGE_ENCRYPT, &attributes); + if (ret != 0) { + wpa_printf(MSG_ERROR, "failed to get key attributes"); + ret = -1; + goto cleanup; + } + + ret = mbedtls_pk_import_into_psa(pkey, &attributes, &key_id); + if (ret != 0) { + wpa_printf(MSG_ERROR, "failed to import key into PSA"); + ret = -1; + goto cleanup; + } + + size_t output_len = 0; + status = psa_asymmetric_encrypt(key_id, PSA_ALG_RSA_PKCS1V15_CRYPT, in, inlen, NULL, 0, out, *outlen, &output_len); + if (status != PSA_SUCCESS) { + wpa_printf(MSG_ERROR, "Failed to encrypt data, returned %d", (int) status); + ret = -1; + goto cleanup; + } + + *outlen = output_len; cleanup: + + if (key_id) { + printf("Destroying key\n"); + psa_reset_key_attributes(&attributes); + psa_destroy_key(key_id); + } return ret; } @@ -205,22 +240,54 @@ int crypto_private_key_decrypt_pkcs1_v15(struct crypto_private_key *key, const u8 *in, size_t inlen, u8 *out, size_t *outlen) { - int ret; - size_t i; + int ret = 0; mbedtls_pk_context *pkey = (mbedtls_pk_context *)key; + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_key_id_t key_id = 0; if (!pkey) { + wpa_printf(MSG_ERROR, "failed to allocate memory"); + ret = -1; + goto cleanup; + } + + psa_status_t status = psa_crypto_init(); + if (status != PSA_SUCCESS) { + wpa_printf(MSG_ERROR, "Failed to initialize PSA crypto, returned %d", (int) status); return -1; } - i = mbedtls_rsa_get_len(mbedtls_pk_rsa(*pkey)); - ret = mbedtls_rsa_rsaes_pkcs1_v15_decrypt(mbedtls_pk_rsa(*pkey), mbedtls_esp_random, - NULL, &i, in, out, *outlen); - - if (ret == 0) { - *outlen = i; + ret = mbedtls_pk_get_psa_attributes(pkey, PSA_KEY_USAGE_DECRYPT, &attributes); + if (ret != 0) { + wpa_printf(MSG_ERROR, "failed to get key attributes"); + ret = -1; + goto cleanup; } + ret = mbedtls_pk_import_into_psa(pkey, &attributes, &key_id); + if (ret != 0) { + wpa_printf(MSG_ERROR, "failed to import key into PSA"); + ret = -1; + goto cleanup; + } + + size_t output_len = 0; + size_t heap_free_before = esp_get_free_heap_size(); + status = psa_asymmetric_decrypt(key_id, PSA_ALG_RSA_PKCS1V15_CRYPT, in, inlen, NULL, 0, out, *outlen, &output_len); + if (status != PSA_SUCCESS) { + printf("Failed to decrypt data, returned %d", (int) status); + ret = -1; + goto cleanup; + } + size_t heap_free_after = esp_get_free_heap_size(); + printf("Heap free before: %d, Heap free after: %d, used: %d\n", heap_free_before, heap_free_after, heap_free_before - heap_free_after); + *outlen = output_len; + +cleanup: + if (key_id) { + psa_reset_key_attributes(&attributes); + psa_destroy_key(key_id); + } return ret; } @@ -228,22 +295,54 @@ int crypto_private_key_sign_pkcs1(struct crypto_private_key *key, const u8 *in, size_t inlen, u8 *out, size_t *outlen) { - int ret; + int ret = 0; mbedtls_pk_context *pkey = (mbedtls_pk_context *)key; + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_key_id_t key_id = 0; if (!pkey) { + wpa_printf(MSG_ERROR, "failed to allocate memory"); + ret = -1; + goto cleanup; + } + + psa_status_t status = psa_crypto_init(); + if (status != PSA_SUCCESS) { + wpa_printf(MSG_ERROR, "Failed to initialize PSA crypto, returned %d", (int) status); return -1; } - if ((ret = mbedtls_rsa_pkcs1_sign(mbedtls_pk_rsa(*pkey), mbedtls_esp_random, NULL, - (mbedtls_pk_rsa(*pkey))->MBEDTLS_PRIVATE(hash_id), - inlen, in, out)) != 0) { - wpa_printf(MSG_ERROR, " failed ! mbedtls_rsa_pkcs1_sign returned %d", ret); + ret = mbedtls_pk_get_psa_attributes(pkey, PSA_KEY_USAGE_SIGN_HASH , &attributes); + if (ret != 0) { + wpa_printf(MSG_ERROR, "failed to get key attributes"); + ret = -1; goto cleanup; } - *outlen = mbedtls_rsa_get_len(mbedtls_pk_rsa(*pkey)); + + ret = mbedtls_pk_import_into_psa(pkey, &attributes, &key_id); + if (ret != 0) { + wpa_printf(MSG_ERROR, "failed to import key into PSA"); + ret = -1; + goto cleanup; + } + + printf("Hash ID: %d\n", (mbedtls_pk_rsa(*pkey))->MBEDTLS_PRIVATE(hash_id)); + + size_t output_len = 0; + status = psa_sign_hash(key_id, PSA_ALG_RSA_PKCS1V15_SIGN_RAW, in, inlen, out, *outlen, &output_len); + if (status != PSA_SUCCESS) { + wpa_printf(MSG_ERROR, "Failed to sign data, returned %d", (int) status); + ret = -1; + goto cleanup; + } + + *outlen = output_len; cleanup: + if (key_id) { + psa_reset_key_attributes(&attributes); + psa_destroy_key(key_id); + } return ret; } diff --git a/components/wpa_supplicant/esp_supplicant/src/crypto/crypto_mbedtls.c b/components/wpa_supplicant/esp_supplicant/src/crypto/crypto_mbedtls.c index 89653b789f..4936fb44db 100644 --- a/components/wpa_supplicant/esp_supplicant/src/crypto/crypto_mbedtls.c +++ b/components/wpa_supplicant/esp_supplicant/src/crypto/crypto_mbedtls.c @@ -36,104 +36,88 @@ #include "mbedtls/esp_config.h" #include "mbedtls/sha1.h" +#include "psa/crypto.h" +#include "mbedtls/psa_util.h" + #ifdef CONFIG_FAST_PBKDF2 #include "fastpbkdf2.h" #include "fastpsk.h" #endif -static int digest_vector(mbedtls_md_type_t md_type, size_t num_elem, +struct crypto_hash { + union { + psa_hash_operation_t *hash_operation; + psa_mac_operation_t *mac_operation; + } u; + int is_mac; + psa_key_id_t key_id; +}; + + +static int digest_vector(psa_algorithm_t alg, size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac) { - size_t i; - const mbedtls_md_info_t *md_info; - mbedtls_md_context_t md_ctx; - int ret; - - mbedtls_md_init(&md_ctx); - - md_info = mbedtls_md_info_from_type(md_type); - if (!md_info) { - wpa_printf(MSG_ERROR, "mbedtls_md_info_from_type() failed"); + psa_status_t status = psa_crypto_init(); + if (status != PSA_SUCCESS) { return -1; } - ret = mbedtls_md_setup(&md_ctx, md_info, 0); - if (ret != 0) { - wpa_printf(MSG_ERROR, "mbedtls_md_setup() returned error"); - goto cleanup; + psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT; + + status = psa_hash_setup(&operation, alg); + if (status != PSA_SUCCESS) { + return -1; } - ret = mbedtls_md_starts(&md_ctx); - if (ret != 0) { - wpa_printf(MSG_ERROR, "mbedtls_md_starts returned error"); - goto cleanup; - } - - for (i = 0; i < num_elem; i++) { - ret = mbedtls_md_update(&md_ctx, addr[i], len[i]); - if (ret != 0) { - wpa_printf(MSG_ERROR, "mbedtls_md_update ret=%d", ret); - goto cleanup; + for (size_t i = 0; i < num_elem; i++) { + status = psa_hash_update(&operation, addr[i], len[i]); + if (status != PSA_SUCCESS) { + return -1; } } - ret = mbedtls_md_finish(&md_ctx, mac); -cleanup: - mbedtls_md_free(&md_ctx); + size_t mac_len; + status = psa_hash_finish(&operation, mac, PSA_HASH_LENGTH(alg), &mac_len); + if (status != PSA_SUCCESS) { + return -1; + } - return ret; + status = psa_hash_abort(&operation); + if (status != PSA_SUCCESS) { + return -1; + } + return 0; } int sha256_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac) { - return digest_vector(MBEDTLS_MD_SHA256, num_elem, addr, len, mac); + return digest_vector(PSA_ALG_SHA_256, num_elem, addr, len, mac); } int sha384_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac) { - return digest_vector(MBEDTLS_MD_SHA384, num_elem, addr, len, mac); + return digest_vector(PSA_ALG_SHA_384, num_elem, addr, len, mac); } int sha512_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac) { - return digest_vector(MBEDTLS_MD_SHA512, num_elem, addr, len, mac); + return digest_vector(PSA_ALG_SHA_512, num_elem, addr, len, mac); } #if CONFIG_MBEDTLS_SHA1_C || CONFIG_MBEDTLS_HARDWARE_SHA int sha1_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac) { -#if defined(MBEDTLS_SHA1_C) - return digest_vector(MBEDTLS_MD_SHA1, num_elem, addr, len, mac); -#elif defined(MBEDTLS_SHA1_ALT) - mbedtls_sha1_context ctx; - size_t i; - int ret; - - mbedtls_sha1_init(&ctx); - for (i = 0; i < num_elem; i++) { - ret = mbedtls_sha1_update(&ctx, addr[i], len[i]); - if (ret != 0) { - goto exit; - } - } - ret = mbedtls_sha1_finish(&ctx, mac); - -exit: - mbedtls_sha1_free(&ctx); - return ret; -#else - return -ENOTSUP; -#endif + return digest_vector(PSA_ALG_SHA_1, num_elem, addr, len, mac); } #endif int md5_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac) { - return digest_vector(MBEDTLS_MD_MD5, num_elem, addr, len, mac); + return digest_vector(PSA_ALG_MD5, num_elem, addr, len, mac); } #ifdef MBEDTLS_MD4_C @@ -146,203 +130,262 @@ int md4_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac) struct crypto_hash * crypto_hash_init(enum crypto_hash_alg alg, const u8 *key, size_t key_len) { - mbedtls_md_context_t *ctx = NULL; - mbedtls_md_type_t md_type; - const mbedtls_md_info_t *md_info; - int ret; - int is_hmac = 0; - - switch (alg) { - case CRYPTO_HASH_ALG_MD5: - case CRYPTO_HASH_ALG_HMAC_MD5: - md_type = MBEDTLS_MD_MD5; - break; - case CRYPTO_HASH_ALG_SHA1: - case CRYPTO_HASH_ALG_HMAC_SHA1: - md_type = MBEDTLS_MD_SHA1; - break; - case CRYPTO_HASH_ALG_SHA256: - case CRYPTO_HASH_ALG_HMAC_SHA256: - md_type = MBEDTLS_MD_SHA256; - break; - case CRYPTO_HASH_ALG_SHA384: - md_type = MBEDTLS_MD_SHA384; - break; - case CRYPTO_HASH_ALG_SHA512: - md_type = MBEDTLS_MD_SHA512; - break; - default: - return NULL; - } - - switch (alg) { - case CRYPTO_HASH_ALG_HMAC_MD5: - case CRYPTO_HASH_ALG_HMAC_SHA1: - case CRYPTO_HASH_ALG_HMAC_SHA256: - is_hmac = 1; - break; - default: - break; - } - ctx = os_zalloc(sizeof(*ctx)); + struct crypto_hash *ctx = os_zalloc(sizeof(struct crypto_hash)); if (ctx == NULL) { return NULL; } - mbedtls_md_init(ctx); - md_info = mbedtls_md_info_from_type(md_type); - if (!md_info) { - goto cleanup; - } - if (mbedtls_md_setup(ctx, md_info, is_hmac) != 0) { - goto cleanup; - } - if (is_hmac) { - ret = mbedtls_md_hmac_starts(ctx, key, key_len); - } else { - ret = mbedtls_md_starts(ctx); - } - if (ret < 0) { - goto cleanup; + psa_status_t status = psa_crypto_init(); + if (status != PSA_SUCCESS) { + os_free(ctx); + return NULL; } - return (struct crypto_hash *)ctx; -cleanup: - mbedtls_md_free(ctx); - os_free(ctx); - return NULL; + psa_algorithm_t psa_alg; + int is_hmac = 0; + + switch(alg) { + case CRYPTO_HASH_ALG_MD5: + case CRYPTO_HASH_ALG_HMAC_MD5: + psa_alg = PSA_ALG_MD5; + break; + case CRYPTO_HASH_ALG_SHA1: + case CRYPTO_HASH_ALG_HMAC_SHA1: + psa_alg = PSA_ALG_SHA_1; + break; + case CRYPTO_HASH_ALG_SHA256: + case CRYPTO_HASH_ALG_HMAC_SHA256: + psa_alg = PSA_ALG_SHA_256; + break; + case CRYPTO_HASH_ALG_SHA384: + psa_alg = PSA_ALG_SHA_384; + break; + case CRYPTO_HASH_ALG_SHA512: + psa_alg = PSA_ALG_SHA_512; + break; + default: + os_free(ctx); + return NULL; + } + + switch(alg) { + case CRYPTO_HASH_ALG_HMAC_MD5: + case CRYPTO_HASH_ALG_HMAC_SHA1: + case CRYPTO_HASH_ALG_HMAC_SHA256: + is_hmac = 1; + break; + default: + break; + } + + // If is_hmac is set, then it is HMAC mode + if (is_hmac) { + if (key == NULL || key_len == 0) { + os_free(ctx); + return NULL; + } + + psa_mac_operation_t *operation = os_zalloc(sizeof(psa_mac_operation_t)); + if (operation == NULL) { + os_free(ctx); + return NULL; + } + + psa_key_id_t key_id = 0; + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_SIGN_MESSAGE); + psa_set_key_algorithm(&attributes, PSA_ALG_HMAC(psa_alg)); + psa_set_key_type(&attributes, PSA_KEY_TYPE_HMAC); + psa_set_key_bits(&attributes, 8 * key_len); + + status = psa_import_key(&attributes, key, key_len, &key_id); + if (status != PSA_SUCCESS) { + os_free(operation); + os_free(ctx); + return NULL; + } + + status = psa_mac_sign_setup(operation, key_id, PSA_ALG_HMAC(psa_alg)); + if (status != PSA_SUCCESS) { + os_free(operation); + os_free(ctx); + return NULL; + } + ctx->is_mac = 1; + ctx->key_id = key_id; + ctx->u.mac_operation = operation; + } else { + psa_hash_operation_t *operation = os_zalloc(sizeof(psa_hash_operation_t)); + if (operation == NULL) { + os_free(ctx); + return NULL; + } + + status = psa_hash_setup(operation, psa_alg); + if (status != PSA_SUCCESS) { + os_free(operation); + os_free(ctx); + return NULL; + } + ctx->is_mac = 0; + ctx->key_id = 0; + ctx->u.hash_operation = operation; + } + + return ctx; } void crypto_hash_update(struct crypto_hash *crypto_ctx, const u8 *data, size_t len) { - int ret; - mbedtls_md_context_t *ctx = (mbedtls_md_context_t *)crypto_ctx; - - if (ctx == NULL) { + if (data == NULL || len == 0) { return; } - if (ctx->MBEDTLS_PRIVATE(hmac_ctx)) { - ret = mbedtls_md_hmac_update(ctx, data, len); + + psa_status_t status = psa_crypto_init(); + if (status != PSA_SUCCESS) { + return; + } + + if (crypto_ctx->is_mac) { + status = psa_mac_update(crypto_ctx->u.mac_operation, data, len); } else { - ret = mbedtls_md_update(ctx, data, len); + status = psa_hash_update(crypto_ctx->u.hash_operation, data, len); } - if (ret != 0) { - wpa_printf(MSG_ERROR, "%s: mbedtls_md_hmac_update failed", __func__); + + if (status != PSA_SUCCESS) { + wpa_printf(MSG_ERROR, "%s: psa_hash_update failed", __func__); } + } int crypto_hash_finish(struct crypto_hash *crypto_ctx, u8 *mac, size_t *len) { int ret = 0; - mbedtls_md_type_t md_type; - mbedtls_md_context_t *ctx = (mbedtls_md_context_t *)crypto_ctx; - if (ctx == NULL) { - return -2; + if (crypto_ctx == NULL) { + ret = -2; + goto err; } if (mac == NULL || len == NULL) { - goto err; - } - - md_type = mbedtls_md_get_type(mbedtls_md_info_from_ctx(ctx)); - switch (md_type) { - case MBEDTLS_MD_MD5: - if (*len < MD5_MAC_LEN) { - *len = MD5_MAC_LEN; - ret = -1; - goto err; - } - *len = MD5_MAC_LEN; - break; - case MBEDTLS_MD_SHA1: - if (*len < SHA1_MAC_LEN) { - *len = SHA1_MAC_LEN; - ret = -1; - goto err; - } - *len = SHA1_MAC_LEN; - break; - case MBEDTLS_MD_SHA256: - if (*len < SHA256_MAC_LEN) { - *len = SHA256_MAC_LEN; - ret = -1; - goto err; - } - *len = SHA256_MAC_LEN; - break; - case MBEDTLS_MD_SHA384: - if (*len < SHA384_MAC_LEN) { - *len = SHA384_MAC_LEN; - ret = -1; - goto err; - } - *len = SHA384_MAC_LEN; - break; - case MBEDTLS_MD_SHA512: - if (*len < SHA512_MAC_LEN) { - *len = SHA512_MAC_LEN; - ret = -1; - goto err; - } - *len = SHA512_MAC_LEN; - break; - default: - *len = 0; ret = -1; goto err; } - if (ctx->MBEDTLS_PRIVATE(hmac_ctx)) { - ret = mbedtls_md_hmac_finish(ctx, mac); - } else { - ret = mbedtls_md_finish(ctx, mac); + + psa_status_t status = psa_crypto_init(); + if (status != PSA_SUCCESS) { + ret = -1; + goto err; } -err: - mbedtls_md_free(ctx); - bin_clear_free(ctx, sizeof(*ctx)); + size_t mac_len = 0; + if (crypto_ctx->is_mac) { + status = psa_mac_sign_finish(crypto_ctx->u.mac_operation, mac, *len, &mac_len); + if (status != PSA_SUCCESS) { + ret = -1; + goto err; + } + } else { + status = psa_hash_finish(crypto_ctx->u.hash_operation, mac, *len, &mac_len); + if (status != PSA_SUCCESS) { + ret = -1; + goto err; + } + } + + *len = mac_len; + +err: + if (crypto_ctx->is_mac) { + psa_mac_abort(crypto_ctx->u.mac_operation); + } else { + psa_hash_abort(crypto_ctx->u.hash_operation); + } + + if (crypto_ctx->key_id) { + psa_destroy_key(crypto_ctx->key_id); + } + if (crypto_ctx->is_mac) { + os_free(crypto_ctx->u.mac_operation); + } else { + os_free(crypto_ctx->u.hash_operation); + } + os_free(crypto_ctx); return ret; } -static int hmac_vector(mbedtls_md_type_t md_type, +static int hmac_vector(psa_algorithm_t alg, const u8 *key, size_t key_len, size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac) { - size_t i; - const mbedtls_md_info_t *md_info; - mbedtls_md_context_t md_ctx; - int ret; - - mbedtls_md_init(&md_ctx); - - md_info = mbedtls_md_info_from_type(md_type); - if (!md_info) { - return -1; + int ret = 0; + psa_key_id_t key_id = 0; + if (key == NULL || key_len == 0 || num_elem == 0 || addr == NULL || len == NULL || mac == NULL) { + ret = -1; + goto err; } - ret = mbedtls_md_setup(&md_ctx, md_info, 1); - if (ret != 0) { - return (ret); + psa_status_t status = psa_crypto_init(); + if (status != PSA_SUCCESS) { + ret = -1; + goto err; } - ret = mbedtls_md_hmac_starts(&md_ctx, key, key_len); - if (ret != 0) { - return (ret); + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_SIGN_MESSAGE); + psa_set_key_algorithm(&attributes, PSA_ALG_HMAC(alg)); + psa_set_key_type(&attributes, PSA_KEY_TYPE_HMAC); + psa_set_key_bits(&attributes, 8 * key_len); + + status = psa_import_key(&attributes, key, key_len, &key_id); + if (status != PSA_SUCCESS) { + ret = -1; + goto err; } - for (i = 0; i < num_elem; i++) { - ret = mbedtls_md_hmac_update(&md_ctx, addr[i], len[i]); - if (ret != 0) { - return (ret); + psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT; + status = psa_mac_sign_setup(&operation, key_id, PSA_ALG_HMAC(alg)); + if (status != PSA_SUCCESS) { + ret = -1; + goto err; + } + + for (size_t i = 0; i < num_elem; i++) { + status = psa_mac_update(&operation, addr[i], len[i]); + if (status != PSA_SUCCESS) { + ret = -1; + goto err; } - } - ret = mbedtls_md_hmac_finish(&md_ctx, mac); + size_t mac_len; + status = psa_mac_sign_finish(&operation, mac, PSA_MAC_LENGTH(PSA_KEY_TYPE_HMAC, 8 * key_len, PSA_ALG_HMAC(alg)), &mac_len); + if (status != PSA_SUCCESS) { + ret = -1; + goto err; + } - mbedtls_md_free(&md_ctx); + status = psa_mac_abort(&operation); + if (status != PSA_SUCCESS) { + ret = -1; + goto err; + } + + status = psa_destroy_key(key_id); + if (status != PSA_SUCCESS) { + ret = -1; + goto err; + } + +err: + + if (ret != 0) { + if (key_id) { + psa_destroy_key(key_id); + } + } return ret; } @@ -350,7 +393,7 @@ static int hmac_vector(mbedtls_md_type_t md_type, int hmac_sha384_vector(const u8 *key, size_t key_len, size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac) { - return hmac_vector(MBEDTLS_MD_SHA384, key, key_len, num_elem, addr, + return hmac_vector(PSA_ALG_SHA_384, key, key_len, num_elem, addr, len, mac); } @@ -363,7 +406,7 @@ int hmac_sha384(const u8 *key, size_t key_len, const u8 *data, int hmac_sha256_vector(const u8 *key, size_t key_len, size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac) { - return hmac_vector(MBEDTLS_MD_SHA256, key, key_len, num_elem, addr, + return hmac_vector(PSA_ALG_SHA_256, key, key_len, num_elem, addr, len, mac); } @@ -376,7 +419,7 @@ int hmac_sha256(const u8 *key, size_t key_len, const u8 *data, int hmac_md5_vector(const u8 *key, size_t key_len, size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac) { - return hmac_vector(MBEDTLS_MD_MD5, key, key_len, + return hmac_vector(PSA_ALG_MD5, key, key_len, num_elem, addr, len, mac); } @@ -390,7 +433,7 @@ int hmac_md5(const u8 *key, size_t key_len, const u8 *data, size_t data_len, int hmac_sha1_vector(const u8 *key, size_t key_len, size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac) { - return hmac_vector(MBEDTLS_MD_SHA1, key, key_len, num_elem, addr, + return hmac_vector(PSA_ALG_SHA_1, key, key_len, num_elem, addr, len, mac); } @@ -403,38 +446,94 @@ int hmac_sha1(const u8 *key, size_t key_len, const u8 *data, size_t data_len, static void *aes_crypt_init(int mode, const u8 *key, size_t len) { - int ret = -1; - mbedtls_aes_context *aes = os_malloc(sizeof(*aes)); - if (!aes) { + psa_status_t status; + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_key_id_t *key_id = os_malloc(sizeof(psa_key_id_t)); + + status = psa_crypto_init(); + if (status != PSA_SUCCESS) { + wpa_printf(MSG_ERROR, "%s: psa_crypto_init failed", __func__); return NULL; } - mbedtls_aes_init(aes); if (mode == MBEDTLS_AES_ENCRYPT) { - ret = mbedtls_aes_setkey_enc(aes, key, len * 8); + psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_ENCRYPT); } else if (mode == MBEDTLS_AES_DECRYPT) { - ret = mbedtls_aes_setkey_dec(aes, key, len * 8); + psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_DECRYPT); } - if (ret < 0) { - mbedtls_aes_free(aes); - os_free(aes); - wpa_printf(MSG_ERROR, "%s: mbedtls_aes_setkey_enc/mbedtls_aes_setkey_dec failed", __func__); + + psa_set_key_algorithm(&attributes, PSA_ALG_ECB_NO_PADDING); + psa_set_key_type(&attributes, PSA_KEY_TYPE_AES); + psa_set_key_bits(&attributes, len * 8); + + status = psa_import_key(&attributes, key, len, key_id); + if (status != PSA_SUCCESS) { + wpa_printf(MSG_ERROR, "%s: psa_import_key failed", __func__); return NULL; } - return (void *) aes; + psa_reset_key_attributes(&attributes); + + return (void *) key_id; } static int aes_crypt(void *ctx, int mode, const u8 *in, u8 *out) { - return mbedtls_aes_crypt_ecb((mbedtls_aes_context *)ctx, - mode, in, out); + psa_status_t status; + psa_key_id_t *key_id = (psa_key_id_t *) ctx; + psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT; + size_t output_len; + + status = psa_crypto_init(); + if (status != PSA_SUCCESS) { + wpa_printf(MSG_ERROR, "%s: psa_crypto_init failed", __func__); + printf("%s: psa_crypto_init failed\n", __func__); + return -1; + } + + if (mode == MBEDTLS_AES_ENCRYPT) { + status = psa_cipher_encrypt_setup(&operation, *key_id, PSA_ALG_ECB_NO_PADDING); + } else if (mode == MBEDTLS_AES_DECRYPT) { + status = psa_cipher_decrypt_setup(&operation, *key_id, PSA_ALG_ECB_NO_PADDING); + } else { + wpa_printf(MSG_ERROR, "%s: invalid mode", __func__); + printf("%s: invalid mode\n", __func__); + return -1; + } + if (status != PSA_SUCCESS) { + wpa_printf(MSG_ERROR, "%s: psa_cipher_encrypt_setup failed", __func__); + printf("%s: psa_cipher_encrypt_setup failed, status: %d\n", __func__, status); + return -1; + } + + status = psa_cipher_update(&operation, in, 16, out, 16, &output_len); + if (status != PSA_SUCCESS) { + wpa_printf(MSG_ERROR, "%s: psa_cipher_update failed", __func__); + printf("%s: psa_cipher_update failed\n", __func__); + return -1; + } + + status = psa_cipher_finish(&operation, out + output_len, 16 - output_len, &output_len); + if (status != PSA_SUCCESS) { + wpa_printf(MSG_ERROR, "%s: psa_cipher_finish failed", __func__); + printf("%s: psa_cipher_finish failed\n", __func__); + return -1; + } + + psa_cipher_abort(&operation); + + return 0; } static void aes_crypt_deinit(void *ctx) { - mbedtls_aes_free((mbedtls_aes_context *)ctx); + psa_key_id_t *key_id = (psa_key_id_t *) ctx; + psa_status_t status = psa_destroy_key(*key_id); + if (status != PSA_SUCCESS) { + printf("%s: psa_destroy_key failed\n", __func__); + } os_free(ctx); + ctx = NULL; } void *aes_encrypt_init(const u8 *key, size_t len) @@ -470,114 +569,159 @@ void aes_decrypt_deinit(void *ctx) #ifdef CONFIG_MBEDTLS_CIPHER_MODE_CBC int aes_128_cbc_encrypt(const u8 *key, const u8 *iv, u8 *data, size_t data_len) { - int ret = 0; - mbedtls_aes_context ctx; - u8 cbc[MBEDTLS_AES_BLOCK_SIZE]; + psa_status_t status; + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_key_id_t key_id; - mbedtls_aes_init(&ctx); - - ret = mbedtls_aes_setkey_enc(&ctx, key, 128); - if (ret < 0) { - mbedtls_aes_free(&ctx); - return ret; + status = psa_crypto_init(); + if (status != PSA_SUCCESS) { + wpa_printf(MSG_ERROR, "%s: psa_crypto_init failed", __func__); + return -1; } - os_memcpy(cbc, iv, MBEDTLS_AES_BLOCK_SIZE); - ret = mbedtls_aes_crypt_cbc(&ctx, MBEDTLS_AES_ENCRYPT, - data_len, cbc, data, data); - mbedtls_aes_free(&ctx); + psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_ENCRYPT); + psa_set_key_algorithm(&attributes, PSA_ALG_CBC_NO_PADDING); + psa_set_key_type(&attributes, PSA_KEY_TYPE_AES); + psa_set_key_bits(&attributes, 128); - return ret; + status = psa_import_key(&attributes, key, 16, &key_id); + if (status != PSA_SUCCESS) { + wpa_printf(MSG_ERROR, "%s: psa_import_key failed", __func__); + return -1; + } + + psa_reset_key_attributes(&attributes); + + psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT; + + status = psa_cipher_encrypt_setup(&operation, key_id, PSA_ALG_CBC_NO_PADDING); + if (status != PSA_SUCCESS) { + wpa_printf(MSG_ERROR, "%s: psa_cipher_encrypt_setup failed", __func__); + return -1; + } + + status = psa_cipher_set_iv(&operation, iv, 16); + if (status != PSA_SUCCESS) { + wpa_printf(MSG_ERROR, "%s: psa_cipher_set_iv failed", __func__); + return -1; + } + + size_t output_length = 0; + status = psa_cipher_update(&operation, data, data_len, data, data_len, &output_length); + if (status != PSA_SUCCESS) { + wpa_printf(MSG_ERROR, "%s: psa_cipher_update failed", __func__); + return -1; + } + + status = psa_cipher_finish(&operation, data + output_length, data_len - output_length, &output_length); + if (status != PSA_SUCCESS) { + wpa_printf(MSG_ERROR, "%s: psa_cipher_finish failed", __func__); + return -1; + } + + psa_cipher_abort(&operation); + + psa_destroy_key(key_id); + + return 0; } int aes_128_cbc_decrypt(const u8 *key, const u8 *iv, u8 *data, size_t data_len) { - int ret = 0; - mbedtls_aes_context ctx; - u8 cbc[MBEDTLS_AES_BLOCK_SIZE]; + psa_status_t status; + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_key_id_t key_id; - mbedtls_aes_init(&ctx); - - ret = mbedtls_aes_setkey_dec(&ctx, key, 128); - if (ret < 0) { - mbedtls_aes_free(&ctx); - return ret; + status = psa_crypto_init(); + if (status != PSA_SUCCESS) { + wpa_printf(MSG_ERROR, "%s: psa_crypto_init failed", __func__); + return -1; } - os_memcpy(cbc, iv, MBEDTLS_AES_BLOCK_SIZE); - ret = mbedtls_aes_crypt_cbc(&ctx, MBEDTLS_AES_DECRYPT, - data_len, cbc, data, data); - mbedtls_aes_free(&ctx); + psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_DECRYPT); + psa_set_key_algorithm(&attributes, PSA_ALG_CBC_NO_PADDING); + psa_set_key_type(&attributes, PSA_KEY_TYPE_AES); + psa_set_key_bits(&attributes, 128); - return ret; + status = psa_import_key(&attributes, key, 16, &key_id); + if (status != PSA_SUCCESS) { + wpa_printf(MSG_ERROR, "%s: psa_import_key failed", __func__); + return -1; + } + + psa_reset_key_attributes(&attributes); + + psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT; + + status = psa_cipher_decrypt_setup(&operation, key_id, PSA_ALG_CBC_NO_PADDING); + if (status != PSA_SUCCESS) { + wpa_printf(MSG_ERROR, "%s: psa_cipher_decrypt_setup failed", __func__); + return -1; + } + + status = psa_cipher_set_iv(&operation, iv, 16); + if (status != PSA_SUCCESS) { + wpa_printf(MSG_ERROR, "%s: psa_cipher_set_iv failed", __func__); + return -1; + } + + size_t output_length = 0; + + status = psa_cipher_update(&operation, data, data_len, data, data_len, &output_length); + if (status != PSA_SUCCESS) { + wpa_printf(MSG_ERROR, "%s: psa_cipher_update failed", __func__); + return -1; + } + + status = psa_cipher_finish(&operation, data + output_length, data_len - output_length, &output_length); + if (status != PSA_SUCCESS) { + wpa_printf(MSG_ERROR, "%s: psa_cipher_finish failed", __func__); + return -1; + } + + psa_cipher_abort(&operation); + + psa_destroy_key(key_id); + + return 0; } #endif /* CONFIG_MBEDTLS_CIPHER_MODE_CBC */ #ifdef CONFIG_TLS_INTERNAL_CLIENT struct crypto_cipher { - mbedtls_cipher_context_t ctx_enc; - mbedtls_cipher_context_t ctx_dec; + void *ctx_enc; + void *ctx_dec; + psa_key_id_t key_id; }; -static int crypto_init_cipher_ctx(mbedtls_cipher_context_t *ctx, - const mbedtls_cipher_info_t *cipher_info, - const u8 *iv, const u8 *key, size_t key_len, - mbedtls_operation_t operation) +static uint32_t alg_to_psa_cipher(enum crypto_cipher_alg alg) { - mbedtls_cipher_init(ctx); - int ret; - - ret = mbedtls_cipher_setup(ctx, cipher_info); - if (ret != 0) { - return -1; - } - - ret = mbedtls_cipher_setkey(ctx, key, key_len * 8, operation); - if (ret != 0) { - wpa_printf(MSG_ERROR, "mbedtls_cipher_setkey returned error=%d", ret); - return -1; - } - ret = mbedtls_cipher_set_iv(ctx, iv, cipher_info->MBEDTLS_PRIVATE(iv_size) << MBEDTLS_IV_SIZE_SHIFT); - if (ret != 0) { - wpa_printf(MSG_ERROR, "mbedtls_cipher_set_iv returned error=%d", ret); - return -1; - } - ret = mbedtls_cipher_reset(ctx); - if (ret != 0) { - wpa_printf(MSG_ERROR, "mbedtls_cipher_reset() returned error=%d", ret); - return -1; + switch (alg) { + case CRYPTO_CIPHER_ALG_AES: + case CRYPTO_CIPHER_ALG_3DES: + case CRYPTO_CIPHER_ALG_DES: + return PSA_ALG_CBC_NO_PADDING; + default: + break; } return 0; } -static mbedtls_cipher_type_t alg_to_mbedtls_cipher(enum crypto_cipher_alg alg, - size_t key_len) +static uint32_t alg_to_psa_key_type(enum crypto_cipher_alg alg) { switch (alg) { case CRYPTO_CIPHER_ALG_AES: - if (key_len == 16) { - return MBEDTLS_CIPHER_AES_128_CBC; - } - if (key_len == 24) { - return MBEDTLS_CIPHER_AES_192_CBC; - } - if (key_len == 32) { - return MBEDTLS_CIPHER_AES_256_CBC; - } - break; -#ifdef MBEDTLS_DES_C + return PSA_KEY_TYPE_AES; case CRYPTO_CIPHER_ALG_3DES: - return MBEDTLS_CIPHER_DES_EDE3_CBC; case CRYPTO_CIPHER_ALG_DES: - return MBEDTLS_CIPHER_DES_CBC; -#endif + return PSA_KEY_TYPE_DES; default: break; } - return MBEDTLS_CIPHER_NONE; + return 0; } struct crypto_cipher *crypto_cipher_init(enum crypto_cipher_alg alg, @@ -585,44 +729,75 @@ struct crypto_cipher *crypto_cipher_init(enum crypto_cipher_alg alg, size_t key_len) { struct crypto_cipher *ctx; - mbedtls_cipher_type_t cipher_type; - const mbedtls_cipher_info_t *cipher_info; ctx = (struct crypto_cipher *)os_zalloc(sizeof(*ctx)); if (!ctx) { return NULL; } - cipher_type = alg_to_mbedtls_cipher(alg, key_len); - if (cipher_type == MBEDTLS_CIPHER_NONE) { - goto cleanup; + psa_status_t status; + psa_key_attributes attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_key_id_t key_id; + + status = psa_crypto_init(); + if (status != PSA_SUCCESS) { + wpa_printf(MSG_ERROR, "%s: psa_crypto_init failed", __func__); + return NULL; } - cipher_info = mbedtls_cipher_info_from_type(cipher_type); - if (cipher_info == NULL) { - goto cleanup; + psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT); + uint32_t psa_alg = alg_to_psa_cipher(alg); + if (psa_alg == 0) { + wpa_printf(MSG_ERROR, "%s: invalid cipher algorithm", __func__); + return NULL; + } + psa_set_key_algorithm(&attributes, psa_alg); + + uint32_t psa_key_type = alg_to_psa_key_type(alg); + if (psa_key_type == 0) { + wpa_printf(MSG_ERROR, "%s: invalid key type", __func__); + return NULL; + } + psa_set_key_type(&attributes, psa_key_type); + psa_set_key_bits(&attributes, key_len * 8); + + status = psa_import_key(&attributes, key, key_len, &key_id); + if (status != PSA_SUCCESS) { + wpa_printf(MSG_ERROR, "%s: psa_import_key failed", __func__); + return NULL; } - /* Init both ctx encryption/decryption */ - if (crypto_init_cipher_ctx(&ctx->ctx_enc, cipher_info, iv, key, - key_len, MBEDTLS_ENCRYPT) < 0) { - goto cleanup; + psa_reset_key_attributes(&attributes); + + psa_cipher_operation_t *enc_operation = os_zalloc(sizeof(psa_cipher_operation_t)); + if (!enc_operation) { + wpa_printf(MSG_ERROR, "%s: os_zalloc failed", __func__); + return NULL; } - if (crypto_init_cipher_ctx(&ctx->ctx_dec, cipher_info, iv, key, - key_len, MBEDTLS_DECRYPT) < 0) { - goto cleanup; + ctx->ctx_enc = (void *)enc_operation; + + status = psa_cipher_encrypt_setup(enc_operation, key_id, psa_alg); + if (status != PSA_SUCCESS) { + wpa_printf(MSG_ERROR, "%s: psa_cipher_encrypt_setup failed", __func__); + return NULL; } -#if defined(CONFIG_MBEDTLS_CIPHER_MODE_WITH_PADDING) - if (mbedtls_cipher_set_padding_mode(&ctx->ctx_enc, MBEDTLS_PADDING_NONE) < 0) { - goto cleanup; + + status = psa_cipher_set_iv(enc_operation, iv, 16); + if (status != PSA_SUCCESS) { + wpa_printf(MSG_ERROR, "%s: psa_cipher_set_iv failed", __func__); + return NULL; } - if (mbedtls_cipher_set_padding_mode(&ctx->ctx_dec, MBEDTLS_PADDING_NONE) < 0) { - goto cleanup; + + psa_cipher_operation_t *dec_operation = os_zalloc(sizeof(psa_cipher_operation_t)); + if (!dec_operation) { + wpa_printf(MSG_ERROR, "%s: os_zalloc failed", __func__); + return NULL; } #endif /* CONFIG_MBEDTLS_CIPHER_MODE_WITH_PADDING */ return ctx; + cleanup: os_free(ctx); return NULL; @@ -631,16 +806,20 @@ cleanup: int crypto_cipher_encrypt(struct crypto_cipher *ctx, const u8 *plain, u8 *crypt, size_t len) { - int ret; - size_t olen = 0; + psa_status_t status; + psa_cipher_operation_t *operation = (psa_cipher_operation_t *)ctx->ctx_enc; - ret = mbedtls_cipher_update(&ctx->ctx_enc, plain, len, crypt, &olen); - if (ret != 0) { + size_t output_length = 0; + + status = psa_cipher_update(operation, plain, len, crypt, len, &output_length); + if (status != PSA_SUCCESS) { + wpa_printf(MSG_ERROR, "%s: psa_cipher_update failed", __func__); return -1; } - ret = mbedtls_cipher_finish(&ctx->ctx_enc, crypt + olen, &olen); - if (ret != 0) { + status = psa_cipher_finish(operation, crypt + output_length, len - output_length, &output_length); + if (status != PSA_SUCCESS) { + wpa_printf(MSG_ERROR, "%s: psa_cipher_finish failed", __func__); return -1; } @@ -650,16 +829,20 @@ int crypto_cipher_encrypt(struct crypto_cipher *ctx, const u8 *plain, int crypto_cipher_decrypt(struct crypto_cipher *ctx, const u8 *crypt, u8 *plain, size_t len) { - int ret; - size_t olen = 0; + psa_status_t status; + psa_cipher_operation_t *operation = (psa_cipher_operation_t *)ctx->ctx_dec; - ret = mbedtls_cipher_update(&ctx->ctx_dec, crypt, len, plain, &olen); - if (ret != 0) { + size_t output_length = 0; + + status = psa_cipher_update(operation, crypt, len, plain, len, &output_length); + if (status != PSA_SUCCESS) { + wpa_printf(MSG_ERROR, "%s: psa_cipher_update failed", __func__); return -1; } - ret = mbedtls_cipher_finish(&ctx->ctx_dec, plain + olen, &olen); - if (ret != 0) { + status = psa_cipher_finish(operation, plain + output_length, len - output_length, &output_length); + if (status != PSA_SUCCESS) { + wpa_printf(MSG_ERROR, "%s: psa_cipher_finish failed", __func__); return -1; } @@ -668,8 +851,13 @@ int crypto_cipher_decrypt(struct crypto_cipher *ctx, const u8 *crypt, void crypto_cipher_deinit(struct crypto_cipher *ctx) { - mbedtls_cipher_free(&ctx->ctx_enc); - mbedtls_cipher_free(&ctx->ctx_dec); + psa_status_t status; + psa_cipher_abort((psa_cipher_operation_t *)ctx->ctx_enc); + psa_cipher_abort((psa_cipher_operation_t *)ctx->ctx_dec); + status = psa_destroy_key(ctx->key_id); + if (status != PSA_SUCCESS) { + wpa_printf(MSG_ERROR, "%s: psa_destroy_key failed", __func__); + } os_free(ctx); } #endif @@ -678,21 +866,62 @@ void crypto_cipher_deinit(struct crypto_cipher *ctx) int aes_ctr_encrypt(const u8 *key, size_t key_len, const u8 *nonce, u8 *data, size_t data_len) { - int ret; - mbedtls_aes_context ctx; - uint8_t stream_block[MBEDTLS_AES_BLOCK_SIZE]; - size_t offset = 0; + psa_status_t status; + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_key_id_t key_id; - mbedtls_aes_init(&ctx); - ret = mbedtls_aes_setkey_enc(&ctx, key, key_len * 8); - if (ret < 0) { - goto cleanup; + status = psa_crypto_init(); + if (status != PSA_SUCCESS) { + wpa_printf(MSG_ERROR, "%s: psa_crypto_init failed", __func__); + return -1; } - ret = mbedtls_aes_crypt_ctr(&ctx, data_len, &offset, (u8 *)nonce, - stream_block, data, data); -cleanup: - mbedtls_aes_free(&ctx); - return ret; + + psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_ENCRYPT); + psa_set_key_algorithm(&attributes, PSA_ALG_CTR); + psa_set_key_type(&attributes, PSA_KEY_TYPE_AES); + psa_set_key_bits(&attributes, key_len * 8); + + status = psa_import_key(&attributes, key, key_len, &key_id); + if (status != PSA_SUCCESS) { + wpa_printf(MSG_ERROR, "%s: psa_import_key failed", __func__); + return -1; + } + + psa_reset_key_attributes(&attributes); + + psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT; + + status = psa_cipher_encrypt_setup(&operation, key_id, PSA_ALG_CTR); + if (status != PSA_SUCCESS) { + wpa_printf(MSG_ERROR, "%s: psa_cipher_encrypt_setup failed", __func__); + return -1; + } + + status = psa_cipher_set_iv(&operation, nonce, 16); + if (status != PSA_SUCCESS) { + wpa_printf(MSG_ERROR, "%s: psa_cipher_set_iv failed", __func__); + return -1; + } + + size_t output_length = 0; + + status = psa_cipher_update(&operation, data, data_len, data, data_len, &output_length); + if (status != PSA_SUCCESS) { + wpa_printf(MSG_ERROR, "%s: psa_cipher_update failed", __func__); + return -1; + } + + status = psa_cipher_finish(&operation, data + output_length, data_len - output_length, &output_length); + if (status != PSA_SUCCESS) { + wpa_printf(MSG_ERROR, "%s: psa_cipher_finish failed", __func__); + return -1; + } + + psa_cipher_abort(&operation); + + psa_destroy_key(key_id); + + return 0; } #endif /* CONFIG_MBEDTLS_CIPHER_MODE_CTR */ @@ -805,29 +1034,54 @@ int pbkdf2_sha1(const char *passphrase, const u8 *ssid, size_t ssid_len, #ifdef MBEDTLS_DES_C int des_encrypt(const u8 *clear, const u8 *key, u8 *cypher) { - int ret; - mbedtls_des_context des; - u8 pkey[8], next, tmp; - int i; + psa_status_t status; + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_key_id_t key_id; - /* Add parity bits to the key */ - next = 0; - for (i = 0; i < 7; i++) { - tmp = key[i]; - pkey[i] = (tmp >> i) | next | 1; - next = tmp << (7 - i); + status = psa_crypto_init(); + if (status != PSA_SUCCESS) { + wpa_printf(MSG_ERROR, "%s: psa_crypto_init failed", __func__); + return -1; } - pkey[i] = next | 1; - mbedtls_des_init(&des); - ret = mbedtls_des_setkey_enc(&des, pkey); - if (ret < 0) { - return ret; + psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_ENCRYPT); + psa_set_key_algorithm(&attributes, PSA_ALG_ECB_NO_PADDING); + psa_set_key_type(&attributes, PSA_KEY_TYPE_DES); + psa_set_key_bits(&attributes, 64); + + status = psa_import_key(&attributes, key, 8, &key_id); + if (status != PSA_SUCCESS) { + wpa_printf(MSG_ERROR, "%s: psa_import_key failed", __func__); + return -1; } - ret = mbedtls_des_crypt_ecb(&des, clear, cypher); - mbedtls_des_free(&des); - return ret; + psa_reset_key_attributes(&attributes); + + psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT; + + status = psa_cipher_encrypt_setup(&operation, key_id, PSA_ALG_ECB_NO_PADDING); + if (status != PSA_SUCCESS) { + wpa_printf(MSG_ERROR, "%s: psa_cipher_encrypt_setup failed", __func__); + return -1; + } + + size_t output_length = 0; + + status = psa_cipher_update(&operation, clear, 8, cypher, 8, &output_length); + if (status != PSA_SUCCESS) { + wpa_printf(MSG_ERROR, "%s: psa_cipher_update failed", __func__); + return -1; + } + + status = psa_cipher_finish(&operation, cypher + output_length, 8 - output_length, &output_length); + if (status != PSA_SUCCESS) { + wpa_printf(MSG_ERROR, "%s: psa_cipher_finish failed", __func__); + return -1; + } + + psa_cipher_abort(&operation); + + psa_destroy_key(key_id); } #endif @@ -837,25 +1091,75 @@ int aes_ccm_ae(const u8 *key, size_t key_len, const u8 *nonce, size_t M, const u8 *plain, size_t plain_len, const u8 *aad, size_t aad_len, u8 *crypt, u8 *auth) { - int ret; - mbedtls_ccm_context ccm; + psa_status_t status; + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_key_id_t key_id; - mbedtls_ccm_init(&ccm); - - ret = mbedtls_ccm_setkey(&ccm, MBEDTLS_CIPHER_ID_AES, - key, key_len * 8); - if (ret < 0) { - wpa_printf(MSG_ERROR, "mbedtls_ccm_setkey failed"); - goto cleanup; + status = psa_crypto_init(); + if (status != PSA_SUCCESS) { + wpa_printf(MSG_ERROR, "%s: psa_crypto_init failed", __func__); + return -1; } - ret = mbedtls_ccm_encrypt_and_tag(&ccm, plain_len, nonce, 13, aad, - aad_len, plain, crypt, auth, M); + psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_ENCRYPT); + psa_set_key_algorithm(&attributes, PSA_ALG_CCM); + psa_set_key_type(&attributes, PSA_KEY_TYPE_AES); + psa_set_key_bits(&attributes, key_len * 8); -cleanup: - mbedtls_ccm_free(&ccm); + status = psa_import_key(&attributes, key, key_len, &key_id); + if (status != PSA_SUCCESS) { + wpa_printf(MSG_ERROR, "%s: psa_import_key failed", __func__); + return -1; + } - return ret; + psa_reset_key_attributes(&attributes); + + psa_aead_operation_t operation = PSA_AEAD_OPERATION_INIT; + + status = psa_aead_encrypt_setup(&operation, key_id, PSA_ALG_CCM); + if (status != PSA_SUCCESS) { + wpa_printf(MSG_ERROR, "%s: psa_aead_encrypt_setup failed", __func__); + return -1; + } + + status = psa_aead_set_nonce(&operation, nonce, 13); + if (status != PSA_SUCCESS) { + wpa_printf(MSG_ERROR, "%s: psa_aead_set_nonce failed", __func__); + return -1; + } + + status = psa_aead_set_lengths(&operation, aad_len, plain_len); + if (status != PSA_SUCCESS) { + wpa_printf(MSG_ERROR, "%s: psa_aead_set_lengths failed", __func__); + return -1; + } + + size_t output_length = 0; + size_t tag_len = 0; + + status = psa_aead_update_ad(&operation, aad, aad_len); + if (status != PSA_SUCCESS) { + wpa_printf(MSG_ERROR, "%s: psa_aead_update_ad failed", __func__); + return -1; + } + + status = psa_aead_update(&operation, plain, plain_len, crypt, plain_len, &output_length); + if (status != PSA_SUCCESS) { + wpa_printf(MSG_ERROR, "%s: psa_aead_update failed", __func__); + return -1; + } + + status = psa_aead_finish(&operation, crypt + output_length, 16 - output_length, &output_length, auth, M, &tag_len); + if (status != PSA_SUCCESS) { + wpa_printf(MSG_ERROR, "%s: psa_aead_finish failed, status: %d\n", __func__, status); + return -1; + } + + psa_aead_abort(&operation); + + psa_destroy_key(key_id); + + return 0; } int aes_ccm_ad(const u8 *key, size_t key_len, const u8 *nonce, @@ -863,25 +1167,75 @@ int aes_ccm_ad(const u8 *key, size_t key_len, const u8 *nonce, const u8 *aad, size_t aad_len, const u8 *auth, u8 *plain) { - int ret; - mbedtls_ccm_context ccm; + psa_status_t status; + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_key_id_t key_id; - mbedtls_ccm_init(&ccm); - - ret = mbedtls_ccm_setkey(&ccm, MBEDTLS_CIPHER_ID_AES, - key, key_len * 8); - if (ret < 0) { - goto cleanup;; + status = psa_crypto_init(); + if (status != PSA_SUCCESS) { + wpa_printf(MSG_ERROR, "%s: psa_crypto_init failed", __func__); + return -1; } - ret = mbedtls_ccm_star_auth_decrypt(&ccm, crypt_len, - nonce, 13, aad, aad_len, - crypt, plain, auth, M); + psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_DECRYPT); + psa_set_key_algorithm(&attributes, PSA_ALG_CCM); + psa_set_key_type(&attributes, PSA_KEY_TYPE_AES); + psa_set_key_bits(&attributes, key_len * 8); -cleanup: - mbedtls_ccm_free(&ccm); + status = psa_import_key(&attributes, key, key_len, &key_id); + if (status != PSA_SUCCESS) { + wpa_printf(MSG_ERROR, "%s: psa_import_key failed", __func__); + return -1; + } - return ret; + psa_reset_key_attributes(&attributes); + + psa_aead_operation_t operation = PSA_AEAD_OPERATION_INIT; + + status = psa_aead_decrypt_setup(&operation, key_id, PSA_ALG_CCM); + if (status != PSA_SUCCESS) { + wpa_printf(MSG_ERROR, "%s: psa_aead_decrypt_setup failed", __func__); + return -1; + } + + status = psa_aead_set_nonce(&operation, nonce, 13); + if (status != PSA_SUCCESS) { + wpa_printf(MSG_ERROR, "%s: psa_aead_set_nonce failed", __func__); + return -1; + } + + status = psa_aead_set_lengths(&operation, aad_len, crypt_len); + if (status != PSA_SUCCESS) { + wpa_printf(MSG_ERROR, "%s: psa_aead_set_lengths failed", __func__); + return -1; + } + + size_t output_length = 0; + size_t tag_len = 0; + + status = psa_aead_update_ad(&operation, aad, aad_len); + if (status != PSA_SUCCESS) { + wpa_printf(MSG_ERROR, "%s: psa_aead_update_ad failed", __func__); + return -1; + } + + status = psa_aead_update(&operation, crypt, crypt_len, plain, crypt_len, &output_length); + if (status != PSA_SUCCESS) { + wpa_printf(MSG_ERROR, "%s: psa_aead_update failed", __func__); + return -1; + } + + status = psa_aead_verify(&operation, plain + output_length, 16 - output_length, &output_length, auth, M); + if (status != PSA_SUCCESS) { + wpa_printf(MSG_ERROR, "%s: psa_aead_verify failed", __func__); + return -1; + } + + psa_aead_abort(&operation); + + psa_destroy_key(key_id); + + return 0; } #endif @@ -889,59 +1243,63 @@ cleanup: int omac1_aes_vector(const u8 *key, size_t key_len, size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac) { - const mbedtls_cipher_info_t *cipher_info; - int i, ret = 0; - mbedtls_cipher_type_t cipher_type; - mbedtls_cipher_context_t ctx; - - switch (key_len) { - case 16: - cipher_type = MBEDTLS_CIPHER_AES_128_ECB; - break; - case 24: - cipher_type = MBEDTLS_CIPHER_AES_192_ECB; - break; - case 32: - cipher_type = MBEDTLS_CIPHER_AES_256_ECB; - break; - default: - cipher_type = MBEDTLS_CIPHER_NONE; - break; - } - cipher_info = mbedtls_cipher_info_from_type(cipher_type); - if (cipher_info == NULL) { - /* Failing at this point must be due to a build issue */ - ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE; - goto cleanup; - } - - if (key == NULL || mac == NULL) { + if (key == NULL || mac == NULL) { return -1; } - mbedtls_cipher_init(&ctx); + psa_status_t status; + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_key_id_t key_id; - ret = mbedtls_cipher_setup(&ctx, cipher_info); - if (ret != 0) { - goto cleanup; + status = psa_crypto_init(); + if (status != PSA_SUCCESS) { + wpa_printf(MSG_ERROR, "%s: psa_crypto_init failed", __func__); + return -1; } - ret = mbedtls_cipher_cmac_starts(&ctx, key, key_len * 8); - if (ret != 0) { - goto cleanup; + psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_SIGN_HASH); + psa_set_key_algorithm(&attributes, PSA_ALG_CMAC); + psa_set_key_type(&attributes, PSA_KEY_TYPE_AES); + psa_set_key_bits(&attributes, key_len * 8); + + status = psa_import_key(&attributes, key, key_len, &key_id); + if (status != PSA_SUCCESS) { + wpa_printf(MSG_ERROR, "%s: psa_import_key failed", __func__); + return -1; } - for (i = 0 ; i < num_elem; i++) { - ret = mbedtls_cipher_cmac_update(&ctx, addr[i], len[i]); - if (ret != 0) { - goto cleanup; + psa_reset_key_attributes(&attributes); + + psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT; + + status = psa_mac_sign_setup(&operation, key_id, PSA_ALG_CMAC); + if (status != PSA_SUCCESS) { + wpa_printf(MSG_ERROR, "%s: psa_mac_sign_setup failed", __func__); + return -1; + } + + for (int i = 0; i < num_elem; i++) { + status = psa_mac_update(&operation, addr[i], len[i]); + if (status != PSA_SUCCESS) { + wpa_printf(MSG_ERROR, "%s: psa_mac_update failed", __func__); + return -1; } } - ret = mbedtls_cipher_cmac_finish(&ctx, mac); -cleanup: - mbedtls_cipher_free(&ctx); - return (ret); + size_t output_length = 0; + + status = psa_mac_sign_finish(&operation, mac, 16, &output_length); + if (status != PSA_SUCCESS) { + wpa_printf(MSG_ERROR, "%s: psa_mac_sign_finish failed", __func__); + return -1; + } + + psa_mac_abort(&operation); + + psa_destroy_key(key_id); + + return 0; + } int omac1_aes_128_vector(const u8 *key, size_t num_elem, diff --git a/components/wpa_supplicant/esp_supplicant/src/crypto/tls_mbedtls.c b/components/wpa_supplicant/esp_supplicant/src/crypto/tls_mbedtls.c index f0c580238d..00826054ed 100644 --- a/components/wpa_supplicant/esp_supplicant/src/crypto/tls_mbedtls.c +++ b/components/wpa_supplicant/esp_supplicant/src/crypto/tls_mbedtls.c @@ -37,6 +37,8 @@ #include "mbedtls/platform.h" #include "eap_peer/eap.h" +#include "mbedtls/psa_util.h" + #ifdef CONFIG_TLSV13 #include "psa/crypto.h" #include "md_psa.h" @@ -177,7 +179,7 @@ static int set_pki_context(tls_context_t *tls, const struct tls_connection_param ret = mbedtls_pk_parse_key(&tls->clientkey, cfg->private_key_blob, cfg->private_key_blob_len, (const unsigned char *)cfg->private_key_passwd, - cfg->private_key_passwd ? os_strlen(cfg->private_key_passwd) : 0, mbedtls_esp_random, NULL); + cfg->private_key_passwd ? os_strlen(cfg->private_key_passwd) : 0, mbedtls_psa_get_random, MBEDTLS_PSA_RANDOM_STATE); if (ret < 0) { wpa_printf(MSG_ERROR, "mbedtls_pk_parse_keyfile returned -0x%x", -ret); return ret; @@ -594,6 +596,12 @@ static int tls_create_mbedtls_handle(struct tls_connection *conn, assert(params != NULL); assert(tls != NULL); + psa_status_t status = psa_crypto_init(); + if (status != PSA_SUCCESS) { + wpa_printf(MSG_ERROR, "Failed to initialize PSA crypto, returned %d", (int) status); + return -1; + } + mbedtls_ssl_init(&tls->ssl); mbedtls_ssl_config_init(&tls->conf); @@ -603,7 +611,7 @@ static int tls_create_mbedtls_handle(struct tls_connection *conn, goto exit; } - mbedtls_ssl_conf_rng(&tls->conf, mbedtls_esp_random, NULL); + mbedtls_ssl_conf_rng(&tls->conf, mbedtls_psa_get_random, MBEDTLS_PSA_RANDOM_STATE); #if defined(CONFIG_MBEDTLS_SSL_PROTO_TLS1_3) && !defined(CONFIG_TLSV13) /* Disable TLSv1.3 even when enabled in MbedTLS and not enabled in WiFi config. diff --git a/components/wpa_supplicant/src/common/dpp_crypto.c b/components/wpa_supplicant/src/common/dpp_crypto.c index b95584e8e1..164d98fcb2 100644 --- a/components/wpa_supplicant/src/common/dpp_crypto.c +++ b/components/wpa_supplicant/src/common/dpp_crypto.c @@ -1016,11 +1016,11 @@ fail: int dpp_auth_derive_l_initiator(struct dpp_authentication *auth) { - struct crypto_ec_group *group; + struct crypto_ec_group *group = NULL; struct crypto_ec_point *L = NULL, *sum = NULL; - struct crypto_ec_point *BR_point, *PR_point; + struct crypto_ec_point *BR_point = NULL, *PR_point = NULL; struct crypto_bignum *lx; - struct crypto_bignum *bI_bn; + struct crypto_bignum *bI_bn = NULL; int ret = -1; /* L = bI * (BR + PR) */ @@ -1042,7 +1042,7 @@ int dpp_auth_derive_l_initiator(struct dpp_authentication *auth) crypto_ec_point_mul((struct crypto_ec *)group, sum, bI_bn, L) != 0 || crypto_ec_get_affine_coordinates((struct crypto_ec *)group, L, lx, NULL) != 0) { wpa_printf(MSG_ERROR, - "OpenSSL: failed: %s", __func__); + "DPP: failed: %s", __func__); goto fail; } @@ -1056,6 +1056,21 @@ fail: crypto_ec_point_deinit(sum, 1); crypto_bignum_deinit(lx, 0); + if (BR_point) { + crypto_ec_point_deinit(BR_point, 0); + } + + if (PR_point) { + crypto_ec_point_deinit(PR_point, 0); + } + + if (group) { + crypto_ec_deinit((struct crypto_ec *)group); + } + + if (bI_bn) { + crypto_bignum_deinit(bI_bn, 0); + } return ret; } diff --git a/components/wpa_supplicant/src/crypto/aes-ccm.c b/components/wpa_supplicant/src/crypto/aes-ccm.c index e5bb94ca08..e14ccdd577 100644 --- a/components/wpa_supplicant/src/crypto/aes-ccm.c +++ b/components/wpa_supplicant/src/crypto/aes-ccm.c @@ -13,6 +13,7 @@ #include "common.h" #include "aes.h" #include "aes_wrap.h" +#include "psa/crypto.h" static void xor_aes_block(u8 *dst, const u8 *src) @@ -129,22 +130,6 @@ static void aes_ccm_encr_auth(void *aes, size_t M, u8 *x, u8 *a, u8 *auth) wpa_hexdump_key(MSG_DEBUG, "CCM U", auth, M); } - -static void aes_ccm_decr_auth(void *aes, size_t M, u8 *a, const u8 *auth, u8 *t) -{ - size_t i; - u8 tmp[AES_BLOCK_SIZE]; - - wpa_hexdump_key(MSG_DEBUG, "CCM U", auth, M); - /* U = T XOR S_0; S_0 = E(K, A_0) */ - WPA_PUT_BE16(&a[AES_BLOCK_SIZE - 2], 0); - aes_encrypt(aes, a, tmp); - for (i = 0; i < M; i++) - t[i] = auth[i] ^ tmp[i]; - wpa_hexdump_key(MSG_DEBUG, "CCM T", t, M); -} - - /* AES-CCM with fixed L=2 and aad_len <= 30 assumption */ int aes_ccm_ae(const u8 *key, size_t key_len, const u8 *nonce, size_t M, const u8 *plain, size_t plain_len, @@ -180,35 +165,73 @@ int aes_ccm_ad(const u8 *key, size_t key_len, const u8 *nonce, size_t M, const u8 *crypt, size_t crypt_len, const u8 *aad, size_t aad_len, const u8 *auth, u8 *plain) { - const size_t L = 2; - void *aes; - u8 x[AES_BLOCK_SIZE], a[AES_BLOCK_SIZE]; - u8 t[AES_BLOCK_SIZE]; + psa_status_t status; + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_key_id_t key_id; - if (aad_len > 30 || M > AES_BLOCK_SIZE) - return -1; + status = psa_crypto_init(); + if (status != PSA_SUCCESS) { + wpa_printf(MSG_ERROR, "%s: psa_crypto_init failed", __func__); + return -1; + } - aes = aes_encrypt_init(key, key_len); - if (aes == NULL) - return -1; + psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_DECRYPT); + psa_set_key_algorithm(&attributes, PSA_ALG_CCM); + psa_set_key_type(&attributes, PSA_KEY_TYPE_AES); + psa_set_key_bits(&attributes, key_len * 8); - /* Decryption */ - aes_ccm_encr_start(L, nonce, a); - aes_ccm_decr_auth(aes, M, a, auth, t); + status = psa_import_key(&attributes, key, key_len, &key_id); + if (status != PSA_SUCCESS) { + wpa_printf(MSG_ERROR, "%s: psa_import_key failed", __func__); + return -1; + } - /* plaintext = msg XOR (S_1 | S_2 | ... | S_n) */ - aes_ccm_encr(aes, L, crypt, crypt_len, plain, a); + psa_reset_key_attributes(&attributes); - aes_ccm_auth_start(aes, M, L, nonce, aad, aad_len, crypt_len, x); - aes_ccm_auth(aes, plain, crypt_len, x); + psa_aead_operation_t operation = PSA_AEAD_OPERATION_INIT; - aes_encrypt_deinit(aes); + status = psa_aead_decrypt_setup(&operation, key_id, PSA_ALG_CCM); + if (status != PSA_SUCCESS) { + wpa_printf(MSG_ERROR, "%s: psa_aead_decrypt_setup failed", __func__); + return -1; + } - if (os_memcmp_const(x, t, M) != 0) { - wpa_printf(MSG_DEBUG, "CCM: Auth mismatch"); - return -1; - } + status = psa_aead_set_nonce(&operation, nonce, 13); + if (status != PSA_SUCCESS) { + wpa_printf(MSG_ERROR, "%s: psa_aead_set_nonce failed", __func__); + return -1; + } - return 0; + status = psa_aead_set_lengths(&operation, aad_len, crypt_len); + if (status != PSA_SUCCESS) { + wpa_printf(MSG_ERROR, "%s: psa_aead_set_lengths failed", __func__); + return -1; + } + + size_t output_length = 0; + + status = psa_aead_update_ad(&operation, aad, aad_len); + if (status != PSA_SUCCESS) { + wpa_printf(MSG_ERROR, "%s: psa_aead_update_ad failed", __func__); + return -1; + } + + status = psa_aead_update(&operation, crypt, crypt_len, plain, crypt_len, &output_length); + if (status != PSA_SUCCESS) { + wpa_printf(MSG_ERROR, "%s: psa_aead_update failed", __func__); + return -1; + } + + status = psa_aead_verify(&operation, plain + output_length, 16 - output_length, &output_length, auth, M); + if (status != PSA_SUCCESS) { + wpa_printf(MSG_ERROR, "%s: psa_aead_verify failed", __func__); + return -1; + } + + psa_aead_abort(&operation); + + psa_destroy_key(key_id); + + return 0; } #endif /* CONFIG_IEEE80211W */ diff --git a/components/wpa_supplicant/src/crypto/des-internal.c b/components/wpa_supplicant/src/crypto/des-internal.c index 5d7cddae1f..beca000e50 100644 --- a/components/wpa_supplicant/src/crypto/des-internal.c +++ b/components/wpa_supplicant/src/crypto/des-internal.c @@ -14,6 +14,7 @@ #include "crypto.h" #include "des_i.h" +#include "psa/crypto.h" /* * This implementation is based on a DES implementation included in * LibTomCrypt. The version here is modified to fit in wpa_supplicant/hostapd @@ -398,29 +399,55 @@ static void desfunc(u32 *block, const u32 *keys) int des_encrypt(const u8 *clear, const u8 *key, u8 *cypher) { - u8 pkey[8], next, tmp; - int i; - u32 ek[32], work[2]; + psa_status_t status; + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_key_id_t key_id; - /* Add parity bits to the key */ - next = 0; - for (i = 0; i < 7; i++) { - tmp = key[i]; - pkey[i] = (tmp >> i) | next | 1; - next = tmp << (7 - i); - } - pkey[i] = next | 1; + status = psa_crypto_init(); + if (status != PSA_SUCCESS) { + printf("%s: psa_crypto_init failed\n", __func__); + return -1; + } - deskey(pkey, 0, ek); + psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_ENCRYPT); + psa_set_key_algorithm(&attributes, PSA_ALG_ECB_NO_PADDING); + psa_set_key_type(&attributes, PSA_KEY_TYPE_DES); + psa_set_key_bits(&attributes, 64); - work[0] = WPA_GET_BE32(clear); - work[1] = WPA_GET_BE32(clear + 4); - desfunc(work, ek); - WPA_PUT_BE32(cypher, work[0]); - WPA_PUT_BE32(cypher + 4, work[1]); + status = psa_import_key(&attributes, key, 8, &key_id); + if (status != PSA_SUCCESS) { + printf("%s: psa_import_key failed, status: %d\n", __func__, status); + return -1; + } + + psa_reset_key_attributes(&attributes); + + psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT; + + status = psa_cipher_encrypt_setup(&operation, key_id, PSA_ALG_ECB_NO_PADDING); + if (status != PSA_SUCCESS) { + printf("%s: psa_cipher_encrypt_setup failed\n", __func__); + return -1; + } + + size_t output_length = 0; + + status = psa_cipher_update(&operation, clear, 8, cypher, 8, &output_length); + if (status != PSA_SUCCESS) { + printf("%s: psa_cipher_update failed\n", __func__); + return -1; + } + + status = psa_cipher_finish(&operation, cypher + output_length, 8 - output_length, &output_length); + if (status != PSA_SUCCESS) { + printf("%s: psa_cipher_finish failed\n", __func__); + return -1; + } + + psa_cipher_abort(&operation); + + psa_destroy_key(key_id); - forced_memzero(pkey, sizeof(pkey)); - forced_memzero(ek, sizeof(ek)); return 0; } diff --git a/components/wpa_supplicant/test_apps/main/test_crypto.c b/components/wpa_supplicant/test_apps/main/test_crypto.c index 23f14b8da5..86b4b36642 100644 --- a/components/wpa_supplicant/test_apps/main/test_crypto.c +++ b/components/wpa_supplicant/test_apps/main/test_crypto.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -13,11 +13,18 @@ #include "utils/common.h" #include "utils/includes.h" #include "crypto/crypto.h" +#include "crypto/aes_wrap.h" #include "mbedtls/ecp.h" +#include "mbedtls/pk.h" #include "test_utils.h" #include "test_wpa_supplicant_common.h" +#include "psa/crypto.h" +#include "mbedtls/psa_util.h" +#include "esp_heap_caps.h" +#include "crypto/sha384.h" + typedef struct crypto_bignum crypto_bignum; TEST_CASE("Test crypto lib bignum apis", "[wpa_crypto]") @@ -536,3 +543,564 @@ TEST_CASE("Test crypto lib ECC apis", "[wpa_crypto]") } } + +TEST_CASE("Test crypto lib aes apis", "[wpa_crypto]") +{ + set_leak_threshold(1); + + { + /* Check init and deinit APIs */ + const uint8_t key_size = 16; + const uint8_t key[16] = {[0 ... key_size - 1] = 0x3A}; + void *ctx = aes_encrypt_init(key, key_size); + TEST_ASSERT_NOT_NULL(ctx); + + aes_encrypt_deinit(ctx); + + ctx = NULL; + + ctx = aes_decrypt_init(key, key_size); + TEST_ASSERT_NOT_NULL(ctx); + aes_decrypt_deinit(ctx); + } + + { + /* Check encrypt and decrypt APIs */ + const uint8_t key_size = 16; + const uint8_t key[16] = {[0 ... key_size - 1] = 0x3A}; + const uint8_t plain[16] = {[0 ... 15] = 0xA5}; + const uint8_t expected_cipher[16] = {0x69, 0x84, 0xC9, 0x14, 0x53, 0x57, 0xE1, 0x09, 0xAA, 0x74, 0xDB, 0x96, 0x8B, 0x17, 0xA0, 0x6A}; + + void *ctx = aes_encrypt_init(key, key_size); + TEST_ASSERT_NOT_NULL(ctx); + + uint8_t crypt[16]; + int ret = aes_encrypt(ctx, plain, crypt); + aes_encrypt_deinit(ctx); + TEST_ASSERT(ret == 0); + TEST_ASSERT(!memcmp(crypt, expected_cipher, 16)); + + ctx = aes_decrypt_init(key, key_size); + TEST_ASSERT_NOT_NULL(ctx); + + uint8_t decrypted[16]; + ret = aes_decrypt(ctx, crypt, decrypted); + aes_decrypt_deinit(ctx); + TEST_ASSERT(ret == 0); + TEST_ASSERT(!memcmp(decrypted, plain, 16)); + } + + { + /* Check encrypt and decrypt 128 bit CBC APIs */ + const uint8_t key_size = 16; + const uint8_t key[16] = {[0 ... key_size - 1] = 0x3A}; + const uint8_t iv[16] = {[0 ... 15] = 0x5A}; + uint8_t plain[16] = {[0 ... 15] = 0xA5}; + + const uint8_t expected_cipher[16] = { + 0xA0, 0x67, 0x6C, 0x77, 0x53, 0xE2, 0x17, 0x63, 0x00, 0x4C, 0xB8, 0xF6, 0xA8, 0x9F, 0xC0, 0xD2 + }; + + int ret = aes_128_cbc_encrypt(key, iv, plain, 16); + TEST_ASSERT(ret == 0); + TEST_ASSERT(!memcmp(plain, expected_cipher, 16)); + + ret = aes_128_cbc_decrypt(key, iv, plain, 16); + TEST_ASSERT(ret == 0); + uint8_t expected_plain[16] = {[0 ... 15] = 0xA5}; + TEST_ASSERT(!memcmp(plain, expected_plain, 16)); + } + + { + /* Check encrypt 128 bit CTR APIs */ + const uint8_t key_size = 16; + const uint8_t key[16] = {[0 ... key_size - 1] = 0x3A}; + const uint8_t iv[16] = {[0 ... 15] = 0x5A}; + uint8_t plain[16] = {[0 ... 15] = 0xA5}; + + const uint8_t expected_cipher[16] = { + 0x44, 0xF5, 0x91, 0x0A, 0xE0, 0xEF, 0x5C, 0xF2, 0x28, 0xEB, 0x74, 0x41, 0xAA, 0xB2, 0x24, 0xE6 + }; + + int ret = aes_128_ctr_encrypt(key, iv, plain, 16); + TEST_ASSERT(ret == 0); + TEST_ASSERT(!memcmp(plain, expected_cipher, 16)); + } + + /* + { + Check internal crypto cipher APIs + const uint8_t key_size = 16; + const uint8_t key[16] = {[0 ... key_size - 1] = 0x3A}; + const uint8_t iv[16] = {[0 ... 15] = 0x5A}; + uint8_t plain[16] = {[0 ... 15] = 0xA5}; + + const uint8_t expected_cipher[16] = { + 0xA0, 0x67, 0x6C, 0x77, 0x53, 0xE2, 0x17, 0x63, 0x00, 0x4C, 0xB8, 0xF6, 0xA8, 0x9F, 0xC0, 0xD2 + }; + + struct crypto_cipher *ctx = crypto_cipher_init(CRYPTO_CIPHER_ALG_AES, iv, key, key_size); + TEST_ASSERT_NOT_NULL(ctx); + + uint8_t crypt[16]; + int ret = crypto_cipher_encrypt(ctx, plain, crypt, 16); + TEST_ASSERT(ret == 0); + TEST_ASSERT(!memcmp(crypt, expected_cipher, 16)); + + ret = crypto_cipher_decrypt(ctx, crypt, plain, 16); + TEST_ASSERT(ret == 0); + uint8_t expected_plain[16] = {[0 ... 15] = 0xA5}; + TEST_ASSERT(!memcmp(plain, expected_plain, 16)); + + crypto_cipher_deinit(ctx); + } + */ + { + /* Check omac1_aes_128 APIs */ + const uint8_t key_size = 16; + const uint8_t key[16] = {[0 ... key_size - 1] = 0x3A}; + const uint8_t data[16] = {[0 ... 15] = 0xA5}; + uint8_t mac[16]; + + const uint8_t expected_mac[16] = { + 0x4e, 0x47, 0xb3, 0xcc, 0xf8, 0x41, 0xd0, 0x2f, 0xeb, 0xc1, 0xa9, 0x90, 0xdf, 0xc8, 0xe4, 0x8d + }; + + int ret = omac1_aes_128(key, data, 16, mac); + TEST_ASSERT(ret == 0); + TEST_ASSERT(!memcmp(mac, expected_mac, 16)); + + /* Also check a negative case */ + const uint8_t expected_mac_neg[16] = { + 0x4e, 0x47, 0xb3, 0xcc, 0xf8, 0x41, 0xd0, 0x2f, 0xeb, 0xc1, 0xa9, 0x90, 0xdf, 0xc8, 0xe4, 0x8e + }; + TEST_ASSERT(memcmp(mac, expected_mac_neg, 16)); + } + + { + /* Check aes_ccm_ae APIs */ + const uint8_t key_size = 16; + const uint8_t key[16] = {[0 ... key_size - 1] = 0x3A}; + const uint8_t nonce[13] = {[0 ... 12] = 0x5A}; + const uint8_t aad[16] = {[0 ... 15] = 0xA5}; + const uint8_t data[16] = {[0 ... 15] = 0xA5}; + uint8_t crypt[16]; + uint8_t tag[16]; + + const uint8_t expected_crypt[16] = { + 0x28, 0xd9, 0xfe, 0x15, 0xc7, 0xc5, 0xc8, 0xb7, 0xc0, 0x18, 0x28, 0x9b, 0x4b, 0x0b, 0xea, 0x66 + }; + + const uint8_t expected_tag[16] = { + 0xbf, 0xf4, 0x0e, 0x51, 0x78, 0xc0, 0xbd, 0x93, 0x29, 0xd7, 0x63, 0x28, 0xc6, 0x71, 0xe6, 0x60 + }; + + int ret = aes_ccm_ae(key, key_size, nonce, 16, data, 16, aad, 16, crypt, tag); + TEST_ASSERT(ret == 0); + TEST_ASSERT(!memcmp(crypt, expected_crypt, 16)); + + uint8_t decrypted[16] = {0}; + + ret = aes_ccm_ad(key, key_size, nonce, 16, crypt, 16, aad, 16, tag, decrypted); + TEST_ASSERT(ret == 0); + TEST_ASSERT(!memcmp(tag, expected_tag, 16)); + TEST_ASSERT(!memcmp(decrypted, data, 16)); + } +} + +// NOTE: This is disable as PSA does not support DES +/* +TEST_CASE("Test crypto lib des apis", "[wpa_crypto]") +{ + { + const uint8_t key[8] = {[0 ... 7] = 0x3A}; + const uint8_t plain[8] = {[0 ... 7] = 0xA5}; + + const uint8_t expected_cipher[8] = { + 0x54, 0x24, 0x29, 0x5E, 0x53, 0x94, 0x1D, 0x8E + }; + + uint8_t crypt[8]; + int ret = des_encrypt(plain, key, crypt); + TEST_ASSERT(ret == 0); + TEST_ASSERT(!memcmp(crypt, expected_cipher, 8)); + } +} +*/ + +TEST_CASE("Test crypto lib ecdsa apis", "[wpa_crypto]") +{ + set_leak_threshold(300); + { + /* Check ecdsa_get_sign apis */ + uint8_t data[64] = {[0 ... 63] = 0xA5}; + + struct crypto_ec_key *eckey = crypto_ec_key_gen(MBEDTLS_ECP_DP_SECP256R1); + TEST_ASSERT_NOT_NULL(eckey); + // Signature length is defined as 2 * key_size + int ret = crypto_ecdsa_get_sign(data, NULL, NULL, eckey, 2 * 32); + TEST_ASSERT(ret == 0); + + uint8_t expected_data[64] = {[0 ... 63] = 0xA5}; + ret = crypto_ec_key_verify_signature(eckey, expected_data, 64, data, 64); + TEST_ASSERT(ret == 0); + + // Negative test case + expected_data[0] = 0x5A; + ret = crypto_ec_key_verify_signature(eckey, expected_data, 64, data, 64); + TEST_ASSERT(ret == -1); + crypto_ec_key_deinit(eckey); + } +} + +TEST_CASE("Test crypto lib hash apis", "[wpa_crypto]") +{ + set_leak_threshold(1); + { + /* Check sha256 APIs */ + const uint8_t *data[1]; + data[0] = calloc(1, 32); + memset((void *)data[0], 0xA5, 32); + uint8_t hash[32]; + + uint8_t expected_hash[32] = { + 0xFC, 0x8B, 0x64, 0x00, 0x1C, 0x5F, 0xDD, 0x0F, 0x2F, 0x40, 0xFB, 0x67, 0xDA, 0xE4, 0xA8, 0x65, 0xA2, 0xC5, 0xBD, 0x17, 0x83, 0x66, 0x76, 0xD6, 0xD5, 0xB5, 0x8B, 0x79, 0x17, 0xE3, 0x37, 0x17 + }; + + size_t len[1] = {32}; + int ret = sha256_vector(1, data, len, hash); + free((void *)data[0]); + TEST_ASSERT(ret == 0); + TEST_ASSERT(!memcmp(hash, expected_hash, 32)); + } + + { + /* Check sha384 APIs */ + const uint8_t *data[1]; + data[0] = calloc(1, 32); + memset((void *)data[0], 0xA5, 32); + uint8_t hash[48]; + + // 80b0d3a08d530e02627c374ef4bf507faa55001e2ffdcd20c0be7d0f47ea600e3d980256699409c673d6fc823742fc20 + uint8_t expected_hash[48] = { + 0x80, 0xB0, 0xD3, 0xA0, 0x8D, 0x53, 0x0E, 0x02, 0x62, 0x7C, 0x37, 0x4E, 0xF4, 0xBF, 0x50, 0x7F, 0xAA, 0x55, 0x00, 0x1E, 0x2F, 0xFD, 0xCD, 0x20, 0xC0, 0xBE, 0x7D, 0x0F, 0x47, 0xEA, 0x60, 0x0E, 0x3D, 0x98, 0x02, 0x56, 0x69, 0x94, 0x09, 0xC6, 0x73, 0xD6, 0xFC, 0x82, 0x37, 0x42, 0xFC, 0x20 + }; + + size_t len[1] = {32}; + int ret = sha384_vector(1, data, len, hash); + free((void *)data[0]); + TEST_ASSERT(ret == 0); + TEST_ASSERT(!memcmp(hash, expected_hash, 48)); + } + + { + /* Check sha512 APIs */ + const uint8_t *data[1]; + data[0] = calloc(1, 32); + memset((void *)data[0], 0xA5, 32); + uint8_t hash[64]; + + // 774B67B3A64977E9A42E46217F17A6E85402A50A1EC8B75EB53FCDD5D4EB4B54D4A249F863E97128CF6529763BC96AA73CA9AE49784D2FF158B324A6016CB518 + uint8_t expected_hash[64] = { + 0x77, 0x4B, 0x67, 0xB3, 0xA6, 0x49, 0x77, 0xE9, 0xA4, 0x2E, 0x46, 0x21, 0x7F, 0x17, 0xA6, 0xE8, 0x54, 0x02, 0xA5, 0x0A, 0x1E, 0xC8, 0xB7, 0x5E, 0xB5, 0x3F, 0xCD, 0xD5, 0xD4, 0xEB, 0x4B, 0x54, 0xD4, 0xA2, 0x49, 0xF8, 0x63, 0xE9, 0x71, 0x28, 0xCF, 0x65, 0x29, 0x76, 0x3B, 0xC9, 0x6A, 0xA7, 0x3C, 0xA9, 0xAE, 0x49, 0x78, 0x4D, 0x2F, 0xF1, 0x58, 0xB3, 0x24, 0xA6, 0x01, 0x6C, 0xB5, 0x18 + }; + + size_t len[1] = {32}; + + int ret = sha512_vector(1, data, len, hash); + free((void *)data[0]); + TEST_ASSERT(ret == 0); + TEST_ASSERT(!memcmp(hash, expected_hash, 64)); + } + + { + /* Check SHA1 APIs */ + const uint8_t *data[1]; + data[0] = calloc(1, 32); + memset((void *)data[0], 0xA5, 32); + uint8_t hash[20]; + size_t len[1] = {32}; + + // 3723E743D2EAB795ED034F03ECD20E69E8839219 + uint8_t expected_hash[20] = { + 0x37, 0x23, 0xE7, 0x43, 0xD2, 0xEA, 0xB7, 0x95, 0xED, 0x03, 0x4F, 0x03, 0xEC, 0xD2, 0x0E, 0x69, 0xE8, 0x83, 0x92, 0x19 + }; + + int ret = sha1_vector(1, data, len, hash); + free((void *)data[0]); + TEST_ASSERT(ret == 0); + TEST_ASSERT(!memcmp(hash, expected_hash, 20)); + } + + { + /* Check MD5 APIs */ + const uint8_t *data[1]; + data[0] = calloc(1, 32); + memset((void *)data[0], 0xA5, 32); + uint8_t hash[16]; + size_t len[1] = {32}; + + // 096CABA666F7B5381886AA0BD54114ED + uint8_t expected_hash[16] = { + 0x09, 0x6C, 0xAB, 0xA6, 0x66, 0xF7, 0xB5, 0x38, 0x18, 0x86, 0xAA, 0x0B, 0xD5, 0x41, 0x14, 0xED + }; + + int ret = md5_vector(1, data, len, hash); + free((void *)data[0]); + TEST_ASSERT(ret == 0); + TEST_ASSERT(!memcmp(hash, expected_hash, 16)); + } + + { + /* Check incremental hash APIs */ + const uint8_t *data[1]; + data[0] = calloc(1, 32); + memset((void *)data[0], 0xA5, 32); + uint8_t hash[32]; + size_t len[1] = {32}; + + uint8_t expected_hash[16] = { + 0x09, 0x6C, 0xAB, 0xA6, 0x66, 0xF7, 0xB5, 0x38, 0x18, 0x86, 0xAA, 0x0B, 0xD5, 0x41, 0x14, 0xED + }; + + struct crypto_hash *ctx = crypto_hash_init(CRYPTO_HASH_ALG_MD5, NULL, 0); + TEST_ASSERT_NOT_NULL(ctx); + + crypto_hash_update(ctx, data[0], 32); + + int ret = crypto_hash_finish(ctx, hash, len); + free((void *)data[0]); + TEST_ASSERT(ret == 0); + TEST_ASSERT(!memcmp(hash, expected_hash, 16)); + } + + { + /* Check incremental hash API with an user side error for memory leaks */ + + struct crypto_hash *ctx = crypto_hash_init(CRYPTO_HASH_ALG_MD5, NULL, 0); + TEST_ASSERT_NOT_NULL(ctx); + + /* Assume a user error occured, no update API call, only finish to free the ctx */ + + int ret = crypto_hash_finish(ctx, NULL, NULL); + TEST_ASSERT(ret == -1); + } + + { + /* Check incremental mac APIs */ + const uint8_t *data[1]; + data[0] = calloc(1, 32); + memset((void *)data[0], 0xA5, 32); + + uint8_t hash[32]; + size_t len[1] = {32}; + + uint8_t key[32] = {[0 ... 31] = 0x3A}; + + // 2b89551909266ed16c077407800210be3c537474ed3d6850ca9f313aea897cd5 + uint8_t expected_hash[32] = { + 0x2B, 0x89, 0x55, 0x19, 0x09, 0x26, 0x6E, 0xD1, 0x6C, 0x07, 0x74, 0x07, 0x80, 0x02, 0x10, 0xBE, 0x3C, 0x53, 0x74, 0x74, 0xED, 0x3D, 0x68, 0x50, 0xCA, 0x9F, 0x31, 0x3A, 0xEA, 0x89, 0x7C, 0xD5 + }; + + struct crypto_hash *ctx = crypto_hash_init(CRYPTO_HASH_ALG_HMAC_SHA256, key, 32); + TEST_ASSERT_NOT_NULL(ctx); + + crypto_hash_update(ctx, data[0], 32); + + int ret = crypto_hash_finish(ctx, hash, len); + free((void *)data[0]); + TEST_ASSERT(ret == 0); + TEST_ASSERT(!memcmp(hash, expected_hash, 32)); + } + + { + /* Check hmac_sha384 APIs */ + const uint8_t data[32] = {[0 ... 31] = 0xA5}; + uint8_t hash[48]; + uint8_t key[32] = {[0 ... 31] = 0x3A}; + + // 8014a069bfa41e5d298e2c6050ad6ca8a3d7ac447068455b035c24c531f67d2687db1259105fabe9cdb0809604e552ce + uint8_t expected_hash[48] = { + 0x80, 0x14, 0xA0, 0x69, 0xBF, 0xA4, 0x1E, 0x5D, 0x29, 0x8E, 0x2C, 0x60, 0x50, 0xAD, 0x6C, 0xA8, 0xA3, 0xD7, 0xAC, 0x44, 0x70, 0x68, 0x45, 0x5B, 0x03, 0x5C, 0x24, 0xC5, 0x31, 0xF6, 0x7D, 0x26, 0x87, 0xDB, 0x12, 0x59, 0x10, 0x5F, 0xAB, 0xE9, 0xCD, 0xB0, 0x80, 0x96, 0x04, 0xE5, 0x52, 0xCE + }; + + int ret = hmac_sha384(key, 32, data, 32, hash); + TEST_ASSERT(ret == 0); + TEST_ASSERT(!memcmp(hash, expected_hash, 48)); + } +} + +TEST_CASE("Test crypto lib rsa apis", "[wpa_crypto]") +{ + set_leak_threshold(1); + { + const char *rsa_key = + "-----BEGIN RSA PRIVATE KEY-----\n" + "MIIEowIBAAKCAQEAojDGyuzNRtqWDS3no8PPA0LFCme4V8qnpKaJnHjp/YxMEcny\n" + "W3eWPBTtL0WUvSRHBY7PgiVTKWKN/4zuRq77XnLxZQuRGYQeLcpLmsyZPArnlfym\n" + "jZRsXPsnPscmbKt5SAxCrFKXKIwZ76rR7he/2OsxQ7O6yfIm3JQQRt1h+PjCvPoq\n" + "JmvqhbMDH/0bTeNEdGPQPEx8+Xohhkb6bYivH8Jcm1FkZTVDfMtZsmismghr7ufB\n" + "gOLrc9NnFO7r9G8MtV+mtqWV8Urm7KkN4fs/e9i8XlHcd7qalSlEtDl0+md6xwV0\n" + "ZFvJQ2jlQEnZ94CEgAwYlpbsGlis+cfjdIf+wQIDAQABAoIBAFRnwey1E5c+BjzR\n" + "mOz25/Kwes6Rb7PweRIMwSy3GD6lFqljSUckkwCte0nQkjlkebmAuqjmN8Mf0Pof\n" + "I5mRUquyccG+JUL8KKB32KS0uUIwAplhpGOlzEcPRTs8dNi03CcMil4XlSa60nyR\n" + "jzKzFVoT+81Z6WlTJbpBK79VUrk4GCNPrvwU3r+H68zOQG0CSia5eoWSOEVuFlSw\n" + "01ixNbQRgCKZQQB72FQAtxBNIiPuWNg1nc+a7GMMKMmzzHr2xNUyv6byiQ0ADW6v\n" + "uOZbuNJ6gy6xltswGjR3mUcmGA9JoLwKTHLKD9qDzAE40RYU/G3I3o1PsbzdYnIr\n" + "hPnoLwkCgYEA0b3vBcpyIld1+BYPB1Q0b5uFbTXbegGvR8jU82ZGWs/uKUpO/wmq\n" + "A3P2Q7Bm+91Zsz0hiQ56k2N2tsb5H/tOcOwBSkzbViJ4w9IroFZydQpv5mZXSELh\n" + "b0wSnet4L99TxsJiA55S6JmawrgRCBGhOsTQA0bKNGFioN1CkcVrjhsCgYEAxfYV\n" + "KvdhmU9hRauYFHYVCiHYTC8ae8W1p8YwUc6N9PnUvUazYCpX257HlQgs0QzIcj0k\n" + "dz9/DqfE6xuPdVzyrFwwdn3MthN6QOWUNEnh0XeVnoUtFS8Tld3YFVO9sCGQg1JV\n" + "OWasqz8G/xxxycjiKp7ls5jcgJ/K5JaNwyJZhFMCgYBacgIxyBQhtP99JN4ENg6K\n" + "llEaQCBN444XcYZLE66BGKtGCPI5zowPAyGOHPK75773qQPeG21GQ5z8wp7JaNBx\n" + "p4QC61OmOCVFpEsF0GF5ETAh9b3rvlOCcBaTHOhuFGsHCenET7DG9v4iu8c0aI3T\n" + "Tu24i/1ESz6Byggb3js8QwKBgBfTlpilTcn2E+8eyB8uVznw+Oeyg62CDmszH325\n" + "LrzdlQ1zBQP+FLUKV1tIsJw4vaeCVHFF4zUQXFMv7gRiO5MjRXH9kjYYAg7tkvj4\n" + "K4Xartd1kAeMsv7GxMtMWPhqEcq8jiVqhj3WSDFMayWuWAppNZx4OZIBqZn5xPZH\n" + "nB6hAoGBAK70lFDgWH7tm6kmmSSSDk9jk4CHiXgWogVGog0+RAtKf4JaFU6Tz5UY\n" + "ejqo/sXVm7GCAKtpQ6iK79ZMmFOVG4fGx3WdrjAmCLspiO3FeJ2dR0hoc/OkbDv/\n" + "QOtjDKCvW8b3bLUD369Yh9GVCur5eJ6sjZga4D7jaSEgON3ENIkE\n" + "-----END RSA PRIVATE KEY-----\n"; + + mbedtls_pk_context *ctx = calloc(1, sizeof(mbedtls_pk_context)); + mbedtls_pk_init(ctx); + + // Read the above key into mbedtls_pk_context + int ret = mbedtls_pk_parse_key(ctx, (const unsigned char *)rsa_key, strlen(rsa_key) + 1, NULL, 0, NULL, MBEDTLS_PSA_RANDOM_STATE); + TEST_ASSERT(ret == 0); + uint8_t data[32] = {[0 ... 31] = 0xA5}; + uint8_t encrypted[2048]; + size_t encrypted_size = 2048; + + psa_crypto_init(); + + ret = crypto_public_key_encrypt_pkcs1_v15((struct crypto_public_key *)ctx, data, 32, encrypted, &encrypted_size); + TEST_ASSERT(ret == 0); + + uint8_t decrypted[32] = {[0 ... 31] = 0}; + size_t decrypted_size = 32; + + ret = crypto_private_key_decrypt_pkcs1_v15((struct crypto_private_key *)ctx, encrypted, encrypted_size, decrypted, &decrypted_size); + TEST_ASSERT(ret == 0); + TEST_ASSERT(!memcmp(data, decrypted, 32)); + mbedtls_pk_free(ctx); + free(ctx); + } + + { + /* Check pkcs1 signature */ + const char *rsa_key = + "-----BEGIN RSA PRIVATE KEY-----\n" + "MIIEowIBAAKCAQEAojDGyuzNRtqWDS3no8PPA0LFCme4V8qnpKaJnHjp/YxMEcny\n" + "W3eWPBTtL0WUvSRHBY7PgiVTKWKN/4zuRq77XnLxZQuRGYQeLcpLmsyZPArnlfym\n" + "jZRsXPsnPscmbKt5SAxCrFKXKIwZ76rR7he/2OsxQ7O6yfIm3JQQRt1h+PjCvPoq\n" + "JmvqhbMDH/0bTeNEdGPQPEx8+Xohhkb6bYivH8Jcm1FkZTVDfMtZsmismghr7ufB\n" + "gOLrc9NnFO7r9G8MtV+mtqWV8Urm7KkN4fs/e9i8XlHcd7qalSlEtDl0+md6xwV0\n" + "ZFvJQ2jlQEnZ94CEgAwYlpbsGlis+cfjdIf+wQIDAQABAoIBAFRnwey1E5c+BjzR\n" + "mOz25/Kwes6Rb7PweRIMwSy3GD6lFqljSUckkwCte0nQkjlkebmAuqjmN8Mf0Pof\n" + "I5mRUquyccG+JUL8KKB32KS0uUIwAplhpGOlzEcPRTs8dNi03CcMil4XlSa60nyR\n" + "jzKzFVoT+81Z6WlTJbpBK79VUrk4GCNPrvwU3r+H68zOQG0CSia5eoWSOEVuFlSw\n" + "01ixNbQRgCKZQQB72FQAtxBNIiPuWNg1nc+a7GMMKMmzzHr2xNUyv6byiQ0ADW6v\n" + "uOZbuNJ6gy6xltswGjR3mUcmGA9JoLwKTHLKD9qDzAE40RYU/G3I3o1PsbzdYnIr\n" + "hPnoLwkCgYEA0b3vBcpyIld1+BYPB1Q0b5uFbTXbegGvR8jU82ZGWs/uKUpO/wmq\n" + "A3P2Q7Bm+91Zsz0hiQ56k2N2tsb5H/tOcOwBSkzbViJ4w9IroFZydQpv5mZXSELh\n" + "b0wSnet4L99TxsJiA55S6JmawrgRCBGhOsTQA0bKNGFioN1CkcVrjhsCgYEAxfYV\n" + "KvdhmU9hRauYFHYVCiHYTC8ae8W1p8YwUc6N9PnUvUazYCpX257HlQgs0QzIcj0k\n" + "dz9/DqfE6xuPdVzyrFwwdn3MthN6QOWUNEnh0XeVnoUtFS8Tld3YFVO9sCGQg1JV\n" + "OWasqz8G/xxxycjiKp7ls5jcgJ/K5JaNwyJZhFMCgYBacgIxyBQhtP99JN4ENg6K\n" + "llEaQCBN444XcYZLE66BGKtGCPI5zowPAyGOHPK75773qQPeG21GQ5z8wp7JaNBx\n" + "p4QC61OmOCVFpEsF0GF5ETAh9b3rvlOCcBaTHOhuFGsHCenET7DG9v4iu8c0aI3T\n" + "Tu24i/1ESz6Byggb3js8QwKBgBfTlpilTcn2E+8eyB8uVznw+Oeyg62CDmszH325\n" + "LrzdlQ1zBQP+FLUKV1tIsJw4vaeCVHFF4zUQXFMv7gRiO5MjRXH9kjYYAg7tkvj4\n" + "K4Xartd1kAeMsv7GxMtMWPhqEcq8jiVqhj3WSDFMayWuWAppNZx4OZIBqZn5xPZH\n" + "nB6hAoGBAK70lFDgWH7tm6kmmSSSDk9jk4CHiXgWogVGog0+RAtKf4JaFU6Tz5UY\n" + "ejqo/sXVm7GCAKtpQ6iK79ZMmFOVG4fGx3WdrjAmCLspiO3FeJ2dR0hoc/OkbDv/\n" + "QOtjDKCvW8b3bLUD369Yh9GVCur5eJ6sjZga4D7jaSEgON3ENIkE\n" + "-----END RSA PRIVATE KEY-----\n"; + + mbedtls_pk_context *ctx = calloc(1, sizeof(mbedtls_pk_context)); + mbedtls_pk_init(ctx); + + // Read the above key into mbedtls_pk_context + int ret = mbedtls_pk_parse_key(ctx, (const unsigned char *)rsa_key, strlen(rsa_key) + 1, NULL, 0, NULL, MBEDTLS_PSA_RANDOM_STATE); + TEST_ASSERT(ret == 0); + + uint8_t data[32] = {[0 ... 31] = 0xA5}; + uint8_t signature[2048]; + size_t signature_size = 2048; + + ret = crypto_private_key_sign_pkcs1((struct crypto_private_key *)ctx, data, 32, signature, &signature_size); + TEST_ASSERT(ret == 0); + + // printf("Signature size: %d\n", signature_size); + // for (int i = 0; i < signature_size; i++) { + // printf("%02X", signature[i]); + // } + // printf("\n"); + + // 700CE7B382057B3DA95734BFF2371A6435E9B226BFE2BB97922529A3331F1DEE57CA02341EE7448A5605813C8124BD64EBC21623EAC7CA8DECB61B615676BA0CBCE3A0B51369E4D69C8C7628AC55952D1553951722C05A0F79F9AC1C17061781532B8E2577529C480F96B93ED73D4079C865D71758ABB6EC4B51C4ED0ED8D47DF82C9B8701E072D5B9786CC835A52F508F2BCC2A762DD8C4BB9C02B44591954EDEF38655A2E551C6BAA0AFA803D583147856980D4EF3A1053A32EB997B3DEF46C86E7BB59F83F7D6FE38E825B60BF42652DF87AA4F19689BFBB6CEF07789A4B3AAD270A4FF9D942083BA08D0D97BD0D707B57424C652850627A505D23E1D0B2E + uint8_t expected_signature[256] = { + 0x70, 0x0C, 0xE7, 0xB3, 0x82, 0x05, 0x7B, 0x3D, 0xA9, 0x57, + 0x34, 0xBF, 0xF2, 0x37, 0x1A, 0x64, 0x35, 0xE9, 0xB2, 0x26, + 0xBF, 0xE2, 0xBB, 0x97, 0x92, 0x25, 0x29, 0xA3, 0x33, 0x1F, + 0x1D, 0xEE, 0x57, 0xCA, 0x02, 0x34, 0x1E, 0xE7, 0x44, 0x8A, + 0x56, 0x05, 0x81, 0x3C, 0x81, 0x24, 0xBD, 0x64, 0xEB, 0xC2, + 0x16, 0x23, 0xEA, 0xC7, 0xCA, 0x8D, 0xEC, 0xB6, 0x1B, 0x61, + 0x56, 0x76, 0xBA, 0x0C, 0xBC, 0xE3, 0xA0, 0xB5, 0x13, 0x69, + 0xE4, 0xD6, 0x9C, 0x8C, 0x76, 0x28, 0xAC, 0x55, 0x95, 0x2D, + 0x15, 0x53, 0x95, 0x17, 0x22, 0xC0, 0x5A, 0x0F, 0x79, 0xF9, + 0xAC, 0x1C, 0x17, 0x06, 0x17, 0x81, 0x53, 0x2B, 0x8E, 0x25, + 0x77, 0x52, 0x9C, 0x48, 0x0F, 0x96, 0xB9, 0x3E, 0xD7, 0x3D, + 0x40, 0x79, 0xC8, 0x65, 0xD7, 0x17, 0x58, 0xAB, 0xB6, 0xEC, + 0x4B, 0x51, 0xC4, 0xED, 0x0E, 0xD8, 0xD4, 0x7D, 0xF8, 0x2C, + 0x9B, 0x87, 0x01, 0xE0, 0x72, 0xD5, 0xB9, 0x78, 0x6C, 0xC8, + 0x35, 0xA5, 0x2F, 0x50, 0x8F, 0x2B, 0xCC, 0x2A, 0x76, 0x2D, + 0xD8, 0xC4, 0xBB, 0x9C, 0x02, 0xB4, 0x45, 0x91, 0x95, 0x4E, + 0xDE, 0xF3, 0x86, 0x55, 0xA2, 0xE5, 0x51, 0xC6, 0xBA, 0xA0, + 0xAF, 0xA8, 0x03, 0xD5, 0x83, 0x14, 0x78, 0x56, 0x98, 0x0D, + 0x4E, 0xF3, 0xA1, 0x05, 0x3A, 0x32, 0xEB, 0x99, 0x7B, 0x3D, + 0xEF, 0x46, 0xC8, 0x6E, 0x7B, 0xB5, 0x9F, 0x83, 0xF7, 0xD6, + 0xFE, 0x38, 0xE8, 0x25, 0xB6, 0x0B, 0xF4, 0x26, 0x52, 0xDF, + 0x87, 0xAA, 0x4F, 0x19, 0x68, 0x9B, 0xFB, 0xB6, 0xCE, 0xF0, + 0x77, 0x89, 0xA4, 0xB3, 0xAA, 0xD2, 0x70, 0xA4, 0xFF, 0x9D, + 0x94, 0x20, 0x83, 0xBA, 0x08, 0xD0, 0xD9, 0x7B, 0xD0, 0xD7, + 0x07, 0xB5, 0x74, 0x24, 0xC6, 0x52, 0x85, 0x06, 0x27, 0xA5, + 0x05, 0xD2, 0x3E, 0x1D, 0x0B, 0x2E + }; + + TEST_ASSERT(signature_size == 256); + for (int i = 0; i < signature_size; i++) { + if (signature[i] != expected_signature[i]) { + printf("Mismatch at index %d\n", i); + printf("Expected: %02X, Got: %02X\n", expected_signature[i], signature[i]); + } + } + + mbedtls_pk_free(ctx); + free(ctx); + } +} + +TEST_CASE("Test crypto lib ec apis", "[wpa_crypto]") +{ + set_leak_threshold(1); + { + psa_key_id_t key_id; + psa_key_attributes_t key_attributes = PSA_KEY_ATTRIBUTES_INIT; + + psa_set_key_usage_flags(&key_attributes, PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE | PSA_KEY_USAGE_EXPORT); + psa_set_key_algorithm(&key_attributes, PSA_ALG_ECDSA(PSA_ALG_SHA_256)); + psa_set_key_type(&key_attributes, PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1)); + psa_set_key_bits(&key_attributes, 256); + + psa_status_t status = psa_generate_key(&key_attributes, &key_id); + TEST_ASSERT(status == PSA_SUCCESS); + + unsigned char *key_buf = NULL; + int ret = crypto_write_pubkey_der((struct crypto_ec_key *)&key_id, &key_buf); + TEST_ASSERT(ret > 0); + free(key_buf); + ESP_LOGI("EC Test", "Public key DER size: %d", ret); + } +} diff --git a/components/wpa_supplicant/test_apps/main/test_dpp.c b/components/wpa_supplicant/test_apps/main/test_dpp.c index 69b5176fe8..e2cf939777 100644 --- a/components/wpa_supplicant/test_apps/main/test_dpp.c +++ b/components/wpa_supplicant/test_apps/main/test_dpp.c @@ -34,7 +34,7 @@ extern size_t dpp_nonce_override_len; TEST_CASE("Test vectors DPP responder p256", "[wpa_dpp]") { - set_leak_threshold(130); + set_leak_threshold(300); /* Global variables */ char command[1200] = {0}; const u8 *frame; diff --git a/components/wpa_supplicant/test_apps/main/test_wpa_supplicant_main.c b/components/wpa_supplicant/test_apps/main/test_wpa_supplicant_main.c index c206b4bf1d..0fc5f1c2fa 100644 --- a/components/wpa_supplicant/test_apps/main/test_wpa_supplicant_main.c +++ b/components/wpa_supplicant/test_apps/main/test_wpa_supplicant_main.c @@ -16,6 +16,8 @@ #include "sha/sha_core.h" #endif +#include "psa/crypto.h" + #define TEST_MEMORY_LEAK_THRESHOLD_DEFAULT 0 static int leak_threshold = TEST_MEMORY_LEAK_THRESHOLD_DEFAULT; void set_leak_threshold(int threshold) @@ -62,12 +64,15 @@ void setUp(void) mbedtls_aes_free(&ctx); #endif // SOC_AES_SUPPORTED + psa_crypto_init(); + before_free_8bit = heap_caps_get_free_size(MALLOC_CAP_8BIT); before_free_32bit = heap_caps_get_free_size(MALLOC_CAP_32BIT); } void tearDown(void) { + mbedtls_psa_crypto_free(); size_t after_free_8bit = heap_caps_get_free_size(MALLOC_CAP_8BIT); size_t after_free_32bit = heap_caps_get_free_size(MALLOC_CAP_32BIT); check_leak(before_free_8bit, after_free_8bit, "8BIT");