From 7aa29a0dbbb77b87ff14ffa003f40d7e7e1a0db5 Mon Sep 17 00:00:00 2001 From: yulong Date: Mon, 13 Aug 2018 15:33:42 +0800 Subject: [PATCH] component/bt: Fixed the vulnerability released by Bluetooth org when using public key not check in the process of ECDH encryption. --- .../stack/smp/include/p_256_ecc_pp.h | 2 ++ .../bt/bluedroid/stack/smp/p_256_ecc_pp.c | 35 +++++++++++++++++++ components/bt/bluedroid/stack/smp/smp_act.c | 7 ++++ 3 files changed, 44 insertions(+) diff --git a/components/bt/bluedroid/stack/smp/include/p_256_ecc_pp.h b/components/bt/bluedroid/stack/smp/include/p_256_ecc_pp.h index 029a79ff16..f91d6056b2 100644 --- a/components/bt/bluedroid/stack/smp/include/p_256_ecc_pp.h +++ b/components/bt/bluedroid/stack/smp/include/p_256_ecc_pp.h @@ -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); diff --git a/components/bt/bluedroid/stack/smp/p_256_ecc_pp.c b/components/bt/bluedroid/stack/smp/p_256_ecc_pp.c index 991b6fd757..23296cd6ab 100644 --- a/components/bt/bluedroid/stack/smp/p_256_ecc_pp.c +++ b/components/bt/bluedroid/stack/smp/p_256_ecc_pp.c @@ -240,4 +240,39 @@ 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; + } +} diff --git a/components/bt/bluedroid/stack/smp/smp_act.c b/components/bt/bluedroid/stack/smp/smp_act.c index 99f248accf..d088d36081 100644 --- a/components/bt/bluedroid/stack/smp/smp_act.c +++ b/components/bt/bluedroid/stack/smp/smp_act.c @@ -22,6 +22,7 @@ #include "btm_int.h" #include "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);