Bluetooth: Make LE Encrypt helpers public
Expose LE Encrypt helpers to applications. If software- based controller is compiled-in, then controller's AES hardware will be used by the exposed helper interface. Change-id: I2bac9dfa5ccb3dd50447079affb52d920ae5bd81 Signed-off-by: Vinayak Chettimada <vinayak.kariappa.chettimada@nordicsemi.no>.
This commit is contained in:
parent
3994f4d5b7
commit
a91dd34830
8 changed files with 202 additions and 125 deletions
|
@ -3,6 +3,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
* Copyright (c) 2017 Nordic Semiconductor ASA
|
||||||
* Copyright (c) 2015-2016 Intel Corporation
|
* Copyright (c) 2015-2016 Intel Corporation
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
@ -469,6 +470,21 @@ int bt_br_set_connectable(bool enable);
|
||||||
*/
|
*/
|
||||||
int bt_rand(void *buf, size_t len);
|
int bt_rand(void *buf, size_t len);
|
||||||
|
|
||||||
|
/** @brief AES encrypt data.
|
||||||
|
*
|
||||||
|
* An AES encrypt helper is used to request the Bluetooth controller's own
|
||||||
|
* hardware to encrypt the plaintext using the key and returns the encrypted
|
||||||
|
* data.
|
||||||
|
*
|
||||||
|
* @param key 128 bit LS byte first key for the encryption of the plaintext
|
||||||
|
* @param plaintext 128 bit LS byte first plaintext data block to be encrypted
|
||||||
|
* @param enc_data 128 bit LS byte first encrypted data block
|
||||||
|
*
|
||||||
|
* @return Zero on success or error code otherwise.
|
||||||
|
*/
|
||||||
|
int bt_encrypt(const uint8_t key[16], const uint8_t plaintext[16],
|
||||||
|
uint8_t enc_data[16]);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @}
|
* @}
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -5,8 +5,13 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <soc.h>
|
#include <soc.h>
|
||||||
|
|
||||||
|
#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BLUETOOTH_DEBUG_HCI_DRIVER)
|
||||||
|
#include <bluetooth/log.h>
|
||||||
|
|
||||||
#include "hal/cpu.h"
|
#include "hal/cpu.h"
|
||||||
#include "hal/rand.h"
|
#include "hal/rand.h"
|
||||||
|
#include "hal/ecb.h"
|
||||||
|
|
||||||
K_MUTEX_DEFINE(mutex_rand);
|
K_MUTEX_DEFINE(mutex_rand);
|
||||||
|
|
||||||
|
@ -23,3 +28,15 @@ int bt_rand(void *buf, size_t len)
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int bt_encrypt(const uint8_t key[16], const uint8_t plaintext[16],
|
||||||
|
uint8_t enc_data[16])
|
||||||
|
{
|
||||||
|
BT_DBG("key %s plaintext %s", bt_hex(key, 16), bt_hex(plaintext, 16));
|
||||||
|
|
||||||
|
ecb_encrypt(key, plaintext, enc_data, NULL);
|
||||||
|
|
||||||
|
BT_DBG("enc_data %s", bt_hex(enc_data, 16));
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
|
@ -31,10 +31,6 @@ config BLUETOOTH_HCI_HOST
|
||||||
default y
|
default y
|
||||||
depends on !BLUETOOTH_HCI_RAW
|
depends on !BLUETOOTH_HCI_RAW
|
||||||
select POLL
|
select POLL
|
||||||
select TINYCRYPT if !BLUETOOTH_CONTROLLER
|
|
||||||
select TINYCRYPT_SHA256 if !BLUETOOTH_CONTROLLER
|
|
||||||
select TINYCRYPT_SHA256_HMAC if !BLUETOOTH_CONTROLLER
|
|
||||||
select TINYCRYPT_SHA256_HMAC_PRNG if !BLUETOOTH_CONTROLLER
|
|
||||||
|
|
||||||
config BLUETOOTH_RECV_IS_RX_THREAD
|
config BLUETOOTH_RECV_IS_RX_THREAD
|
||||||
# Virtual option set by the HCI driver to indicate that there's
|
# Virtual option set by the HCI driver to indicate that there's
|
||||||
|
@ -99,6 +95,18 @@ config BLUETOOTH_RX_STACK_SIZE
|
||||||
accommodate for that.
|
accommodate for that.
|
||||||
|
|
||||||
if BLUETOOTH_HCI_HOST
|
if BLUETOOTH_HCI_HOST
|
||||||
|
config BLUETOOTH_HOST_CRYPTO
|
||||||
|
# Hidden option that compiles in random number generation and AES
|
||||||
|
# encryption support using TinyCrypt library if software-based
|
||||||
|
# controller is disabled.
|
||||||
|
bool
|
||||||
|
default y if !BLUETOOTH_CONTROLLER
|
||||||
|
select TINYCRYPT
|
||||||
|
select TINYCRYPT_AES
|
||||||
|
select TINYCRYPT_SHA256
|
||||||
|
select TINYCRYPT_SHA256_HMAC
|
||||||
|
select TINYCRYPT_SHA256_HMAC_PRNG
|
||||||
|
|
||||||
config BLUETOOTH_INTERNAL_STORAGE
|
config BLUETOOTH_INTERNAL_STORAGE
|
||||||
bool "Use an internal persistent storage handler"
|
bool "Use an internal persistent storage handler"
|
||||||
depends on FILE_SYSTEM
|
depends on FILE_SYSTEM
|
||||||
|
|
|
@ -31,3 +31,5 @@ ifeq ($(CONFIG_BLUETOOTH_CONN),y)
|
||||||
|
|
||||||
obj-$(CONFIG_BLUETOOTH_A2DP) += a2dp.o
|
obj-$(CONFIG_BLUETOOTH_A2DP) += a2dp.o
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
obj-$(CONFIG_BLUETOOTH_HOST_CRYPTO) += crypto.o
|
||||||
|
|
135
subsys/bluetooth/host/crypto.c
Normal file
135
subsys/bluetooth/host/crypto.c
Normal file
|
@ -0,0 +1,135 @@
|
||||||
|
/*
|
||||||
|
* 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>
|
||||||
|
|
||||||
|
#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BLUETOOTH_DEBUG_HCI_CORE)
|
||||||
|
#include <bluetooth/log.h>
|
||||||
|
|
||||||
|
#include "hci_core.h"
|
||||||
|
|
||||||
|
#include <tinycrypt/constants.h>
|
||||||
|
#include <tinycrypt/hmac_prng.h>
|
||||||
|
#include <tinycrypt/aes.h>
|
||||||
|
#include <tinycrypt/utils.h>
|
||||||
|
|
||||||
|
static struct tc_hmac_prng_struct prng;
|
||||||
|
|
||||||
|
static int prng_reseed(struct tc_hmac_prng_struct *h)
|
||||||
|
{
|
||||||
|
uint8_t seed[32];
|
||||||
|
int64_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), (uint8_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;
|
||||||
|
|
||||||
|
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(const uint8_t key[16], const uint8_t plaintext[16],
|
||||||
|
uint8_t enc_data[16])
|
||||||
|
{
|
||||||
|
struct tc_aes_key_sched_struct s;
|
||||||
|
uint8_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;
|
||||||
|
}
|
8
subsys/bluetooth/host/crypto.h
Normal file
8
subsys/bluetooth/host/crypto.h
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2016-2017 Nordic Semiconductor ASA
|
||||||
|
* Copyright (c) 2015-2016 Intel Corporation
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
int prng_init(void);
|
|
@ -1,6 +1,7 @@
|
||||||
/* hci_core.c - HCI core Bluetooth handling */
|
/* hci_core.c - HCI core Bluetooth handling */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
* Copyright (c) 2017 Nordic Semiconductor ASA
|
||||||
* Copyright (c) 2015-2016 Intel Corporation
|
* Copyright (c) 2015-2016 Intel Corporation
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
@ -35,6 +36,10 @@
|
||||||
#include "l2cap_internal.h"
|
#include "l2cap_internal.h"
|
||||||
#include "smp.h"
|
#include "smp.h"
|
||||||
|
|
||||||
|
#if defined(CONFIG_BLUETOOTH_HOST_CRYPTO)
|
||||||
|
#include "crypto.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Peripheral timeout to initialize Connection Parameter Update procedure */
|
/* Peripheral timeout to initialize Connection Parameter Update procedure */
|
||||||
#define CONN_UPDATE_TIMEOUT K_SECONDS(5)
|
#define CONN_UPDATE_TIMEOUT K_SECONDS(5)
|
||||||
#define RPA_TIMEOUT K_SECONDS(CONFIG_BLUETOOTH_RPA_TIMEOUT)
|
#define RPA_TIMEOUT K_SECONDS(CONFIG_BLUETOOTH_RPA_TIMEOUT)
|
||||||
|
@ -2354,94 +2359,6 @@ static void hci_cmd_status(struct net_buf *buf)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if !defined(CONFIG_BLUETOOTH_CONTROLLER)
|
|
||||||
#include <tinycrypt/constants.h>
|
|
||||||
#include <tinycrypt/hmac_prng.h>
|
|
||||||
#include <tinycrypt/utils.h>
|
|
||||||
|
|
||||||
static struct tc_hmac_prng_struct prng;
|
|
||||||
|
|
||||||
static int prng_reseed(struct tc_hmac_prng_struct *h)
|
|
||||||
{
|
|
||||||
uint8_t seed[32];
|
|
||||||
int64_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), (uint8_t *)&extra,
|
|
||||||
sizeof(extra));
|
|
||||||
if (ret == TC_CRYPTO_FAIL) {
|
|
||||||
BT_ERR("Failed to re-seed PRNG");
|
|
||||||
return -EIO;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int prng_init(struct tc_hmac_prng_struct *h)
|
|
||||||
{
|
|
||||||
struct bt_hci_rp_le_rand *rp;
|
|
||||||
struct net_buf *rsp;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
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(h, 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(h);
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
#endif /* !CONFIG_BLUETOOTH_CONTROLLER */
|
|
||||||
|
|
||||||
static int start_le_scan(uint8_t scan_type, uint16_t interval, uint16_t window,
|
static int start_le_scan(uint8_t scan_type, uint16_t interval, uint16_t window,
|
||||||
uint8_t filter_dup)
|
uint8_t filter_dup)
|
||||||
{
|
{
|
||||||
|
@ -2995,12 +2912,12 @@ static int common_init(void)
|
||||||
hci_reset_complete(rsp);
|
hci_reset_complete(rsp);
|
||||||
net_buf_unref(rsp);
|
net_buf_unref(rsp);
|
||||||
|
|
||||||
|
#if defined(CONFIG_BLUETOOTH_HOST_CRYPTO)
|
||||||
/*
|
/*
|
||||||
* initialize PRNG right after reset so that it is safe to use it later
|
* initialize PRNG right after reset so that it is safe to use it later
|
||||||
* on in initialization process
|
* on in initialization process
|
||||||
*/
|
*/
|
||||||
#if !defined(CONFIG_BLUETOOTH_CONTROLLER)
|
err = prng_init();
|
||||||
err = prng_init(&prng);
|
|
||||||
if (err) {
|
if (err) {
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
* Copyright (c) 2017 Nordic Semiconductor ASA
|
||||||
* Copyright (c) 2015-2016 Intel Corporation
|
* Copyright (c) 2015-2016 Intel Corporation
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
@ -285,33 +286,6 @@ static uint8_t get_pair_method(struct bt_smp *smp, uint8_t remote_io)
|
||||||
return gen_method_sc[remote_io][get_io_capa()];
|
return gen_method_sc[remote_io][get_io_capa()];
|
||||||
}
|
}
|
||||||
|
|
||||||
static int le_encrypt(const uint8_t key[16], const uint8_t plaintext[16],
|
|
||||||
uint8_t enc_data[16])
|
|
||||||
{
|
|
||||||
struct tc_aes_key_sched_struct s;
|
|
||||||
uint8_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;
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct net_buf *smp_create_pdu(struct bt_conn *conn, uint8_t op,
|
static struct net_buf *smp_create_pdu(struct bt_conn *conn, uint8_t op,
|
||||||
size_t len)
|
size_t len)
|
||||||
{
|
{
|
||||||
|
@ -338,7 +312,7 @@ static int smp_ah(const uint8_t irk[16], const uint8_t r[3], uint8_t out[3])
|
||||||
memcpy(res, r, 3);
|
memcpy(res, r, 3);
|
||||||
memset(res + 3, 0, 13);
|
memset(res + 3, 0, 13);
|
||||||
|
|
||||||
err = le_encrypt(irk, res, res);
|
err = bt_encrypt(irk, res, res);
|
||||||
if (err) {
|
if (err) {
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
@ -1578,7 +1552,7 @@ static int smp_c1(const uint8_t k[16], const uint8_t r[16],
|
||||||
/* Using enc_data as temporary output buffer */
|
/* Using enc_data as temporary output buffer */
|
||||||
xor_128(r, p1, enc_data);
|
xor_128(r, p1, enc_data);
|
||||||
|
|
||||||
err = le_encrypt(k, enc_data, enc_data);
|
err = bt_encrypt(k, enc_data, enc_data);
|
||||||
if (err) {
|
if (err) {
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
@ -1592,7 +1566,7 @@ static int smp_c1(const uint8_t k[16], const uint8_t r[16],
|
||||||
|
|
||||||
xor_128(enc_data, p2, enc_data);
|
xor_128(enc_data, p2, enc_data);
|
||||||
|
|
||||||
return le_encrypt(k, enc_data, enc_data);
|
return bt_encrypt(k, enc_data, enc_data);
|
||||||
}
|
}
|
||||||
#endif /* !CONFIG_BLUETOOTH_SMP_SC_ONLY */
|
#endif /* !CONFIG_BLUETOOTH_SMP_SC_ONLY */
|
||||||
|
|
||||||
|
@ -1823,7 +1797,7 @@ static int smp_s1(const uint8_t k[16], const uint8_t r1[16],
|
||||||
memcpy(out + 8, r1, 8);
|
memcpy(out + 8, r1, 8);
|
||||||
|
|
||||||
/* s1(k, r1 , r2) = e(k, r') */
|
/* s1(k, r1 , r2) = e(k, r') */
|
||||||
return le_encrypt(k, out, out);
|
return bt_encrypt(k, out, out);
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint8_t legacy_get_pair_method(struct bt_smp *smp, uint8_t remote_io)
|
static uint8_t legacy_get_pair_method(struct bt_smp *smp, uint8_t remote_io)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue