mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
Merge branch 'bugfix/btdm_ecdh_public_key_not_check' into 'master'
component/bt: Fixed the vulnerability released by Bluetooth org when using… See merge request idf/esp-idf!2933
This commit is contained in:
commit
886bf4b88e
@ -1117,6 +1117,12 @@ UT_010_04:
|
|||||||
- UT_T1_RMT
|
- UT_T1_RMT
|
||||||
- psram
|
- psram
|
||||||
|
|
||||||
|
UT_601_01:
|
||||||
|
<<: *unit_test_template
|
||||||
|
tags:
|
||||||
|
- ESP32_IDF
|
||||||
|
- UT_T1_1
|
||||||
|
|
||||||
IT_001_01:
|
IT_001_01:
|
||||||
<<: *test_template
|
<<: *test_template
|
||||||
tags:
|
tags:
|
||||||
|
@ -58,6 +58,8 @@ extern elliptic_curve_t curve_p256;
|
|||||||
|
|
||||||
void ECC_PointMult_Bin_NAF(Point *q, Point *p, DWORD *n, uint32_t keyLength);
|
void ECC_PointMult_Bin_NAF(Point *q, Point *p, DWORD *n, uint32_t keyLength);
|
||||||
|
|
||||||
|
bool ECC_CheckPointIsInElliCur_P256(Point *p);
|
||||||
|
|
||||||
#define ECC_PointMult(q, p, n, keyLength) ECC_PointMult_Bin_NAF(q, p, n, keyLength)
|
#define ECC_PointMult(q, p, n, keyLength) ECC_PointMult_Bin_NAF(q, p, n, keyLength)
|
||||||
|
|
||||||
void p_256_init_curve(UINT32 keyLength);
|
void p_256_init_curve(UINT32 keyLength);
|
||||||
|
@ -240,4 +240,40 @@ void ECC_PointMult_Bin_NAF(Point *q, Point *p, DWORD *n, uint32_t keyLength)
|
|||||||
multiprecision_mersenns_mult_mod(q->y, q->y, q->z, keyLength);
|
multiprecision_mersenns_mult_mod(q->y, q->y, q->z, keyLength);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ECC_CheckPointIsInElliCur_P256(Point *p)
|
||||||
|
{
|
||||||
|
/* y^2 % q */
|
||||||
|
DWORD y_y_q[KEY_LENGTH_DWORDS_P256] = {0x0};
|
||||||
|
/* x^2 % q */
|
||||||
|
DWORD x_x_q[KEY_LENGTH_DWORDS_P256] = {0x0};
|
||||||
|
/* x % q */
|
||||||
|
DWORD x_q[KEY_LENGTH_DWORDS_P256] = {0x0};
|
||||||
|
/* x^2, To prevent overflow, the length of the x square here needs to
|
||||||
|
be expanded to two times the original one. */
|
||||||
|
DWORD x_x[2*KEY_LENGTH_DWORDS_P256] = {0x0};
|
||||||
|
/* y_y_q =(p->y)^2(mod q) */
|
||||||
|
multiprecision_mersenns_squa_mod(y_y_q, p->y, KEY_LENGTH_DWORDS_P256);
|
||||||
|
/* Calculate the value of p->x square, x_x = (p->x)^2 */
|
||||||
|
multiprecision_mult(x_x, p->x, p->x, KEY_LENGTH_DWORDS_P256);
|
||||||
|
/* The function of the elliptic curve is y^2 = x^3 - 3x + b (mod q) ==>
|
||||||
|
y^2 = (x^2 - 3)*x + b (mod q),
|
||||||
|
so we calculate the x^2 - 3 value here */
|
||||||
|
x_x[0] -= 3;
|
||||||
|
/* Using math relations. (a*b) % q = ((a%q)*(b%q)) % q ==>
|
||||||
|
(x^2 - 3)*x = (((x^2 - 3) % q) * x % q) % q */
|
||||||
|
multiprecision_fast_mod_P256(x_x_q, x_x);
|
||||||
|
/* x_x = x_x_q * x_q */
|
||||||
|
multiprecision_mult(x_x, x_x_q, p->x, KEY_LENGTH_DWORDS_P256);
|
||||||
|
/* x_q = x_x % q */
|
||||||
|
multiprecision_fast_mod_P256(x_q, x_x);
|
||||||
|
/* Save the result in x_x_q */
|
||||||
|
multiprecision_add_mod(x_x_q, x_q, curve_p256.b, KEY_LENGTH_DWORDS_P256);
|
||||||
|
/* compare the y_y_q and x_x_q, see if they are on a given elliptic curve. */
|
||||||
|
if (multiprecision_compare(y_y_q, x_x_q, KEY_LENGTH_DWORDS_P256)) {
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
#include "btm_int.h"
|
#include "btm_int.h"
|
||||||
#include "stack/l2c_api.h"
|
#include "stack/l2c_api.h"
|
||||||
#include "smp_int.h"
|
#include "smp_int.h"
|
||||||
|
#include "p_256_ecc_pp.h"
|
||||||
//#include "utils/include/bt_utils.h"
|
//#include "utils/include/bt_utils.h"
|
||||||
|
|
||||||
#if SMP_INCLUDED == TRUE
|
#if SMP_INCLUDED == TRUE
|
||||||
@ -668,6 +669,12 @@ void smp_process_pairing_public_key(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
|
|||||||
|
|
||||||
STREAM_TO_ARRAY(p_cb->peer_publ_key.x, p, BT_OCTET32_LEN);
|
STREAM_TO_ARRAY(p_cb->peer_publ_key.x, p, BT_OCTET32_LEN);
|
||||||
STREAM_TO_ARRAY(p_cb->peer_publ_key.y, p, BT_OCTET32_LEN);
|
STREAM_TO_ARRAY(p_cb->peer_publ_key.y, p, BT_OCTET32_LEN);
|
||||||
|
/* In order to prevent the x and y coordinates of the public key from being modified,
|
||||||
|
we need to check whether the x and y coordinates are on the given elliptic curve. */
|
||||||
|
if (!ECC_CheckPointIsInElliCur_P256((Point *)&p_cb->peer_publ_key)) {
|
||||||
|
SMP_TRACE_ERROR("%s, Invalid Public key.", __func__);
|
||||||
|
smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &reason);
|
||||||
|
}
|
||||||
p_cb->flags |= SMP_PAIR_FLAG_HAVE_PEER_PUBL_KEY;
|
p_cb->flags |= SMP_PAIR_FLAG_HAVE_PEER_PUBL_KEY;
|
||||||
|
|
||||||
smp_wait_for_both_public_keys(p_cb, NULL);
|
smp_wait_for_both_public_keys(p_cb, NULL);
|
||||||
|
5
components/bt/test/component.mk
Normal file
5
components/bt/test/component.mk
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
#
|
||||||
|
#Component Makefile
|
||||||
|
#
|
||||||
|
|
||||||
|
COMPONENT_ADD_LDFLAGS = -Wl,--whole-archive -l$(COMPONENT_NAME) -Wl,--no-whole-archive
|
107
components/bt/test/test_smp.c
Normal file
107
components/bt/test/test_smp.c
Normal file
@ -0,0 +1,107 @@
|
|||||||
|
/*
|
||||||
|
Tests for the BLE SMP implementation
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <esp_types.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <malloc.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "freertos/FreeRTOS.h"
|
||||||
|
#include "freertos/task.h"
|
||||||
|
#include "freertos/semphr.h"
|
||||||
|
#include "freertos/queue.h"
|
||||||
|
#include "freertos/xtensa_api.h"
|
||||||
|
#include "unity.h"
|
||||||
|
#include "esp_heap_caps.h"
|
||||||
|
#include "esp_log.h"
|
||||||
|
#include "freertos/ringbuf.h"
|
||||||
|
#include "esp_system.h"
|
||||||
|
#include "nvs_flash.h"
|
||||||
|
|
||||||
|
#include "esp_bt.h"
|
||||||
|
#include "esp_bt_main.h"
|
||||||
|
#include "esp_bt_device.h"
|
||||||
|
#include "esp_gap_ble_api.h"
|
||||||
|
|
||||||
|
#define TAG "ble_smp_test"
|
||||||
|
|
||||||
|
#define KEY_LENGTH_DWORDS_P256 8
|
||||||
|
|
||||||
|
typedef unsigned long DWORD;
|
||||||
|
typedef uint32_t UINT32;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
DWORD x[KEY_LENGTH_DWORDS_P256];
|
||||||
|
DWORD y[KEY_LENGTH_DWORDS_P256];
|
||||||
|
DWORD z[KEY_LENGTH_DWORDS_P256];
|
||||||
|
} Point;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
// curve's coefficients
|
||||||
|
DWORD a[KEY_LENGTH_DWORDS_P256];
|
||||||
|
DWORD b[KEY_LENGTH_DWORDS_P256];
|
||||||
|
|
||||||
|
//whether a is -3
|
||||||
|
int a_minus3;
|
||||||
|
|
||||||
|
// prime modulus
|
||||||
|
DWORD p[KEY_LENGTH_DWORDS_P256];
|
||||||
|
|
||||||
|
// Omega, p = 2^m -omega
|
||||||
|
DWORD omega[KEY_LENGTH_DWORDS_P256];
|
||||||
|
|
||||||
|
// base point, a point on E of order r
|
||||||
|
Point G;
|
||||||
|
|
||||||
|
} elliptic_curve_t;
|
||||||
|
|
||||||
|
extern void ECC_PointMult_Bin_NAF(Point *q, Point *p, DWORD *n, uint32_t keyLength);
|
||||||
|
extern bool ECC_CheckPointIsInElliCur_P256(Point *p);
|
||||||
|
extern void p_256_init_curve(UINT32 keyLength);
|
||||||
|
extern elliptic_curve_t curve_p256;
|
||||||
|
|
||||||
|
static void bt_rand(void *buf, size_t len)
|
||||||
|
{
|
||||||
|
if (!len) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Reset the buf value to the fixed value.
|
||||||
|
memset(buf, 0x55, len);
|
||||||
|
|
||||||
|
for (int i = 0; i < (int)(len / sizeof(uint32_t)); i++) {
|
||||||
|
uint32_t rand = esp_random();
|
||||||
|
memcpy(buf + i*sizeof(uint32_t), &rand, sizeof(uint32_t));
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("ble_smp_public_key_check", "[ble_smp]")
|
||||||
|
{
|
||||||
|
/* We wait init finish 200ms here */
|
||||||
|
vTaskDelay(200 / portTICK_PERIOD_MS);
|
||||||
|
Point public_key;
|
||||||
|
DWORD private_key[KEY_LENGTH_DWORDS_P256] = {[0 ... (KEY_LENGTH_DWORDS_P256 - 1)] = 0x12345678};
|
||||||
|
p_256_init_curve(KEY_LENGTH_DWORDS_P256);
|
||||||
|
ECC_PointMult_Bin_NAF(&public_key, &(curve_p256.G), private_key, KEY_LENGTH_DWORDS_P256);
|
||||||
|
/* Check Is the public key generated by the system on the given elliptic curve */
|
||||||
|
TEST_ASSERT(ECC_CheckPointIsInElliCur_P256(&public_key));
|
||||||
|
/* We simulate the attacker and set the y coordinate of the public key to 0. */
|
||||||
|
for (int i = 0; i < KEY_LENGTH_DWORDS_P256; i++) {
|
||||||
|
public_key.y[i] = 0x0;
|
||||||
|
}
|
||||||
|
/* At this point the public key should not be on the given elliptic curve. */
|
||||||
|
TEST_ASSERT(!ECC_CheckPointIsInElliCur_P256(&public_key));
|
||||||
|
/* Test whether the G point on the protocol is on a given elliptic curve */
|
||||||
|
TEST_ASSERT(ECC_CheckPointIsInElliCur_P256(&(curve_p256.G)));
|
||||||
|
/* test 100 times when the private key is generated by the random number. */
|
||||||
|
for (int j = 0; j < 100; j++) {
|
||||||
|
bt_rand(private_key, sizeof(DWORD)*KEY_LENGTH_DWORDS_P256);
|
||||||
|
ECC_PointMult_Bin_NAF(&public_key, &(curve_p256.G), private_key, KEY_LENGTH_DWORDS_P256);
|
||||||
|
/* Check Is the public key generated by the system on the given elliptic curve */
|
||||||
|
TEST_ASSERT(ECC_CheckPointIsInElliCur_P256(&public_key));
|
||||||
|
}
|
||||||
|
}
|
3
tools/unit-test-app/configs/bt
Normal file
3
tools/unit-test-app/configs/bt
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
TEST_COMPONENTS=bt
|
||||||
|
CONFIG_BT_ENABLED=y
|
||||||
|
CONFIG_UNITY_FREERTOS_STACK_SIZE=12288
|
@ -1 +1 @@
|
|||||||
EXCLUDE_COMPONENTS=libsodium
|
EXCLUDE_COMPONENTS=libsodium bt
|
||||||
|
@ -1,2 +1,3 @@
|
|||||||
TEST_COMPONENTS=libsodium
|
TEST_COMPONENTS=libsodium
|
||||||
|
EXCLUDE_COMPONENTS=bt
|
||||||
CONFIG_UNITY_FREERTOS_STACK_SIZE=12288
|
CONFIG_UNITY_FREERTOS_STACK_SIZE=12288
|
||||||
|
@ -1,2 +1,2 @@
|
|||||||
EXCLUDE_COMPONENTS=libsodium
|
EXCLUDE_COMPONENTS=libsodium bt
|
||||||
CONFIG_SPIRAM_SUPPORT=y
|
CONFIG_SPIRAM_SUPPORT=y
|
||||||
|
@ -1,2 +1,3 @@
|
|||||||
|
EXCLUDE_COMPONENTS=bt
|
||||||
CONFIG_OPTIMIZATION_LEVEL_RELEASE=y
|
CONFIG_OPTIMIZATION_LEVEL_RELEASE=y
|
||||||
CONFIG_OPTIMIZATION_ASSERTIONS_SILENT=y
|
CONFIG_OPTIMIZATION_ASSERTIONS_SILENT=y
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
EXCLUDE_COMPONENTS=libsodium
|
EXCLUDE_COMPONENTS=libsodium bt
|
||||||
CONFIG_MEMMAP_SMP=n
|
CONFIG_MEMMAP_SMP=n
|
||||||
CONFIG_FREERTOS_UNICORE=y
|
CONFIG_FREERTOS_UNICORE=y
|
||||||
|
Loading…
Reference in New Issue
Block a user