We need to make sure that within Zephyr different users of the PSA APIs don't interfere with each other because of using the same numerical IDs for persistent assets. This takes care of the PSA key IDs when using persistent keys through the PSA Crypto API. See the comments in `<zephyr/psa/key_ids.h>` for more information. This removes the recently-introduced Kconfig options that allowed changing the base IDs subsystems were using for their persistent keys. Signed-off-by: Tomi Fontanilles <tomi.fontanilles@nordicsemi.no>
125 lines
3.5 KiB
C
125 lines
3.5 KiB
C
/* 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;
|
|
}
|