zephyr/subsys/bluetooth/crypto/bt_crypto.c
Valerio Setti da9ab6f593 bt: crypto/host: remove CONFIG_BT_USE_PSA_API symbol
CONFIG_BT_USE_PSA_API was used in BT crypto/host modules to select
PSA crypto API over TinyCrypt (which was the default until now).
Since TinyCrypt is being deprecated and PSA crypto API is the new
standard library for crypto operations, CONFIG_BT_USE_PSA_API is
no more needed.

Signed-off-by: Valerio Setti <vsetti@baylibre.com>
2024-11-27 16:40:47 -05:00

272 lines
5.7 KiB
C

/* Copyright (c) 2022 Nordic Semiconductor ASA
* SPDX-License-Identifier: Apache-2.0
*/
#include <errno.h>
#include <string.h>
#include <zephyr/sys/byteorder.h>
#include "psa/crypto.h"
#include "common/bt_str.h"
#include "bt_crypto.h"
#define LOG_LEVEL CONFIG_BT_CRYPTO_LOG_LEVEL
#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(bt_crypto);
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;
}
int bt_crypto_h8(const uint8_t k[16], const uint8_t s[16], const uint8_t key_id[4], uint8_t res[16])
{
uint8_t key_id_s[4];
uint8_t iks[16];
uint8_t ks[16];
uint8_t ss[16];
int err;
LOG_DBG("k %s", bt_hex(k, 16));
LOG_DBG("s %s", bt_hex(s, 16));
LOG_DBG("key_id %s", bt_hex(key_id, 4));
sys_memcpy_swap(ks, k, 16);
sys_memcpy_swap(ss, s, 16);
err = bt_crypto_aes_cmac(ss, ks, 16, iks);
if (err) {
return err;
}
sys_memcpy_swap(key_id_s, key_id, 4);
err = bt_crypto_aes_cmac(iks, key_id_s, 4, res);
if (err) {
return err;
}
LOG_DBG("res %s", bt_hex(res, 16));
sys_mem_swap(res, 16);
return 0;
}