Skip to content

Commit

Permalink
pal: add crypto keys module
Browse files Browse the repository at this point in the history
[KRKNWK-19108]
Add sidewalk pal module to store persistent keys.
It uses secure storage via psa api.
use secure keys in mfg pal.
use secure keys in kv storage pal.

Signed-off-by: Krzysztof Taborowski <[email protected]>
  • Loading branch information
ktaborowski committed Aug 2, 2024
1 parent 58c646d commit 6ac5ba4
Show file tree
Hide file tree
Showing 15 changed files with 730 additions and 4 deletions.
4 changes: 4 additions & 0 deletions Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,10 @@ config SIDEWALK_ON_DEV_CERT
bool "Enable Sidewalk on device certification"
depends on SHELL

config SIDEWALK_CRYPTO_PSA_KEY_STORAGE
bool "Enable psa crypto storage for persistent Sidewalk keys [EXPERIMENTAL]"
select EXPERIMENTAL

config SIDEWALK_PAL_RADIO_SOURCE
bool "Build sub-GHz radio driver from sources [EXPERIMENTAL]"
select EXPERIMENTAL
Expand Down
3 changes: 3 additions & 0 deletions Kconfig.dependencies
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,9 @@ config SIDEWALK_CRYPTO
imply PSA_WANT_KEY_TYPE_HMAC
imply PSA_WANT_GENERATE_RANDOM
imply MBEDTLS_ENABLE_HEAP
imply MBEDTLS_PSA_CRYPTO_STORAGE_C if SIDEWALK_CRYPTO_PSA_KEY_STORAGE
imply TRUSTED_STORAGE if SIDEWALK_CRYPTO_PSA_KEY_STORAGE
imply HW_UNIQUE_KEY_WRITE_ON_CRYPTO_INIT if SIDEWALK_CRYPTO_PSA_KEY_STORAGE
help
Sidewalk security module

Expand Down
94 changes: 94 additions & 0 deletions subsys/sal/sid_pal/include/sid_crypto_keys.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
/*
* Copyright (c) 2024 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
*/

#ifndef SID_CRYPTO_KEYS_H
#define SID_CRYPTO_KEYS_H

#include <psa/crypto.h>

#define SID_CRYPTO_KEYS_ID_IS_SIDEWALK_KEY(_id) (PSA_KEY_ID_USER_MIN <= _id && _id < SID_CRYPTO_KEY_ID_LAST)

/**
* @brief Persistent psa key ids used in Sidewalk.
*/
typedef enum {
SID_CRYPTO_MFG_ED25519_PRIV_KEY_ID = PSA_KEY_ID_USER_MIN,
SID_CRYPTO_MFG_SECP_256R1_PRIV_KEY_ID,
SID_CRYPTO_KV_WAN_MASTER_KEY_ID,
SID_CRYPTO_KV_APP_KEY_KEY_ID,
SID_CRYPTO_KV_D2D_KEY_ID,
SID_CRYPTO_KEY_ID_LAST
} sid_crypto_key_id_t;

/**
* @brief Init secure key storage for Sidewalk keys.
*
* @return 0 on success, or -errno on failure.
*/
int sid_crypto_keys_init(void);

/**
* @brief Import key value form buffer.
*
* @note key value under given key id will be overwritten.
*
* @param id [in] Key id to import data.
* @param data [in] raw key data on input.
* @param size [in] size of raw key data buffer.
* @return 0 on success, or -errno on failure.
*/
int sid_crypto_keys_new_import(psa_key_id_t id, uint8_t *data, size_t size);

/**
* @brief Generate a new key value.
*
* @note key value under given key id will be overwritten.
*
* @param id [in] Key id to generate new.
* @return 0 on success, or -errno on failure.
*/
int sid_crypto_keys_new_generate(psa_key_id_t id);

/**
* @brief Set key id in buffer.
*
* @param id [in] Key id to write to the data buffer.
* @param buffer [out] key id fulfilled with zeros.
* @param size [in] size of raw key data buffer.
* @return 0 on success, or -errno on failure.
*/
int sid_crypto_keys_buffer_set(psa_key_id_t id, uint8_t *buffer, size_t size);

/**
* @brief Get key id from buffer.
*
* @param id [out] psa key id from key data buffer.
* If key not found set to PSA_KEY_ID_NULL.
* @param buffer [in] key data buffer.
* @param size [in] size of key data buffer.
* @return 0 on success, or -errno on failure.
* -ENOENT - if no key in buffer.
*/
int sid_crypto_keys_buffer_get(psa_key_id_t *id, uint8_t *buffer, size_t size);

/**
* @brief Destroy key.
*
* @note This operation is irreversible.
*
* @param id [in] psa key id to be permanently removed.
* @return 0 on success, or -errno on failure.
*/
int sid_crypto_keys_delete(psa_key_id_t id);

/**
* @brief Deinit sidewalk key storage.
*
* @return 0 on success, or -errno on failure.
*/
int sid_crypto_keys_deinit(void);

