Bluetooth: host: Introduce a new bt_hci_le_rand() call
In order to get rid of the duplication of the code that we had until now in the tree, consolidate the handling of multiple calls to bt_hci_cmd_send_sync(BT_HCI_OP_LE_RAND, ...) in a single location, namely in hci_core. This allows all of the users of this HCI command to use a single implementation of the iterated sending of the HCI command to fill a buffer with random bytes. Signed-off-by: Carles Cufi <carles.cufi@nordicsemi.no>
This commit is contained in:
parent
eb0de3384d
commit
00636682ca
4 changed files with 56 additions and 82 deletions
|
@ -20,31 +20,11 @@ static int entropy_bt_init(const struct device *dev)
|
||||||
static int entropy_bt_get_entropy(const struct device *dev,
|
static int entropy_bt_get_entropy(const struct device *dev,
|
||||||
uint8_t *buffer, uint16_t length)
|
uint8_t *buffer, uint16_t length)
|
||||||
{
|
{
|
||||||
struct bt_hci_rp_le_rand *rp;
|
|
||||||
struct net_buf *rsp;
|
|
||||||
int req, ret;
|
|
||||||
|
|
||||||
if (!bt_is_ready()) {
|
if (!bt_is_ready()) {
|
||||||
return -EAGAIN;
|
return -EAGAIN;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (length > 0) {
|
return bt_hci_le_rand(buffer, length);
|
||||||
/* 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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* HCI commands cannot be run from an interrupt context */
|
/* HCI commands cannot be run from an interrupt context */
|
||||||
|
|
|
@ -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);
|
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
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -33,22 +33,11 @@ static int prng_reseed(struct tc_hmac_prng_struct *h)
|
||||||
{
|
{
|
||||||
uint8_t seed[32];
|
uint8_t seed[32];
|
||||||
int64_t extra;
|
int64_t extra;
|
||||||
size_t i;
|
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
for (i = 0; i < (sizeof(seed) / 8); i++) {
|
ret = bt_hci_le_rand(seed, sizeof(seed));
|
||||||
struct bt_hci_rp_le_rand *rp;
|
if (ret) {
|
||||||
struct net_buf *rsp;
|
return ret;
|
||||||
|
|
||||||
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();
|
extra = k_uptime_get();
|
||||||
|
@ -65,26 +54,15 @@ static int prng_reseed(struct tc_hmac_prng_struct *h)
|
||||||
|
|
||||||
int prng_init(void)
|
int prng_init(void)
|
||||||
{
|
{
|
||||||
struct bt_hci_rp_le_rand *rp;
|
uint8_t perso[8];
|
||||||
struct net_buf *rsp;
|
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
/* Check first that HCI_LE_Rand is supported */
|
ret = bt_hci_le_rand(perso, sizeof(perso));
|
||||||
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);
|
|
||||||
if (ret) {
|
if (ret) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
rp = (void *)rsp->data;
|
ret = tc_hmac_prng_init(&prng, perso, sizeof(perso));
|
||||||
|
|
||||||
ret = tc_hmac_prng_init(&prng, rp->rand, sizeof(rp->rand));
|
|
||||||
|
|
||||||
net_buf_unref(rsp);
|
|
||||||
|
|
||||||
if (ret == TC_CRYPTO_FAIL) {
|
if (ret == TC_CRYPTO_FAIL) {
|
||||||
BT_ERR("Failed to initialize PRNG");
|
BT_ERR("Failed to initialize PRNG");
|
||||||
return -EIO;
|
return -EIO;
|
||||||
|
@ -118,39 +96,7 @@ int bt_rand(void *buf, size_t len)
|
||||||
#else /* !CONFIG_BT_HOST_CRYPTO_PRNG */
|
#else /* !CONFIG_BT_HOST_CRYPTO_PRNG */
|
||||||
int bt_rand(void *buf, size_t len)
|
int bt_rand(void *buf, size_t len)
|
||||||
{
|
{
|
||||||
int ret, size;
|
return bt_hci_le_rand(buf, len);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_BT_HOST_CRYPTO_PRNG */
|
#endif /* CONFIG_BT_HOST_CRYPTO_PRNG */
|
||||||
|
|
||||||
|
|
|
@ -331,6 +331,38 @@ int bt_hci_cmd_send_sync(uint16_t opcode, struct net_buf *buf,
|
||||||
return 0;
|
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)
|
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;
|
struct bt_hci_rp_le_read_max_data_len *rp;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue