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