1 /******************************************************************************
2 *
3 * Copyright 2019 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
19 #include "security/pairing_handler_le.h"
20
21 #include "os/rand.h"
22
23 namespace bluetooth {
24 namespace security {
25
GenerateOobData()26 MyOobData PairingHandlerLe::GenerateOobData() {
27 MyOobData data{};
28 std::tie(data.private_key, data.public_key) = GenerateECDHKeyPair();
29
30 data.r = bluetooth::os::GenerateRandom<16>();
31 data.c = crypto_toolbox::f4(data.public_key.x.data(), data.public_key.x.data(), data.r, 0);
32 return data;
33 }
34
PairingMain(InitialInformations i)35 void PairingHandlerLe::PairingMain(InitialInformations i) {
36 LOG_INFO("Pairing Started");
37
38 if (i.remotely_initiated) {
39 LOG_INFO("Was remotely initiated, presenting user with the accept prompt");
40 i.user_interface_handler->Post(common::BindOnce(&UI::DisplayPairingPrompt, common::Unretained(i.user_interface),
41 i.remote_connection_address, i.remote_name));
42
43 // If pairing was initiated by remote device, wait for the user to accept
44 // the request from the UI.
45 LOG_INFO("Waiting for the prompt response");
46 std::optional<PairingEvent> pairingAccepted = WaitUiPairingAccept();
47 if (!pairingAccepted || pairingAccepted->ui_value == 0) {
48 LOG_INFO("User either did not accept the remote pairing, or the prompt timed out");
49 // TODO: Uncomment this one once we find a way to attempt to send packet when the link is down
50 // SendL2capPacket(i, PairingFailedBuilder::Create(PairingFailedReason::UNSPECIFIED_REASON));
51 i.OnPairingFinished(PairingFailure("User either did not accept the remote pairing, or the prompt timed out"));
52 return;
53 }
54
55 LOG_INFO("Pairing prompt accepted");
56 }
57
58 /************************************************ PHASE 1 *********************************************************/
59 Phase1ResultOrFailure phase_1_result = ExchangePairingFeature(i);
60 if (std::holds_alternative<PairingFailure>(phase_1_result)) {
61 LOG_WARN("Pairing failed in phase 1");
62 // We already send pairing fialed in lower layer. Which one should do that ? how about disconneciton?
63 // SendL2capPacket(i, PairingFailedBuilder::Create(PairingFailedReason::UNSPECIFIED_REASON));
64 // TODO: disconnect?
65 i.OnPairingFinished(std::get<PairingFailure>(phase_1_result));
66 return;
67 }
68
69 auto [pairing_request, pairing_response] = std::get<Phase1Result>(phase_1_result);
70
71 /************************************************ PHASE 2 *********************************************************/
72 bool isSecureConnections = pairing_request.GetAuthReq() & pairing_response.GetAuthReq() & AuthReqMaskSc;
73 if (isSecureConnections) {
74 // 2.3.5.6 LE Secure Connections pairing phase 2
75 LOG_INFO("Pairing Phase 2 LE Secure connections Started");
76
77 /*
78 TODO: what to do with this piece of spec ?
79 If Secure Connections pairing has been initiated over BR/EDR, the
80 following fields of the SM Pairing Request PDU are reserved for future use:
81 • the IO Capability field,
82 • the OOB data flag field, and
83 • all bits in the Auth Req field except the CT2 bit.
84 */
85
86 OobDataFlag remote_have_oob_data =
87 IAmMaster(i) ? pairing_response.GetOobDataFlag() : pairing_request.GetOobDataFlag();
88
89 auto key_exchange_result = ExchangePublicKeys(i, remote_have_oob_data);
90 if (std::holds_alternative<PairingFailure>(key_exchange_result)) {
91 LOG_ERROR("Public key exchange failed");
92 i.OnPairingFinished(std::get<PairingFailure>(key_exchange_result));
93 return;
94 }
95 auto [PKa, PKb, dhkey] = std::get<KeyExchangeResult>(key_exchange_result);
96
97 // Public key exchange finished, Diffie-Hellman key computed.
98
99 Stage1ResultOrFailure stage1result = DoSecureConnectionsStage1(i, PKa, PKb, pairing_request, pairing_response);
100 if (std::holds_alternative<PairingFailure>(stage1result)) {
101 i.OnPairingFinished(std::get<PairingFailure>(stage1result));
102 return;
103 }
104
105 Stage2ResultOrFailure stage_2_result = DoSecureConnectionsStage2(i, PKa, PKb, pairing_request, pairing_response,
106 std::get<Stage1Result>(stage1result), dhkey);
107 if (std::holds_alternative<PairingFailure>(stage_2_result)) {
108 i.OnPairingFinished(std::get<PairingFailure>(stage_2_result));
109 return;
110 }
111
112 Octet16 ltk = std::get<Octet16>(stage_2_result);
113 if (IAmMaster(i)) {
114 LOG_INFO("Sending start encryption request");
115 SendHciLeStartEncryption(i, i.connection_handle, {0}, {0}, ltk);
116 }
117
118 } else {
119 // 2.3.5.5 LE legacy pairing phase 2
120 LOG_INFO("Pairing Phase 2 LE legacy pairing Started");
121
122 LegacyStage1ResultOrFailure stage1result = DoLegacyStage1(i, pairing_request, pairing_response);
123 if (std::holds_alternative<PairingFailure>(stage1result)) {
124 LOG_ERROR("Phase 1 failed");
125 i.OnPairingFinished(std::get<PairingFailure>(stage1result));
126 return;
127 }
128
129 Octet16 tk = std::get<Octet16>(stage1result);
130 StkOrFailure stage2result = DoLegacyStage2(i, pairing_request, pairing_response, tk);
131 if (std::holds_alternative<PairingFailure>(stage2result)) {
132 LOG_ERROR("stage 2 failed");
133 i.OnPairingFinished(std::get<PairingFailure>(stage2result));
134 return;
135 }
136
137 Octet16 stk = std::get<Octet16>(stage2result);
138 if (IAmMaster(i)) {
139 LOG_INFO("Sending start encryption request");
140 SendHciLeStartEncryption(i, i.connection_handle, {0}, {0}, stk);
141 }
142 }
143
144 /************************************************ PHASE 3 *********************************************************/
145 LOG_INFO("Waiting for encryption changed");
146 auto encryption_change_result = WaitEncryptionChanged();
147 if (std::holds_alternative<PairingFailure>(encryption_change_result)) {
148 i.OnPairingFinished(std::get<PairingFailure>(encryption_change_result));
149 return;
150 } else if (std::holds_alternative<EncryptionChangeView>(encryption_change_result)) {
151 EncryptionChangeView encryption_changed = std::get<EncryptionChangeView>(encryption_change_result);
152 if (encryption_changed.GetStatus() != hci::ErrorCode::SUCCESS ||
153 encryption_changed.GetEncryptionEnabled() != hci::EncryptionEnabled::ON) {
154 i.OnPairingFinished(PairingFailure("Encryption change failed"));
155 return;
156 }
157 } else if (std::holds_alternative<EncryptionKeyRefreshCompleteView>(encryption_change_result)) {
158 EncryptionKeyRefreshCompleteView encryption_changed =
159 std::get<EncryptionKeyRefreshCompleteView>(encryption_change_result);
160 if (encryption_changed.GetStatus() != hci::ErrorCode::SUCCESS) {
161 i.OnPairingFinished(PairingFailure("Encryption key refresh failed"));
162 return;
163 }
164 } else {
165 i.OnPairingFinished(PairingFailure("Unknown case of encryption change result"));
166 return;
167 }
168 LOG_INFO("Encryption change finished successfully");
169
170 DistributedKeysOrFailure keyExchangeStatus = DistributeKeys(i, pairing_response, isSecureConnections);
171 if (std::holds_alternative<PairingFailure>(keyExchangeStatus)) {
172 i.OnPairingFinished(std::get<PairingFailure>(keyExchangeStatus));
173 LOG_ERROR("Key exchange failed");
174 return;
175 }
176
177 // If it's secure connections pairing, do cross-transport key derivation
178 DistributedKeys distributed_keys = std::get<DistributedKeys>(keyExchangeStatus);
179 if ((pairing_response.GetAuthReq() & AuthReqMaskSc) && distributed_keys.ltk.has_value()) {
180 bool use_h7 = (pairing_response.GetAuthReq() & AuthReqMaskCt2);
181 Octet16 link_key = crypto_toolbox::ltk_to_link_key(*(distributed_keys.ltk), use_h7);
182 distributed_keys.link_key = link_key;
183 }
184
185 // bool bonding = pairing_request.GetAuthReq() & pairing_response.GetAuthReq() & AuthReqMaskBondingFlag;
186
187 i.OnPairingFinished(PairingResult{
188 .connection_address = i.remote_connection_address,
189 .distributed_keys = std::get<DistributedKeys>(keyExchangeStatus),
190 });
191
192 LOG_INFO("Pairing finished successfully.");
193 }
194
ExchangePairingFeature(const InitialInformations & i)195 Phase1ResultOrFailure PairingHandlerLe::ExchangePairingFeature(const InitialInformations& i) {
196 LOG_INFO("Phase 1 start");
197
198 if (IAmMaster(i)) {
199 // Send Pairing Request
200 const auto& x = i.myPairingCapabilities;
201 auto pairing_request_builder =
202 PairingRequestBuilder::Create(x.io_capability, x.oob_data_flag, x.auth_req, x.maximum_encryption_key_size,
203 x.initiator_key_distribution, x.responder_key_distribution);
204 // basically pairing_request = myPairingCapabilities;
205
206 // Convert builder to view
207 std::shared_ptr<std::vector<uint8_t>> packet_bytes = std::make_shared<std::vector<uint8_t>>();
208 BitInserter it(*packet_bytes);
209 pairing_request_builder->Serialize(it);
210 PacketView<kLittleEndian> packet_bytes_view(packet_bytes);
211 auto temp_cmd_view = CommandView::Create(packet_bytes_view);
212 auto pairing_request = PairingRequestView::Create(temp_cmd_view);
213 ASSERT(pairing_request.IsValid());
214
215 LOG_INFO("Sending Pairing Request");
216 SendL2capPacket(i, std::move(pairing_request_builder));
217
218 LOG_INFO("Waiting for Pairing Response");
219 auto response = WaitPairingResponse();
220
221 /* There is a potential collision where the slave initiates the pairing at the same time we initiate it, by sending
222 * security request. */
223 if (std::holds_alternative<PairingFailure>(response) &&
224 std::get<PairingFailure>(response).received_code_ == Code::SECURITY_REQUEST) {
225 LOG_INFO("Received security request, waiting for Pairing Response again...");
226 response = WaitPairingResponse();
227 }
228
229 if (std::holds_alternative<PairingFailure>(response)) {
230 // TODO: should the failure reason be different in some cases ? How about
231 // when we lost connection ? Don't send anything at all, or have L2CAP
232 // layer ignore it?
233 SendL2capPacket(i, PairingFailedBuilder::Create(PairingFailedReason::UNSPECIFIED_REASON));
234 return std::get<PairingFailure>(response);
235 }
236
237 auto pairing_response = std::get<PairingResponseView>(response);
238
239 LOG_INFO("Phase 1 finish");
240 return Phase1Result{pairing_request, pairing_response};
241 } else {
242 std::optional<PairingRequestView> pairing_request;
243
244 if (i.remotely_initiated) {
245 if (!i.pairing_request.has_value()) {
246 return PairingFailure("You must pass PairingRequest as a initial information to slave!");
247 }
248
249 pairing_request = i.pairing_request.value();
250
251 if (!pairing_request->IsValid()) return PairingFailure("Malformed PairingRequest");
252 } else {
253 SendL2capPacket(i, SecurityRequestBuilder::Create(i.myPairingCapabilities.auth_req));
254
255 LOG_INFO("Waiting for Pairing Request");
256 auto request = WaitPairingRequest();
257 if (std::holds_alternative<PairingFailure>(request)) {
258 LOG_INFO("%s", std::get<PairingFailure>(request).message.c_str());
259 SendL2capPacket(i, PairingFailedBuilder::Create(PairingFailedReason::UNSPECIFIED_REASON));
260 return std::get<PairingFailure>(request);
261 }
262
263 pairing_request = std::get<PairingRequestView>(request);
264 }
265
266 // Send Pairing Request
267 const auto& x = i.myPairingCapabilities;
268 // basically pairing_response_builder = my_first_packet;
269 // We are not allowed to enable bits that the remote did not allow us to set in initiator_key_dist and
270 // responder_key_distribution
271 auto pairing_response_builder =
272 PairingResponseBuilder::Create(x.io_capability, x.oob_data_flag, x.auth_req, x.maximum_encryption_key_size,
273 x.initiator_key_distribution & pairing_request->GetInitiatorKeyDistribution(),
274 x.responder_key_distribution & pairing_request->GetResponderKeyDistribution());
275
276 // Convert builder to view
277 std::shared_ptr<std::vector<uint8_t>> packet_bytes = std::make_shared<std::vector<uint8_t>>();
278 BitInserter it(*packet_bytes);
279 pairing_response_builder->Serialize(it);
280 PacketView<kLittleEndian> packet_bytes_view(packet_bytes);
281 auto temp_cmd_view = CommandView::Create(packet_bytes_view);
282 auto pairing_response = PairingResponseView::Create(temp_cmd_view);
283 ASSERT(pairing_response.IsValid());
284
285 LOG_INFO("Sending Pairing Response");
286 SendL2capPacket(i, std::move(pairing_response_builder));
287
288 LOG_INFO("Phase 1 finish");
289 return Phase1Result{pairing_request.value(), pairing_response};
290 }
291 }
292
DistributeKeys(const InitialInformations & i,const PairingResponseView & pairing_response,bool isSecureConnections)293 DistributedKeysOrFailure PairingHandlerLe::DistributeKeys(const InitialInformations& i,
294 const PairingResponseView& pairing_response,
295 bool isSecureConnections) {
296 uint8_t keys_i_receive =
297 IAmMaster(i) ? pairing_response.GetResponderKeyDistribution() : pairing_response.GetInitiatorKeyDistribution();
298 uint8_t keys_i_send =
299 IAmMaster(i) ? pairing_response.GetInitiatorKeyDistribution() : pairing_response.GetResponderKeyDistribution();
300
301 // In Secure Connections on the LE Transport, the EncKey field shall be ignored
302 if (isSecureConnections) {
303 keys_i_send = (~KeyMaskEnc) & keys_i_send;
304 keys_i_receive = (~KeyMaskEnc) & keys_i_receive;
305 }
306
307 LOG_INFO("Key distribution start, keys_i_send=0x%02x, keys_i_receive=0x%02x", keys_i_send, keys_i_receive);
308
309 // TODO: obtain actual values!
310 Octet16 my_ltk = {0};
311 uint16_t my_ediv{0};
312 std::array<uint8_t, 8> my_rand = {0};
313
314 Octet16 my_irk = {0x01};
315 Address my_identity_address;
316 AddrType my_identity_address_type = AddrType::PUBLIC;
317 Octet16 my_signature_key{0};
318
319 if (IAmMaster(i)) {
320 // EncKey is unused for LE Secure Connections
321 DistributedKeysOrFailure keys = ReceiveKeys(keys_i_receive);
322 if (std::holds_alternative<PairingFailure>(keys)) {
323 return keys;
324 }
325
326 SendKeys(i, keys_i_send, my_ltk, my_ediv, my_rand, my_irk, my_identity_address, my_identity_address_type,
327 my_signature_key);
328 LOG_INFO("Key distribution finish");
329 return keys;
330 } else {
331 SendKeys(i, keys_i_send, my_ltk, my_ediv, my_rand, my_irk, my_identity_address, my_identity_address_type,
332 my_signature_key);
333
334 DistributedKeysOrFailure keys = ReceiveKeys(keys_i_receive);
335 if (std::holds_alternative<PairingFailure>(keys)) {
336 return keys;
337 }
338 LOG_INFO("Key distribution finish");
339 return keys;
340 }
341 }
342
ReceiveKeys(const uint8_t & keys_i_receive)343 DistributedKeysOrFailure PairingHandlerLe::ReceiveKeys(const uint8_t& keys_i_receive) {
344 std::optional<Octet16> ltk; /* Legacy only */
345 std::optional<uint16_t> ediv; /* Legacy only */
346 std::optional<std::array<uint8_t, 8>> rand; /* Legacy only */
347 std::optional<hci::AddressWithType> identity_address;
348 std::optional<Octet16> irk;
349 std::optional<Octet16> signature_key;
350
351 if (keys_i_receive & KeyMaskEnc) {
352 {
353 auto packet = WaitEncryptionInformation();
354 if (std::holds_alternative<PairingFailure>(packet)) {
355 LOG_ERROR(" Was expecting Encryption Information but did not receive!");
356 return std::get<PairingFailure>(packet);
357 }
358 ltk = std::get<EncryptionInformationView>(packet).GetLongTermKey();
359 }
360
361 {
362 auto packet = WaitMasterIdentification();
363 if (std::holds_alternative<PairingFailure>(packet)) {
364 LOG_ERROR(" Was expecting Master Identification but did not receive!");
365 return std::get<PairingFailure>(packet);
366 }
367 ediv = std::get<MasterIdentificationView>(packet).GetEdiv();
368 rand = std::get<MasterIdentificationView>(packet).GetRand();
369 }
370 }
371
372 if (keys_i_receive & KeyMaskId) {
373 auto packet = WaitIdentityInformation();
374 if (std::holds_alternative<PairingFailure>(packet)) {
375 LOG_ERROR(" Was expecting Identity Information but did not receive!");
376 return std::get<PairingFailure>(packet);
377 }
378
379 LOG_INFO("Received Identity Information");
380 irk = std::get<IdentityInformationView>(packet).GetIdentityResolvingKey();
381
382 auto iapacket = WaitIdentityAddressInformation();
383 if (std::holds_alternative<PairingFailure>(iapacket)) {
384 LOG_ERROR(
385 "Was expecting Identity Address Information but did "
386 "not receive!");
387 return std::get<PairingFailure>(iapacket);
388 }
389 LOG_INFO("Received Identity Address Information");
390 auto iapacketview = std::get<IdentityAddressInformationView>(iapacket);
391 identity_address = hci::AddressWithType(iapacketview.GetBdAddr(), iapacketview.GetAddrType() == AddrType::PUBLIC
392 ? hci::AddressType::PUBLIC_DEVICE_ADDRESS
393 : hci::AddressType::RANDOM_DEVICE_ADDRESS);
394 }
395
396 if (keys_i_receive & KeyMaskSign) {
397 auto packet = WaitSigningInformation();
398 if (std::holds_alternative<PairingFailure>(packet)) {
399 LOG_ERROR(" Was expecting Signing Information but did not receive!");
400 return std::get<PairingFailure>(packet);
401 }
402
403 LOG_INFO("Received Signing Information");
404 signature_key = std::get<SigningInformationView>(packet).GetSignatureKey();
405 }
406
407 return DistributedKeys{.ltk = ltk,
408 .ediv = ediv,
409 .rand = rand,
410 .identity_address = identity_address,
411 .irk = irk,
412 .signature_key = signature_key};
413 }
414
SendKeys(const InitialInformations & i,const uint8_t & keys_i_send,Octet16 ltk,uint16_t ediv,std::array<uint8_t,8> rand,Octet16 irk,Address identity_address,AddrType identity_addres_type,Octet16 signature_key)415 void PairingHandlerLe::SendKeys(const InitialInformations& i, const uint8_t& keys_i_send, Octet16 ltk, uint16_t ediv,
416 std::array<uint8_t, 8> rand, Octet16 irk, Address identity_address,
417 AddrType identity_addres_type, Octet16 signature_key) {
418 if (keys_i_send & KeyMaskEnc) {
419 LOG_INFO("Sending Encryption Information");
420 SendL2capPacket(i, EncryptionInformationBuilder::Create(ltk));
421 LOG_INFO("Sending Master Identification");
422 SendL2capPacket(i, MasterIdentificationBuilder::Create(ediv, rand));
423 }
424
425 if (keys_i_send & KeyMaskId) {
426 LOG_INFO("Sending Identity Information");
427 SendL2capPacket(i, IdentityInformationBuilder::Create(irk));
428 LOG_INFO("Sending Identity Address Information");
429 SendL2capPacket(i, IdentityAddressInformationBuilder::Create(identity_addres_type, identity_address));
430 }
431
432 if (keys_i_send & KeyMaskSign) {
433 LOG_INFO("Sending Signing Information");
434 SendL2capPacket(i, SigningInformationBuilder::Create(signature_key));
435 }
436 }
437
438 } // namespace security
439 } // namespace bluetooth