Bluetooth: Fix infinite recursion in host-based bt_rand
Fix infinite recursion in host-based bt_rand function. This would call HCI LE Random Number command, which would in turn call bt_rand, causing an infinite recursion. bt_rand -> prng_reseed -> BT_HCI_OP_LE_RAND -> le_rand -> bt_rand To solve this issue the controller should avoid doing calls into the host, so all calls to bt_rand in the controller should be replaced with a call to a controller function. Fixes #22202 Signed-off-by: Joakim Andersson <joakim.andersson@nordicsemi.no>
This commit is contained in:
parent
adac4cbafa
commit
291ebdd4e4
7 changed files with 36 additions and 29 deletions
|
@ -4,33 +4,16 @@
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <drivers/entropy.h>
|
|
||||||
|
|
||||||
#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BT_DEBUG_HCI_DRIVER)
|
#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BT_DEBUG_HCI_DRIVER)
|
||||||
#define LOG_MODULE_NAME bt_ctlr_crypto
|
#define LOG_MODULE_NAME bt_ctlr_crypto
|
||||||
#include "common/log.h"
|
#include "common/log.h"
|
||||||
|
#include "../util/util.h"
|
||||||
|
|
||||||
#include "hal/ecb.h"
|
#include "hal/ecb.h"
|
||||||
|
|
||||||
static struct device *entropy_driver;
|
|
||||||
|
|
||||||
int bt_rand(void *buf, size_t len)
|
int bt_rand(void *buf, size_t len)
|
||||||
{
|
{
|
||||||
struct device *dev = entropy_driver;
|
return util_rand(buf, len);
|
||||||
|
|
||||||
if (unlikely(!dev)) {
|
|
||||||
/* Only one entropy device exists, so this is safe even
|
|
||||||
* if the whole operation isn't atomic.
|
|
||||||
*/
|
|
||||||
dev = device_get_binding(CONFIG_ENTROPY_NAME);
|
|
||||||
__ASSERT((dev != NULL),
|
|
||||||
"Device driver for %s (CONFIG_ENTROPY_NAME) not found. "
|
|
||||||
"Check your build configuration!",
|
|
||||||
CONFIG_ENTROPY_NAME);
|
|
||||||
entropy_driver = dev;
|
|
||||||
}
|
|
||||||
|
|
||||||
return entropy_get_entropy(dev, (u8_t *)buf, len);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int bt_encrypt_le(const u8_t key[16], const u8_t plaintext[16],
|
int bt_encrypt_le(const u8_t key[16], const u8_t plaintext[16],
|
||||||
|
|
|
@ -868,7 +868,7 @@ static void le_rand(struct net_buf *buf, struct net_buf **evt)
|
||||||
rp = hci_cmd_complete(evt, sizeof(*rp));
|
rp = hci_cmd_complete(evt, sizeof(*rp));
|
||||||
rp->status = 0x00;
|
rp->status = 0x00;
|
||||||
|
|
||||||
bt_rand(rp->rand, count);
|
util_rand(rp->rand, count);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void le_read_supp_states(struct net_buf *buf, struct net_buf **evt)
|
static void le_read_supp_states(struct net_buf *buf, struct net_buf **evt)
|
||||||
|
|
|
@ -6489,7 +6489,7 @@ again:
|
||||||
LL_ASSERT(retry);
|
LL_ASSERT(retry);
|
||||||
retry--;
|
retry--;
|
||||||
|
|
||||||
bt_rand(&access_addr, sizeof(u32_t));
|
util_rand(&access_addr, sizeof(u32_t));
|
||||||
|
|
||||||
bit_idx = 31U;
|
bit_idx = 31U;
|
||||||
transitions = 0U;
|
transitions = 0U;
|
||||||
|
@ -11992,7 +11992,7 @@ u32_t radio_connect_enable(u8_t adv_addr_type, u8_t *adv_addr, u16_t interval,
|
||||||
conn->llcp_feature.features = LL_FEAT;
|
conn->llcp_feature.features = LL_FEAT;
|
||||||
access_addr = access_addr_get();
|
access_addr = access_addr_get();
|
||||||
memcpy(&conn->access_addr[0], &access_addr, sizeof(conn->access_addr));
|
memcpy(&conn->access_addr[0], &access_addr, sizeof(conn->access_addr));
|
||||||
bt_rand(&conn->crc_init[0], 3);
|
util_rand(&conn->crc_init[0], 3);
|
||||||
memcpy(&conn->data_chan_map[0], &_radio.data_chan_map[0],
|
memcpy(&conn->data_chan_map[0], &_radio.data_chan_map[0],
|
||||||
sizeof(conn->data_chan_map));
|
sizeof(conn->data_chan_map));
|
||||||
conn->data_chan_count = _radio.data_chan_count;
|
conn->data_chan_count = _radio.data_chan_count;
|
||||||
|
@ -12333,8 +12333,8 @@ u8_t ll_enc_req_send(u16_t handle, u8_t *rand, u8_t *ediv, u8_t *ltk)
|
||||||
memcpy(enc_req->rand, rand, sizeof(enc_req->rand));
|
memcpy(enc_req->rand, rand, sizeof(enc_req->rand));
|
||||||
enc_req->ediv[0] = ediv[0];
|
enc_req->ediv[0] = ediv[0];
|
||||||
enc_req->ediv[1] = ediv[1];
|
enc_req->ediv[1] = ediv[1];
|
||||||
bt_rand(enc_req->skdm, sizeof(enc_req->skdm));
|
util_rand(enc_req->skdm, sizeof(enc_req->skdm));
|
||||||
bt_rand(enc_req->ivm, sizeof(enc_req->ivm));
|
util_rand(enc_req->ivm, sizeof(enc_req->ivm));
|
||||||
} else if (conn->enc_rx && conn->enc_tx) {
|
} else if (conn->enc_rx && conn->enc_tx) {
|
||||||
memcpy(&conn->llcp_enc.rand[0], rand,
|
memcpy(&conn->llcp_enc.rand[0], rand,
|
||||||
sizeof(conn->llcp_enc.rand));
|
sizeof(conn->llcp_enc.rand));
|
||||||
|
|
|
@ -101,7 +101,7 @@ u8_t ll_create_connection(u16_t scan_interval, u16_t scan_window,
|
||||||
access_addr_get(access_addr);
|
access_addr_get(access_addr);
|
||||||
memcpy(conn_lll->access_addr, &access_addr,
|
memcpy(conn_lll->access_addr, &access_addr,
|
||||||
sizeof(conn_lll->access_addr));
|
sizeof(conn_lll->access_addr));
|
||||||
bt_rand(&conn_lll->crc_init[0], 3);
|
util_rand(&conn_lll->crc_init[0], 3);
|
||||||
|
|
||||||
conn_lll->handle = 0xFFFF;
|
conn_lll->handle = 0xFFFF;
|
||||||
conn_lll->interval = interval;
|
conn_lll->interval = interval;
|
||||||
|
@ -156,7 +156,7 @@ u8_t ll_create_connection(u16_t scan_interval, u16_t scan_window,
|
||||||
|
|
||||||
conn_lll->data_chan_count =
|
conn_lll->data_chan_count =
|
||||||
ull_conn_chan_map_cpy(conn_lll->data_chan_map);
|
ull_conn_chan_map_cpy(conn_lll->data_chan_map);
|
||||||
bt_rand(&hop, sizeof(u8_t));
|
util_rand(&hop, sizeof(u8_t));
|
||||||
conn_lll->data_chan_hop = 5 + (hop % 12);
|
conn_lll->data_chan_hop = 5 + (hop % 12);
|
||||||
conn_lll->data_chan_sel = 0;
|
conn_lll->data_chan_sel = 0;
|
||||||
conn_lll->data_chan_use = 0;
|
conn_lll->data_chan_use = 0;
|
||||||
|
@ -389,8 +389,8 @@ u8_t ll_enc_req_send(u16_t handle, u8_t *rand, u8_t *ediv, u8_t *ltk)
|
||||||
memcpy(enc_req->rand, rand, sizeof(enc_req->rand));
|
memcpy(enc_req->rand, rand, sizeof(enc_req->rand));
|
||||||
enc_req->ediv[0] = ediv[0];
|
enc_req->ediv[0] = ediv[0];
|
||||||
enc_req->ediv[1] = ediv[1];
|
enc_req->ediv[1] = ediv[1];
|
||||||
bt_rand(enc_req->skdm, sizeof(enc_req->skdm));
|
util_rand(enc_req->skdm, sizeof(enc_req->skdm));
|
||||||
bt_rand(enc_req->ivm, sizeof(enc_req->ivm));
|
util_rand(enc_req->ivm, sizeof(enc_req->ivm));
|
||||||
} else if (conn->lll.enc_rx && conn->lll.enc_tx) {
|
} else if (conn->lll.enc_rx && conn->lll.enc_tx) {
|
||||||
memcpy(&conn->llcp_enc.rand[0], rand,
|
memcpy(&conn->llcp_enc.rand[0], rand,
|
||||||
sizeof(conn->llcp_enc.rand));
|
sizeof(conn->llcp_enc.rand));
|
||||||
|
@ -709,7 +709,7 @@ again:
|
||||||
LL_ASSERT(retry);
|
LL_ASSERT(retry);
|
||||||
retry--;
|
retry--;
|
||||||
|
|
||||||
bt_rand(access_addr, 4);
|
util_rand(access_addr, 4);
|
||||||
aa = sys_get_le32(access_addr);
|
aa = sys_get_le32(access_addr);
|
||||||
|
|
||||||
bit_idx = 31U;
|
bit_idx = 31U;
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <zephyr/types.h>
|
#include <zephyr/types.h>
|
||||||
|
#include <drivers/entropy.h>
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -36,3 +37,21 @@ u8_t util_ones_count_get(u8_t *octets, u8_t octets_len)
|
||||||
|
|
||||||
return one_count;
|
return one_count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int util_rand(void *buf, size_t len)
|
||||||
|
{
|
||||||
|
static struct device *dev;
|
||||||
|
|
||||||
|
if (unlikely(!dev)) {
|
||||||
|
/* Only one entropy device exists, so this is safe even
|
||||||
|
* if the whole operation isn't atomic.
|
||||||
|
*/
|
||||||
|
dev = device_get_binding(CONFIG_ENTROPY_NAME);
|
||||||
|
__ASSERT((dev != NULL),
|
||||||
|
"Device driver for %s (CONFIG_ENTROPY_NAME) not found. "
|
||||||
|
"Check your build configuration!",
|
||||||
|
CONFIG_ENTROPY_NAME);
|
||||||
|
}
|
||||||
|
|
||||||
|
return entropy_get_entropy(dev, (u8_t *)buf, len);
|
||||||
|
}
|
||||||
|
|
|
@ -13,4 +13,8 @@
|
||||||
#define TRIPLE_BUFFER_SIZE 3
|
#define TRIPLE_BUFFER_SIZE 3
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
u8_t util_ones_count_get(u8_t *octets, u8_t octets_len);
|
u8_t util_ones_count_get(u8_t *octets, u8_t octets_len);
|
||||||
|
|
||||||
|
int util_rand(void *buf, size_t len);
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
#include <bluetooth/bluetooth.h>
|
#include <bluetooth/bluetooth.h>
|
||||||
#include <bluetooth/hci.h>
|
#include <bluetooth/hci.h>
|
||||||
#include <bluetooth/conn.h>
|
#include <bluetooth/conn.h>
|
||||||
|
#include <bluetooth/crypto.h>
|
||||||
|
|
||||||
#include <tinycrypt/constants.h>
|
#include <tinycrypt/constants.h>
|
||||||
#include <tinycrypt/hmac_prng.h>
|
#include <tinycrypt/hmac_prng.h>
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue