diff --git a/drivers/entropy/entropy_bt_hci.c b/drivers/entropy/entropy_bt_hci.c index d2a52cceb8f..815d6237b7f 100644 --- a/drivers/entropy/entropy_bt_hci.c +++ b/drivers/entropy/entropy_bt_hci.c @@ -20,31 +20,11 @@ static int entropy_bt_init(const struct device *dev) static int entropy_bt_get_entropy(const struct device *dev, uint8_t *buffer, uint16_t length) { - struct bt_hci_rp_le_rand *rp; - struct net_buf *rsp; - int req, ret; - if (!bt_is_ready()) { return -EAGAIN; } - while (length > 0) { - /* Number of bytes to fill on this iteration */ - req = MIN(length, sizeof(rp->rand)); - /* Request the next 8 bytes over HCI */ - ret = bt_hci_cmd_send_sync(BT_HCI_OP_LE_RAND, NULL, &rsp); - if (ret) { - return ret; - } - /* Copy random data into buffer */ - rp = (void *)rsp->data; - memcpy(buffer, rp->rand, req); - - net_buf_unref(rsp); - buffer += req; - length -= req; - } - return 0; + return bt_hci_le_rand(buffer, length); } /* HCI commands cannot be run from an interrupt context */ diff --git a/include/bluetooth/hci.h b/include/bluetooth/hci.h index 0d57e06c37f..aa4494f3fda 100644 --- a/include/bluetooth/hci.h +++ b/include/bluetooth/hci.h @@ -2873,6 +2873,22 @@ typedef bool bt_hci_vnd_evt_cb_t(struct net_buf_simple *buf); */ int bt_hci_register_vnd_evt_cb(bt_hci_vnd_evt_cb_t cb); +/** @brief Get Random bytes from the LE Controller. + * + * Send the HCI_LE_Rand to the LE Controller as many times as required to + * fill the provided @p buffer. + * + * @note This function is provided as a helper to gather an arbitrary number of + * random bytes from an LE Controller using the HCI_LE_Rand command. + * + * @param buffer Buffer to fill with random bytes. + * @param len Length of the buffer in bytes. + * + * @return 0 on success or negative error value on failure. + */ +int bt_hci_le_rand(void *buffer, size_t len); + + #ifdef __cplusplus } #endif diff --git a/subsys/bluetooth/host/crypto.c b/subsys/bluetooth/host/crypto.c index b91373e2924..aba458cc93a 100644 --- a/subsys/bluetooth/host/crypto.c +++ b/subsys/bluetooth/host/crypto.c @@ -33,22 +33,11 @@ static int prng_reseed(struct tc_hmac_prng_struct *h) { uint8_t seed[32]; int64_t extra; - size_t i; int ret; - 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); + ret = bt_hci_le_rand(seed, sizeof(seed)); + if (ret) { + return ret; } extra = k_uptime_get(); @@ -65,26 +54,15 @@ static int prng_reseed(struct tc_hmac_prng_struct *h) int prng_init(void) { - struct bt_hci_rp_le_rand *rp; - struct net_buf *rsp; + uint8_t perso[8]; int ret; - /* Check first that HCI_LE_Rand is supported */ - if (!BT_CMD_TEST(bt_dev.supported_commands, 27, 7)) { - return -ENOTSUP; - } - - ret = bt_hci_cmd_send_sync(BT_HCI_OP_LE_RAND, NULL, &rsp); + ret = bt_hci_le_rand(perso, sizeof(perso)); if (ret) { return ret; } - rp = (void *)rsp->data; - - ret = tc_hmac_prng_init(&prng, rp->rand, sizeof(rp->rand)); - - net_buf_unref(rsp); - + ret = tc_hmac_prng_init(&prng, perso, sizeof(perso)); if (ret == TC_CRYPTO_FAIL) { BT_ERR("Failed to initialize PRNG"); return -EIO; @@ -118,39 +96,7 @@ int bt_rand(void *buf, size_t len) #else /* !CONFIG_BT_HOST_CRYPTO_PRNG */ int bt_rand(void *buf, size_t len) { - int ret, size; - size_t i = 0; - - /* Check first that HCI_LE_Rand is supported */ - if (!BT_CMD_TEST(bt_dev.supported_commands, 27, 7)) { - return -ENOTSUP; - } - - while (len) { - 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; - if (rp->status) { - return -EIO; - } - - size = MIN(len, sizeof(rp->rand)); - - (void)memcpy((uint8_t *)buf + i, rp->rand, size); - - net_buf_unref(rsp); - - i += size; - len -= size; - } - - return 0; + return bt_hci_le_rand(buf, len); } #endif /* CONFIG_BT_HOST_CRYPTO_PRNG */ diff --git a/subsys/bluetooth/host/hci_core.c b/subsys/bluetooth/host/hci_core.c index e728bb93cdd..d99ae30e5e1 100644 --- a/subsys/bluetooth/host/hci_core.c +++ b/subsys/bluetooth/host/hci_core.c @@ -331,6 +331,38 @@ int bt_hci_cmd_send_sync(uint16_t opcode, struct net_buf *buf, return 0; } +int bt_hci_le_rand(void *buffer, size_t len) +{ + struct bt_hci_rp_le_rand *rp; + struct net_buf *rsp; + size_t count; + int err; + + /* Check first that HCI_LE_Rand is supported */ + if (!BT_CMD_TEST(bt_dev.supported_commands, 27, 7)) { + return -ENOTSUP; + } + + while (len > 0) { + /* Number of bytes to fill on this iteration */ + count = MIN(len, sizeof(rp->rand)); + /* Request the next 8 bytes over HCI */ + err = bt_hci_cmd_send_sync(BT_HCI_OP_LE_RAND, NULL, &rsp); + if (err) { + return err; + } + /* Copy random data into buffer */ + rp = (void *)rsp->data; + memcpy(buffer, rp->rand, count); + + net_buf_unref(rsp); + buffer = (uint8_t *)buffer + count; + len -= count; + } + + return 0; +} + static int hci_le_read_max_data_len(uint16_t *tx_octets, uint16_t *tx_time) { struct bt_hci_rp_le_read_max_data_len *rp;