#endif /* SID_CRYPTO_KEYS_H */
1 change: 1 addition & 0 deletions subsys/sal/sid_pal/src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ zephyr_library_sources_ifdef(CONFIG_SIDEWALK_VENDOR_SERVICE sid_ble_vnd_service.
zephyr_library_sources_ifdef(CONFIG_SIDEWALK_LOGGING_SERVICE sid_ble_log_service.c)

zephyr_library_sources_ifdef(CONFIG_SIDEWALK_CRYPTO sid_crypto.c)
zephyr_library_sources_ifdef(CONFIG_SIDEWALK_CRYPTO_PSA_KEY_STORAGE sid_crypto_keys.c)

zephyr_library_sources_ifdef(CONFIG_SIDEWALK_MFG_STORAGE sid_mfg_storage.c)

Expand Down
84 changes: 80 additions & 4 deletions subsys/sal/sid_pal/src/sid_crypto.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@
*/

#include <sid_pal_crypto_ifc.h>
#ifdef CONFIG_SIDEWALK_CRYPTO_PSA_KEY_STORAGE
#include <sid_crypto_keys.h>
#endif /* CONFIG_SIDEWALK_CRYPTO_PSA_KEY_STORAGE */

#include <zephyr/device.h>
#include <zephyr/kernel.h>
Expand Down Expand Up @@ -151,6 +154,13 @@ static psa_status_t prepare_key(const uint8_t *key, size_t key_length, size_t ke
return PSA_ERROR_DATA_INVALID;
}

#ifdef CONFIG_SIDEWALK_CRYPTO_PSA_KEY_STORAGE
int err = sid_crypto_keys_buffer_get(key_handle, (uint8_t *)key, key_length);
if (!err && SID_CRYPTO_KEYS_ID_IS_SIDEWALK_KEY(*key_handle)) {
return PSA_SUCCESS;
}
#endif /* CONFIG_SIDEWALK_CRYPTO_PSA_KEY_STORAGE */

psa_set_key_usage_flags(&attributes, usage_flags);
psa_set_key_lifetime(&attributes, PSA_KEY_LIFETIME_VOLATILE);
psa_set_key_algorithm(&attributes, alg);
Expand Down Expand Up @@ -365,6 +375,13 @@ static psa_status_t aead_decrypt(psa_key_handle_t key_handle, sid_pal_aead_param

sid_error_t sid_pal_crypto_init(void)
{
#ifdef CONFIG_SIDEWALK_CRYPTO_PSA_KEY_STORAGE
int err = sid_crypto_keys_init();
if (err) {
LOG_ERR("Keys init failed! (err: %d)", err);
return SID_ERROR_NOT_FOUND;
}
#endif /* CONFIG_SIDEWALK_CRYPTO_PSA_KEY_STORAGE */
psa_status_t status = psa_crypto_init();

if (PSA_SUCCESS == status) {
Expand All @@ -379,6 +396,14 @@ sid_error_t sid_pal_crypto_init(void)

sid_error_t sid_pal_crypto_deinit(void)
{
#ifdef CONFIG_SIDEWALK_CRYPTO_PSA_KEY_STORAGE
int err = sid_crypto_keys_deinit();
if (err) {
LOG_ERR("Keys deinit failed! (err: %d)", err);
return SID_ERROR_NOT_FOUND;
}
#endif /* CONFIG_SIDEWALK_CRYPTO_PSA_KEY_STORAGE */

is_initialized = false;
return SID_ERROR_NONE;
}
Expand Down Expand Up @@ -499,9 +524,17 @@ sid_error_t sid_pal_crypto_hmac(sid_pal_hmac_params_t *params)
}
}

#ifdef CONFIG_SIDEWALK_CRYPTO_PSA_KEY_STORAGE
if (!SID_CRYPTO_KEYS_ID_IS_SIDEWALK_KEY(key_handle)) {
if (PSA_SUCCESS != psa_destroy_key(key_handle)) {
LOG_WRN("Destroy key failed!");
}
}
#else
if (PSA_SUCCESS != psa_destroy_key(key_handle)) {
LOG_WRN("Destroy key failed!");
}
#endif /* CONFIG_SIDEWALK_CRYPTO_PSA_KEY_STORAGE */
}

return get_error(status, __func__);
Expand Down Expand Up @@ -576,9 +609,17 @@ sid_error_t sid_pal_crypto_aes_crypt(sid_pal_aes_params_t *params)
return SID_ERROR_INVALID_ARGS;
}

#ifdef CONFIG_SIDEWALK_CRYPTO_PSA_KEY_STORAGE
if (!SID_CRYPTO_KEYS_ID_IS_SIDEWALK_KEY(key_handle)) {
if (PSA_SUCCESS != psa_destroy_key(key_handle)) {
LOG_WRN("Destroy key failed!");
}
}
#else
if (PSA_SUCCESS != psa_destroy_key(key_handle)) {
LOG_WRN("Destroy key failed!");
}
#endif /* CONFIG_SIDEWALK_CRYPTO_PSA_KEY_STORAGE */
}

