Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
79 changes: 79 additions & 0 deletions src/libAtomVM/otp_crypto.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,28 @@
#include <mbedtls/sha512.h>
#include <mbedtls/version.h>

#ifdef MBEDTLS_PSA_CRYPTO_C
#include <psa/crypto.h>
#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,
Expand Down Expand Up @@ -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[])
{
Expand Down Expand Up @@ -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
Expand All @@ -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;
Expand Down
Loading