Skip to content

Commit

Permalink
pal: on dev cert support secure keys
Browse files Browse the repository at this point in the history
[KRKNWK-19108]

Signed-off-by: Krzysztof Taborowski <[email protected]>
  • Loading branch information
ktaborowski committed Sep 4, 2024
1 parent 1bbcc23 commit 2aed5b4
Show file tree
Hide file tree
Showing 11 changed files with 300 additions and 66 deletions.
1 change: 1 addition & 0 deletions Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,7 @@ config SIDEWALK_ON_DEV_CERT

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

config SIDEWALK_PAL_RADIO_SOURCE
Expand Down
1 change: 1 addition & 0 deletions Kconfig.dependencies
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ config SIDEWALK_CRYPTO
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 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
27 changes: 26 additions & 1 deletion subsys/sal/common/sid_on_dev_cert/sid_on_dev_cert.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@
#include <sid_pal_crypto_ifc.h>
#include <sid_pal_mfg_store_ifc.h>

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

#include <stdlib.h>
#include <string.h>
#include <sys/_stdint.h>
Expand Down Expand Up @@ -337,7 +341,23 @@ sid_error_t sid_on_dev_cert_generate_csr(enum sid_on_dev_cert_algo_type algo, ui
}

// Generate key pair
if ((ret = sid_pal_crypto_ecc_key_gen(&key_params)) == SID_ERROR_NONE) {
#ifdef CONFIG_SIDEWALK_CRYPTO_PSA_KEY_STORAGE
ret = SID_ERROR_GENERIC;
psa_key_id_t key_id =
(algo == SID_ODC_CRYPT_ALGO_ED25519) ? SID_CRYPTO_MFG_ED25519_PRIV_KEY_ID :
(algo == SID_ODC_CRYPT_ALGO_P256R1) ? SID_CRYPTO_MFG_SECP_256R1_PRIV_KEY_ID :
PSA_KEY_ID_NULL;
int err = sid_crypto_keys_new_generate(key_id, key_params.puk, key_params.puk_size);
if (!err) {
err = sid_crypto_keys_buffer_set(key_id, key_params.prk, key_params.prk_size);
if (!err) {
ret = SID_ERROR_NONE;
}
}
#else
ret = sid_pal_crypto_ecc_key_gen(&key_params);
#endif /* CONFIG_SIDEWALK_CRYPTO_PSA_KEY_STORAGE */
if (ret == SID_ERROR_NONE) {
/*
* Signing the certificate CSR
* Message_to_sign = Public key || SMSN
Expand Down Expand Up @@ -641,6 +661,11 @@ sid_error_t sid_on_dev_cert_verify_and_store(void)
goto exit;
}

#ifdef CONFIG_SIDEWALK_CRYPTO_PSA_KEY_STORAGE
memset(context->device_ed25519_prk, 0, SID_ODC_ED25519_PRK_SIZE);
memset(context->device_p256r1_prk, 0, SID_ODC_P256R1_PRK_SIZE);
#endif /* CONFIG_SIDEWALK_CRYPTO_PSA_KEY_STORAGE */

status = write_to_mfg_store(SID_PAL_MFG_STORE_SMSN, context->smsn, SID_ODC_SMSN_SIZE) &&
write_to_mfg_store(SID_PAL_MFG_STORE_APID, context->apid,
SID_PAL_MFG_STORE_APID_SIZE) &&
Expand Down
17 changes: 9 additions & 8 deletions subsys/sal/sid_pal/include/sid_crypto_keys.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,19 @@

#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)
#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_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;

/**
Expand Down Expand Up @@ -50,7 +51,7 @@ int sid_crypto_keys_new_import(psa_key_id_t id, uint8_t *data, size_t size);
* @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);
int sid_crypto_keys_new_generate(psa_key_id_t id, uint8_t *puk, size_t puk_size);

/**
* @brief Set key id in buffer.
Expand Down
21 changes: 16 additions & 5 deletions subsys/sal/sid_pal/src/sid_crypto_keys.c
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ int sid_crypto_keys_new_import(psa_key_id_t id, uint8_t *data, size_t size)
/* Import key to secure storage */
status = psa_import_key(&attributes, data, size, &out_id);
if (PSA_SUCCESS == status && out_id == id) {
LOG_HEXDUMP_DBG(data, size, "found new key: ");
LOG_DBG("psa_import_key success");
} else {
LOG_ERR("psa_import_key failed! (err %d id %d)", status, id);
return -EACCES;
Expand All @@ -100,10 +100,10 @@ int sid_crypto_keys_new_import(psa_key_id_t id, uint8_t *data, size_t size)
return ESUCCESS;
}

int sid_crypto_keys_new_generate(psa_key_id_t id)
int sid_crypto_keys_new_generate(psa_key_id_t id, uint8_t *puk, size_t puk_size)
{
/* Check arguments */
if (PSA_KEY_ID_NULL == id) {
if (PSA_KEY_ID_NULL == id || !puk || !puk_size) {
return -EINVAL;
}

Expand All @@ -116,6 +116,7 @@ int sid_crypto_keys_new_generate(psa_key_id_t id)

/* Configure the key attributes */
psa_key_id_t out_id = PSA_KEY_ID_NULL;
size_t out_size = 0;
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
sid_crypto_keys_attributes_set(id, &attributes);

Expand All @@ -124,10 +125,20 @@ int sid_crypto_keys_new_generate(psa_key_id_t id)
if (PSA_SUCCESS == status && out_id == id) {
LOG_DBG("key generation success");
} else {
LOG_ERR("psa_import_key failed! (err %d id %d)", status, id);
LOG_ERR("psa_generate_key failed! (err %d id %d)", status, id);
return -EACCES;
}

/* Export public key */
status = psa_export_public_key(id, puk, puk_size, &out_size);
if (PSA_SUCCESS == status && out_size == puk_size) {
LOG_DBG("export public key success");
} else {
LOG_ERR("psa_export_public_key failed! (err %d id %d)", status, id);
LOG_ERR("psa_export_public_key failed! (expected %d was %d)", puk_size, out_size);
return -EBADF;
}

/* Clear key data */
status = psa_purge_key(id);
if (status != PSA_SUCCESS) {
Expand All @@ -151,7 +162,7 @@ int sid_crypto_keys_buffer_set(psa_key_id_t id, uint8_t *data, size_t size)
memset(data, 0, size);
psa_key_id_t *data_id = (psa_key_id_t *)data;
*data_id = id;
LOG_HEXDUMP_DBG(data, size, "saved new key: ");
LOG_DBG("key buffer set %d", id);

return ESUCCESS;
}
Expand Down
111 changes: 75 additions & 36 deletions subsys/sal/sid_pal/src/sid_storage.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,30 @@
#include <sid_crypto_keys.h>

#define STORAGE_KV_INTERNAL_PROTOCOL_GROUP_ID 0
#define STORAGE_KV_WAN_MASTER_KEY 28
#define STORAGE_KV_APP_MASTER_KEY 30
#define STORAGE_KV_D2D_MASTER_KEY 48
#define STORAGE_KV_WAN_MASTER_KEY (28)
#define STORAGE_KV_APP_MASTER_KEY (30)
#define STORAGE_KV_D2D_MASTER_KEY (48)
#define STORAGE_MASTER_KEY_SIZE (16)
#endif /* CONFIG_SIDEWALK_CRYPTO_PSA_KEY_STORAGE */

#include <zephyr/logging/log.h>
#include <settings_utils.h>

LOG_MODULE_REGISTER(sid_storage, CONFIG_SIDEWALK_LOG_LEVEL);

#define STORAGE_SERIAL_SIZE (32)

static void settings_serialize_group(char *serial, size_t serial_size, uint16_t group)
{
snprintf(serial, serial_size, "sidewalk/storage/%04x", group);
}

static void settings_serialize_group_key(char *serial, size_t serial_size, uint16_t group,
uint16_t key)
{
snprintf(serial, serial_size, "sidewalk/storage/%04x/%04x", group, key);
}

#ifdef CONFIG_SIDEWALK_CRYPTO_PSA_KEY_STORAGE
static psa_key_id_t storage2key_id(uint16_t group, uint16_t key)
{
Expand All @@ -42,6 +56,37 @@ static psa_key_id_t storage2key_id(uint16_t group, uint16_t key)
}
return PSA_KEY_ID_NULL;
}

static void storage_key_save_secure(uint16_t group, uint16_t key)
{
int err = 0;
char serial[STORAGE_SERIAL_SIZE] = { 0 };
uint8_t data[STORAGE_MASTER_KEY_SIZE];
psa_key_id_t key_id = storage2key_id(group, key);

settings_serialize_group_key(serial, sizeof(serial), group, key);
err = settings_utils_load_immediate_value(serial, (void *)data, STORAGE_MASTER_KEY_SIZE);
if (err == -ENOENT) {
LOG_DBG("not found key %04x", key);
return;
}
if (err < 0) {
LOG_ERR("load key %04x err %d", key, err);
return;
}

err = sid_crypto_keys_new_import(key_id, (void *)data, STORAGE_MASTER_KEY_SIZE);
if (err) {
LOG_ERR("crypto import %d err %d", key_id, err);
return;
}

err = settings_delete(serial);
if (err) {
LOG_ERR("delete key %04x err %d", key, err);
return;
}
}
#endif /* CONFIG_SIDEWALK_CRYPTO_PSA_KEY_STORAGE */

sid_error_t sid_pal_storage_kv_init()
Expand All @@ -59,18 +104,15 @@ sid_error_t sid_pal_storage_kv_init()
}

LOG_DBG("Initialized KV storage");
return SID_ERROR_NONE;
}

static void settings_serialize_group(char *serial, size_t serial_size, uint16_t group)
{
snprintf(serial, serial_size, "sidewalk/storage/%04x", group);
}
#ifdef CONFIG_SIDEWALK_CRYPTO_PSA_KEY_STORAGE
storage_key_save_secure(STORAGE_KV_INTERNAL_PROTOCOL_GROUP_ID, STORAGE_KV_WAN_MASTER_KEY);
storage_key_save_secure(STORAGE_KV_INTERNAL_PROTOCOL_GROUP_ID,
STORAGE_KV_APP_MASTER_KEY);
storage_key_save_secure(STORAGE_KV_INTERNAL_PROTOCOL_GROUP_ID, STORAGE_KV_D2D_MASTER_KEY);
#endif /* CONFIG_SIDEWALK_CRYPTO_PSA_KEY_STORAGE */

static void settings_serialize_group_key(char *serial, size_t serial_size, uint16_t group,
uint16_t key)
{
snprintf(serial, serial_size, "sidewalk/storage/%04x/%04x", group, key);
return SID_ERROR_NONE;
}

sid_error_t sid_pal_storage_kv_record_get(uint16_t group, uint16_t key, void *p_data, uint32_t len)
Expand All @@ -92,12 +134,12 @@ sid_error_t sid_pal_storage_kv_record_get(uint16_t group, uint16_t key, void *p_
}
#endif /* CONFIG_SIDEWALK_CRYPTO_PSA_KEY_STORAGE */

char serial[32] = { 0 };
char serial[STORAGE_SERIAL_SIZE] = { 0 };
settings_serialize_group_key(serial, sizeof(serial), group, key);
int rc = settings_utils_load_immediate_value(serial, p_data, len);
if (rc <= 0)
if (rc <= 0) {
return SID_ERROR_NOT_FOUND;
else
} else
return SID_ERROR_NONE;
}

