From f16738b62b954d51e1b90ac68b8ccb7e2de7beca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Th=C3=A9o=20Battrel?= Date: Mon, 31 Oct 2022 14:58:02 +0100 Subject: [PATCH] Bluetooth: Move crypto toolbox functions from `smp.c` to their own files MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 --- drivers/bluetooth/CMakeLists.txt | 1 + subsys/bluetooth/CMakeLists.txt | 1 + subsys/bluetooth/Kconfig | 1 + subsys/bluetooth/bt_crypto/CMakeLists.txt | 7 + subsys/bluetooth/bt_crypto/Kconfig | 21 + subsys/bluetooth/bt_crypto/bt_crypto.c | 258 ++++++++++++ .../bluetooth/bt_crypto/include/bt_crypto.h | 124 ++++++ subsys/bluetooth/host/Kconfig | 4 +- subsys/bluetooth/host/smp.c | 397 +++--------------- tests/bluetooth/bt_crypto/CMakeLists.txt | 9 + tests/bluetooth/bt_crypto/Kconfig | 8 + tests/bluetooth/bt_crypto/prj.conf | 7 + .../bluetooth/bt_crypto/src/test_bt_crypto.c | 162 +++++++ tests/bluetooth/bt_crypto/testcase.yaml | 4 + 14 files changed, 672 insertions(+), 332 deletions(-) create mode 100644 subsys/bluetooth/bt_crypto/CMakeLists.txt create mode 100644 subsys/bluetooth/bt_crypto/Kconfig create mode 100644 subsys/bluetooth/bt_crypto/bt_crypto.c create mode 100644 subsys/bluetooth/bt_crypto/include/bt_crypto.h create mode 100644 tests/bluetooth/bt_crypto/CMakeLists.txt create mode 100644 tests/bluetooth/bt_crypto/Kconfig create mode 100644 tests/bluetooth/bt_crypto/prj.conf create mode 100644 tests/bluetooth/bt_crypto/src/test_bt_crypto.c create mode 100644 tests/bluetooth/bt_crypto/testcase.yaml diff --git a/drivers/bluetooth/CMakeLists.txt b/drivers/bluetooth/CMakeLists.txt index 14fa865f870..80f780ccb71 100644 --- a/drivers/bluetooth/CMakeLists.txt +++ b/drivers/bluetooth/CMakeLists.txt @@ -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) diff --git a/subsys/bluetooth/CMakeLists.txt b/subsys/bluetooth/CMakeLists.txt index c020481f7a4..a1cd6b51bbd 100644 --- a/subsys/bluetooth/CMakeLists.txt +++ b/subsys/bluetooth/CMakeLists.txt @@ -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) diff --git a/subsys/bluetooth/Kconfig b/subsys/bluetooth/Kconfig index d1cbef42f59..fee0c992047 100644 --- a/subsys/bluetooth/Kconfig +++ b/subsys/bluetooth/Kconfig @@ -186,6 +186,7 @@ rsource "common/Kconfig" rsource "host/Kconfig" rsource "controller/Kconfig" rsource "shell/Kconfig" +rsource "bt_crypto/Kconfig" endif # BT_HCI diff --git a/subsys/bluetooth/bt_crypto/CMakeLists.txt b/subsys/bluetooth/bt_crypto/CMakeLists.txt new file mode 100644 index 00000000000..fc0a6f95cbe --- /dev/null +++ b/subsys/bluetooth/bt_crypto/CMakeLists.txt @@ -0,0 +1,7 @@ +# SPDX-License-Identifier: Apache-2.0 + +zephyr_library() + +zephyr_include_directories(include) + +zephyr_library_sources(bt_crypto.c) diff --git a/subsys/bluetooth/bt_crypto/Kconfig b/subsys/bluetooth/bt_crypto/Kconfig new file mode 100644 index 00000000000..bbbefe1299f --- /dev/null +++ b/subsys/bluetooth/bt_crypto/Kconfig @@ -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. diff --git a/subsys/bluetooth/bt_crypto/bt_crypto.c b/subsys/bluetooth/bt_crypto/bt_crypto.c new file mode 100644 index 00000000000..b8c44deafbe --- /dev/null +++ b/subsys/bluetooth/bt_crypto/bt_crypto.c @@ -0,0 +1,258 @@ +/* Copyright (c) 2022 Nordic Semiconductor ASA + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +#include + +#include +#include +#include + +#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; +} diff --git a/subsys/bluetooth/bt_crypto/include/bt_crypto.h b/subsys/bluetooth/bt_crypto/include/bt_crypto.h new file mode 100644 index 00000000000..d74a76bc196 --- /dev/null +++ b/subsys/bluetooth/bt_crypto/include/bt_crypto.h @@ -0,0 +1,124 @@ +/* Copyright (c) 2022 Nordic Semiconductor ASA + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +#include + +/** + * @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]); diff --git a/subsys/bluetooth/host/Kconfig b/subsys/bluetooth/host/Kconfig index f19e8cd18ab..1c9ebda17d6 100644 --- a/subsys/bluetooth/host/Kconfig +++ b/subsys/bluetooth/host/Kconfig @@ -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 diff --git a/subsys/bluetooth/host/smp.c b/subsys/bluetooth/host/smp.c index 9d689475bc3..d6cab4ed2a2 100644 --- a/subsys/bluetooth/host/smp.c +++ b/subsys/bluetooth/host/smp.c @@ -10,28 +10,25 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include -#include #include +#include #include + +#include +#include +#include +#include +#include +#include +#include #include #include -#include #include -#include +#include -#include -#include -#include -#include -#include +#include -#include -#include -#include -#include - -#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; } diff --git a/tests/bluetooth/bt_crypto/CMakeLists.txt b/tests/bluetooth/bt_crypto/CMakeLists.txt new file mode 100644 index 00000000000..0da1d4e73f9 --- /dev/null +++ b/tests/bluetooth/bt_crypto/CMakeLists.txt @@ -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 +) diff --git a/tests/bluetooth/bt_crypto/Kconfig b/tests/bluetooth/bt_crypto/Kconfig new file mode 100644 index 00000000000..659cfac43b9 --- /dev/null +++ b/tests/bluetooth/bt_crypto/Kconfig @@ -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" diff --git a/tests/bluetooth/bt_crypto/prj.conf b/tests/bluetooth/bt_crypto/prj.conf new file mode 100644 index 00000000000..84088e6b035 --- /dev/null +++ b/tests/bluetooth/bt_crypto/prj.conf @@ -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 diff --git a/tests/bluetooth/bt_crypto/src/test_bt_crypto.c b/tests/bluetooth/bt_crypto/src/test_bt_crypto.c new file mode 100644 index 00000000000..b0248cbdb95 --- /dev/null +++ b/tests/bluetooth/bt_crypto/src/test_bt_crypto.c @@ -0,0 +1,162 @@ +/* Copyright (c) 2022 Nordic Semiconductor ASA + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "zephyr/ztest_assert.h" + +#include +#include + +#include + +#include + +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); +} diff --git a/tests/bluetooth/bt_crypto/testcase.yaml b/tests/bluetooth/bt_crypto/testcase.yaml new file mode 100644 index 00000000000..0587776cdb6 --- /dev/null +++ b/tests/bluetooth/bt_crypto/testcase.yaml @@ -0,0 +1,4 @@ +tests: + bluetooth.bt_crypto: + platform_allow: native_posix native_posix_64 qemu_x86 qemu_cortex_m3 + tags: bluetooth