1 /******************************************************************************
2 *
3 * Copyright 2016 The Android Open Source Project
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at:
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 ******************************************************************************/
18 #include <stdarg.h>
19
20 #include <gmock/gmock.h>
21 #include <gtest/gtest.h>
22
23 #include "bt_trace.h"
24 #include "hcidefs.h"
25 #include "stack/include/smp_api.h"
26 #include "stack/smp/p_256_ecc_pp.h"
27 #include "stack/smp/smp_int.h"
28
29 /*
30 * This test verifies various key distribution methods in SMP works using the
31 * following parameter set:
32 *
33 * When testing target as Master (Initiator is local, Responder is remote)
34 *
35 * Initiator's Pairing Request: 0x070710000001(01)
36 * Responder's Pairing Response: 0x050008000003(02)
37 * Initiator's Bluetooth Address: 0xA1A2A3A4A5A6
38 * Initiator's Bluetooth Address Type: 0x01
39 * Responder's Bluetooth Address: 0xB1B2B3B4B5B6
40 * Responder's Bluetooth Address Type: 0x00
41 * Initiator's Random Number: 0x5783D52156AD6F0E6388274EC6702EE0
42 * TK Encryption Key: 0x0
43 *
44 * Correct values:
45 *
46 * p1: 0x05000800000302070710000001010001
47 * p1 XOR r: 0x5283dd2156ae6d096498274ec7712ee1
48 * p1 prime: 0x02c7aa2a9857ac866ff91232df0e3c95
49 * p2: 0x00000000a1a2a3a4a5a6b1b2b3b4b5b6
50 * MConfirm (c1): 0x1e1e3fef878988ead2a74dc5bef13b86
51 *
52 * NOTE: All these values are presented in mathematical reasonable canonical
53 * form that has MSB on the left and LSB on the right. In Bluetooth packets,
54 * they are mostly reversed to be Little Endian which have LSB on the left and
55 * MSB on the right.
56 */
57
58 // Set remote bda to 0xB1B2B3B4B5B6
BTM_ReadRemoteConnectionAddr(const RawAddress & pseudo_addr,RawAddress & conn_addr,tBLE_ADDR_TYPE * p_addr_type)59 bool BTM_ReadRemoteConnectionAddr(const RawAddress& pseudo_addr,
60 RawAddress& conn_addr,
61 tBLE_ADDR_TYPE* p_addr_type) {
62 conn_addr = RawAddress({0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6});
63 *p_addr_type = 0x00;
64 return true;
65 }
66
67 // Set local_bda to 0xA1A2A3A4A5A6
BTM_ReadConnectionAddr(const RawAddress & remote_bda,RawAddress & local_conn_addr,tBLE_ADDR_TYPE * p_addr_type)68 void BTM_ReadConnectionAddr(const RawAddress& remote_bda,
69 RawAddress& local_conn_addr,
70 tBLE_ADDR_TYPE* p_addr_type) {
71 local_conn_addr = RawAddress({0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6});
72 *p_addr_type = 0x01;
73 }
74
75 // Require bte_logmsg.cc to run, here is just to fake it as we don't care about
76 // trace in unit test
LogMsg(uint32_t trace_set_mask,const char * fmt_str,...)77 void LogMsg(uint32_t trace_set_mask, const char* fmt_str, ...) {
78 va_list args;
79 va_start(args, fmt_str);
80 vprintf(fmt_str, args);
81 va_end(args);
82 }
83
84 extern Octet16 smp_gen_p1_4_confirm(tSMP_CB* p_cb,
85 tBLE_ADDR_TYPE remote_bd_addr_type);
86
87 extern Octet16 smp_gen_p2_4_confirm(tSMP_CB* p_cb,
88 const RawAddress& remote_bda);
89
90 extern tSMP_STATUS smp_calculate_comfirm(tSMP_CB* p_cb, const Octet16& rand,
91 Octet16* output);
92
93 namespace testing {
94
dump_uint128(const Octet16 & a,char * buffer)95 void dump_uint128(const Octet16& a, char* buffer) {
96 for (unsigned int i = 0; i < OCTET16_LEN; ++i) {
97 snprintf(buffer, 3, "%02x", a[i]);
98 buffer += 2;
99 }
100 *buffer = '\0';
101 }
102
dump_uint128_reverse(const Octet16 & a,char * buffer)103 void dump_uint128_reverse(const Octet16& a, char* buffer) {
104 for (int i = (int)(OCTET16_LEN - 1); i >= 0; --i) {
105 snprintf(buffer, 3, "%02x", a[i]);
106 buffer += 2;
107 }
108 *buffer = '\0';
109 }
110
print_uint128(const Octet16 & a)111 void print_uint128(const Octet16& a) {
112 for (unsigned int i = 0; i < OCTET16_LEN; ++i) {
113 printf("%02x", a[i]);
114 }
115 printf("\n");
116 }
117
parse_uint128(const char * input)118 Octet16 parse_uint128(const char* input) {
119 Octet16 output{0};
120 for (unsigned int count = 0; count < OCTET16_LEN; count++) {
121 sscanf(input, "%2hhx", &output[count]);
122 input += 2;
123 }
124 return output;
125 }
126
127 class SmpCalculateConfirmTest : public Test {
128 protected:
129 tSMP_CB p_cb_;
130 // Set random to 0x5783D52156AD6F0E6388274EC6702EE0
131 Octet16 rand_{0x57, 0x83, 0xD5, 0x21, 0x56, 0xAD, 0x6F, 0x0E,
132 0x63, 0x88, 0x27, 0x4E, 0xC6, 0x70, 0x2E, 0xE0};
133
SetUp()134 void SetUp() {
135 p_cb_.tk = {0};
136 // Set pairing request packet to 0x070710000001(01)
137 p_cb_.local_io_capability = 0x01;
138 p_cb_.loc_oob_flag = 0x00;
139 p_cb_.loc_auth_req = 0x00;
140 p_cb_.loc_enc_size = 0x10;
141 p_cb_.local_i_key = 0x07;
142 p_cb_.local_r_key = 0x07;
143 // Set pairing response packet to 0x050008000003(02)
144 p_cb_.peer_io_caps = 0x03;
145 p_cb_.peer_oob_flag = 0x00;
146 p_cb_.peer_auth_req = 0x00;
147 p_cb_.peer_enc_size = 0x08;
148 p_cb_.peer_i_key = 0x00;
149 p_cb_.peer_r_key = 0x05;
150 // Set role to master
151 p_cb_.role = HCI_ROLE_MASTER;
152 std::reverse(rand_.begin(), rand_.end());
153 }
TearDown()154 void TearDown() {}
155
156 public:
157 };
158
159 // Test smp_gen_p2_4_confirm function implementation
TEST_F(SmpCalculateConfirmTest,test_smp_gen_p2_4_confirm_as_master)160 TEST_F(SmpCalculateConfirmTest, test_smp_gen_p2_4_confirm_as_master) {
161 RawAddress remote_bda;
162 tBLE_ADDR_TYPE remote_bd_addr_type = 0;
163 BTM_ReadRemoteConnectionAddr(p_cb_.pairing_bda, remote_bda,
164 &remote_bd_addr_type);
165 BTM_ReadConnectionAddr(p_cb_.pairing_bda, p_cb_.local_bda, &p_cb_.addr_type);
166 Octet16 p2 = smp_gen_p2_4_confirm(&p_cb_, remote_bda);
167 // Correct p2 is 0x00000000a1a2a3a4a5a6b1b2b3b4b5b6
168 const char expected_p2_str[] = "00000000a1a2a3a4a5a6b1b2b3b4b5b6";
169 char p2_str[2 * OCTET16_LEN + 1];
170 dump_uint128_reverse(p2, p2_str);
171 ASSERT_THAT(p2_str, StrEq(expected_p2_str));
172 }
173
174 // Test smp_gen_p1_4_confirm and aes_128 function implementation
TEST_F(SmpCalculateConfirmTest,test_aes_128_as_master)175 TEST_F(SmpCalculateConfirmTest, test_aes_128_as_master) {
176 RawAddress remote_bda;
177 tBLE_ADDR_TYPE remote_bd_addr_type = 0;
178 BTM_ReadRemoteConnectionAddr(p_cb_.pairing_bda, remote_bda,
179 &remote_bd_addr_type);
180 BTM_ReadConnectionAddr(p_cb_.pairing_bda, p_cb_.local_bda, &p_cb_.addr_type);
181 Octet16 p1 = smp_gen_p1_4_confirm(&p_cb_, remote_bd_addr_type);
182 // Correct p1 is 0x05000800000302070710000001010001
183 const char expected_p1_str[] = "05000800000302070710000001010001";
184 char p1_str[2 * OCTET16_LEN + 1];
185 dump_uint128_reverse(p1, p1_str);
186 ASSERT_THAT(p1_str, StrEq(expected_p1_str));
187 smp_xor_128(&p1, rand_);
188 // Correct p1 xor r is 0x5283dd2156ae6d096498274ec7712ee1
189 const char expected_p1_xor_r_str[] = "5283dd2156ae6d096498274ec7712ee1";
190 char p1_xor_r_str[2 * OCTET16_LEN + 1];
191 dump_uint128_reverse(p1, p1_xor_r_str);
192 ASSERT_THAT(p1_xor_r_str, StrEq(expected_p1_xor_r_str));
193 Octet16 output = crypto_toolbox::aes_128(p_cb_.tk, p1.data(), OCTET16_LEN);
194 const char expected_p1_prime_str[] = "02c7aa2a9857ac866ff91232df0e3c95";
195 char p1_prime_str[2 * OCTET16_LEN + 1];
196 dump_uint128_reverse(output, p1_prime_str);
197 ASSERT_THAT(p1_prime_str, StrEq(expected_p1_prime_str));
198 }
199
200 // Test smp_calculate_comfirm function implementation
TEST_F(SmpCalculateConfirmTest,test_smp_calculate_comfirm_as_master)201 TEST_F(SmpCalculateConfirmTest, test_smp_calculate_comfirm_as_master) {
202 Octet16 output;
203 tSMP_STATUS status = smp_calculate_comfirm(&p_cb_, rand_, &output);
204 EXPECT_EQ(status, SMP_SUCCESS);
205 // Correct MConfirm is 0x1e1e3fef878988ead2a74dc5bef13b86
206 const char expected_confirm_str[] = "1e1e3fef878988ead2a74dc5bef13b86";
207 char confirm_str[2 * OCTET16_LEN + 1];
208 dump_uint128_reverse(output, confirm_str);
209 ASSERT_THAT(confirm_str, StrEq(expected_confirm_str));
210 }
211
212 // Test ECC point validation
TEST(SmpEccValidationTest,test_valid_points)213 TEST(SmpEccValidationTest, test_valid_points) {
214 Point p;
215
216 // Test data from Bluetooth Core Specification
217 // Version 5.0 | Vol 2, Part G | 7.1.2
218
219 // Sample 1
220 p.x[7] = 0x20b003d2;
221 p.x[6] = 0xf297be2c;
222 p.x[5] = 0x5e2c83a7;
223 p.x[4] = 0xe9f9a5b9;
224 p.x[3] = 0xeff49111;
225 p.x[2] = 0xacf4fddb;
226 p.x[1] = 0xcc030148;
227 p.x[0] = 0x0e359de6;
228
229 p.y[7] = 0xdc809c49;
230 p.y[6] = 0x652aeb6d;
231 p.y[5] = 0x63329abf;
232 p.y[4] = 0x5a52155c;
233 p.y[3] = 0x766345c2;
234 p.y[2] = 0x8fed3024;
235 p.y[1] = 0x741c8ed0;
236 p.y[0] = 0x1589d28b;
237
238 EXPECT_TRUE(ECC_ValidatePoint(p));
239
240 // Sample 2
241 p.x[7] = 0x2c31a47b;
242 p.x[6] = 0x5779809e;
243 p.x[5] = 0xf44cb5ea;
244 p.x[4] = 0xaf5c3e43;
245 p.x[3] = 0xd5f8faad;
246 p.x[2] = 0x4a8794cb;
247 p.x[1] = 0x987e9b03;
248 p.x[0] = 0x745c78dd;
249
250 p.y[7] = 0x91951218;
251 p.y[6] = 0x3898dfbe;
252 p.y[5] = 0xcd52e240;
253 p.y[4] = 0x8e43871f;
254 p.y[3] = 0xd0211091;
255 p.y[2] = 0x17bd3ed4;
256 p.y[1] = 0xeaf84377;
257 p.y[0] = 0x43715d4f;
258
259 EXPECT_TRUE(ECC_ValidatePoint(p));
260 }
261
TEST(SmpEccValidationTest,test_invalid_points)262 TEST(SmpEccValidationTest, test_invalid_points) {
263 Point p;
264 multiprecision_init(p.x, 8);
265 multiprecision_init(p.y, 8);
266
267 EXPECT_FALSE(ECC_ValidatePoint(p));
268
269 // Sample 1
270 p.x[7] = 0x20b003d2;
271 p.x[6] = 0xf297be2c;
272 p.x[5] = 0x5e2c83a7;
273 p.x[4] = 0xe9f9a5b9;
274 p.x[3] = 0xeff49111;
275 p.x[2] = 0xacf4fddb;
276 p.x[1] = 0xcc030148;
277 p.x[0] = 0x0e359de6;
278
279 EXPECT_FALSE(ECC_ValidatePoint(p));
280
281 p.y[7] = 0xdc809c49;
282 p.y[6] = 0x652aeb6d;
283 p.y[5] = 0x63329abf;
284 p.y[4] = 0x5a52155c;
285 p.y[3] = 0x766345c2;
286 p.y[2] = 0x8fed3024;
287 p.y[1] = 0x741c8ed0;
288 p.y[0] = 0x1589d28b;
289
290 p.y[0]--;
291
292 EXPECT_FALSE(ECC_ValidatePoint(p));
293 }
294 } // namespace testing
295