1 /*
2  *  Copyright 2020 The Android Open Source Project
3  *
4  *  Licensed under the Apache License, Version 2.0 (the "License");
5  *  you may not use this file except in compliance with the License.
6  *  You may obtain a copy of the License at:
7  *
8  *  http://www.apache.org/licenses/LICENSE-2.0
9  *
10  *  Unless required by applicable law or agreed to in writing, software
11  *  distributed under the License is distributed on an "AS IS" BASIS,
12  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  *  See the License for the specific language governing permissions and
14  *  limitations under the License.
15  *
16  */
17 
18 #include <gmock/gmock.h>
19 #include <gtest/gtest.h>
20 
21 #include <vector>
22 
23 #include "common/init_flags.h"
24 #include "common/strings.h"
25 #include "hci/hci_layer_mock.h"
26 #include "internal_include/bt_target.h"
27 #include "stack/btm/btm_ble_sec.h"
28 #include "stack/btm/btm_dev.h"
29 #include "stack/btm/btm_int_types.h"
30 #include "stack/btm/btm_sec.h"
31 #include "stack/btm/btm_sec_cb.h"
32 #include "stack/btm/security_device_record.h"
33 #include "stack/test/btm/btm_test_fixtures.h"
34 #include "test/mock/mock_main_shim_entry.h"
35 #include "types/raw_address.h"
36 
37 extern tBTM_CB btm_cb;
38 
39 using namespace bluetooth;
40 
41 using testing::Return;
42 using testing::Test;
43 
44 namespace {
45 const RawAddress kRawAddress = RawAddress({0x11, 0x22, 0x33, 0x44, 0x55, 0x66});
46 const uint8_t kBdName[] = "kBdName";
47 constexpr char kTimeFormat[] = "%Y-%m-%d %H:%M:%S";
48 }  // namespace
49 
50 namespace bluetooth {
51 namespace testing {
52 namespace legacy {
53 
54 void wipe_secrets_and_remove(tBTM_SEC_DEV_REC* p_dev_rec);
55 
56 }  // namespace legacy
57 }  // namespace testing
58 }  // namespace bluetooth
59 
60 using bluetooth::testing::legacy::wipe_secrets_and_remove;
61 
62 constexpr size_t kBtmSecMaxDeviceRecords =
63     static_cast<size_t>(BTM_SEC_MAX_DEVICE_RECORDS + 1);
64 
65 class StackBtmSecTest : public BtmWithMocksTest {
66  public:
67  protected:
SetUp()68   void SetUp() override { BtmWithMocksTest::SetUp(); }
TearDown()69   void TearDown() override { BtmWithMocksTest::TearDown(); }
70 };
71 
72 class StackBtmSecWithQueuesTest : public StackBtmSecTest {
73  public:
74  protected:
SetUp()75   void SetUp() override {
76     StackBtmSecTest::SetUp();
77     up_thread_ = new bluetooth::os::Thread(
78         "up_thread", bluetooth::os::Thread::Priority::NORMAL);
79     up_handler_ = new bluetooth::os::Handler(up_thread_);
80     down_thread_ = new bluetooth::os::Thread(
81         "down_thread", bluetooth::os::Thread::Priority::NORMAL);
82     down_handler_ = new bluetooth::os::Handler(down_thread_);
83     bluetooth::hci::testing::mock_hci_layer_ = &mock_hci_;
84     bluetooth::hci::testing::mock_gd_shim_handler_ = up_handler_;
85   }
TearDown()86   void TearDown() override {
87     up_handler_->Clear();
88     delete up_handler_;
89     delete up_thread_;
90     down_handler_->Clear();
91     delete down_handler_;
92     delete down_thread_;
93     StackBtmSecTest::TearDown();
94   }
95   bluetooth::common::BidiQueue<bluetooth::hci::ScoView,
96                                bluetooth::hci::ScoBuilder>
97       sco_queue_{10};
98   bluetooth::hci::testing::MockHciLayer mock_hci_;
99   bluetooth::os::Thread* up_thread_;
100   bluetooth::os::Handler* up_handler_;
101   bluetooth::os::Thread* down_thread_;
102   bluetooth::os::Handler* down_handler_;
103 };
104 
105 class StackBtmSecWithInitFreeTest : public StackBtmSecWithQueuesTest {
106  public:
107  protected:
SetUp()108   void SetUp() override {
109     StackBtmSecWithQueuesTest::SetUp();
110     BTM_Sec_Init();
111   }
TearDown()112   void TearDown() override {
113     BTM_Sec_Free();
114     StackBtmSecWithQueuesTest::TearDown();
115   }
116 };
117 
TEST_F(StackBtmSecWithInitFreeTest,btm_sec_encrypt_change)118 TEST_F(StackBtmSecWithInitFreeTest, btm_sec_encrypt_change) {
119   bluetooth::common::InitFlags::SetAllForTesting();
120 
121   RawAddress bd_addr = RawAddress({0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6});
122   const uint16_t classic_handle = 0x1234;
123   const uint16_t ble_handle = 0x9876;
124 
125   // Check the collision conditionals
126   ::btm_sec_cb.collision_start_time = 0UL;
127   btm_sec_encrypt_change(classic_handle, HCI_ERR_LMP_ERR_TRANS_COLLISION, 0x01);
128   uint64_t collision_start_time = ::btm_sec_cb.collision_start_time;
129   ASSERT_NE(0UL, collision_start_time);
130 
131   ::btm_sec_cb.collision_start_time = 0UL;
132   btm_sec_encrypt_change(classic_handle, HCI_ERR_DIFF_TRANSACTION_COLLISION,
133                          0x01);
134   collision_start_time = ::btm_sec_cb.collision_start_time;
135   ASSERT_NE(0UL, collision_start_time);
136 
137   // No device
138   ::btm_sec_cb.collision_start_time = 0;
139   btm_sec_encrypt_change(classic_handle, HCI_SUCCESS, 0x01);
140   ASSERT_EQ(0UL, ::btm_sec_cb.collision_start_time);
141 
142   // Setup device
143   tBTM_SEC_DEV_REC* device_record = btm_sec_allocate_dev_rec();
144   ASSERT_NE(nullptr, device_record);
145   ASSERT_EQ(BTM_SEC_IN_USE, device_record->sec_rec.sec_flags);
146   device_record->bd_addr = bd_addr;
147   device_record->hci_handle = classic_handle;
148   device_record->ble_hci_handle = ble_handle;
149 
150   // With classic device encryption enable
151   btm_sec_encrypt_change(classic_handle, HCI_SUCCESS, 0x01);
152   ASSERT_EQ(BTM_SEC_IN_USE | BTM_SEC_AUTHENTICATED | BTM_SEC_ENCRYPTED,
153             device_record->sec_rec.sec_flags);
154 
155   // With classic device encryption disable
156   btm_sec_encrypt_change(classic_handle, HCI_SUCCESS, 0x00);
157   ASSERT_EQ(BTM_SEC_IN_USE | BTM_SEC_AUTHENTICATED,
158             device_record->sec_rec.sec_flags);
159   device_record->sec_rec.sec_flags = BTM_SEC_IN_USE;
160 
161   // With le device encryption enable
162   btm_sec_encrypt_change(ble_handle, HCI_SUCCESS, 0x01);
163   ASSERT_EQ(BTM_SEC_IN_USE | BTM_SEC_LE_ENCRYPTED,
164             device_record->sec_rec.sec_flags);
165 
166   // With le device encryption disable
167   btm_sec_encrypt_change(ble_handle, HCI_SUCCESS, 0x00);
168   ASSERT_EQ(BTM_SEC_IN_USE, device_record->sec_rec.sec_flags);
169   device_record->sec_rec.sec_flags = BTM_SEC_IN_USE;
170 
171   wipe_secrets_and_remove(device_record);
172 }
173 
TEST_F(StackBtmSecWithInitFreeTest,BTM_SetEncryption)174 TEST_F(StackBtmSecWithInitFreeTest, BTM_SetEncryption) {
175   const RawAddress bd_addr = RawAddress({0x11, 0x22, 0x33, 0x44, 0x55, 0x66});
176   const tBT_TRANSPORT transport{BT_TRANSPORT_LE};
177   tBTM_SEC_CALLBACK* p_callback{nullptr};
178   tBTM_BLE_SEC_ACT sec_act{BTM_BLE_SEC_ENCRYPT};
179 
180   // No device
181   ASSERT_EQ(BTM_WRONG_MODE, BTM_SetEncryption(bd_addr, transport, p_callback,
182                                               nullptr, sec_act));
183 
184   // With device
185   tBTM_SEC_DEV_REC* device_record = btm_sec_allocate_dev_rec();
186   ASSERT_NE(nullptr, device_record);
187   device_record->bd_addr = bd_addr;
188   device_record->hci_handle = 0x1234;
189 
190   ASSERT_EQ(BTM_WRONG_MODE, BTM_SetEncryption(bd_addr, transport, p_callback,
191                                               nullptr, sec_act));
192 
193   wipe_secrets_and_remove(device_record);
194 }
195 
TEST_F(StackBtmSecTest,btm_ble_sec_req_act_text)196 TEST_F(StackBtmSecTest, btm_ble_sec_req_act_text) {
197   ASSERT_EQ("BTM_BLE_SEC_REQ_ACT_NONE",
198             btm_ble_sec_req_act_text(BTM_BLE_SEC_REQ_ACT_NONE));
199   ASSERT_EQ("BTM_BLE_SEC_REQ_ACT_ENCRYPT",
200             btm_ble_sec_req_act_text(BTM_BLE_SEC_REQ_ACT_ENCRYPT));
201   ASSERT_EQ("BTM_BLE_SEC_REQ_ACT_PAIR",
202             btm_ble_sec_req_act_text(BTM_BLE_SEC_REQ_ACT_PAIR));
203   ASSERT_EQ("BTM_BLE_SEC_REQ_ACT_DISCARD",
204             btm_ble_sec_req_act_text(BTM_BLE_SEC_REQ_ACT_DISCARD));
205 }
206 
TEST_F(StackBtmSecWithInitFreeTest,btm_sec_allocate_dev_rec__all)207 TEST_F(StackBtmSecWithInitFreeTest, btm_sec_allocate_dev_rec__all) {
208   tBTM_SEC_DEV_REC* records[kBtmSecMaxDeviceRecords];
209 
210   // Fill up the records
211   for (size_t i = 0; i < kBtmSecMaxDeviceRecords; i++) {
212     ASSERT_EQ(i, list_length(::btm_sec_cb.sec_dev_rec));
213     records[i] = btm_sec_allocate_dev_rec();
214     ASSERT_NE(nullptr, records[i]);
215   }
216 
217   // Second pass up the records
218   for (size_t i = 0; i < kBtmSecMaxDeviceRecords; i++) {
219     ASSERT_EQ(kBtmSecMaxDeviceRecords, list_length(::btm_sec_cb.sec_dev_rec));
220     records[i] = btm_sec_allocate_dev_rec();
221     ASSERT_NE(nullptr, records[i]);
222   }
223 
224   // NOTE: The memory allocated for each record is automatically
225   // allocated by the btm module and freed when the device record
226   // list is freed.
227   // Further, the memory for each record is reused when necessary.
228 }
229 
TEST_F(StackBtmSecTest,btm_oob_data_text)230 TEST_F(StackBtmSecTest, btm_oob_data_text) {
231   std::vector<std::pair<tBTM_OOB_DATA, std::string>> datas = {
232       std::make_pair(BTM_OOB_NONE, "BTM_OOB_NONE"),
233       std::make_pair(BTM_OOB_PRESENT_192, "BTM_OOB_PRESENT_192"),
234       std::make_pair(BTM_OOB_PRESENT_256, "BTM_OOB_PRESENT_256"),
235       std::make_pair(BTM_OOB_PRESENT_192_AND_256,
236                      "BTM_OOB_PRESENT_192_AND_256"),
237       std::make_pair(BTM_OOB_UNKNOWN, "BTM_OOB_UNKNOWN"),
238   };
239   for (const auto& data : datas) {
240     ASSERT_STREQ(data.second.c_str(), btm_oob_data_text(data.first).c_str());
241   }
242   auto unknown = base::StringPrintf("UNKNOWN[%hhu]",
243                                     std::numeric_limits<std::uint8_t>::max());
244   ASSERT_STREQ(unknown.c_str(),
245                btm_oob_data_text(static_cast<tBTM_OOB_DATA>(
246                                      std::numeric_limits<std::uint8_t>::max()))
247                    .c_str());
248 }
249 
TEST_F(StackBtmSecTest,bond_type_text)250 TEST_F(StackBtmSecTest, bond_type_text) {
251   std::vector<std::pair<tBTM_BOND_TYPE, std::string>> datas = {
252       std::make_pair(BOND_TYPE_UNKNOWN, "BOND_TYPE_UNKNOWN"),
253       std::make_pair(BOND_TYPE_PERSISTENT, "BOND_TYPE_PERSISTENT"),
254       std::make_pair(BOND_TYPE_TEMPORARY, "BOND_TYPE_TEMPORARY"),
255   };
256   for (const auto& data : datas) {
257     ASSERT_STREQ(data.second.c_str(), bond_type_text(data.first).c_str());
258   }
259   auto unknown = base::StringPrintf("UNKNOWN[%hhu]",
260                                     std::numeric_limits<std::uint8_t>::max());
261   ASSERT_STREQ(unknown.c_str(),
262                bond_type_text(static_cast<tBTM_BOND_TYPE>(
263                                   std::numeric_limits<std::uint8_t>::max()))
264                    .c_str());
265 }
266 
TEST_F(StackBtmSecWithInitFreeTest,wipe_secrets_and_remove)267 TEST_F(StackBtmSecWithInitFreeTest, wipe_secrets_and_remove) {
268   bluetooth::common::InitFlags::SetAllForTesting();
269 
270   RawAddress bd_addr = RawAddress({0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6});
271   const uint16_t classic_handle = 0x1234;
272   const uint16_t ble_handle = 0x9876;
273 
274   // Setup device
275   tBTM_SEC_DEV_REC* device_record = btm_sec_allocate_dev_rec();
276   ASSERT_NE(nullptr, device_record);
277   ASSERT_EQ(BTM_SEC_IN_USE, device_record->sec_rec.sec_flags);
278   device_record->bd_addr = bd_addr;
279   device_record->hci_handle = classic_handle;
280   device_record->ble_hci_handle = ble_handle;
281 
282   wipe_secrets_and_remove(device_record);
283 }
284 
TEST_F(StackBtmSecWithInitFreeTest,btm_sec_rmt_name_request_complete)285 TEST_F(StackBtmSecWithInitFreeTest, btm_sec_rmt_name_request_complete) {
286   btm_cb.history_ = std::make_shared<TimestampedStringCircularBuffer>(
287       kBtmLogHistoryBufferSize);
288 
289   btm_sec_rmt_name_request_complete(&kRawAddress, kBdName, HCI_SUCCESS);
290   btm_sec_rmt_name_request_complete(nullptr, nullptr, HCI_SUCCESS);
291   btm_sec_rmt_name_request_complete(nullptr, kBdName, HCI_SUCCESS);
292   btm_sec_rmt_name_request_complete(&kRawAddress, nullptr, HCI_SUCCESS);
293 
294   btm_sec_rmt_name_request_complete(&kRawAddress, kBdName, HCI_ERR_HW_FAILURE);
295   btm_sec_rmt_name_request_complete(nullptr, nullptr, HCI_ERR_HW_FAILURE);
296   btm_sec_rmt_name_request_complete(nullptr, kBdName, HCI_ERR_HW_FAILURE);
297   btm_sec_rmt_name_request_complete(&kRawAddress, nullptr, HCI_ERR_HW_FAILURE);
298 
299   std::vector<common::TimestampedEntry<std::string>> history =
300       btm_cb.history_->Pull();
301   for (auto& record : history) {
302     time_t then = record.timestamp / 1000;
303     struct tm tm;
304     localtime_r(&then, &tm);
305     auto s2 = common::StringFormatTime(kTimeFormat, tm);
306     log::debug("{}.{} {}", s2,
307                static_cast<unsigned int>(record.timestamp % 1000),
308                record.entry);
309   }
310   ASSERT_EQ(8U, history.size());
311 }
312