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_v3.1' into 'release/v3.1'
Bugfix/btdm ecdh public key not check v3.1 (backport v3.1) See merge request idf/esp-idf!2991
This commit is contained in:
commit
39dd71d958
@ -1009,6 +1009,12 @@ UT_010_04:
|
||||
- UT_T1_RMT
|
||||
- psram
|
||||
|
||||
UT_601_01:
|
||||
<<: *unit_test_template
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- UT_T1_1
|
||||
|
||||
IT_001_01:
|
||||
<<: *test_template
|
||||
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);
|
||||
|
||||
bool ECC_CheckPointIsInElliCur_P256(Point *p);
|
||||
|
||||
#define ECC_PointMult(q, p, n, keyLength) ECC_PointMult_Bin_NAF(q, p, n, 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);
|
||||
}
|
||||
|
||||
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 "stack/l2c_api.h"
|
||||
#include "smp_int.h"
|
||||
#include "p_256_ecc_pp.h"
|
||||
//#include "utils/include/bt_utils.h"
|
||||
|
||||
#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.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;
|
||||
|
||||
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
|
||||
EXCLUDE_COMPONENTS=bt
|
||||
CONFIG_UNITY_FREERTOS_STACK_SIZE=12288
|
||||
|
@ -1,2 +1,2 @@
|
||||
EXCLUDE_COMPONENTS=libsodium
|
||||
EXCLUDE_COMPONENTS=libsodium bt
|
||||
CONFIG_SPIRAM_SUPPORT=y
|
||||
|
@ -1,2 +1,3 @@
|
||||
EXCLUDE_COMPONENTS=bt
|
||||
CONFIG_OPTIMIZATION_LEVEL_RELEASE=y
|
||||
CONFIG_OPTIMIZATION_ASSERTIONS_SILENT=y
|
||||
|
@ -1,3 +1,3 @@
|
||||
EXCLUDE_COMPONENTS=libsodium
|
||||
EXCLUDE_COMPONENTS=libsodium bt
|
||||
CONFIG_MEMMAP_SMP=n
|
||||
CONFIG_FREERTOS_UNICORE=y
|
||||
|
Loading…
Reference in New Issue
Block a user