OSDN Git Service

DO NOT MERGE SMP: Validate remote elliptic curve points
authorAndre Eisenbach <eisenbach@google.com>
Thu, 1 Mar 2018 21:27:01 +0000 (13:27 -0800)
committerandroid-build-team Robot <android-build-team-robot@google.com>
Fri, 25 May 2018 18:41:52 +0000 (18:41 +0000)
Fixes: 72377774
Test: net_test_stack_smp (where applicable)
Change-Id: Iefcf97364493467075fadefd77d12716f71cd4f6
(cherry picked from commit 9181ec28da94705a763edbe60bd2a87e5f882beb)
(cherry picked from commit e11ebfc21963ae905d58c034310efeca0e7cd2ee)

stack/smp/p_256_ecc_pp.cc
stack/smp/p_256_ecc_pp.h
stack/smp/smp_act.cc

index b416e1d..911dc54 100644 (file)
@@ -245,3 +245,25 @@ void ECC_PointMult_Bin_NAF(Point* q, Point* p, uint32_t* n,
   multiprecision_mersenns_mult_mod(q->z, q->z, minus_p.x, keyLength);
   multiprecision_mersenns_mult_mod(q->y, q->y, q->z, keyLength);
 }
   multiprecision_mersenns_mult_mod(q->z, q->z, minus_p.x, keyLength);
   multiprecision_mersenns_mult_mod(q->y, q->y, q->z, keyLength);
 }
+
+bool ECC_ValidatePoint(const Point& pt) {
+  const size_t kl = KEY_LENGTH_DWORDS_P256;
+  p_256_init_curve(kl);
+
+  // Ensure y^2 = x^3 + a*x + b (mod p); a = -3
+
+  // y^2 mod p
+  uint32_t y2_mod[kl] = {0};
+  multiprecision_mersenns_squa_mod(y2_mod, (uint32_t*)pt.y, kl);
+
+  // Right hand side calculation
+  uint32_t rhs[kl] = {0};
+  multiprecision_mersenns_squa_mod(rhs, (uint32_t*)pt.x, kl);
+  uint32_t three[kl] = {0};
+  three[0] = 3;
+  multiprecision_sub_mod(rhs, rhs, three, kl);
+  multiprecision_mersenns_mult_mod(rhs, rhs, (uint32_t*)pt.x, kl);
+  multiprecision_add_mod(rhs, rhs, curve_p256.b, kl);
+
+  return multiprecision_compare(rhs, y2_mod, kl) == 0;
+}
index dcc4211..b7a8e00 100644 (file)
@@ -25,6 +25,7 @@
 
 #pragma once
 
 
 #pragma once
 
+#include <cstdbool>
 #include "p_256_multprecision.h"
 
 typedef struct {
 #include "p_256_multprecision.h"
 
 typedef struct {
@@ -55,6 +56,8 @@ typedef struct {
 extern elliptic_curve_t curve;
 extern elliptic_curve_t curve_p256;
 
 extern elliptic_curve_t curve;
 extern elliptic_curve_t curve_p256;
 
+bool ECC_ValidatePoint(const Point& p);
+
 void ECC_PointMult_Bin_NAF(Point* q, Point* p, uint32_t* n, uint32_t keyLength);
 
 #define ECC_PointMult(q, p, n, keyLength) \
 void ECC_PointMult_Bin_NAF(Point* q, Point* p, uint32_t* n, uint32_t keyLength);
 
 #define ECC_PointMult(q, p, n, keyLength) \
index df9fab9..2103776 100644 (file)
@@ -22,6 +22,7 @@
 #include "include/bt_target.h"
 #include "stack/btm/btm_int.h"
 #include "stack/include/l2c_api.h"
 #include "include/bt_target.h"
 #include "stack/btm/btm_int.h"
 #include "stack/include/l2c_api.h"
+#include "stack/smp/p_256_ecc_pp.h"
 #include "stack/smp/smp_int.h"
 #include "utils/include/bt_utils.h"
 
 #include "stack/smp/smp_int.h"
 #include "utils/include/bt_utils.h"
 
@@ -655,6 +656,17 @@ 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);
 
   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);
+
+  Point pt;
+  memcpy(pt.x, p_cb->peer_publ_key.x, BT_OCTET32_LEN);
+  memcpy(pt.y, p_cb->peer_publ_key.y, BT_OCTET32_LEN);
+
+  if (!ECC_ValidatePoint(pt)) {
+    android_errorWriteLog(0x534e4554, "72377774");
+    smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &reason);
+    return;
+  }
+
   p_cb->flags |= SMP_PAIR_FLAG_HAVE_PEER_PUBL_KEY;
 
   smp_wait_for_both_public_keys(p_cb, NULL);
   p_cb->flags |= SMP_PAIR_FLAG_HAVE_PEER_PUBL_KEY;
 
   smp_wait_for_both_public_keys(p_cb, NULL);