feat(bt): Add initial support of Bluetooth Classic on ESP32-S31

- feat(soc_caps): Enable BT Classic and BLE in esp32s31
- Add git submodule for ESP32-S31 bt controller lib files
- changed sdkconfig.defaults and README for Bluetooth Classic examples
- change(docs): Added vendor HCI documentations for ESP32-S31
- change(Bluedroid): Adapt to ESP32-S31 due to some API differences on
  Bluetooth controller from ESP32
- change(bt): Modify CMakeLists.txt to support the Bluetooth dual-mode
  architecture on ESP32-S31
- change(bt): Add ECC P-192 functions to tinycrypt
This commit is contained in:
wangmengyang
2026-04-21 17:50:34 +08:00
committed by Wang Mengyang
parent 9c2bde6b64
commit 11268d8bfb
95 changed files with 5312 additions and 165 deletions
+6 -1
View File
@@ -8,10 +8,13 @@ config BT_ALARM_MAX_NUM
choice BT_SMP_CRYPTO_STACK
prompt "SMP cryptographic stack"
depends on (BT_BLE_SMP_ENABLE || BT_SMP_ENABLE || BT_NIMBLE_SECURITY_ENABLE || BT_LE_SECURITY_ENABLE)
depends on (BT_BLE_SMP_ENABLE || BT_SMP_ENABLE || BT_NIMBLE_SECURITY_ENABLE || BT_LE_SECURITY_ENABLE || \
BT_CTRL_BREDR_ENABLE)
default BT_SMP_CRYPTO_STACK_TINYCRYPT
help
Select the cryptographic library to use for SMP operations (AES, AES-CMAC, ECDH P-256).
With BR/EDR controller enabled, mbedTLS also enables SHA-256 (for the BR/EDR port)
and ECDH for P-192 on the controller port.
config BT_SMP_CRYPTO_STACK_TINYCRYPT
bool "TinyCrypt"
@@ -22,6 +25,8 @@ choice BT_SMP_CRYPTO_STACK
This is the default option.
config BT_SMP_CRYPTO_STACK_MBEDTLS
# BT Classic requires ECC P-192, which is removed in mbedtls 4.1.0
depends on !BT_CTRL_BREDR_ENABLE
bool "mbedTLS"
select MBEDTLS_AES_C
select MBEDTLS_CMAC_C
@@ -77,12 +77,24 @@
#ifndef __TC_UECC_H__
#define __TC_UECC_H__
#include "sdkconfig.h"
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
#define uECC_VLI_NATIVE_LITTLE_ENDIAN 1
#define uECC_SUPPORTS_secp256r1 1
#ifndef uECC_SUPPORTS_secp192r1
#if defined(CONFIG_BT_CTRL_BREDR_ENABLE) && (CONFIG_BT_SMP_CRYPTO_STACK_TINYCRYPT)
#define uECC_SUPPORTS_secp192r1 1
#else
#define uECC_SUPPORTS_secp192r1 0
#endif
#endif
/* Word size (4 bytes considering 32-bits architectures) */
#define uECC_WORD_SIZE 4
@@ -112,6 +124,13 @@ typedef uint64_t uECC_dword_t;
/* Number of bytes to represent an element of the the curve p-256: */
#define NUM_ECC_BYTES (uECC_WORD_SIZE*NUM_ECC_WORDS)
#if uECC_SUPPORTS_secp192r1
/* Number of words of 32 bits to represent an element of the the curve p-192: */
#define NUM_ECC_WORDS_SECP192R1 6
/* Number of bytes to represent an element of the the curve p-192: */
#define NUM_ECC_BYTES_SECP192R1 (uECC_WORD_SIZE * NUM_ECC_WORDS_SECP192R1)
#endif
/* structure that represents an elliptic curve (e.g. p256):*/
struct uECC_Curve_t;
typedef const struct uECC_Curve_t * uECC_Curve;
@@ -200,6 +219,43 @@ static const struct uECC_Curve_t curve_secp256r1 = {
uECC_Curve uECC_secp256r1(void);
#if uECC_SUPPORTS_secp192r1
uECC_Curve uECC_secp192r1(void);
/*
* @brief Computes result = product % curve_p (NIST P-192)
* from http://www.nsa.gov/ia/_files/nist-routines.pdf
* @param result OUT -- product % curve_p
* @param product IN -- value to be reduced mod curve_p
*/
void vli_mmod_fast_secp192r1(unsigned int *result, unsigned int *product);
/* definition of curve NIST p-192: */
static const struct uECC_Curve_t curve_secp192r1 = { NUM_ECC_WORDS_SECP192R1,
NUM_ECC_BYTES_SECP192R1,
192, /* num_n_bits */
{ BYTES_TO_WORDS_8(FF, FF, FF, FF, FF, FF, FF, FF),
BYTES_TO_WORDS_8(FE, FF, FF, FF, FF, FF, FF, FF),
BYTES_TO_WORDS_8(FF, FF, FF, FF, FF, FF, FF, FF) },
{ BYTES_TO_WORDS_8(31, 28, D2, B4, B1, C9, 6B, 14),
BYTES_TO_WORDS_8(36, F8, DE, 99, FF, FF, FF, FF),
BYTES_TO_WORDS_8(FF, FF, FF, FF, FF, FF, FF, FF) },
{ BYTES_TO_WORDS_8(12, 10, FF, 82, FD, 0A, FF, F4),
BYTES_TO_WORDS_8(00, 88, A1, 43, EB, 20, BF, 7C),
BYTES_TO_WORDS_8(F6, 90, 30, B0, 0E, A8, 8D, 18),
BYTES_TO_WORDS_8(11, 48, 79, 1E, A1, 77, F9, 73),
BYTES_TO_WORDS_8(D5, CD, 24, 6B, ED, 11, 10, 63),
BYTES_TO_WORDS_8(78, DA, C8, FF, 95, 2B, 19, 07) },
{ BYTES_TO_WORDS_8(B1, B9, 46, C1, EC, DE, B8, FE),
BYTES_TO_WORDS_8(49, 30, 24, 72, AB, E9, A7, 0F),
BYTES_TO_WORDS_8(E7, 80, 9C, E5, 19, 05, 21, 64) },
&double_jacobian_default,
&x_side_default,
&vli_mmod_fast_secp192r1 };
#endif /* uECC_SUPPORTS_secp192r1 */
/*
* @brief Generates a random integer in the range 0 < random < top.
* Both random and top have num_words words.
+51 -5
View File
@@ -542,6 +542,41 @@ void x_side_default(uECC_word_t *result,
uECC_vli_modAdd(result, result, curve->b, curve->p, num_words);
}
#if uECC_SUPPORTS_secp192r1
uECC_Curve uECC_secp192r1(void)
{
return &curve_secp192r1;
}
void vli_mmod_fast_secp192r1(unsigned int *result, unsigned int *product)
{
unsigned int tmp[NUM_ECC_WORDS_SECP192R1];
int carry;
uECC_vli_set(result, product, NUM_ECC_WORDS_SECP192R1);
uECC_vli_set(tmp, &product[6], NUM_ECC_WORDS_SECP192R1);
carry = uECC_vli_add(result, result, tmp, NUM_ECC_WORDS_SECP192R1);
tmp[0] = tmp[1] = 0;
tmp[2] = product[6];
tmp[3] = product[7];
tmp[4] = product[8];
tmp[5] = product[9];
carry += uECC_vli_add(result, result, tmp, NUM_ECC_WORDS_SECP192R1);
tmp[0] = tmp[2] = product[10];
tmp[1] = tmp[3] = product[11];
tmp[4] = tmp[5] = 0;
carry += uECC_vli_add(result, result, tmp, NUM_ECC_WORDS_SECP192R1);
while (carry || uECC_vli_cmp_unsafe(curve_secp192r1.p, result, NUM_ECC_WORDS_SECP192R1) != 1) {
carry -= uECC_vli_sub(result, result, curve_secp192r1.p, NUM_ECC_WORDS_SECP192R1);
}
}
#endif /* uECC_SUPPORTS_secp192r1 */
uECC_Curve uECC_secp256r1(void)
{
return &curve_secp256r1;
@@ -766,8 +801,12 @@ void EccPoint_mult(uECC_word_t * result, const uECC_word_t * point,
#if SOC_ECC_SUPPORTED && !SOC_ESP_NIMBLE_CONTROLLER
wordcount_t num_words = curve->num_words;
/* Only p256r1 is supported currently. */
assert (curve == uECC_secp256r1());
/* Only p256r1 and p192r1 are supported currently. */
assert(curve == uECC_secp256r1()
#if uECC_SUPPORTS_secp192r1
|| curve == uECC_secp192r1()
#endif /* #if uECC_SUPPORTS_secp192r1 */
);
esp_tinycrypt_calc_ecc_mult((const uint8_t *)&point[0], (const uint8_t *)&point[num_words],
(uint8_t *)scalar, (uint8_t *)&result[0], (uint8_t *)&result[num_words],
@@ -936,8 +975,11 @@ int uECC_valid_point(const uECC_word_t *point, uECC_Curve curve)
}
#if SOC_ECC_SUPPORTED && !SOC_ESP_NIMBLE_CONTROLLER
/* Only p256r1 is supported currently. */
if (curve != uECC_secp256r1()) {
if (curve != uECC_secp256r1()
#if uECC_SUPPORTS_secp192r1
&& curve != uECC_secp192r1()
#endif /* uECC_SUPPORTS_secp192r1 */
) {
return -5;
}
@@ -964,14 +1006,16 @@ int uECC_valid_point(const uECC_word_t *point, uECC_Curve curve)
int uECC_valid_public_key(const uint8_t *public_key, uECC_Curve curve)
{
uECC_word_t _public[NUM_ECC_WORDS * 2];
wordcount_t num_point_words = curve->num_words * 2;
uECC_vli_clear(_public, NUM_ECC_WORDS * 2);
uECC_vli_bytesToNative(_public, public_key, curve->num_bytes);
uECC_vli_bytesToNative(
_public + curve->num_words,
public_key + curve->num_bytes,
curve->num_bytes);
if (uECC_vli_cmp_unsafe(_public, curve->G, NUM_ECC_WORDS * 2) == 0) {
if (uECC_vli_cmp_unsafe(_public, curve->G, num_point_words) == 0) {
return -4;
}
@@ -984,6 +1028,8 @@ int uECC_compute_public_key(const uint8_t *private_key, uint8_t *public_key,
uECC_word_t _private[NUM_ECC_WORDS];
uECC_word_t _public[NUM_ECC_WORDS * 2];
uECC_vli_clear(_private, NUM_ECC_WORDS);
uECC_vli_clear(_public, NUM_ECC_WORDS * 2);
uECC_vli_bytesToNative(
_private,
private_key,