blob: 2f010a012ea083e376c3f4e6931dea58a1ca7b25 [file] [log] [blame]
/* Copyright (c) 2024 Nordic Semiconductor
* SPDX-License-Identifier: Apache-2.0
*/
#include <psa/crypto.h>
#include <zephyr/logging/log.h>
#include <zephyr/psa/key_ids.h>
LOG_MODULE_REGISTER(persistent_key);
#define SAMPLE_KEY_ID ZEPHYR_PSA_APPLICATION_KEY_ID_RANGE_BEGIN
#define SAMPLE_KEY_TYPE PSA_KEY_TYPE_AES
#define SAMPLE_ALG PSA_ALG_CTR
#define SAMPLE_KEY_BITS 256
int generate_persistent_key(void)
{
LOG_INF("Generating a persistent key...");
psa_status_t ret;
psa_key_id_t key_id;
psa_key_attributes_t key_attributes = PSA_KEY_ATTRIBUTES_INIT;
psa_set_key_lifetime(&key_attributes, PSA_KEY_LIFETIME_PERSISTENT);
psa_set_key_usage_flags(&key_attributes, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT);
psa_set_key_id(&key_attributes, SAMPLE_KEY_ID);
psa_set_key_type(&key_attributes, SAMPLE_KEY_TYPE);
psa_set_key_algorithm(&key_attributes, SAMPLE_ALG);
psa_set_key_bits(&key_attributes, SAMPLE_KEY_BITS);
ret = psa_generate_key(&key_attributes, &key_id);
if (ret != PSA_SUCCESS) {
LOG_ERR("Failed to generate the key. (%d)", ret);
return -1;
}
__ASSERT_NO_MSG(key_id == SAMPLE_KEY_ID);
/* Purge the key from volatile memory. Has the same affect than resetting the device. */
ret = psa_purge_key(SAMPLE_KEY_ID);
if (ret != PSA_SUCCESS) {
LOG_ERR("Failed to purge the generated key from volatile memory. (%d).", ret);
return -1;
}
LOG_INF("Persistent key generated.");
return 0;
}
int use_persistent_key(void)
{
LOG_INF("Using the persistent key to encrypt and decrypt some plaintext...");
psa_status_t ret;
size_t ciphertext_len;
size_t decrypted_text_len;
static uint8_t plaintext[] =
"Example plaintext to demonstrate basic usage of a persistent key.";
static uint8_t ciphertext[PSA_CIPHER_ENCRYPT_OUTPUT_SIZE(SAMPLE_KEY_TYPE, SAMPLE_ALG,
sizeof(plaintext))];
static uint8_t decrypted_text[sizeof(plaintext)];
ret = psa_cipher_encrypt(SAMPLE_KEY_ID, SAMPLE_ALG, plaintext, sizeof(plaintext),
ciphertext, sizeof(ciphertext), &ciphertext_len);
if (ret != PSA_SUCCESS) {
LOG_ERR("Failed to encrypt the plaintext. (%d)", ret);
return -1;
}
ret = psa_cipher_decrypt(SAMPLE_KEY_ID, SAMPLE_ALG, ciphertext, ciphertext_len,
decrypted_text, sizeof(decrypted_text), &decrypted_text_len);
if (ret != PSA_SUCCESS) {
LOG_ERR("Failed to decrypt the ciphertext. (%d)", ret);
return -1;
}
__ASSERT_NO_MSG(decrypted_text_len == sizeof(plaintext));
/* Make sure the decryption gives us the original plaintext back. */
if (memcmp(plaintext, decrypted_text, sizeof(plaintext))) {
LOG_HEXDUMP_INF(plaintext, sizeof(plaintext), "Plaintext:");
LOG_HEXDUMP_INF(ciphertext, ciphertext_len, "Ciphertext:");
LOG_HEXDUMP_INF(decrypted_text, sizeof(decrypted_text), "Decrypted text:");
LOG_ERR("The decrypted text doesn't match the plaintext.");
return -1;
}
LOG_INF("Persistent key usage successful.");
return 0;
}
static int destroy_persistent_key(void)
{
LOG_INF("Destroying the persistent key...");
psa_status_t ret;
ret = psa_destroy_key(SAMPLE_KEY_ID);
if (ret != PSA_SUCCESS) {
LOG_ERR("Failed to destroy the key. (%d)", ret);
return -1;
}
LOG_INF("Persistent key destroyed.");
return 0;
}
int main(void)
{
LOG_INF("Persistent key sample started.");
/* Ensure there is not already a key with this ID. */
psa_destroy_key(SAMPLE_KEY_ID);
if (generate_persistent_key()) {
return -1;
}
if (use_persistent_key()) {
return -1;
}
if (destroy_persistent_key()) {
return -1;
}
LOG_INF("Sample finished successfully.");
return 0;
}