return get_error(status, __func__);
Expand Down Expand Up @@ -649,9 +690,17 @@ sid_error_t sid_pal_crypto_aead_crypt(sid_pal_aead_params_t *params)
return SID_ERROR_INVALID_ARGS;
}

#ifdef CONFIG_SIDEWALK_CRYPTO_PSA_KEY_STORAGE
if (!SID_CRYPTO_KEYS_ID_IS_SIDEWALK_KEY(key_handle)) {
if (PSA_SUCCESS != psa_destroy_key(key_handle)) {
LOG_WRN("Destroy key failed!");
}
}
#else
if (PSA_SUCCESS != psa_destroy_key(key_handle)) {
LOG_WRN("Destroy key failed!");
}
#endif /* CONFIG_SIDEWALK_CRYPTO_PSA_KEY_STORAGE */
}

return get_error(status, __func__);
Expand Down Expand Up @@ -715,16 +764,18 @@ sid_error_t sid_pal_crypto_ecc_dsa(sid_pal_dsa_params_t *params)
ECC_FAMILY_TYPE(params->mode, type), &key_handle);

if (PSA_SUCCESS == status) {
LOG_DBG("Key import success.");
LOG_DBG("Key import success. handle %04x", key_handle);

switch (params->mode) {
case SID_PAL_CRYPTO_VERIFY:
LOG_DBG("dsa verify");
status = psa_verify_message(key_handle, alg, params->in, params->in_size,
params->signature, params->sig_size);

break;
case SID_PAL_CRYPTO_SIGN: {
size_t out_len;
LOG_DBG("dsa sign");

status = psa_sign_message(key_handle, alg, params->in, params->in_size,
params->signature, params->sig_size, &out_len);
Expand All @@ -733,9 +784,17 @@ sid_error_t sid_pal_crypto_ecc_dsa(sid_pal_dsa_params_t *params)
return SID_ERROR_INVALID_ARGS;
}

#ifdef CONFIG_SIDEWALK_CRYPTO_PSA_KEY_STORAGE
if (!SID_CRYPTO_KEYS_ID_IS_SIDEWALK_KEY(key_handle)) {
if (PSA_SUCCESS != psa_destroy_key(key_handle)) {
LOG_WRN("Destroy key failed!");
}
}
#else
if (PSA_SUCCESS != psa_destroy_key(key_handle)) {
LOG_WRN("Destroy key failed!");
}
#endif /* CONFIG_SIDEWALK_CRYPTO_PSA_KEY_STORAGE */
}

return get_error(status, __func__);
Expand Down Expand Up @@ -796,10 +855,19 @@ sid_error_t sid_pal_crypto_ecc_ecdh(sid_pal_ecdh_params_t *params)
status = psa_raw_key_agreement(PSA_ALG_ECDH, priv_key_handle, pub_key, pub_key_size,
params->shared_secret, params->shared_secret_sz,
&out_len);
}
LOG_DBG("ecdh key agreement %s", (PSA_SUCCESS == status) ? "success." : "failed!");

if (PSA_SUCCESS != psa_destroy_key(priv_key_handle)) {
LOG_WRN("Destroy key failed!");
#ifdef CONFIG_SIDEWALK_CRYPTO_PSA_KEY_STORAGE
if (!SID_CRYPTO_KEYS_ID_IS_SIDEWALK_KEY(priv_key_handle)) {
if (PSA_SUCCESS != psa_destroy_key(priv_key_handle)) {
LOG_WRN("Destroy key failed!");
}
}
#else
if (PSA_SUCCESS != psa_destroy_key(priv_key_handle)) {
LOG_WRN("Destroy key failed!");
}
#endif /* CONFIG_SIDEWALK_CRYPTO_PSA_KEY_STORAGE */
}

return get_error(status, __func__);
Expand Down Expand Up @@ -877,9 +945,17 @@ sid_error_t sid_pal_crypto_ecc_key_gen(sid_pal_ecc_key_gen_params_t *params)
(PSA_SUCCESS == status) ? "success." : "failed!");
}

#ifdef CONFIG_SIDEWALK_CRYPTO_PSA_KEY_STORAGE
if (!SID_CRYPTO_KEYS_ID_IS_SIDEWALK_KEY(keys_handle)) {
if (PSA_SUCCESS != psa_destroy_key(keys_handle)) {
LOG_WRN("Destroy key failed!");
}
}
#else
if (PSA_SUCCESS != psa_destroy_key(keys_handle)) {
LOG_WRN("Destroy key failed!");
}
#endif /* CONFIG_SIDEWALK_CRYPTO_PSA_KEY_STORAGE */
}
psa_reset_key_attributes(&key_attributes);

Expand Down
Loading

0 comments on commit 6ac5ba4

Please sign in to comment.