• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <gmock/gmock.h>
19 #include <gtest/gtest.h>
20 #include <stdarg.h>
21 
22 #include <string>
23 
24 #include "bt_trace.h"
25 #include "hci/include/packet_fragmenter.h"
26 #include "internal_include/stack_config.h"
27 #include "stack/btm/btm_int_types.h"
28 #include "stack/include/acl_api.h"
29 #include "stack/include/bt_octets.h"
30 #include "stack/include/smp_api.h"
31 #include "stack/smp/p_256_ecc_pp.h"
32 #include "stack/smp/smp_int.h"
33 #include "test/mock/mock_stack_acl.h"
34 #include "types/hci_role.h"
35 #include "types/raw_address.h"
36 
37 tBTM_CB btm_cb;
38 std::map<std::string, int> mock_function_count_map;
39 
40 const std::string kSmpOptions("mock smp options");
41 const std::string kBroadcastAudioConfigOptions(
42     "mock broadcast audio config options");
get_trace_config_enabled(void)43 bool get_trace_config_enabled(void) { return false; }
get_pts_avrcp_test(void)44 bool get_pts_avrcp_test(void) { return false; }
get_pts_secure_only_mode(void)45 bool get_pts_secure_only_mode(void) { return false; }
get_pts_conn_updates_disabled(void)46 bool get_pts_conn_updates_disabled(void) { return false; }
get_pts_crosskey_sdp_disable(void)47 bool get_pts_crosskey_sdp_disable(void) { return false; }
get_pts_smp_options(void)48 const std::string* get_pts_smp_options(void) { return &kSmpOptions; }
get_pts_smp_failure_case(void)49 int get_pts_smp_failure_case(void) { return 123; }
get_pts_force_eatt_for_notifications(void)50 bool get_pts_force_eatt_for_notifications(void) { return false; }
get_pts_connect_eatt_unconditionally(void)51 bool get_pts_connect_eatt_unconditionally(void) { return false; }
get_pts_connect_eatt_before_encryption(void)52 bool get_pts_connect_eatt_before_encryption(void) { return false; }
get_pts_unencrypt_broadcast(void)53 bool get_pts_unencrypt_broadcast(void) { return false; }
get_pts_eatt_peripheral_collision_support(void)54 bool get_pts_eatt_peripheral_collision_support(void) { return false; }
get_pts_use_eatt_for_all_services(void)55 bool get_pts_use_eatt_for_all_services(void) { return false; }
get_pts_force_le_audio_multiple_contexts_metadata(void)56 bool get_pts_force_le_audio_multiple_contexts_metadata(void) { return false; }
get_pts_l2cap_ecoc_upper_tester(void)57 bool get_pts_l2cap_ecoc_upper_tester(void) { return false; }
get_pts_l2cap_ecoc_min_key_size(void)58 int get_pts_l2cap_ecoc_min_key_size(void) { return -1; }
get_pts_l2cap_ecoc_initial_chan_cnt(void)59 int get_pts_l2cap_ecoc_initial_chan_cnt(void) { return -1; }
get_pts_l2cap_ecoc_connect_remaining(void)60 bool get_pts_l2cap_ecoc_connect_remaining(void) { return false; }
get_pts_l2cap_ecoc_send_num_of_sdu(void)61 int get_pts_l2cap_ecoc_send_num_of_sdu(void) { return -1; }
get_pts_l2cap_ecoc_reconfigure(void)62 bool get_pts_l2cap_ecoc_reconfigure(void) { return false; }
get_pts_broadcast_audio_config_options(void)63 const std::string* get_pts_broadcast_audio_config_options(void) {
64   return &kBroadcastAudioConfigOptions;
65 }
get_pts_le_audio_disable_ases_before_stopping(void)66 bool get_pts_le_audio_disable_ases_before_stopping(void) { return false; }
get_all(void)67 config_t* get_all(void) { return nullptr; }
packet_fragmenter_get_interface()68 const packet_fragmenter_t* packet_fragmenter_get_interface() { return nullptr; }
69 
70 stack_config_t mock_stack_config{
71     .get_trace_config_enabled = get_trace_config_enabled,
72     .get_pts_avrcp_test = get_pts_avrcp_test,
73     .get_pts_secure_only_mode = get_pts_secure_only_mode,
74     .get_pts_conn_updates_disabled = get_pts_conn_updates_disabled,
75     .get_pts_crosskey_sdp_disable = get_pts_crosskey_sdp_disable,
76     .get_pts_smp_options = get_pts_smp_options,
77     .get_pts_smp_failure_case = get_pts_smp_failure_case,
78     .get_pts_force_eatt_for_notifications =
79         get_pts_force_eatt_for_notifications,
80     .get_pts_connect_eatt_unconditionally =
81         get_pts_connect_eatt_unconditionally,
82     .get_pts_connect_eatt_before_encryption =
83         get_pts_connect_eatt_before_encryption,
84     .get_pts_unencrypt_broadcast = get_pts_unencrypt_broadcast,
85     .get_pts_eatt_peripheral_collision_support =
86         get_pts_eatt_peripheral_collision_support,
87     .get_pts_use_eatt_for_all_services = get_pts_use_eatt_for_all_services,
88     .get_pts_l2cap_ecoc_upper_tester = get_pts_l2cap_ecoc_upper_tester,
89     .get_pts_force_le_audio_multiple_contexts_metadata =
90         get_pts_force_le_audio_multiple_contexts_metadata,
91     .get_pts_l2cap_ecoc_min_key_size = get_pts_l2cap_ecoc_min_key_size,
92     .get_pts_l2cap_ecoc_initial_chan_cnt = get_pts_l2cap_ecoc_initial_chan_cnt,
93     .get_pts_l2cap_ecoc_connect_remaining =
94         get_pts_l2cap_ecoc_connect_remaining,
95     .get_pts_l2cap_ecoc_send_num_of_sdu = get_pts_l2cap_ecoc_send_num_of_sdu,
96     .get_pts_l2cap_ecoc_reconfigure = get_pts_l2cap_ecoc_reconfigure,
97     .get_pts_broadcast_audio_config_options =
98         get_pts_broadcast_audio_config_options,
99     .get_pts_le_audio_disable_ases_before_stopping =
100         get_pts_le_audio_disable_ases_before_stopping,
101     .get_all = get_all,
102 };
stack_config_get_interface(void)103 const stack_config_t* stack_config_get_interface(void) {
104   return &mock_stack_config;
105 }
106 
107 /*
108  * This test verifies various key distribution methods in SMP works using the
109  * following parameter set:
110  *
111  * When testing target as Central (Initiator is local, Responder is remote)
112  *
113  * Initiator's Pairing Request: 0x070710000001(01)
114  * Responder's Pairing Response: 0x050008000003(02)
115  * Initiator's Bluetooth Address: 0xA1A2A3A4A5A6
116  * Initiator's Bluetooth Address Type: 0x01
117  * Responder's Bluetooth Address: 0xB1B2B3B4B5B6
118  * Responder's Bluetooth Address Type: 0x00
119  * Initiator's Random Number: 0x5783D52156AD6F0E6388274EC6702EE0
120  * TK Encryption Key: 0x0
121  *
122  * Correct values:
123  *
124  * p1: 0x05000800000302070710000001010001
125  * p1 XOR r: 0x5283dd2156ae6d096498274ec7712ee1
126  * p1 prime: 0x02c7aa2a9857ac866ff91232df0e3c95
127  * p2: 0x00000000a1a2a3a4a5a6b1b2b3b4b5b6
128  * MConfirm (c1): 0x1e1e3fef878988ead2a74dc5bef13b86
129  *
130  * NOTE: All these values are presented in mathematical reasonable canonical
131  * form that has MSB on the left and LSB on the right. In Bluetooth packets,
132  * they are mostly reversed to be Little Endian which have LSB on the left and
133  * MSB on the right.
134  */
135 
136 // Require bte_logmsg.cc to run, here is just to fake it as we don't care about
137 // trace in unit test
LogMsg(uint32_t trace_set_mask,const char * fmt_str,...)138 void LogMsg(uint32_t trace_set_mask, const char* fmt_str, ...) {
139   va_list args;
140   va_start(args, fmt_str);
141   vprintf(fmt_str, args);
142   va_end(args);
143 }
144 
145 extern Octet16 smp_gen_p1_4_confirm(tSMP_CB* p_cb,
146                                     tBLE_ADDR_TYPE remote_bd_addr_type);
147 
148 extern Octet16 smp_gen_p2_4_confirm(tSMP_CB* p_cb,
149                                     const RawAddress& remote_bda);
150 
151 extern tSMP_STATUS smp_calculate_comfirm(tSMP_CB* p_cb, const Octet16& rand,
152                                          Octet16* output);
153 
154 namespace testing {
155 
dump_uint128(const Octet16 & a,char * buffer)156 void dump_uint128(const Octet16& a, char* buffer) {
157   for (unsigned int i = 0; i < OCTET16_LEN; ++i) {
158     snprintf(buffer, 3, "%02x", a[i]);
159     buffer += 2;
160   }
161   *buffer = '\0';
162 }
163 
dump_uint128_reverse(const Octet16 & a,char * buffer)164 void dump_uint128_reverse(const Octet16& a, char* buffer) {
165   for (int i = (int)(OCTET16_LEN - 1); i >= 0; --i) {
166     snprintf(buffer, 3, "%02x", a[i]);
167     buffer += 2;
168   }
169   *buffer = '\0';
170 }
171 
print_uint128(const Octet16 & a)172 void print_uint128(const Octet16& a) {
173   for (unsigned int i = 0; i < OCTET16_LEN; ++i) {
174     printf("%02x", a[i]);
175   }
176   printf("\n");
177 }
178 
parse_uint128(const char * input)179 Octet16 parse_uint128(const char* input) {
180   Octet16 output{0};
181   for (unsigned int count = 0; count < OCTET16_LEN; count++) {
182     sscanf(input, "%2hhx", &output[count]);
183     input += 2;
184   }
185   return output;
186 }
187 
188 class SmpCalculateConfirmTest : public Test {
189  protected:
190   tSMP_CB p_cb_;
191   // Set random to 0x5783D52156AD6F0E6388274EC6702EE0
192   Octet16 rand_{0x57, 0x83, 0xD5, 0x21, 0x56, 0xAD, 0x6F, 0x0E,
193                 0x63, 0x88, 0x27, 0x4E, 0xC6, 0x70, 0x2E, 0xE0};
194 
SetUp()195   void SetUp() override {
196     p_cb_.tk = {0};
197     // Set pairing request packet to 0x070710000001(01)
198     p_cb_.local_io_capability = 0x01;
199     p_cb_.loc_oob_flag = 0x00;
200     p_cb_.loc_auth_req = 0x00;
201     p_cb_.loc_enc_size = 0x10;
202     p_cb_.local_i_key = 0x07;
203     p_cb_.local_r_key = 0x07;
204     // Set pairing response packet to 0x050008000003(02)
205     p_cb_.peer_io_caps = 0x03;
206     p_cb_.peer_oob_flag = 0x00;
207     p_cb_.peer_auth_req = 0x00;
208     p_cb_.peer_enc_size = 0x08;
209     p_cb_.peer_i_key = 0x00;
210     p_cb_.peer_r_key = 0x05;
211     // Set role to central
212     p_cb_.role = HCI_ROLE_CENTRAL;
213     std::reverse(rand_.begin(), rand_.end());
214   }
TearDown()215   void TearDown() override {}
216 
217  public:
218 };
219 
220 // Test smp_gen_p2_4_confirm function implementation
TEST_F(SmpCalculateConfirmTest,test_smp_gen_p2_4_confirm_as_central)221 TEST_F(SmpCalculateConfirmTest, test_smp_gen_p2_4_confirm_as_central) {
222   // Set local_bda to 0xA1A2A3A4A5A6
223   test::mock::stack_acl::BTM_ReadConnectionAddr.body =
224       [](const RawAddress& remote_bda, RawAddress& local_conn_addr,
225          tBLE_ADDR_TYPE* p_addr_type) {
226         local_conn_addr = RawAddress({0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6});
227         *p_addr_type = BLE_ADDR_RANDOM;
228       };
229 
230   // Set remote bda to 0xB1B2B3B4B5B6
231   test::mock::stack_acl::BTM_ReadRemoteConnectionAddr.body =
232       [](const RawAddress& pseudo_addr, RawAddress& conn_addr,
233          tBLE_ADDR_TYPE* p_addr_type) {
234         conn_addr = RawAddress({0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6});
235         *p_addr_type = BLE_ADDR_PUBLIC;
236         return true;
237       };
238 
239   RawAddress remote_bda;
240   tBLE_ADDR_TYPE remote_bd_addr_type = BLE_ADDR_PUBLIC;
241   BTM_ReadRemoteConnectionAddr(p_cb_.pairing_bda, remote_bda,
242                                &remote_bd_addr_type);
243   BTM_ReadConnectionAddr(p_cb_.pairing_bda, p_cb_.local_bda, &p_cb_.addr_type);
244   Octet16 p2 = smp_gen_p2_4_confirm(&p_cb_, remote_bda);
245   // Correct p2 is 0x00000000a1a2a3a4a5a6b1b2b3b4b5b6
246   const char expected_p2_str[] = "00000000a1a2a3a4a5a6b1b2b3b4b5b6";
247   char p2_str[2 * OCTET16_LEN + 1];
248   dump_uint128_reverse(p2, p2_str);
249   ASSERT_THAT(p2_str, StrEq(expected_p2_str));
250 
251   test::mock::stack_acl::BTM_ReadConnectionAddr = {};
252   test::mock::stack_acl::BTM_ReadRemoteConnectionAddr = {};
253 }
254 
255 // Test smp_gen_p1_4_confirm and aes_128 function implementation
TEST_F(SmpCalculateConfirmTest,test_aes_128_as_central)256 TEST_F(SmpCalculateConfirmTest, test_aes_128_as_central) {
257   // Set local_bda to 0xA1A2A3A4A5A6
258   test::mock::stack_acl::BTM_ReadConnectionAddr.body =
259       [](const RawAddress& remote_bda, RawAddress& local_conn_addr,
260          tBLE_ADDR_TYPE* p_addr_type) {
261         local_conn_addr = RawAddress({0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6});
262         *p_addr_type = BLE_ADDR_RANDOM;
263       };
264 
265   // Set remote bda to 0xB1B2B3B4B5B6
266   test::mock::stack_acl::BTM_ReadRemoteConnectionAddr.body =
267       [](const RawAddress& pseudo_addr, RawAddress& conn_addr,
268          tBLE_ADDR_TYPE* p_addr_type) {
269         conn_addr = RawAddress({0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6});
270         *p_addr_type = BLE_ADDR_PUBLIC;
271         return true;
272       };
273 
274   RawAddress remote_bda;
275   tBLE_ADDR_TYPE remote_bd_addr_type = BLE_ADDR_PUBLIC;
276   BTM_ReadRemoteConnectionAddr(p_cb_.pairing_bda, remote_bda,
277                                &remote_bd_addr_type);
278   BTM_ReadConnectionAddr(p_cb_.pairing_bda, p_cb_.local_bda, &p_cb_.addr_type);
279   Octet16 p1 = smp_gen_p1_4_confirm(&p_cb_, remote_bd_addr_type);
280   // Correct p1 is 0x05000800000302070710000001010001
281   const char expected_p1_str[] = "05000800000302070710000001010001";
282   char p1_str[2 * OCTET16_LEN + 1];
283   dump_uint128_reverse(p1, p1_str);
284   ASSERT_THAT(p1_str, StrEq(expected_p1_str));
285   smp_xor_128(&p1, rand_);
286   // Correct p1 xor r is 0x5283dd2156ae6d096498274ec7712ee1
287   const char expected_p1_xor_r_str[] = "5283dd2156ae6d096498274ec7712ee1";
288   char p1_xor_r_str[2 * OCTET16_LEN + 1];
289   dump_uint128_reverse(p1, p1_xor_r_str);
290   ASSERT_THAT(p1_xor_r_str, StrEq(expected_p1_xor_r_str));
291   Octet16 output = crypto_toolbox::aes_128(p_cb_.tk, p1.data(), OCTET16_LEN);
292   const char expected_p1_prime_str[] = "02c7aa2a9857ac866ff91232df0e3c95";
293   char p1_prime_str[2 * OCTET16_LEN + 1];
294   dump_uint128_reverse(output, p1_prime_str);
295   ASSERT_THAT(p1_prime_str, StrEq(expected_p1_prime_str));
296 
297   test::mock::stack_acl::BTM_ReadConnectionAddr = {};
298   test::mock::stack_acl::BTM_ReadRemoteConnectionAddr = {};
299 }
300 
301 // Test smp_calculate_comfirm function implementation
TEST_F(SmpCalculateConfirmTest,test_smp_calculate_comfirm_as_central)302 TEST_F(SmpCalculateConfirmTest, test_smp_calculate_comfirm_as_central) {
303   // Set local_bda to 0xA1A2A3A4A5A6
304   test::mock::stack_acl::BTM_ReadConnectionAddr.body =
305       [](const RawAddress& remote_bda, RawAddress& local_conn_addr,
306          tBLE_ADDR_TYPE* p_addr_type) {
307         local_conn_addr = RawAddress({0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6});
308         *p_addr_type = BLE_ADDR_RANDOM;
309       };
310 
311   // Set remote bda to 0xB1B2B3B4B5B6
312   test::mock::stack_acl::BTM_ReadRemoteConnectionAddr.body =
313       [](const RawAddress& pseudo_addr, RawAddress& conn_addr,
314          tBLE_ADDR_TYPE* p_addr_type) {
315         conn_addr = RawAddress({0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6});
316         *p_addr_type = BLE_ADDR_PUBLIC;
317         return true;
318       };
319 
320   Octet16 output;
321   tSMP_STATUS status = smp_calculate_comfirm(&p_cb_, rand_, &output);
322   EXPECT_EQ(status, SMP_SUCCESS);
323   // Correct MConfirm is 0x1e1e3fef878988ead2a74dc5bef13b86
324   const char expected_confirm_str[] = "1e1e3fef878988ead2a74dc5bef13b86";
325   char confirm_str[2 * OCTET16_LEN + 1];
326   dump_uint128_reverse(output, confirm_str);
327   ASSERT_THAT(confirm_str, StrEq(expected_confirm_str));
328 
329   test::mock::stack_acl::BTM_ReadConnectionAddr = {};
330   test::mock::stack_acl::BTM_ReadRemoteConnectionAddr = {};
331 }
332 
333 // Test ECC point validation
TEST(SmpEccValidationTest,test_valid_points)334 TEST(SmpEccValidationTest, test_valid_points) {
335   Point p;
336 
337   // Test data from Bluetooth Core Specification
338   // Version 5.0 | Vol 2, Part G | 7.1.2
339 
340   // Sample 1
341   p.x[7] = 0x20b003d2;
342   p.x[6] = 0xf297be2c;
343   p.x[5] = 0x5e2c83a7;
344   p.x[4] = 0xe9f9a5b9;
345   p.x[3] = 0xeff49111;
346   p.x[2] = 0xacf4fddb;
347   p.x[1] = 0xcc030148;
348   p.x[0] = 0x0e359de6;
349 
350   p.y[7] = 0xdc809c49;
351   p.y[6] = 0x652aeb6d;
352   p.y[5] = 0x63329abf;
353   p.y[4] = 0x5a52155c;
354   p.y[3] = 0x766345c2;
355   p.y[2] = 0x8fed3024;
356   p.y[1] = 0x741c8ed0;
357   p.y[0] = 0x1589d28b;
358 
359   EXPECT_TRUE(ECC_ValidatePoint(p));
360 
361   // Sample 2
362   p.x[7] = 0x2c31a47b;
363   p.x[6] = 0x5779809e;
364   p.x[5] = 0xf44cb5ea;
365   p.x[4] = 0xaf5c3e43;
366   p.x[3] = 0xd5f8faad;
367   p.x[2] = 0x4a8794cb;
368   p.x[1] = 0x987e9b03;
369   p.x[0] = 0x745c78dd;
370 
371   p.y[7] = 0x91951218;
372   p.y[6] = 0x3898dfbe;
373   p.y[5] = 0xcd52e240;
374   p.y[4] = 0x8e43871f;
375   p.y[3] = 0xd0211091;
376   p.y[2] = 0x17bd3ed4;
377   p.y[1] = 0xeaf84377;
378   p.y[0] = 0x43715d4f;
379 
380   EXPECT_TRUE(ECC_ValidatePoint(p));
381 }
382 
TEST(SmpEccValidationTest,test_invalid_points)383 TEST(SmpEccValidationTest, test_invalid_points) {
384   Point p;
385   multiprecision_init(p.x);
386   multiprecision_init(p.y);
387 
388   EXPECT_FALSE(ECC_ValidatePoint(p));
389 
390   // Sample 1
391   p.x[7] = 0x20b003d2;
392   p.x[6] = 0xf297be2c;
393   p.x[5] = 0x5e2c83a7;
394   p.x[4] = 0xe9f9a5b9;
395   p.x[3] = 0xeff49111;
396   p.x[2] = 0xacf4fddb;
397   p.x[1] = 0xcc030148;
398   p.x[0] = 0x0e359de6;
399 
400   EXPECT_FALSE(ECC_ValidatePoint(p));
401 
402   p.y[7] = 0xdc809c49;
403   p.y[6] = 0x652aeb6d;
404   p.y[5] = 0x63329abf;
405   p.y[4] = 0x5a52155c;
406   p.y[3] = 0x766345c2;
407   p.y[2] = 0x8fed3024;
408   p.y[1] = 0x741c8ed0;
409   p.y[0] = 0x1589d28b;
410 
411   p.y[0]--;
412 
413   EXPECT_FALSE(ECC_ValidatePoint(p));
414 }
415 }  // namespace testing
416