Hi!
I am currently testing out the TF-M features on the nRF9160 and I want to encrypt some data on the device. So my plan here is to use symmetric encryption with a key derived using ECDH.
To accomplish this I want to only exchange public keys between the device and the receiver. My idea is that I can use the HUK in the device to derive an ECC(secp256r1) key pair on the device and print the pulbic key as well as flashing the other public key onto the device during production.
I have tried to change the hw_unique_key sample to generate an ECC key pair, but with no luck. Do you have any clues for me?
I am currently on NCS 2.1.1 and this is the code I am currently using which gives me a "psa_key_derivation_output_key returned error: -147" which should indicate a hardware error:
#include <zephyr/kernel.h> #include <zephyr/sys/printk.h> #include <string.h> #include <stdio.h> #include <hw_unique_key.h> #include <psa/crypto.h> #include <tfm_crypto_defs.h> psa_key_id_t derive_asymmetric_key(psa_key_attributes_t *attributes) { psa_status_t status; psa_key_derivation_operation_t op = PSA_KEY_DERIVATION_OPERATION_INIT; psa_key_id_t key_id_out = 0; /* Set up a key derivation operation with HUK derivation as the alg */ status = psa_key_derivation_setup(&op, TFM_CRYPTO_ALG_HUK_DERIVATION); if (status != PSA_SUCCESS) { printk("psa_key_derivation_setup returned error: %d\n", status); return 0; } /* Create the encryption key from the key derivation operation */ status = psa_key_derivation_output_key(attributes, &op, &key_id_out); if (status != PSA_SUCCESS) { printk("psa_key_derivation_output_key returned error: %d\n", status); return 0; } printk("(Key resides internally in TF-M)\n"); /* Free resources associated with the key derivation operation */ status = psa_key_derivation_abort(&op); if (status != PSA_SUCCESS) { printk("psa_key_derivation_abort returned error: %d\n", status); return 0; } return key_id_out; } void hex_dump(uint8_t *buff, uint32_t len) { for (int i = 0; i < len; i++) { printk("%s%02x", i && ((i % 32) == 0) ? "\n" : "", buff[i]); } printk("\n"); } void main(void) { psa_status_t status; psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; psa_key_id_t key_id_out = 0; printk("Derive a key, then use it to encrypt a message.\n\n"); status = psa_crypto_init(); if (status != PSA_SUCCESS) { printk("psa_crypto_init returned error: %d\n", status); return; } printk("Deriving key\n"); /* Set the key attributes for the storage key */ psa_set_key_usage_flags(&attributes, (PSA_KEY_USAGE_DERIVE | PSA_KEY_USAGE_VERIFY_DERIVATION)); psa_set_key_type(&attributes, PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1)); psa_set_key_bits(&attributes, 256); key_id_out = derive_asymmetric_key(&attributes); if (key_id_out == 0) { return; } printk("Key ID: 0x%x\n\n", key_id_out); uint8_t public_key[256]; size_t public_key_size = 0; status = psa_export_public_key(key_id_out, public_key, sizeof(public_key), &public_key_size); if (status != PSA_SUCCESS) { printk("Could not export public key: %d\n", status); } printk("Public key:\n"); hex_dump(public_key, public_key_size); }