mirror of
https://github.com/zephyrproject-rtos/zephyr
synced 2025-09-11 00:52:44 +00:00
The API name space for Bluetooth is bt_* and BT_* so it makes sense to align the Kconfig name space with this. The additional benefit is that this also makes the names shorter. It is also in line with what Linux uses for Bluetooth Kconfig entries. Some Bluetooth-related Networking Kconfig defines are renamed as well in order to be consistent, such as NET_L2_BLUETOOTH. Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
161 lines
3.0 KiB
C
161 lines
3.0 KiB
C
/*
|
|
* Copyright (c) 2017 Nordic Semiconductor ASA
|
|
* Copyright (c) 2015-2016 Intel Corporation
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
|
|
#include <string.h>
|
|
#include <errno.h>
|
|
|
|
#include <zephyr.h>
|
|
#include <misc/byteorder.h>
|
|
|
|
#include <bluetooth/bluetooth.h>
|
|
#include <bluetooth/hci.h>
|
|
#include <bluetooth/conn.h>
|
|
|
|
#include <tinycrypt/constants.h>
|
|
#include <tinycrypt/hmac_prng.h>
|
|
#include <tinycrypt/aes.h>
|
|
#include <tinycrypt/utils.h>
|
|
|
|
#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BT_DEBUG_HCI_CORE)
|
|
#include "common/log.h"
|
|
|
|
#include "hci_core.h"
|
|
|
|
static struct tc_hmac_prng_struct prng;
|
|
|
|
static int prng_reseed(struct tc_hmac_prng_struct *h)
|
|
{
|
|
u8_t seed[32];
|
|
s64_t extra;
|
|
int ret, i;
|
|
|
|
for (i = 0; i < (sizeof(seed) / 8); i++) {
|
|
struct bt_hci_rp_le_rand *rp;
|
|
struct net_buf *rsp;
|
|
|
|
ret = bt_hci_cmd_send_sync(BT_HCI_OP_LE_RAND, NULL, &rsp);
|
|
if (ret) {
|
|
return ret;
|
|
}
|
|
|
|
rp = (void *)rsp->data;
|
|
memcpy(&seed[i * 8], rp->rand, 8);
|
|
|
|
net_buf_unref(rsp);
|
|
}
|
|
|
|
extra = k_uptime_get();
|
|
|
|
ret = tc_hmac_prng_reseed(h, seed, sizeof(seed), (u8_t *)&extra,
|
|
sizeof(extra));
|
|
if (ret == TC_CRYPTO_FAIL) {
|
|
BT_ERR("Failed to re-seed PRNG");
|
|
return -EIO;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int prng_init(void)
|
|
{
|
|
struct bt_hci_rp_le_rand *rp;
|
|
struct net_buf *rsp;
|
|
int ret;
|
|
|
|
/* Check first that HCI_LE_Rand is supported */
|
|
if (!(bt_dev.supported_commands[27] & BIT(7))) {
|
|
return -ENOTSUP;
|
|
}
|
|
|
|
ret = bt_hci_cmd_send_sync(BT_HCI_OP_LE_RAND, NULL, &rsp);
|
|
if (ret) {
|
|
return ret;
|
|
}
|
|
|
|
rp = (void *)rsp->data;
|
|
|
|
ret = tc_hmac_prng_init(&prng, rp->rand, sizeof(rp->rand));
|
|
|
|
net_buf_unref(rsp);
|
|
|
|
if (ret == TC_CRYPTO_FAIL) {
|
|
BT_ERR("Failed to initialize PRNG");
|
|
return -EIO;
|
|
}
|
|
|
|
/* re-seed is needed after init */
|
|
return prng_reseed(&prng);
|
|
}
|
|
|
|
int bt_rand(void *buf, size_t len)
|
|
{
|
|
int ret;
|
|
|
|
ret = tc_hmac_prng_generate(buf, len, &prng);
|
|
if (ret == TC_HMAC_PRNG_RESEED_REQ) {
|
|
ret = prng_reseed(&prng);
|
|
if (ret) {
|
|
return ret;
|
|
}
|
|
|
|
ret = tc_hmac_prng_generate(buf, len, &prng);
|
|
}
|
|
|
|
if (ret == TC_CRYPTO_SUCCESS) {
|
|
return 0;
|
|
}
|
|
|
|
return -EIO;
|
|
}
|
|
|
|
int bt_encrypt_le(const u8_t key[16], const u8_t plaintext[16],
|
|
u8_t enc_data[16])
|
|
{
|
|
struct tc_aes_key_sched_struct s;
|
|
u8_t tmp[16];
|
|
|
|
BT_DBG("key %s plaintext %s", bt_hex(key, 16), bt_hex(plaintext, 16));
|
|
|
|
sys_memcpy_swap(tmp, key, 16);
|
|
|
|
if (tc_aes128_set_encrypt_key(&s, tmp) == TC_CRYPTO_FAIL) {
|
|
return -EINVAL;
|
|
}
|
|
|
|
sys_memcpy_swap(tmp, plaintext, 16);
|
|
|
|
if (tc_aes_encrypt(enc_data, tmp, &s) == TC_CRYPTO_FAIL) {
|
|
return -EINVAL;
|
|
}
|
|
|
|
sys_mem_swap(enc_data, 16);
|
|
|
|
BT_DBG("enc_data %s", bt_hex(enc_data, 16));
|
|
|
|
return 0;
|
|
}
|
|
|
|
int bt_encrypt_be(const u8_t key[16], const u8_t plaintext[16],
|
|
u8_t enc_data[16])
|
|
{
|
|
struct tc_aes_key_sched_struct s;
|
|
|
|
BT_DBG("key %s plaintext %s", bt_hex(key, 16), bt_hex(plaintext, 16));
|
|
|
|
if (tc_aes128_set_encrypt_key(&s, key) == TC_CRYPTO_FAIL) {
|
|
return -EINVAL;
|
|
}
|
|
|
|
if (tc_aes_encrypt(enc_data, plaintext, &s) == TC_CRYPTO_FAIL) {
|
|
return -EINVAL;
|
|
}
|
|
|
|
BT_DBG("enc_data %s", bt_hex(enc_data, 16));
|
|
|
|
return 0;
|
|
}
|