Expand All @@ -106,7 +148,7 @@ sid_error_t sid_pal_storage_kv_record_get_len(uint16_t group, uint16_t key, uint
if (!p_len) {
return SID_ERROR_NULL_POINTER;
}
char serial[32] = { 0 };
char serial[STORAGE_SERIAL_SIZE] = { 0 };
settings_serialize_group_key(serial, sizeof(serial), group, key);
int rc = settings_utils_get_value_size(serial, p_len);
if (rc < 0 || *p_len == 0)
Expand Down Expand Up @@ -138,7 +180,7 @@ sid_error_t sid_pal_storage_kv_record_set(uint16_t group, uint16_t key, void con
}
#endif /* CONFIG_SIDEWALK_CRYPTO_PSA_KEY_STORAGE */

char serial[32] = { 0 };
char serial[STORAGE_SERIAL_SIZE] = { 0 };
settings_serialize_group_key(serial, sizeof(serial), group, key);

int rc = settings_save_one(serial, (const void *)p_data, len);
Expand Down Expand Up @@ -170,7 +212,7 @@ sid_error_t sid_pal_storage_kv_record_delete(uint16_t group, uint16_t key)
}
#endif /* CONFIG_SIDEWALK_CRYPTO_PSA_KEY_STORAGE */

char serial[32] = { 0 };
char serial[STORAGE_SERIAL_SIZE] = { 0 };
settings_serialize_group_key(serial, sizeof(serial), group, key);
int rc = settings_delete(serial);
if (rc == 0) {
Expand All @@ -184,7 +226,7 @@ int delete_subtree_cb(const char *key, size_t len, settings_read_cb read_cb, voi
void *param)
{
char *subtree = (char *)param;
char serial[32] = { 0 };
char serial[STORAGE_SERIAL_SIZE] = { 0 };
snprintf(serial, sizeof(serial), "%s/%s", subtree, key);
int rc = settings_delete(serial);
if (rc != 0) {
Expand All @@ -196,6 +238,19 @@ int delete_subtree_cb(const char *key, size_t len, settings_read_cb read_cb, voi

sid_error_t sid_pal_storage_kv_group_delete(uint16_t group)
{
char serial[STORAGE_SERIAL_SIZE] = { 0 };
settings_serialize_group(serial, sizeof(serial), group);
int rc = settings_load_subtree_direct(serial, delete_subtree_cb, (void *)serial);
if (rc != 0) {
LOG_ERR("Failed to delete group. Returned errno %d", rc);
return SID_ERROR_STORAGE_ERASE_FAIL;
}
rc = settings_commit();
if (rc != 0) {
LOG_ERR("Failed to commit changes. Returned errno %d", rc);
return SID_ERROR_GENERIC;
}

#ifdef CONFIG_SIDEWALK_CRYPTO_PSA_KEY_STORAGE
bool key_delete_fail = false;
if (STORAGE_KV_INTERNAL_PROTOCOL_GROUP_ID == group) {
Expand All @@ -216,22 +271,6 @@ sid_error_t sid_pal_storage_kv_group_delete(uint16_t group)
key_delete_fail = true;
}
}
#endif /* CONFIG_SIDEWALK_CRYPTO_PSA_KEY_STORAGE */

char serial[32] = { 0 };
settings_serialize_group(serial, sizeof(serial), group);
int rc = settings_load_subtree_direct(serial, delete_subtree_cb, (void *)serial);
if (rc != 0) {
LOG_ERR("Failed to delete group. Returned errno %d", rc);
return SID_ERROR_STORAGE_ERASE_FAIL;
}
rc = settings_commit();
if (rc != 0) {
LOG_ERR("Failed to commit changes. Returned errno %d", rc);
return SID_ERROR_GENERIC;
}

#ifdef CONFIG_SIDEWALK_CRYPTO_PSA_KEY_STORAGE
if (key_delete_fail) {
return SID_ERROR_STORAGE_ERASE_FAIL;
}
Expand Down
4 changes: 4 additions & 0 deletions tests/functional/crypto_keys/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ config SIDEWALK_CRYPTO
config SIDEWALK_STORAGE
default y

config SIDEWALK_SETTINGS_UTILS
default y

config SIDEWALK_CRYPTO_PSA_KEY_STORAGE
default y

Expand All @@ -34,5 +37,6 @@ config HEAP_MEM_POOL_SIZE
config MBEDTLS_HEAP_SIZE
default 4096

rsource "Kconfig.defconfig"
source "Kconfig.zephyr"
source "${ZEPHYR_BASE}/../sidewalk/Kconfig.dependencies"
17 changes: 17 additions & 0 deletions tests/functional/crypto_keys/Kconfig.defconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#
# Copyright (c) 2024 Nordic Semiconductor ASA
#
# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
#

config PSA_USE_CC3XX_KEY_AGREEMENT_DRIVER
default n if SOC_NRF52840 || SOC_NRF5340_CPUAPP

config PSA_USE_CC3XX_ASYMMETRIC_SIGNATURE_DRIVER
default n if SOC_NRF52840 || SOC_NRF5340_CPUAPP

config PSA_USE_CC3XX_ASYMMETRIC_ENCRYPTION_DRIVER
default n if SOC_NRF52840 || SOC_NRF5340_CPUAPP

config PSA_USE_CC3XX_KEY_MANAGEMENT_DRIVER
default n if SOC_NRF52840 || SOC_NRF5340_CPUAPP
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#
# Copyright (c) 2024 Nordic Semiconductor ASA
#
# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
#

CONFIG_SOC_FLASH_NRF_TIMEOUT_MULTIPLIER=100
Loading

0 comments on commit 2aed5b4

Please sign in to comment.