Bluetooth: Move crypto toolbox functions from smp.c
to their own files
Move functions defined in the Cryptographic toolbox of the Bluetooth specification inside their own files in the following folder: `zephyr/subsys/bluetooth/bt_crypto`. The functions were previously implemented in `zephyr/subsys/bluetooth/host/smp.c`. The cryptographic toolbox functions can now be accessed from outside of the host. In addition to that, tests for each cryptographic toolbox functions have been added. Signed-off-by: Théo Battrel <theo.battrel@nordicsemi.no>
This commit is contained in:
parent
12b4187092
commit
f16738b62b
|
@ -1,5 +1,6 @@
|
|||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
zephyr_library()
|
||||
zephyr_library_property(ALLOW_EMPTY TRUE)
|
||||
zephyr_library_include_directories(${ZEPHYR_BASE}/subsys/bluetooth)
|
||||
add_subdirectory(hci)
|
||||
|
|
|
@ -10,6 +10,7 @@ add_subdirectory_ifdef(CONFIG_BT_SHELL shell)
|
|||
add_subdirectory_ifdef(CONFIG_BT_CONN services)
|
||||
add_subdirectory_ifdef(CONFIG_BT_MESH mesh)
|
||||
add_subdirectory_ifdef(CONFIG_BT_AUDIO audio)
|
||||
add_subdirectory_ifdef(CONFIG_BT_CRYPTO bt_crypto)
|
||||
|
||||
if(CONFIG_BT_CTLR AND CONFIG_BT_LL_SW_SPLIT)
|
||||
add_subdirectory(controller)
|
||||
|
|
|
@ -186,6 +186,7 @@ rsource "common/Kconfig"
|
|||
rsource "host/Kconfig"
|
||||
rsource "controller/Kconfig"
|
||||
rsource "shell/Kconfig"
|
||||
rsource "bt_crypto/Kconfig"
|
||||
|
||||
endif # BT_HCI
|
||||
|
||||
|
|
7
subsys/bluetooth/bt_crypto/CMakeLists.txt
Normal file
7
subsys/bluetooth/bt_crypto/CMakeLists.txt
Normal file
|
@ -0,0 +1,7 @@
|
|||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
zephyr_library()
|
||||
|
||||
zephyr_include_directories(include)
|
||||
|
||||
zephyr_library_sources(bt_crypto.c)
|
21
subsys/bluetooth/bt_crypto/Kconfig
Normal file
21
subsys/bluetooth/bt_crypto/Kconfig
Normal file
|
@ -0,0 +1,21 @@
|
|||
# Copyright (c) 2022 Nordic Semiconductor ASA
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
config BT_CRYPTO
|
||||
bool
|
||||
select TINYCRYPT
|
||||
select TINYCRYPT_AES
|
||||
select TINYCRYPT_AES_CMAC
|
||||
help
|
||||
This option enables the Bluetooth Cryptographic Toolbox.
|
||||
|
||||
config BT_DEBUG_CRYPTO
|
||||
bool "Bluetooth Cryptographic Toolbox debug"
|
||||
depends on BT_CRYPTO
|
||||
help
|
||||
This option enables debug log output for the Bluetooth
|
||||
Cryptographic Toolbox.
|
||||
|
||||
WARNING: This option prints out private security keys such as
|
||||
the Long Term Key.
|
||||
Use of this feature in production is strongly discouraged.
|
258
subsys/bluetooth/bt_crypto/bt_crypto.c
Normal file
258
subsys/bluetooth/bt_crypto/bt_crypto.c
Normal file
|
@ -0,0 +1,258 @@
|
|||
/* Copyright (c) 2022 Nordic Semiconductor ASA
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <zephyr/sys/byteorder.h>
|
||||
|
||||
#include <bt_crypto.h>
|
||||
#include <tinycrypt/cmac_mode.h>
|
||||
#include <tinycrypt/constants.h>
|
||||
|
||||
#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BT_DEBUG_CRYPTO)
|
||||
#define LOG_MODULE_NAME bt_crypto_toolbox
|
||||
#include "common/bt_str.h"
|
||||
#include "common/log.h"
|
||||
|
||||
int bt_crypto_aes_cmac(const uint8_t *key, const uint8_t *in, size_t len, uint8_t *out)
|
||||
{
|
||||
struct tc_aes_key_sched_struct sched;
|
||||
struct tc_cmac_struct state;
|
||||
|
||||
if (tc_cmac_setup(&state, key, &sched) == TC_CRYPTO_FAIL) {
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
if (tc_cmac_update(&state, in, len) == TC_CRYPTO_FAIL) {
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
if (tc_cmac_final(out, &state) == TC_CRYPTO_FAIL) {
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int bt_crypto_f4(const uint8_t *u, const uint8_t *v, const uint8_t *x, uint8_t z, uint8_t res[16])
|
||||
{
|
||||
uint8_t xs[16];
|
||||
uint8_t m[65];
|
||||
int err;
|
||||
|
||||
LOG_DBG("u %s", bt_hex(u, 32));
|
||||
LOG_DBG("v %s", bt_hex(v, 32));
|
||||
LOG_DBG("x %s z 0x%x", bt_hex(x, 16), z);
|
||||
|
||||
/*
|
||||
* U, V and Z are concatenated and used as input m to the function
|
||||
* AES-CMAC and X is used as the key k.
|
||||
*
|
||||
* Core Spec 4.2 Vol 3 Part H 2.2.5
|
||||
*
|
||||
* note:
|
||||
* bt_smp_aes_cmac uses BE data and smp_f4 accept LE so we swap
|
||||
*/
|
||||
sys_memcpy_swap(m, u, 32);
|
||||
sys_memcpy_swap(m + 32, v, 32);
|
||||
m[64] = z;
|
||||
|
||||
sys_memcpy_swap(xs, x, 16);
|
||||
|
||||
err = bt_crypto_aes_cmac(xs, m, sizeof(m), res);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
|
||||
sys_mem_swap(res, 16);
|
||||
|
||||
LOG_DBG("res %s", bt_hex(res, 16));
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
int bt_crypto_f5(const uint8_t *w, const uint8_t *n1, const uint8_t *n2, const bt_addr_le_t *a1,
|
||||
const bt_addr_le_t *a2, uint8_t *mackey, uint8_t *ltk)
|
||||
{
|
||||
static const uint8_t salt[16] = {0x6c, 0x88, 0x83, 0x91, 0xaa, 0xf5, 0xa5, 0x38,
|
||||
0x60, 0x37, 0x0b, 0xdb, 0x5a, 0x60, 0x83, 0xbe};
|
||||
uint8_t m[53] = {0x00, /* counter */
|
||||
0x62, 0x74, 0x6c, 0x65, /* keyID */
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*n1*/
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*2*/
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* a1 */
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* a2 */
|
||||
0x01, 0x00 /* length */};
|
||||
uint8_t t[16], ws[32];
|
||||
int err;
|
||||
|
||||
LOG_DBG("w %s", bt_hex(w, 32));
|
||||
LOG_DBG("n1 %s", bt_hex(n1, 16));
|
||||
LOG_DBG("n2 %s", bt_hex(n2, 16));
|
||||
|
||||
sys_memcpy_swap(ws, w, 32);
|
||||
|
||||
err = bt_crypto_aes_cmac(salt, ws, 32, t);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
|
||||
LOG_DBG("t %s", bt_hex(t, 16));
|
||||
|
||||
sys_memcpy_swap(m + 5, n1, 16);
|
||||
sys_memcpy_swap(m + 21, n2, 16);
|
||||
m[37] = a1->type;
|
||||
sys_memcpy_swap(m + 38, a1->a.val, 6);
|
||||
m[44] = a2->type;
|
||||
sys_memcpy_swap(m + 45, a2->a.val, 6);
|
||||
|
||||
err = bt_crypto_aes_cmac(t, m, sizeof(m), mackey);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
|
||||
LOG_DBG("mackey %1s", bt_hex(mackey, 16));
|
||||
|
||||
sys_mem_swap(mackey, 16);
|
||||
|
||||
/* counter for ltk is 1 */
|
||||
m[0] = 0x01;
|
||||
|
||||
err = bt_crypto_aes_cmac(t, m, sizeof(m), ltk);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
|
||||
LOG_DBG("ltk %s", bt_hex(ltk, 16));
|
||||
|
||||
sys_mem_swap(ltk, 16);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int bt_crypto_f6(const uint8_t *w, const uint8_t *n1, const uint8_t *n2, const uint8_t *r,
|
||||
const uint8_t *iocap, const bt_addr_le_t *a1, const bt_addr_le_t *a2,
|
||||
uint8_t *check)
|
||||
{
|
||||
uint8_t ws[16];
|
||||
uint8_t m[65];
|
||||
int err;
|
||||
|
||||
LOG_DBG("w %s", bt_hex(w, 16));
|
||||
LOG_DBG("n1 %s", bt_hex(n1, 16));
|
||||
LOG_DBG("n2 %s", bt_hex(n2, 16));
|
||||
LOG_DBG("r %s", bt_hex(r, 16));
|
||||
LOG_DBG("io_cap %s", bt_hex(iocap, 3));
|
||||
LOG_DBG("a1 %s", bt_hex(a1, 7));
|
||||
LOG_DBG("a2 %s", bt_hex(a2, 7));
|
||||
|
||||
sys_memcpy_swap(m, n1, 16);
|
||||
sys_memcpy_swap(m + 16, n2, 16);
|
||||
sys_memcpy_swap(m + 32, r, 16);
|
||||
sys_memcpy_swap(m + 48, iocap, 3);
|
||||
|
||||
m[51] = a1->type;
|
||||
memcpy(m + 52, a1->a.val, 6);
|
||||
sys_memcpy_swap(m + 52, a1->a.val, 6);
|
||||
|
||||
m[58] = a2->type;
|
||||
memcpy(m + 59, a2->a.val, 6);
|
||||
sys_memcpy_swap(m + 59, a2->a.val, 6);
|
||||
|
||||
sys_memcpy_swap(ws, w, 16);
|
||||
|
||||
err = bt_crypto_aes_cmac(ws, m, sizeof(m), check);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
|
||||
LOG_DBG("res %s", bt_hex(check, 16));
|
||||
|
||||
sys_mem_swap(check, 16);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int bt_crypto_g2(const uint8_t u[32], const uint8_t v[32], const uint8_t x[16], const uint8_t y[16],
|
||||
uint32_t *passkey)
|
||||
{
|
||||
uint8_t m[80], xs[16];
|
||||
int err;
|
||||
|
||||
LOG_DBG("u %s", bt_hex(u, 32));
|
||||
LOG_DBG("v %s", bt_hex(v, 32));
|
||||
LOG_DBG("x %s", bt_hex(x, 16));
|
||||
LOG_DBG("y %s", bt_hex(y, 16));
|
||||
|
||||
sys_memcpy_swap(m, u, 32);
|
||||
sys_memcpy_swap(m + 32, v, 32);
|
||||
sys_memcpy_swap(m + 64, y, 16);
|
||||
|
||||
sys_memcpy_swap(xs, x, 16);
|
||||
|
||||
/* reuse xs (key) as buffer for result */
|
||||
err = bt_crypto_aes_cmac(xs, m, sizeof(m), xs);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
LOG_DBG("res %s", bt_hex(xs, 16));
|
||||
|
||||
memcpy(passkey, xs + 12, 4);
|
||||
*passkey = sys_be32_to_cpu(*passkey) % 1000000;
|
||||
|
||||
LOG_DBG("passkey %u", *passkey);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int bt_crypto_h6(const uint8_t w[16], const uint8_t key_id[4], uint8_t res[16])
|
||||
{
|
||||
uint8_t ws[16];
|
||||
uint8_t key_id_s[4];
|
||||
int err;
|
||||
|
||||
LOG_DBG("w %s", bt_hex(w, 16));
|
||||
LOG_DBG("key_id %s", bt_hex(key_id, 4));
|
||||
|
||||
sys_memcpy_swap(ws, w, 16);
|
||||
sys_memcpy_swap(key_id_s, key_id, 4);
|
||||
|
||||
err = bt_crypto_aes_cmac(ws, key_id_s, 4, res);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
|
||||
LOG_DBG("res %s", bt_hex(res, 16));
|
||||
|
||||
sys_mem_swap(res, 16);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int bt_crypto_h7(const uint8_t salt[16], const uint8_t w[16], uint8_t res[16])
|
||||
{
|
||||
uint8_t ws[16];
|
||||
uint8_t salt_s[16];
|
||||
int err;
|
||||
|
||||
LOG_DBG("w %s", bt_hex(w, 16));
|
||||
LOG_DBG("salt %s", bt_hex(salt, 16));
|
||||
|
||||
sys_memcpy_swap(ws, w, 16);
|
||||
sys_memcpy_swap(salt_s, salt, 16);
|
||||
|
||||
err = bt_crypto_aes_cmac(salt_s, ws, 16, res);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
|
||||
LOG_DBG("res %s", bt_hex(res, 16));
|
||||
|
||||
sys_mem_swap(res, 16);
|
||||
|
||||
return 0;
|
||||
}
|
124
subsys/bluetooth/bt_crypto/include/bt_crypto.h
Normal file
124
subsys/bluetooth/bt_crypto/include/bt_crypto.h
Normal file
|
@ -0,0 +1,124 @@
|
|||
/* Copyright (c) 2022 Nordic Semiconductor ASA
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <zephyr/bluetooth/bluetooth.h>
|
||||
|
||||
/**
|
||||
* @brief Cypher based Message Authentication Code (CMAC) with AES 128 bit
|
||||
*
|
||||
* Defined in Core Vol. 3, part H 2.2.5.
|
||||
*
|
||||
* @param[in] key 128-bit key
|
||||
* @param[in] in message to be authenticated
|
||||
* @param[in] len length of the message in octets
|
||||
* @param[out] out message authentication code
|
||||
*
|
||||
* @retval 0 Computation was successful. @p res contains the result.
|
||||
* @retval -EIO Computation failed.
|
||||
*/
|
||||
int bt_crypto_aes_cmac(const uint8_t *key, const uint8_t *in, size_t len, uint8_t *out);
|
||||
|
||||
/**
|
||||
* @brief Cryptographic Toolbox f4
|
||||
*
|
||||
* Defined in Core Vol. 3, part H 2.2.6.
|
||||
*
|
||||
* @param[in] u 256-bit
|
||||
* @param[in] v 256-bit
|
||||
* @param[in] x 128-bit key
|
||||
* @param[in] z 8-bit
|
||||
* @param[out] res
|
||||
*
|
||||
* @retval 0 Computation was successful. @p res contains the result.
|
||||
* @retval -EIO Computation failed.
|
||||
*/
|
||||
int bt_crypto_f4(const uint8_t *u, const uint8_t *v, const uint8_t *x, uint8_t z, uint8_t res[16]);
|
||||
|
||||
/**
|
||||
* @brief Cryptographic Toolbox f5
|
||||
*
|
||||
* Defined in Core Vol. 3, part H 2.2.7.
|
||||
*
|
||||
* @param[in] w 256-bit
|
||||
* @param[in] n1 128-bit
|
||||
* @param[in] n2 128-bit
|
||||
* @param[in] a1 56-bit
|
||||
* @param[in] a2 56-bit
|
||||
* @param[out] mackey most significant 128-bit of the result
|
||||
* @param[out] ltk least significant 128-bit of the result
|
||||
*
|
||||
* @retval 0 Computation was successful. @p res contains the result.
|
||||
* @retval -EIO Computation failed.
|
||||
*/
|
||||
int bt_crypto_f5(const uint8_t *w, const uint8_t *n1, const uint8_t *n2, const bt_addr_le_t *a1,
|
||||
const bt_addr_le_t *a2, uint8_t *mackey, uint8_t *ltk);
|
||||
|
||||
/**
|
||||
* @brief Cryptographic Toolbox f6
|
||||
*
|
||||
* Defined in Core Vol. 3, part H 2.2.8.
|
||||
*
|
||||
* @param[in] w 128-bit
|
||||
* @param[in] n1 128-bit
|
||||
* @param[in] n2 128-bit
|
||||
* @param[in] r 128-bit
|
||||
* @param[in] iocap 24-bit
|
||||
* @param[in] a1 56-bit
|
||||
* @param[in] a2 56-bit
|
||||
* @param[out] check
|
||||
*
|
||||
* @retval 0 Computation was successful. @p res contains the result.
|
||||
* @retval -EIO Computation failed.
|
||||
*/
|
||||
int bt_crypto_f6(const uint8_t *w, const uint8_t *n1, const uint8_t *n2, const uint8_t *r,
|
||||
const uint8_t *iocap, const bt_addr_le_t *a1, const bt_addr_le_t *a2,
|
||||
uint8_t *check);
|
||||
|
||||
/**
|
||||
* @brief Cryptographic Toolbox g2
|
||||
|
||||
* Defined in Core Vol. 3, part H 2.2.9.
|
||||
*
|
||||
* @param[in] u 256-bit
|
||||
* @param[in] v 256-bit
|
||||
* @param[in] x 128-bit
|
||||
* @param[in] y 128-bit
|
||||
* @param[out] passkey
|
||||
*
|
||||
* @retval 0 Computation was successful. @p res contains the result.
|
||||
* @retval -EIO Computation failed.
|
||||
*/
|
||||
int bt_crypto_g2(const uint8_t u[32], const uint8_t v[32], const uint8_t x[16], const uint8_t y[16],
|
||||
uint32_t *passkey);
|
||||
|
||||
/**
|
||||
* @brief Cryptographic Toolbox h6
|
||||
*
|
||||
* Link key conversion defined in Core Vol. 3, part H 2.2.10.
|
||||
*
|
||||
* @param[in] w 128-bit key
|
||||
* @param[in] key_id 32-bit
|
||||
* @param[out] res 128-bit
|
||||
*
|
||||
* @retval 0 Computation was successful. @p res contains the result.
|
||||
* @retval -EIO Computation failed.
|
||||
*/
|
||||
int bt_crypto_h6(const uint8_t w[16], const uint8_t key_id[4], uint8_t res[16]);
|
||||
|
||||
/**
|
||||
* @brief Cryptographic Toolbox h7
|
||||
*
|
||||
* Link key conversion defined in Core Vol. 3, part H 2.2.11.
|
||||
*
|
||||
* @param[in] salt 128-bit key
|
||||
* @param[in] w 128-bit input of the AES-CMAC function
|
||||
* @param[out] res 128-bit
|
||||
*
|
||||
* @retval 0 Computation was successful. @p res contains the result.
|
||||
* @retval -EIO Computation failed.
|
||||
*/
|
||||
int bt_crypto_h7(const uint8_t salt[16], const uint8_t w[16], uint8_t res[16]);
|
|
@ -316,9 +316,7 @@ config BT_REMOTE_INFO
|
|||
|
||||
config BT_SMP
|
||||
bool "Security Manager Protocol support"
|
||||
select TINYCRYPT
|
||||
select TINYCRYPT_AES
|
||||
select TINYCRYPT_AES_CMAC
|
||||
select BT_CRYPTO
|
||||
select BT_RPA
|
||||
select BT_ECC
|
||||
help
|
||||
|
|
|
@ -10,28 +10,25 @@
|
|||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <zephyr/kernel.h>
|
||||
#include <stddef.h>
|
||||
#include <errno.h>
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <zephyr/bluetooth/bluetooth.h>
|
||||
#include <zephyr/bluetooth/buf.h>
|
||||
#include <zephyr/bluetooth/conn.h>
|
||||
#include <zephyr/bluetooth/hci.h>
|
||||
#include <zephyr/debug/stack.h>
|
||||
#include <zephyr/kernel.h>
|
||||
#include <zephyr/net/buf.h>
|
||||
#include <zephyr/sys/__assert.h>
|
||||
#include <zephyr/sys/atomic.h>
|
||||
#include <zephyr/sys/util.h>
|
||||
#include <zephyr/sys/byteorder.h>
|
||||
#include <zephyr/debug/stack.h>
|
||||
#include <zephyr/sys/util.h>
|
||||
|
||||
#include <zephyr/net/buf.h>
|
||||
#include <zephyr/bluetooth/hci.h>
|
||||
#include <zephyr/bluetooth/bluetooth.h>
|
||||
#include <zephyr/bluetooth/conn.h>
|
||||
#include <zephyr/bluetooth/buf.h>
|
||||
#include <bt_crypto.h>
|
||||
|
||||
#include <tinycrypt/constants.h>
|
||||
#include <tinycrypt/aes.h>
|
||||
#include <tinycrypt/utils.h>
|
||||
#include <tinycrypt/cmac_mode.h>
|
||||
|
||||
#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BT_DEBUG_SMP)
|
||||
#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BT_DEBUG_SMP)
|
||||
#define LOG_MODULE_NAME bt_smp
|
||||
#include "common/log.h"
|
||||
#include "common/bt_str.h"
|
||||
|
@ -513,229 +510,6 @@ static struct net_buf *smp_create_pdu(struct bt_smp *smp, uint8_t op, size_t len
|
|||
return buf;
|
||||
}
|
||||
|
||||
/* Cypher based Message Authentication Code (CMAC) with AES 128 bit
|
||||
*
|
||||
* Input : key ( 128-bit key )
|
||||
* : in ( message to be authenticated )
|
||||
* : len ( length of the message in octets )
|
||||
* Output : out ( message authentication code )
|
||||
*/
|
||||
static int bt_smp_aes_cmac(const uint8_t *key, const uint8_t *in, size_t len,
|
||||
uint8_t *out)
|
||||
{
|
||||
struct tc_aes_key_sched_struct sched;
|
||||
struct tc_cmac_struct state;
|
||||
|
||||
if (tc_cmac_setup(&state, key, &sched) == TC_CRYPTO_FAIL) {
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
if (tc_cmac_update(&state, in, len) == TC_CRYPTO_FAIL) {
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
if (tc_cmac_final(out, &state) == TC_CRYPTO_FAIL) {
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int smp_d1(const uint8_t *key, uint16_t d, uint16_t r, uint8_t res[16])
|
||||
{
|
||||
int err;
|
||||
|
||||
BT_DBG("key %s d %u r %u", bt_hex(key, 16), d, r);
|
||||
|
||||
sys_put_le16(d, &res[0]);
|
||||
sys_put_le16(r, &res[2]);
|
||||
memset(&res[4], 0, 16 - 4);
|
||||
|
||||
err = bt_encrypt_le(key, res, res);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
|
||||
BT_DBG("res %s", bt_hex(res, 16));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int smp_f4(const uint8_t *u, const uint8_t *v, const uint8_t *x,
|
||||
uint8_t z, uint8_t res[16])
|
||||
{
|
||||
uint8_t xs[16];
|
||||
uint8_t m[65];
|
||||
int err;
|
||||
|
||||
BT_DBG("u %s", bt_hex(u, 32));
|
||||
BT_DBG("v %s", bt_hex(v, 32));
|
||||
BT_DBG("x %s z 0x%x", bt_hex(x, 16), z);
|
||||
|
||||
/*
|
||||
* U, V and Z are concatenated and used as input m to the function
|
||||
* AES-CMAC and X is used as the key k.
|
||||
*
|
||||
* Core Spec 4.2 Vol 3 Part H 2.2.5
|
||||
*
|
||||
* note:
|
||||
* bt_smp_aes_cmac uses BE data and smp_f4 accept LE so we swap
|
||||
*/
|
||||
sys_memcpy_swap(m, u, 32);
|
||||
sys_memcpy_swap(m + 32, v, 32);
|
||||
m[64] = z;
|
||||
|
||||
sys_memcpy_swap(xs, x, 16);
|
||||
|
||||
err = bt_smp_aes_cmac(xs, m, sizeof(m), res);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
|
||||
sys_mem_swap(res, 16);
|
||||
|
||||
BT_DBG("res %s", bt_hex(res, 16));
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static int smp_f5(const uint8_t *w, const uint8_t *n1, const uint8_t *n2,
|
||||
const bt_addr_le_t *a1, const bt_addr_le_t *a2, uint8_t *mackey,
|
||||
uint8_t *ltk)
|
||||
{
|
||||
static const uint8_t salt[16] = { 0x6c, 0x88, 0x83, 0x91, 0xaa, 0xf5,
|
||||
0xa5, 0x38, 0x60, 0x37, 0x0b, 0xdb,
|
||||
0x5a, 0x60, 0x83, 0xbe };
|
||||
uint8_t m[53] = { 0x00, /* counter */
|
||||
0x62, 0x74, 0x6c, 0x65, /* keyID */
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*n1*/
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*2*/
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* a1 */
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* a2 */
|
||||
0x01, 0x00 /* length */ };
|
||||
uint8_t t[16], ws[32];
|
||||
int err;
|
||||
|
||||
BT_DBG("w %s", bt_hex(w, 32));
|
||||
BT_DBG("n1 %s", bt_hex(n1, 16));
|
||||
BT_DBG("n2 %s", bt_hex(n2, 16));
|
||||
|
||||
sys_memcpy_swap(ws, w, 32);
|
||||
|
||||
err = bt_smp_aes_cmac(salt, ws, 32, t);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
|
||||
BT_DBG("t %s", bt_hex(t, 16));
|
||||
|
||||
sys_memcpy_swap(m + 5, n1, 16);
|
||||
sys_memcpy_swap(m + 21, n2, 16);
|
||||
m[37] = a1->type;
|
||||
sys_memcpy_swap(m + 38, a1->a.val, 6);
|
||||
m[44] = a2->type;
|
||||
sys_memcpy_swap(m + 45, a2->a.val, 6);
|
||||
|
||||
err = bt_smp_aes_cmac(t, m, sizeof(m), mackey);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
|
||||
BT_DBG("mackey %1s", bt_hex(mackey, 16));
|
||||
|
||||
sys_mem_swap(mackey, 16);
|
||||
|
||||
/* counter for ltk is 1 */
|
||||
m[0] = 0x01;
|
||||
|
||||
err = bt_smp_aes_cmac(t, m, sizeof(m), ltk);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
|
||||
BT_DBG("ltk %s", bt_hex(ltk, 16));
|
||||
|
||||
sys_mem_swap(ltk, 16);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int smp_f6(const uint8_t *w, const uint8_t *n1, const uint8_t *n2,
|
||||
const uint8_t *r, const uint8_t *iocap, const bt_addr_le_t *a1,
|
||||
const bt_addr_le_t *a2, uint8_t *check)
|
||||
{
|
||||
uint8_t ws[16];
|
||||
uint8_t m[65];
|
||||
int err;
|
||||
|
||||
BT_DBG("w %s", bt_hex(w, 16));
|
||||
BT_DBG("n1 %s", bt_hex(n1, 16));
|
||||
BT_DBG("n2 %s", bt_hex(n2, 16));
|
||||
BT_DBG("r %s", bt_hex(r, 16));
|
||||
BT_DBG("io_cap %s", bt_hex(iocap, 3));
|
||||
BT_DBG("a1 %s", bt_hex(a1, 7));
|
||||
BT_DBG("a2 %s", bt_hex(a2, 7));
|
||||
|
||||
sys_memcpy_swap(m, n1, 16);
|
||||
sys_memcpy_swap(m + 16, n2, 16);
|
||||
sys_memcpy_swap(m + 32, r, 16);
|
||||
sys_memcpy_swap(m + 48, iocap, 3);
|
||||
|
||||
m[51] = a1->type;
|
||||
memcpy(m + 52, a1->a.val, 6);
|
||||
sys_memcpy_swap(m + 52, a1->a.val, 6);
|
||||
|
||||
m[58] = a2->type;
|
||||
memcpy(m + 59, a2->a.val, 6);
|
||||
sys_memcpy_swap(m + 59, a2->a.val, 6);
|
||||
|
||||
sys_memcpy_swap(ws, w, 16);
|
||||
|
||||
err = bt_smp_aes_cmac(ws, m, sizeof(m), check);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
|
||||
BT_DBG("res %s", bt_hex(check, 16));
|
||||
|
||||
sys_mem_swap(check, 16);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int smp_g2(const uint8_t u[32], const uint8_t v[32],
|
||||
const uint8_t x[16], const uint8_t y[16], uint32_t *passkey)
|
||||
{
|
||||
uint8_t m[80], xs[16];
|
||||
int err;
|
||||
|
||||
BT_DBG("u %s", bt_hex(u, 32));
|
||||
BT_DBG("v %s", bt_hex(v, 32));
|
||||
BT_DBG("x %s", bt_hex(x, 16));
|
||||
BT_DBG("y %s", bt_hex(y, 16));
|
||||
|
||||
sys_memcpy_swap(m, u, 32);
|
||||
sys_memcpy_swap(m + 32, v, 32);
|
||||
sys_memcpy_swap(m + 64, y, 16);
|
||||
|
||||
sys_memcpy_swap(xs, x, 16);
|
||||
|
||||
/* reuse xs (key) as buffer for result */
|
||||
err = bt_smp_aes_cmac(xs, m, sizeof(m), xs);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
BT_DBG("res %s", bt_hex(xs, 16));
|
||||
|
||||
memcpy(passkey, xs + 12, 4);
|
||||
*passkey = sys_be32_to_cpu(*passkey) % 1000000;
|
||||
|
||||
BT_DBG("passkey %u", *passkey);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static uint8_t get_encryption_key_size(struct bt_smp *smp)
|
||||
{
|
||||
struct bt_smp_pairing *req, *rsp;
|
||||
|
@ -882,54 +656,6 @@ static void smp_sign_info_sent(struct bt_conn *conn, void *user_data, int err)
|
|||
#endif /* CONFIG_BT_SIGNING */
|
||||
|
||||
#if defined(CONFIG_BT_BREDR)
|
||||
static int smp_h6(const uint8_t w[16], const uint8_t key_id[4], uint8_t res[16])
|
||||
{
|
||||
uint8_t ws[16];
|
||||
uint8_t key_id_s[4];
|
||||
int err;
|
||||
|
||||
BT_DBG("w %s", bt_hex(w, 16));
|
||||
BT_DBG("key_id %s", bt_hex(key_id, 4));
|
||||
|
||||
sys_memcpy_swap(ws, w, 16);
|
||||
sys_memcpy_swap(key_id_s, key_id, 4);
|
||||
|
||||
err = bt_smp_aes_cmac(ws, key_id_s, 4, res);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
|
||||
BT_DBG("res %s", bt_hex(res, 16));
|
||||
|
||||
sys_mem_swap(res, 16);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int smp_h7(const uint8_t salt[16], const uint8_t w[16], uint8_t res[16])
|
||||
{
|
||||
uint8_t ws[16];
|
||||
uint8_t salt_s[16];
|
||||
int err;
|
||||
|
||||
BT_DBG("w %s", bt_hex(w, 16));
|
||||
BT_DBG("salt %s", bt_hex(salt, 16));
|
||||
|
||||
sys_memcpy_swap(ws, w, 16);
|
||||
sys_memcpy_swap(salt_s, salt, 16);
|
||||
|
||||
err = bt_smp_aes_cmac(salt_s, ws, 16, res);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
|
||||
BT_DBG("res %s", bt_hex(res, 16));
|
||||
|
||||
sys_mem_swap(res, 16);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void sc_derive_link_key(struct bt_smp *smp)
|
||||
{
|
||||
/* constants as specified in Core Spec Vol.3 Part H 2.4.2.4 */
|
||||
|
@ -958,7 +684,7 @@ static void sc_derive_link_key(struct bt_smp *smp)
|
|||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00 };
|
||||
|
||||
if (smp_h7(salt, conn->le.keys->ltk.val, ilk)) {
|
||||
if (bt_crypto_h7(salt, conn->le.keys->ltk.val, ilk)) {
|
||||
bt_keys_link_key_clear(link_key);
|
||||
return;
|
||||
}
|
||||
|
@ -966,13 +692,13 @@ static void sc_derive_link_key(struct bt_smp *smp)
|
|||
/* constants as specified in Core Spec Vol.3 Part H 2.4.2.4 */
|
||||
static const uint8_t tmp1[4] = { 0x31, 0x70, 0x6d, 0x74 };
|
||||
|
||||
if (smp_h6(conn->le.keys->ltk.val, tmp1, ilk)) {
|
||||
if (bt_crypto_h6(conn->le.keys->ltk.val, tmp1, ilk)) {
|
||||
bt_keys_link_key_clear(link_key);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (smp_h6(ilk, lebr, link_key->val)) {
|
||||
if (bt_crypto_h6(ilk, lebr, link_key->val)) {
|
||||
bt_keys_link_key_clear(link_key);
|
||||
}
|
||||
|
||||
|
@ -1157,7 +883,7 @@ static void smp_br_derive_ltk(struct bt_smp_br *smp)
|
|||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00 };
|
||||
|
||||
if (smp_h7(salt, link_key->val, ilk)) {
|
||||
if (bt_crypto_h7(salt, link_key->val, ilk)) {
|
||||
bt_keys_link_key_clear(link_key);
|
||||
return;
|
||||
}
|
||||
|
@ -1165,13 +891,13 @@ static void smp_br_derive_ltk(struct bt_smp_br *smp)
|
|||
/* constants as specified in Core Spec Vol.3 Part H 2.4.2.5 */
|
||||
static const uint8_t tmp2[4] = { 0x32, 0x70, 0x6d, 0x74 };
|
||||
|
||||
if (smp_h6(link_key->val, tmp2, ilk)) {
|
||||
if (bt_crypto_h6(link_key->val, tmp2, ilk)) {
|
||||
bt_keys_clear(keys);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (smp_h6(ilk, brle, keys->ltk.val)) {
|
||||
if (bt_crypto_h6(ilk, brle, keys->ltk.val)) {
|
||||
bt_keys_clear(keys);
|
||||
return;
|
||||
}
|
||||
|
@ -2139,7 +1865,7 @@ static uint8_t smp_send_pairing_confirm(struct bt_smp *smp)
|
|||
|
||||
req = net_buf_add(buf, sizeof(*req));
|
||||
|
||||
if (smp_f4(sc_public_key, smp->pkey, smp->prnd, r, req->val)) {
|
||||
if (bt_crypto_f4(sc_public_key, smp->pkey, smp->prnd, r, req->val)) {
|
||||
net_buf_unref(buf);
|
||||
return BT_SMP_ERR_UNSPECIFIED;
|
||||
}
|
||||
|
@ -3487,17 +3213,15 @@ static uint8_t compute_and_send_central_dhcheck(struct bt_smp *smp)
|
|||
}
|
||||
|
||||
/* calculate LTK and mackey */
|
||||
if (smp_f5(smp->dhkey, smp->prnd, smp->rrnd,
|
||||
&smp->chan.chan.conn->le.init_addr,
|
||||
&smp->chan.chan.conn->le.resp_addr, smp->mackey,
|
||||
smp->tk)) {
|
||||
if (bt_crypto_f5(smp->dhkey, smp->prnd, smp->rrnd, &smp->chan.chan.conn->le.init_addr,
|
||||
&smp->chan.chan.conn->le.resp_addr, smp->mackey, smp->tk)) {
|
||||
BT_ERR("Calculate LTK failed");
|
||||
return BT_SMP_ERR_UNSPECIFIED;
|
||||
}
|
||||
/* calculate local DHKey check */
|
||||
if (smp_f6(smp->mackey, smp->prnd, smp->rrnd, r, &smp->preq[1],
|
||||
&smp->chan.chan.conn->le.init_addr,
|
||||
&smp->chan.chan.conn->le.resp_addr, e)) {
|
||||
if (bt_crypto_f6(smp->mackey, smp->prnd, smp->rrnd, r, &smp->preq[1],
|
||||
&smp->chan.chan.conn->le.init_addr, &smp->chan.chan.conn->le.resp_addr,
|
||||
e)) {
|
||||
BT_ERR("Calculate local DHKey check failed");
|
||||
return BT_SMP_ERR_UNSPECIFIED;
|
||||
}
|
||||
|
@ -3534,18 +3258,16 @@ static uint8_t compute_and_check_and_send_periph_dhcheck(struct bt_smp *smp)
|
|||
}
|
||||
|
||||
/* calculate LTK and mackey */
|
||||
if (smp_f5(smp->dhkey, smp->rrnd, smp->prnd,
|
||||
&smp->chan.chan.conn->le.init_addr,
|
||||
&smp->chan.chan.conn->le.resp_addr, smp->mackey,
|
||||
smp->tk)) {
|
||||
if (bt_crypto_f5(smp->dhkey, smp->rrnd, smp->prnd, &smp->chan.chan.conn->le.init_addr,
|
||||
&smp->chan.chan.conn->le.resp_addr, smp->mackey, smp->tk)) {
|
||||
BT_ERR("Calculate LTK failed");
|
||||
return BT_SMP_ERR_UNSPECIFIED;
|
||||
}
|
||||
|
||||
/* calculate local DHKey check */
|
||||
if (smp_f6(smp->mackey, smp->prnd, smp->rrnd, r, &smp->prsp[1],
|
||||
&smp->chan.chan.conn->le.resp_addr,
|
||||
&smp->chan.chan.conn->le.init_addr, e)) {
|
||||
if (bt_crypto_f6(smp->mackey, smp->prnd, smp->rrnd, r, &smp->prsp[1],
|
||||
&smp->chan.chan.conn->le.resp_addr, &smp->chan.chan.conn->le.init_addr,
|
||||
e)) {
|
||||
BT_ERR("Calculate local DHKey check failed");
|
||||
return BT_SMP_ERR_UNSPECIFIED;
|
||||
}
|
||||
|
@ -3559,9 +3281,9 @@ static uint8_t compute_and_check_and_send_periph_dhcheck(struct bt_smp *smp)
|
|||
}
|
||||
|
||||
/* calculate remote DHKey check */
|
||||
if (smp_f6(smp->mackey, smp->rrnd, smp->prnd, r, &smp->preq[1],
|
||||
&smp->chan.chan.conn->le.init_addr,
|
||||
&smp->chan.chan.conn->le.resp_addr, re)) {
|
||||
if (bt_crypto_f6(smp->mackey, smp->rrnd, smp->prnd, r, &smp->preq[1],
|
||||
&smp->chan.chan.conn->le.init_addr, &smp->chan.chan.conn->le.resp_addr,
|
||||
re)) {
|
||||
BT_ERR("Calculate remote DHKey check failed");
|
||||
return BT_SMP_ERR_UNSPECIFIED;
|
||||
}
|
||||
|
@ -3702,7 +3424,7 @@ static uint8_t sc_smp_check_confirm(struct bt_smp *smp)
|
|||
return BT_SMP_ERR_UNSPECIFIED;
|
||||
}
|
||||
|
||||
if (smp_f4(smp->pkey, sc_public_key, smp->rrnd, r, cfm)) {
|
||||
if (bt_crypto_f4(smp->pkey, sc_public_key, smp->rrnd, r, cfm)) {
|
||||
BT_ERR("Calculate confirm failed");
|
||||
return BT_SMP_ERR_UNSPECIFIED;
|
||||
}
|
||||
|
@ -3789,8 +3511,8 @@ static uint8_t smp_pairing_random(struct bt_smp *smp, struct net_buf *buf)
|
|||
switch (smp->method) {
|
||||
case PASSKEY_CONFIRM:
|
||||
/* compare passkey before calculating LTK */
|
||||
if (smp_g2(sc_public_key, smp->pkey, smp->prnd,
|
||||
smp->rrnd, &passkey)) {
|
||||
if (bt_crypto_g2(sc_public_key, smp->pkey, smp->prnd, smp->rrnd,
|
||||
&passkey)) {
|
||||
return BT_SMP_ERR_UNSPECIFIED;
|
||||
}
|
||||
|
||||
|
@ -3834,8 +3556,7 @@ static uint8_t smp_pairing_random(struct bt_smp *smp, struct net_buf *buf)
|
|||
#if defined(CONFIG_BT_PERIPHERAL)
|
||||
switch (smp->method) {
|
||||
case PASSKEY_CONFIRM:
|
||||
if (smp_g2(smp->pkey, sc_public_key, smp->rrnd, smp->prnd,
|
||||
&passkey)) {
|
||||
if (bt_crypto_g2(smp->pkey, sc_public_key, smp->rrnd, smp->prnd, &passkey)) {
|
||||
return BT_SMP_ERR_UNSPECIFIED;
|
||||
}
|
||||
|
||||
|
@ -4489,9 +4210,9 @@ static uint8_t smp_dhkey_check(struct bt_smp *smp, struct net_buf *buf)
|
|||
}
|
||||
|
||||
/* calculate remote DHKey check for comparison */
|
||||
if (smp_f6(smp->mackey, smp->rrnd, smp->prnd, r, &smp->prsp[1],
|
||||
&smp->chan.chan.conn->le.resp_addr,
|
||||
&smp->chan.chan.conn->le.init_addr, e)) {
|
||||
if (bt_crypto_f6(smp->mackey, smp->rrnd, smp->prnd, r, &smp->prsp[1],
|
||||
&smp->chan.chan.conn->le.resp_addr,
|
||||
&smp->chan.chan.conn->le.init_addr, e)) {
|
||||
return BT_SMP_ERR_UNSPECIFIED;
|
||||
}
|
||||
|
||||
|
@ -4882,7 +4603,7 @@ static int smp_sign_buf(const uint8_t *key, uint8_t *msg, uint16_t len)
|
|||
sys_mem_swap(m, len + sizeof(cnt));
|
||||
sys_memcpy_swap(key_s, key, 16);
|
||||
|
||||
err = bt_smp_aes_cmac(key_s, m, len + sizeof(cnt), tmp);
|
||||
err = bt_crypto_aes_cmac(key_s, m, len + sizeof(cnt), tmp);
|
||||
if (err) {
|
||||
BT_ERR("Data signing failed");
|
||||
return err;
|
||||
|
@ -4992,6 +4713,25 @@ int bt_smp_sign(struct bt_conn *conn, struct net_buf *buf)
|
|||
}
|
||||
#endif /* CONFIG_BT_SIGNING */
|
||||
|
||||
static int smp_d1(const uint8_t *key, uint16_t d, uint16_t r, uint8_t res[16])
|
||||
{
|
||||
int err;
|
||||
|
||||
BT_DBG("key %s d %u r %u", bt_hex(key, 16), d, r);
|
||||
|
||||
sys_put_le16(d, &res[0]);
|
||||
sys_put_le16(r, &res[2]);
|
||||
memset(&res[4], 0, 16 - 4);
|
||||
|
||||
err = bt_encrypt_le(key, res, res);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
|
||||
BT_DBG("res %s", bt_hex(res, 16));
|
||||
return 0;
|
||||
}
|
||||
|
||||
int bt_smp_irk_get(uint8_t *ir, uint8_t *irk)
|
||||
{
|
||||
uint8_t invalid_ir[16] = { 0 };
|
||||
|
@ -5031,7 +4771,7 @@ static int aes_test(const char *prefix, const uint8_t *key, const uint8_t *m,
|
|||
|
||||
BT_DBG("%s: AES CMAC of message with len %u", prefix, len);
|
||||
|
||||
bt_smp_aes_cmac(key, m, len, out);
|
||||
bt_crypto_aes_cmac(key, m, len, out);
|
||||
if (!memcmp(out, mac, 16)) {
|
||||
BT_DBG("%s: Success", prefix);
|
||||
} else {
|
||||
|
@ -5191,7 +4931,7 @@ static int smp_f4_test(void)
|
|||
uint8_t res[16];
|
||||
int err;
|
||||
|
||||
err = smp_f4(u, v, x, z, res);
|
||||
err = bt_crypto_f4(u, v, x, z, res);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
|
@ -5226,7 +4966,7 @@ static int smp_f5_test(void)
|
|||
uint8_t mackey[16], ltk[16];
|
||||
int err;
|
||||
|
||||
err = smp_f5(w, n1, n2, &a1, &a2, mackey, ltk);
|
||||
err = bt_crypto_f5(w, n1, n2, &a1, &a2, mackey, ltk);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
|
@ -5258,7 +4998,7 @@ static int smp_f6_test(void)
|
|||
uint8_t res[16];
|
||||
int err;
|
||||
|
||||
err = smp_f6(w, n1, n2, r, io_cap, &a1, &a2, res);
|
||||
err = bt_crypto_f6(w, n1, n2, r, io_cap, &a1, &a2, res);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
|
@ -5286,7 +5026,7 @@ static int smp_g2_test(void)
|
|||
uint32_t val;
|
||||
int err;
|
||||
|
||||
err = smp_g2(u, v, x, y, &val);
|
||||
err = bt_crypto_g2(u, v, x, y, &val);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
|
@ -5309,7 +5049,7 @@ static int smp_h6_test(void)
|
|||
uint8_t res[16];
|
||||
int err;
|
||||
|
||||
err = smp_h6(w, key_id, res);
|
||||
err = bt_crypto_h6(w, key_id, res);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
|
@ -5332,7 +5072,7 @@ static int smp_h7_test(void)
|
|||
uint8_t res[16];
|
||||
int err;
|
||||
|
||||
err = smp_h7(salt, w, res);
|
||||
err = bt_crypto_h7(salt, w, res);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
|
@ -5580,8 +5320,7 @@ int bt_smp_le_oob_generate_sc_data(struct bt_le_oob_sc_data *le_sc_oob)
|
|||
}
|
||||
}
|
||||
|
||||
err = smp_f4(sc_public_key, sc_public_key, le_sc_oob->r, 0,
|
||||
le_sc_oob->c);
|
||||
err = bt_crypto_f4(sc_public_key, sc_public_key, le_sc_oob->r, 0, le_sc_oob->c);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
|
@ -5618,7 +5357,7 @@ static int le_sc_oob_pairing_continue(struct bt_smp *smp)
|
|||
int err;
|
||||
uint8_t c[16];
|
||||
|
||||
err = smp_f4(smp->pkey, smp->pkey, smp->oobd_remote->r, 0, c);
|
||||
err = bt_crypto_f4(smp->pkey, smp->pkey, smp->oobd_remote->r, 0, c);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
|
|
9
tests/bluetooth/bt_crypto/CMakeLists.txt
Normal file
9
tests/bluetooth/bt_crypto/CMakeLists.txt
Normal file
|
@ -0,0 +1,9 @@
|
|||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
cmake_minimum_required(VERSION 3.20.0)
|
||||
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
|
||||
project(app)
|
||||
|
||||
target_sources(app PRIVATE
|
||||
src/test_bt_crypto.c
|
||||
)
|
8
tests/bluetooth/bt_crypto/Kconfig
Normal file
8
tests/bluetooth/bt_crypto/Kconfig
Normal file
|
@ -0,0 +1,8 @@
|
|||
# Copyright (c) 2022 Nordic Semiconductor ASA
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
config BT_CRYPTO
|
||||
default y
|
||||
|
||||
# Include Zephyr's Kconfig.
|
||||
source "Kconfig"
|
7
tests/bluetooth/bt_crypto/prj.conf
Normal file
7
tests/bluetooth/bt_crypto/prj.conf
Normal file
|
@ -0,0 +1,7 @@
|
|||
CONFIG_TEST=y
|
||||
CONFIG_ZTEST=y
|
||||
CONFIG_ZTEST_NEW_API=y
|
||||
|
||||
CONFIG_BT=y
|
||||
CONFIG_BT_CTLR=n
|
||||
CONFIG_BT_NO_DRIVER=y
|
162
tests/bluetooth/bt_crypto/src/test_bt_crypto.c
Normal file
162
tests/bluetooth/bt_crypto/src/test_bt_crypto.c
Normal file
|
@ -0,0 +1,162 @@
|
|||
/* Copyright (c) 2022 Nordic Semiconductor ASA
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include "zephyr/ztest_assert.h"
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <zephyr/ztest.h>
|
||||
|
||||
#include <bt_crypto.h>
|
||||
|
||||
ZTEST_SUITE(bt_crypto, NULL, NULL, NULL, NULL, NULL);
|
||||
|
||||
ZTEST(bt_crypto, test_result_aes_cmac)
|
||||
{
|
||||
static const uint8_t key[] = {0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
|
||||
0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c};
|
||||
static const uint8_t M[] = {
|
||||
0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73,
|
||||
0x93, 0x17, 0x2a, 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c, 0x9e, 0xb7,
|
||||
0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51, 0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4,
|
||||
0x11, 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef, 0xf6, 0x9f, 0x24, 0x45,
|
||||
0xdf, 0x4f, 0x9b, 0x17, 0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10};
|
||||
|
||||
uint8_t exp_mac1[] = {0xbb, 0x1d, 0x69, 0x29, 0xe9, 0x59, 0x37, 0x28,
|
||||
0x7f, 0xa3, 0x7d, 0x12, 0x9b, 0x75, 0x67, 0x46};
|
||||
uint8_t exp_mac2[] = {0x07, 0x0a, 0x16, 0xb4, 0x6b, 0x4d, 0x41, 0x44,
|
||||
0xf7, 0x9b, 0xdd, 0x9d, 0xd0, 0x4a, 0x28, 0x7c};
|
||||
uint8_t exp_mac3[] = {0xdf, 0xa6, 0x67, 0x47, 0xde, 0x9a, 0xe6, 0x30,
|
||||
0x30, 0xca, 0x32, 0x61, 0x14, 0x97, 0xc8, 0x27};
|
||||
uint8_t exp_mac4[] = {0x51, 0xf0, 0xbe, 0xbf, 0x7e, 0x3b, 0x9d, 0x92,
|
||||
0xfc, 0x49, 0x74, 0x17, 0x79, 0x36, 0x3c, 0xfe};
|
||||
uint8_t res[16];
|
||||
|
||||
bt_crypto_aes_cmac(key, M, 0, res);
|
||||
zassert_mem_equal(res, exp_mac1, 16);
|
||||
|
||||
bt_crypto_aes_cmac(key, M, 16, res);
|
||||
zassert_mem_equal(res, exp_mac2, 16);
|
||||
|
||||
bt_crypto_aes_cmac(key, M, 40, res);
|
||||
zassert_mem_equal(res, exp_mac3, 16);
|
||||
|
||||
bt_crypto_aes_cmac(key, M, 64, res);
|
||||
zassert_mem_equal(res, exp_mac4, 16);
|
||||
}
|
||||
|
||||
ZTEST(bt_crypto, test_result_f4)
|
||||
{
|
||||
uint8_t u[32] = {0xe6, 0x9d, 0x35, 0x0e, 0x48, 0x01, 0x03, 0xcc, 0xdb, 0xfd, 0xf4,
|
||||
0xac, 0x11, 0x91, 0xf4, 0xef, 0xb9, 0xa5, 0xf9, 0xe9, 0xa7, 0x83,
|
||||
0x2c, 0x5e, 0x2c, 0xbe, 0x97, 0xf2, 0xd2, 0x03, 0xb0, 0x20};
|
||||
uint8_t v[32] = {0xfd, 0xc5, 0x7f, 0xf4, 0x49, 0xdd, 0x4f, 0x6b, 0xfb, 0x7c, 0x9d,
|
||||
0xf1, 0xc2, 0x9a, 0xcb, 0x59, 0x2a, 0xe7, 0xd4, 0xee, 0xfb, 0xfc,
|
||||
0x0a, 0x90, 0x9a, 0xbb, 0xf6, 0x32, 0x3d, 0x8b, 0x18, 0x55};
|
||||
uint8_t x[16] = {0xab, 0xae, 0x2b, 0x71, 0xec, 0xb2, 0xff, 0xff,
|
||||
0x3e, 0x73, 0x77, 0xd1, 0x54, 0x84, 0xcb, 0xd5};
|
||||
uint8_t z = 0x00;
|
||||
|
||||
uint8_t exp_res[16] = {0x2d, 0x87, 0x74, 0xa9, 0xbe, 0xa1, 0xed, 0xf1,
|
||||
0x1c, 0xbd, 0xa9, 0x07, 0xf1, 0x16, 0xc9, 0xf2};
|
||||
uint8_t res[16];
|
||||
|
||||
bt_crypto_f4(u, v, x, z, res);
|
||||
zassert_mem_equal(res, exp_res, 16);
|
||||
}
|
||||
|
||||
ZTEST(bt_crypto, test_result_f5)
|
||||
{
|
||||
uint8_t w[32] = {0x98, 0xa6, 0xbf, 0x73, 0xf3, 0x34, 0x8d, 0x86, 0xf1, 0x66, 0xf8,
|
||||
0xb4, 0x13, 0x6b, 0x79, 0x99, 0x9b, 0x7d, 0x39, 0x0a, 0xa6, 0x10,
|
||||
0x10, 0x34, 0x05, 0xad, 0xc8, 0x57, 0xa3, 0x34, 0x02, 0xec};
|
||||
uint8_t n1[16] = {0xab, 0xae, 0x2b, 0x71, 0xec, 0xb2, 0xff, 0xff,
|
||||
0x3e, 0x73, 0x77, 0xd1, 0x54, 0x84, 0xcb, 0xd5};
|
||||
uint8_t n2[16] = {0xcf, 0xc4, 0x3d, 0xff, 0xf7, 0x83, 0x65, 0x21,
|
||||
0x6e, 0x5f, 0xa7, 0x25, 0xcc, 0xe7, 0xe8, 0xa6};
|
||||
bt_addr_le_t a1 = {.type = 0x00, .a.val = {0xce, 0xbf, 0x37, 0x37, 0x12, 0x56}};
|
||||
bt_addr_le_t a2 = {.type = 0x00, .a.val = {0xc1, 0xcf, 0x2d, 0x70, 0x13, 0xa7}};
|
||||
|
||||
uint8_t exp_ltk[16] = {0x38, 0x0a, 0x75, 0x94, 0xb5, 0x22, 0x05, 0x98,
|
||||
0x23, 0xcd, 0xd7, 0x69, 0x11, 0x79, 0x86, 0x69};
|
||||
uint8_t exp_mackey[16] = {0x20, 0x6e, 0x63, 0xce, 0x20, 0x6a, 0x3f, 0xfd,
|
||||
0x02, 0x4a, 0x08, 0xa1, 0x76, 0xf1, 0x65, 0x29};
|
||||
uint8_t mackey[16], ltk[16];
|
||||
|
||||
bt_crypto_f5(w, n1, n2, &a1, &a2, mackey, ltk);
|
||||
zassert_mem_equal(mackey, exp_mackey, 16);
|
||||
zassert_mem_equal(ltk, exp_ltk, 16);
|
||||
}
|
||||
|
||||
ZTEST(bt_crypto, test_result_f6)
|
||||
{
|
||||
uint8_t w[16] = {0x20, 0x6e, 0x63, 0xce, 0x20, 0x6a, 0x3f, 0xfd,
|
||||
0x02, 0x4a, 0x08, 0xa1, 0x76, 0xf1, 0x65, 0x29};
|
||||
uint8_t n1[16] = {0xab, 0xae, 0x2b, 0x71, 0xec, 0xb2, 0xff, 0xff,
|
||||
0x3e, 0x73, 0x77, 0xd1, 0x54, 0x84, 0xcb, 0xd5};
|
||||
uint8_t n2[16] = {0xcf, 0xc4, 0x3d, 0xff, 0xf7, 0x83, 0x65, 0x21,
|
||||
0x6e, 0x5f, 0xa7, 0x25, 0xcc, 0xe7, 0xe8, 0xa6};
|
||||
uint8_t r[16] = {0xc8, 0x0f, 0x2d, 0x0c, 0xd2, 0x42, 0xda, 0x08,
|
||||
0x54, 0xbb, 0x53, 0xb4, 0x3b, 0x34, 0xa3, 0x12};
|
||||
uint8_t io_cap[3] = {0x02, 0x01, 0x01};
|
||||
bt_addr_le_t a1 = {.type = 0x00, .a.val = {0xce, 0xbf, 0x37, 0x37, 0x12, 0x56}};
|
||||
bt_addr_le_t a2 = {.type = 0x00, .a.val = {0xc1, 0xcf, 0x2d, 0x70, 0x13, 0xa7}};
|
||||
|
||||
uint8_t exp_res[16] = {0x61, 0x8f, 0x95, 0xda, 0x09, 0x0b, 0x6c, 0xd2,
|
||||
0xc5, 0xe8, 0xd0, 0x9c, 0x98, 0x73, 0xc4, 0xe3};
|
||||
uint8_t res[16];
|
||||
|
||||
bt_crypto_f6(w, n1, n2, r, io_cap, &a1, &a2, res);
|
||||
zassert_mem_equal(res, exp_res, 16);
|
||||
}
|
||||
|
||||
ZTEST(bt_crypto, test_result_g2)
|
||||
{
|
||||
uint8_t u[32] = {0xe6, 0x9d, 0x35, 0x0e, 0x48, 0x01, 0x03, 0xcc, 0xdb, 0xfd, 0xf4,
|
||||
0xac, 0x11, 0x91, 0xf4, 0xef, 0xb9, 0xa5, 0xf9, 0xe9, 0xa7, 0x83,
|
||||
0x2c, 0x5e, 0x2c, 0xbe, 0x97, 0xf2, 0xd2, 0x03, 0xb0, 0x20};
|
||||
uint8_t v[32] = {0xfd, 0xc5, 0x7f, 0xf4, 0x49, 0xdd, 0x4f, 0x6b, 0xfb, 0x7c, 0x9d,
|
||||
0xf1, 0xc2, 0x9a, 0xcb, 0x59, 0x2a, 0xe7, 0xd4, 0xee, 0xfb, 0xfc,
|
||||
0x0a, 0x90, 0x9a, 0xbb, 0xf6, 0x32, 0x3d, 0x8b, 0x18, 0x55};
|
||||
uint8_t x[16] = {0xab, 0xae, 0x2b, 0x71, 0xec, 0xb2, 0xff, 0xff,
|
||||
0x3e, 0x73, 0x77, 0xd1, 0x54, 0x84, 0xcb, 0xd5};
|
||||
uint8_t y[16] = {0xcf, 0xc4, 0x3d, 0xff, 0xf7, 0x83, 0x65, 0x21,
|
||||
0x6e, 0x5f, 0xa7, 0x25, 0xcc, 0xe7, 0xe8, 0xa6};
|
||||
|
||||
uint32_t exp_res = 0x2f9ed5ba % 1000000;
|
||||
uint32_t res;
|
||||
|
||||
bt_crypto_g2(u, v, x, y, &res);
|
||||
zassert_equal(res, exp_res);
|
||||
}
|
||||
|
||||
ZTEST(bt_crypto, test_result_h6)
|
||||
{
|
||||
uint8_t w[16] = {0x9b, 0x7d, 0x39, 0x0a, 0xa6, 0x10, 0x10, 0x34,
|
||||
0x05, 0xad, 0xc8, 0x57, 0xa3, 0x34, 0x02, 0xec};
|
||||
uint8_t key_id[4] = {0x72, 0x62, 0x65, 0x6c};
|
||||
|
||||
uint8_t exp_res[16] = {0x99, 0x63, 0xb1, 0x80, 0xe2, 0xa9, 0xd3, 0xe8,
|
||||
0x1c, 0xc9, 0x6d, 0xe7, 0x02, 0xe1, 0x9a, 0x2d};
|
||||
uint8_t res[16];
|
||||
|
||||
bt_crypto_h6(w, key_id, res);
|
||||
zassert_mem_equal(res, exp_res, 16);
|
||||
}
|
||||
|
||||
ZTEST(bt_crypto, test_result_h7)
|
||||
{
|
||||
uint8_t salt[16] = {0x31, 0x70, 0x6d, 0x74, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
||||
uint8_t w[16] = {0x9b, 0x7d, 0x39, 0x0a, 0xa6, 0x10, 0x10, 0x34,
|
||||
0x05, 0xad, 0xc8, 0x57, 0xa3, 0x34, 0x02, 0xec};
|
||||
|
||||
uint8_t exp_res[16] = {0x11, 0x70, 0xa5, 0x75, 0x2a, 0x8c, 0x99, 0xd2,
|
||||
0xec, 0xc0, 0xa3, 0xc6, 0x97, 0x35, 0x17, 0xfb};
|
||||
uint8_t res[16];
|
||||
|
||||
bt_crypto_h7(salt, w, res);
|
||||
zassert_mem_equal(res, exp_res, 16);
|
||||
}
|
4
tests/bluetooth/bt_crypto/testcase.yaml
Normal file
4
tests/bluetooth/bt_crypto/testcase.yaml
Normal file
|
@ -0,0 +1,4 @@
|
|||
tests:
|
||||
bluetooth.bt_crypto:
|
||||
platform_allow: native_posix native_posix_64 qemu_x86 qemu_cortex_m3
|
||||
tags: bluetooth
|
Loading…
Reference in a new issue