From 8b827d1f1ff784344dec6c790d5ef01de65e229c Mon Sep 17 00:00:00 2001 From: Davide Bettio Date: Fri, 16 Jan 2026 01:36:48 +0100 Subject: [PATCH] WIP: generate key using PSA API Signed-off-by: Davide Bettio --- src/libAtomVM/otp_crypto.c | 79 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) diff --git a/src/libAtomVM/otp_crypto.c b/src/libAtomVM/otp_crypto.c index f773f83241..bf507c6aeb 100644 --- a/src/libAtomVM/otp_crypto.c +++ b/src/libAtomVM/otp_crypto.c @@ -39,11 +39,28 @@ #include #include +#ifdef MBEDTLS_PSA_CRYPTO_C +#include +#endif + // #define ENABLE_TRACE +#include "term.h" #include "trace.h" #define MAX_MD_SIZE 64 +#ifdef MBEDTLS_PSA_CRYPTO_C +static void f(void) +{ + if (UNLIKELY(psa_crypto_init() != PSA_SUCCESS)) { + abort(); + } + + fprintf(stderr, "PSA: %i\n", PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_TWISTED_EDWARDS)); + fprintf(stderr, "PSA: %i\n", PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_MONTGOMERY)); +} +#endif + enum crypto_algorithm { CryptoInvalidAlgorithm = 0, @@ -564,6 +581,56 @@ static term nif_crypto_crypto_one_time(Context *ctx, int argc, term argv[]) RAISE_ERROR(make_crypto_error(__FILE__, source_line, err_msg, ctx)); } +#ifdef MBEDTLS_PSA_CRYPTO_C +static term nif_crypto_generate_key(Context *ctx, int argc, term argv[]) +{ + UNUSED(ctx); + UNUSED(argc); + UNUSED(argv); + + f(); + + size_t key_bits = 256; + + psa_status_t status; + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_key_id_t key_id; + + psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_EXPORT); + psa_set_key_algorithm(&attributes, + PSA_ALG_DETERMINISTIC_ECDSA(PSA_ALG_SHA_256)); + psa_set_key_type(&attributes, + PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1)); + psa_set_key_bits(&attributes, key_bits); + status = psa_generate_key(&attributes, &key_id); + if (status != PSA_SUCCESS) { + printf("Failed to generate key\n"); + return term_invalid_term(); + } + psa_reset_key_attributes(&attributes); + + uint8_t exported_priv[PSA_KEY_EXPORT_ECC_KEY_PAIR_MAX_SIZE(256)]; + size_t exported_priv_length = 0; + status = psa_export_key(key_id, exported_priv, sizeof(exported_priv), + &exported_priv_length); + if (status != PSA_SUCCESS) { + printf("Failed to export private key\n"); + return term_invalid_term(); + } + + uint8_t exported_pub[PSA_KEY_EXPORT_ECC_PUBLIC_KEY_MAX_SIZE(key_bits)]; + size_t exported_pub_length = 0; + status = psa_export_public_key(key_id, exported_pub, sizeof(exported_pub), + &exported_pub_length); + if (status != PSA_SUCCESS) { + printf("Failed to export public key\n"); + return term_invalid_term(); + } + + return OK_ATOM; +} +#endif + // not static since we are using it elsewhere to provide backward compatibility term nif_crypto_strong_rand_bytes(Context *ctx, int argc, term argv[]) { @@ -606,6 +673,12 @@ static const struct Nif crypto_crypto_one_time_nif = { .base.type = NIFFunctionType, .nif_ptr = nif_crypto_crypto_one_time }; +#ifdef MBEDTLS_PSA_CRYPTO_C +static const struct Nif crypto_generate_key_nif = { + .base.type = NIFFunctionType, + .nif_ptr = nif_crypto_generate_key +}; +#endif static const struct Nif crypto_strong_rand_bytes_nif = { .base.type = NIFFunctionType, .nif_ptr = nif_crypto_strong_rand_bytes @@ -631,6 +704,12 @@ const struct Nif *otp_crypto_nif_get_nif(const char *nifname) TRACE("Resolved platform nif %s ...\n", nifname); return &crypto_crypto_one_time_nif; } +#ifdef MBEDTLS_PSA_CRYPTO_C + if (strcmp("crypto_generate_key/2", rest) == 0) { + TRACE("Resolved platform nif %s ...\n", nifname); + return &crypto_generate_key_nif; + } +#endif if (strcmp("strong_rand_bytes/1", rest) == 0) { TRACE("Resolved platform nif %s ...\n", nifname); return &crypto_strong_rand_bytes_nif;