A mesh key type has been added to be able to choose the different key representation for different security libraries. The type as well as some functionality related to Mesh key management has been added as a public API. If tynicrypt is chosen then keys have representation as 16 bytes array. If mbedTLS with PSA is used then keys are the PSA key id. Raw value is not kept within BLE Mesh stack for mbedTLS. Keys are imported into the security library and key ids are gotten back. This refactoring has been done for the network(including all derivated keys), application, device, and session keys. Signed-off-by: Aleksandr Khromykh <aleksandr.khromykh@nordicsemi.no>
154 lines
3.5 KiB
C
154 lines
3.5 KiB
C
/*
|
|
* Copyright (c) 2017 Intel Corporation
|
|
* Copyright (c) 2023 Nordic Semiconductor ASA
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
|
|
#include <errno.h>
|
|
|
|
#include <tinycrypt/constants.h>
|
|
#include <tinycrypt/utils.h>
|
|
#include <tinycrypt/aes.h>
|
|
#include <tinycrypt/cmac_mode.h>
|
|
#include <tinycrypt/ccm_mode.h>
|
|
#include <tinycrypt/ecc.h>
|
|
#include <tinycrypt/ecc_dh.h>
|
|
#include <tinycrypt/hmac.h>
|
|
|
|
#include <zephyr/bluetooth/mesh.h>
|
|
#include <zephyr/bluetooth/crypto.h>
|
|
|
|
#define LOG_LEVEL CONFIG_BT_MESH_CRYPTO_LOG_LEVEL
|
|
#include <zephyr/logging/log.h>
|
|
LOG_MODULE_REGISTER(bt_mesh_crypto_tc);
|
|
|
|
#include "mesh.h"
|
|
#include "crypto.h"
|
|
#include "prov.h"
|
|
|
|
static struct {
|
|
bool is_ready;
|
|
uint8_t private_key_be[PRIV_KEY_SIZE];
|
|
uint8_t public_key_be[PUB_KEY_SIZE];
|
|
} key;
|
|
|
|
int bt_mesh_encrypt(const struct bt_mesh_key *key, const uint8_t plaintext[16],
|
|
uint8_t enc_data[16])
|
|
{
|
|
return bt_encrypt_be(key->key, plaintext, enc_data);
|
|
}
|
|
|
|
int bt_mesh_ccm_encrypt(const struct bt_mesh_key *key, uint8_t nonce[13], const uint8_t *plaintext,
|
|
size_t len, const uint8_t *aad, size_t aad_len, uint8_t *enc_data,
|
|
size_t mic_size)
|
|
{
|
|
return bt_ccm_encrypt(key->key, nonce, plaintext, len, aad, aad_len, enc_data, mic_size);
|
|
}
|
|
|
|
int bt_mesh_ccm_decrypt(const struct bt_mesh_key *key, uint8_t nonce[13], const uint8_t *enc_data,
|
|
size_t len, const uint8_t *aad, size_t aad_len, uint8_t *plaintext,
|
|
size_t mic_size)
|
|
{
|
|
return bt_ccm_decrypt(key->key, nonce, enc_data, len, aad, aad_len, plaintext, mic_size);
|
|
}
|
|
|
|
int bt_mesh_aes_cmac_raw_key(const uint8_t key[16], struct bt_mesh_sg *sg, size_t sg_len,
|
|
uint8_t mac[16])
|
|
{
|
|
struct tc_aes_key_sched_struct sched;
|
|
struct tc_cmac_struct state;
|
|
|
|
if (tc_cmac_setup(&state, key, &sched) == TC_CRYPTO_FAIL) {
|
|
return -EIO;
|
|
}
|
|
|
|
for (; sg_len; sg_len--, sg++) {
|
|
if (tc_cmac_update(&state, sg->data, sg->len) == TC_CRYPTO_FAIL) {
|
|
return -EIO;
|
|
}
|
|
}
|
|
|
|
if (tc_cmac_final(mac, &state) == TC_CRYPTO_FAIL) {
|
|
return -EIO;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int bt_mesh_aes_cmac_mesh_key(const struct bt_mesh_key *key, struct bt_mesh_sg *sg,
|
|
size_t sg_len, uint8_t mac[16])
|
|
{
|
|
return bt_mesh_aes_cmac_raw_key(key->key, sg, sg_len, mac);
|
|
}
|
|
|
|
int bt_mesh_sha256_hmac_raw_key(const uint8_t key[32], struct bt_mesh_sg *sg, size_t sg_len,
|
|
uint8_t mac[32])
|
|
{
|
|
struct tc_hmac_state_struct h;
|
|
|
|
if (tc_hmac_set_key(&h, key, 32) == TC_CRYPTO_FAIL) {
|
|
return -EIO;
|
|
}
|
|
|
|
if (tc_hmac_init(&h) == TC_CRYPTO_FAIL) {
|
|
return -EIO;
|
|
}
|
|
|
|
for (; sg_len; sg_len--, sg++) {
|
|
if (tc_hmac_update(&h, sg->data, sg->len) == TC_CRYPTO_FAIL) {
|
|
return -EIO;
|
|
}
|
|
}
|
|
|
|
if (tc_hmac_final(mac, 32, &h) == TC_CRYPTO_FAIL) {
|
|
return -EIO;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int bt_mesh_pub_key_gen(void)
|
|
{
|
|
int rc = uECC_make_key(key.public_key_be, key.private_key_be, &curve_secp256r1);
|
|
|
|
if (rc == TC_CRYPTO_FAIL) {
|
|
key.is_ready = false;
|
|
LOG_ERR("Failed to create public/private pair");
|
|
return -EIO;
|
|
}
|
|
|
|
key.is_ready = true;
|
|
|
|
return 0;
|
|
}
|
|
|
|
const uint8_t *bt_mesh_pub_key_get(void)
|
|
{
|
|
return key.is_ready ? key.public_key_be : NULL;
|
|
}
|
|
|
|
int bt_mesh_dhkey_gen(const uint8_t *pub_key, const uint8_t *priv_key, uint8_t *dhkey)
|
|
{
|
|
if (uECC_valid_public_key(pub_key, &curve_secp256r1)) {
|
|
LOG_ERR("Public key is not valid");
|
|
return -EIO;
|
|
} else if (uECC_shared_secret(pub_key, priv_key ? priv_key : key.private_key_be, dhkey,
|
|
&curve_secp256r1) != TC_CRYPTO_SUCCESS) {
|
|
LOG_ERR("DHKey generation failed");
|
|
return -EIO;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
__weak int default_CSPRNG(uint8_t *dst, unsigned int len)
|
|
{
|
|
return !bt_rand(dst, len);
|
|
}
|
|
|
|
int bt_mesh_crypto_init(void)
|
|
{
|
|
return 0;
|
|
}
|