• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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   uint8_t key_size =
72       std::min(pairing_request.GetMaximumEncryptionKeySize(), pairing_response.GetMaximumEncryptionKeySize());
73   if (key_size < 7 || key_size > 16) {
74     LOG_WARN("Resulting key size is bad %d", key_size);
75     SendL2capPacket(i, PairingFailedBuilder::Create(PairingFailedReason::ENCRYPTION_KEY_SIZE));
76     i.OnPairingFinished(PairingFailure("Resulting key size is bad", PairingFailedReason::ENCRYPTION_KEY_SIZE));
77     return;
78   }
79   if (key_size != 16) {
80     LOG_WARN("Resulting key size is less than 16 octets!");
81   }
82 
83   /************************************************ PHASE 2 *********************************************************/
84   bool isSecureConnections = pairing_request.GetAuthReq() & pairing_response.GetAuthReq() & AuthReqMaskSc;
85   if (isSecureConnections) {
86     // 2.3.5.6 LE Secure Connections pairing phase 2
87     LOG_INFO("Pairing Phase 2 LE Secure connections Started");
88 
89     /*
90     TODO: what to do with this piece of spec ?
91     If Secure Connections pairing has been initiated over BR/EDR, the
92     following fields of the SM Pairing Request PDU are reserved for future use:
93      • the IO Capability field,
94      • the OOB data flag field, and
95      • all bits in the Auth Req field except the CT2 bit.
96     */
97 
98     OobDataFlag remote_have_oob_data =
99         IAmCentral(i) ? pairing_response.GetOobDataFlag() : pairing_request.GetOobDataFlag();
100 
101     auto key_exchange_result = ExchangePublicKeys(i, remote_have_oob_data);
102     if (std::holds_alternative<PairingFailure>(key_exchange_result)) {
103       LOG_ERROR("Public key exchange failed");
104       i.OnPairingFinished(std::get<PairingFailure>(key_exchange_result));
105       return;
106     }
107     auto [PKa, PKb, dhkey] = std::get<KeyExchangeResult>(key_exchange_result);
108 
109     // Public key exchange finished, Diffie-Hellman key computed.
110 
111     Stage1ResultOrFailure stage1result = DoSecureConnectionsStage1(i, PKa, PKb, pairing_request, pairing_response);
112     if (std::holds_alternative<PairingFailure>(stage1result)) {
113       i.OnPairingFinished(std::get<PairingFailure>(stage1result));
114       return;
115     }
116 
117     Stage2ResultOrFailure stage_2_result = DoSecureConnectionsStage2(i, PKa, PKb, pairing_request, pairing_response,
118                                                                      std::get<Stage1Result>(stage1result), dhkey);
119     if (std::holds_alternative<PairingFailure>(stage_2_result)) {
120       i.OnPairingFinished(std::get<PairingFailure>(stage_2_result));
121       return;
122     }
123 
124     Octet16 ltk = std::get<Octet16>(stage_2_result);
125     // Mask the key
126     std::fill(ltk.begin() + key_size, ltk.end(), 0x00);
127 
128     if (IAmCentral(i)) {
129       LOG_INFO("Sending start encryption request");
130       SendHciLeStartEncryption(i, i.connection_handle, {0}, {0}, ltk);
131     } else {
132       auto ltk_req = WaitLeLongTermKeyRequest();
133       SendHciLeLongTermKeyReply(i, i.connection_handle, ltk);
134     }
135   } else {
136     // 2.3.5.5 LE legacy pairing phase 2
137     LOG_INFO("Pairing Phase 2 LE legacy pairing Started");
138 
139     LegacyStage1ResultOrFailure stage1result = DoLegacyStage1(i, pairing_request, pairing_response);
140     if (std::holds_alternative<PairingFailure>(stage1result)) {
141       LOG_ERROR("Phase 1 failed");
142       i.OnPairingFinished(std::get<PairingFailure>(stage1result));
143       return;
144     }
145 
146     Octet16 tk = std::get<Octet16>(stage1result);
147     StkOrFailure stage2result = DoLegacyStage2(i, pairing_request, pairing_response, tk);
148     if (std::holds_alternative<PairingFailure>(stage2result)) {
149       LOG_ERROR("stage 2 failed");
150       i.OnPairingFinished(std::get<PairingFailure>(stage2result));
151       return;
152     }
153 
154     Octet16 stk = std::get<Octet16>(stage2result);
155     // Mask the key
156     std::fill(stk.begin() + key_size, stk.end(), 0x00);
157     if (IAmCentral(i)) {
158       LOG_INFO("Sending start encryption request");
159       SendHciLeStartEncryption(i, i.connection_handle, {0}, {0}, stk);
160     } else {
161       auto ltk_req = WaitLeLongTermKeyRequest();
162       SendHciLeLongTermKeyReply(i, i.connection_handle, stk);
163     }
164   }
165 
166   /************************************************ PHASE 3 *********************************************************/
167   LOG_INFO("Waiting for encryption changed");
168   auto encryption_change_result = WaitEncryptionChanged();
169   if (std::holds_alternative<PairingFailure>(encryption_change_result)) {
170     i.OnPairingFinished(std::get<PairingFailure>(encryption_change_result));
171     return;
172   } else if (std::holds_alternative<EncryptionChangeView>(encryption_change_result)) {
173     EncryptionChangeView encryption_changed = std::get<EncryptionChangeView>(encryption_change_result);
174     if (encryption_changed.GetStatus() != hci::ErrorCode::SUCCESS ||
175         encryption_changed.GetEncryptionEnabled() != hci::EncryptionEnabled::ON) {
176       i.OnPairingFinished(PairingFailure("Encryption change failed"));
177       return;
178     }
179   } else if (std::holds_alternative<EncryptionKeyRefreshCompleteView>(encryption_change_result)) {
180     EncryptionKeyRefreshCompleteView encryption_changed =
181         std::get<EncryptionKeyRefreshCompleteView>(encryption_change_result);
182     if (encryption_changed.GetStatus() != hci::ErrorCode::SUCCESS) {
183       i.OnPairingFinished(PairingFailure("Encryption key refresh failed"));
184       return;
185     }
186   } else {
187     i.OnPairingFinished(PairingFailure("Unknown case of encryption change result"));
188     return;
189   }
190   LOG_INFO("Encryption change finished successfully");
191 
192   DistributedKeysOrFailure keyExchangeStatus = DistributeKeys(i, pairing_response, isSecureConnections);
193   if (std::holds_alternative<PairingFailure>(keyExchangeStatus)) {
194     i.OnPairingFinished(std::get<PairingFailure>(keyExchangeStatus));
195     LOG_ERROR("Key exchange failed");
196     return;
197   }
198 
199   // If it's secure connections pairing, do cross-transport key derivation
200   DistributedKeys distributed_keys = std::get<DistributedKeys>(keyExchangeStatus);
201   if ((pairing_response.GetAuthReq() & AuthReqMaskSc) && distributed_keys.remote_ltk.has_value()) {
202     bool use_h7 = (pairing_response.GetAuthReq() & AuthReqMaskCt2);
203     Octet16 link_key = crypto_toolbox::ltk_to_link_key(*(distributed_keys.remote_ltk), use_h7);
204     distributed_keys.remote_link_key = link_key;
205   }
206 
207   // bool bonding = pairing_request.GetAuthReq() & pairing_response.GetAuthReq() & AuthReqMaskBondingFlag;
208 
209   i.OnPairingFinished(PairingResult{
210       .connection_address = i.remote_connection_address,
211       .distributed_keys = distributed_keys,
212       .key_size = key_size,
213   });
214 
215   LOG_INFO("Pairing finished successfully.");
216 }
217 
ExchangePairingFeature(const InitialInformations & i)218 Phase1ResultOrFailure PairingHandlerLe::ExchangePairingFeature(const InitialInformations& i) {
219   LOG_INFO("Phase 1 start");
220 
221   if (IAmCentral(i)) {
222     // Send Pairing Request
223     const auto& x = i.myPairingCapabilities;
224     auto pairing_request_builder =
225         PairingRequestBuilder::Create(x.io_capability, x.oob_data_flag, x.auth_req, x.maximum_encryption_key_size,
226                                       x.initiator_key_distribution, x.responder_key_distribution);
227     // basically pairing_request = myPairingCapabilities;
228 
229     // Convert builder to view
230     std::shared_ptr<std::vector<uint8_t>> packet_bytes = std::make_shared<std::vector<uint8_t>>();
231     BitInserter it(*packet_bytes);
232     pairing_request_builder->Serialize(it);
233     PacketView<kLittleEndian> packet_bytes_view(packet_bytes);
234     auto temp_cmd_view = CommandView::Create(packet_bytes_view);
235     auto pairing_request = PairingRequestView::Create(temp_cmd_view);
236     ASSERT(pairing_request.IsValid());
237 
238     LOG_INFO("Sending Pairing Request");
239     SendL2capPacket(i, std::move(pairing_request_builder));
240 
241     LOG_INFO("Waiting for Pairing Response");
242     auto response = WaitPairingResponse();
243 
244     /* There is a potential collision where the peripheral initiates the pairing at the same time we initiate it, by
245      * sending security request. */
246     if (std::holds_alternative<PairingFailure>(response) &&
247         std::get<PairingFailure>(response).received_code_ == Code::SECURITY_REQUEST) {
248       LOG_INFO("Received security request, waiting for Pairing Response again...");
249       response = WaitPairingResponse();
250     }
251 
252     if (std::holds_alternative<PairingFailure>(response)) {
253       // TODO: should the failure reason be different in some cases ? How about
254       // when we lost connection ? Don't send anything at all, or have L2CAP
255       // layer ignore it?
256       SendL2capPacket(i, PairingFailedBuilder::Create(PairingFailedReason::UNSPECIFIED_REASON));
257       return std::get<PairingFailure>(response);
258     }
259 
260     auto pairing_response = std::get<PairingResponseView>(response);
261 
262     LOG_INFO("Phase 1 finish");
263     return Phase1Result{pairing_request, pairing_response};
264   } else {
265     std::optional<PairingRequestView> pairing_request;
266 
267     if (i.remotely_initiated) {
268       if (!i.pairing_request.has_value()) {
269         return PairingFailure("You must pass PairingRequest as a initial information to peripheral!");
270       }
271 
272       pairing_request = i.pairing_request.value();
273 
274       if (!pairing_request->IsValid()) return PairingFailure("Malformed PairingRequest");
275     } else {
276       SendL2capPacket(i, SecurityRequestBuilder::Create(i.myPairingCapabilities.auth_req));
277 
278       LOG_INFO("Waiting for Pairing Request");
279       auto request = WaitPairingRequest();
280       if (std::holds_alternative<PairingFailure>(request)) {
281         LOG_INFO("%s", std::get<PairingFailure>(request).message.c_str());
282         SendL2capPacket(i, PairingFailedBuilder::Create(PairingFailedReason::UNSPECIFIED_REASON));
283         return std::get<PairingFailure>(request);
284       }
285 
286       pairing_request = std::get<PairingRequestView>(request);
287     }
288 
289     uint8_t key_size = pairing_request->GetMaximumEncryptionKeySize();
290     if (key_size < 7 || key_size > 16) {
291       LOG_WARN("Resulting key size is bad %d", key_size);
292       SendL2capPacket(i, PairingFailedBuilder::Create(PairingFailedReason::ENCRYPTION_KEY_SIZE));
293       return PairingFailure("Resulting key size is bad", PairingFailedReason::ENCRYPTION_KEY_SIZE);
294     }
295 
296     // Send Pairing Request
297     const auto& x = i.myPairingCapabilities;
298     // basically pairing_response_builder = my_first_packet;
299     // We are not allowed to enable bits that the remote did not allow us to set in initiator_key_dist and
300     // responder_key_distribution
301     auto pairing_response_builder =
302         PairingResponseBuilder::Create(x.io_capability, x.oob_data_flag, x.auth_req, x.maximum_encryption_key_size,
303                                        x.initiator_key_distribution & pairing_request->GetInitiatorKeyDistribution(),
304                                        x.responder_key_distribution & pairing_request->GetResponderKeyDistribution());
305 
306     // Convert builder to view
307     std::shared_ptr<std::vector<uint8_t>> packet_bytes = std::make_shared<std::vector<uint8_t>>();
308     BitInserter it(*packet_bytes);
309     pairing_response_builder->Serialize(it);
310     PacketView<kLittleEndian> packet_bytes_view(packet_bytes);
311     auto temp_cmd_view = CommandView::Create(packet_bytes_view);
312     auto pairing_response = PairingResponseView::Create(temp_cmd_view);
313     ASSERT(pairing_response.IsValid());
314 
315     LOG_INFO("Sending Pairing Response");
316     SendL2capPacket(i, std::move(pairing_response_builder));
317 
318     LOG_INFO("Phase 1 finish");
319     return Phase1Result{pairing_request.value(), pairing_response};
320   }
321 }
322 
DistributeKeys(const InitialInformations & i,const PairingResponseView & pairing_response,bool isSecureConnections)323 DistributedKeysOrFailure PairingHandlerLe::DistributeKeys(const InitialInformations& i,
324                                                           const PairingResponseView& pairing_response,
325                                                           bool isSecureConnections) {
326   uint8_t keys_i_receive =
327       IAmCentral(i) ? pairing_response.GetResponderKeyDistribution() : pairing_response.GetInitiatorKeyDistribution();
328   uint8_t keys_i_send =
329       IAmCentral(i) ? pairing_response.GetInitiatorKeyDistribution() : pairing_response.GetResponderKeyDistribution();
330 
331   // In Secure Connections on the LE Transport, the EncKey field shall be ignored
332   if (isSecureConnections) {
333     keys_i_send = (~KeyMaskEnc) & keys_i_send;
334     keys_i_receive = (~KeyMaskEnc) & keys_i_receive;
335   }
336 
337   LOG_INFO("Key distribution start, keys_i_send=0x%02x, keys_i_receive=0x%02x", keys_i_send, keys_i_receive);
338 
339   // TODO: obtain actual values, and apply key_size to the LTK
340   Octet16 my_ltk = bluetooth::os::GenerateRandom<16>();
341   uint16_t my_ediv = bluetooth::os::GenerateRandom();
342   std::array<uint8_t, 8> my_rand = bluetooth::os::GenerateRandom<8>();
343 
344   Octet16 my_irk = i.my_identity_resolving_key;
345   Address my_identity_address = i.my_identity_address.GetAddress();
346   AddrType my_identity_address_type =
347       static_cast<bluetooth::security::AddrType>(i.my_identity_address.GetAddressType());
348   Octet16 my_signature_key{0};
349 
350   if (IAmCentral(i)) {
351     // EncKey is unused for LE Secure Connections
352     DistributedKeysOrFailure keys = ReceiveKeys(keys_i_receive);
353     if (std::holds_alternative<PairingFailure>(keys)) {
354       return keys;
355     }
356 
357     SendKeys(i, keys_i_send, my_ltk, my_ediv, my_rand, my_irk, my_identity_address, my_identity_address_type,
358              my_signature_key);
359 
360     std::get<DistributedKeys>(keys).local_ltk = my_ltk;
361     std::get<DistributedKeys>(keys).local_ediv = my_ediv;
362     std::get<DistributedKeys>(keys).local_rand = my_rand;
363     LOG_INFO("Key distribution finish");
364     return keys;
365   } else {
366     SendKeys(i, keys_i_send, my_ltk, my_ediv, my_rand, my_irk, my_identity_address, my_identity_address_type,
367              my_signature_key);
368 
369     DistributedKeysOrFailure keys = ReceiveKeys(keys_i_receive);
370     if (std::holds_alternative<PairingFailure>(keys)) {
371       return keys;
372     }
373 
374     std::get<DistributedKeys>(keys).local_ltk = my_ltk;
375     std::get<DistributedKeys>(keys).local_ediv = my_ediv;
376     std::get<DistributedKeys>(keys).local_rand = my_rand;
377     LOG_INFO("Key distribution finish");
378     return keys;
379   }
380 }
381 
ReceiveKeys(const uint8_t & keys_i_receive)382 DistributedKeysOrFailure PairingHandlerLe::ReceiveKeys(const uint8_t& keys_i_receive) {
383   std::optional<Octet16> ltk;                 /* Legacy only */
384   std::optional<uint16_t> ediv;               /* Legacy only */
385   std::optional<std::array<uint8_t, 8>> rand; /* Legacy only */
386   std::optional<hci::AddressWithType> identity_address;
387   std::optional<Octet16> irk;
388   std::optional<Octet16> signature_key;
389 
390   if (keys_i_receive & KeyMaskEnc) {
391     {
392       auto packet = WaitEncryptionInformation();
393       if (std::holds_alternative<PairingFailure>(packet)) {
394         LOG_ERROR(" Was expecting Encryption Information but did not receive!");
395         return std::get<PairingFailure>(packet);
396       }
397       ltk = std::get<EncryptionInformationView>(packet).GetLongTermKey();
398     }
399 
400     {
401       auto packet = WaitCentralIdentification();
402       if (std::holds_alternative<PairingFailure>(packet)) {
403         LOG_ERROR(" Was expecting Central Identification but did not receive!");
404         return std::get<PairingFailure>(packet);
405       }
406       ediv = std::get<CentralIdentificationView>(packet).GetEdiv();
407       rand = std::get<CentralIdentificationView>(packet).GetRand();
408     }
409   }
410 
411   if (keys_i_receive & KeyMaskId) {
412     auto packet = WaitIdentityInformation();
413     if (std::holds_alternative<PairingFailure>(packet)) {
414       LOG_ERROR(" Was expecting Identity Information but did not receive!");
415       return std::get<PairingFailure>(packet);
416     }
417 
418     LOG_INFO("Received Identity Information");
419     irk = std::get<IdentityInformationView>(packet).GetIdentityResolvingKey();
420 
421     auto iapacket = WaitIdentityAddressInformation();
422     if (std::holds_alternative<PairingFailure>(iapacket)) {
423       LOG_ERROR(
424           "Was expecting Identity Address Information but did "
425           "not receive!");
426       return std::get<PairingFailure>(iapacket);
427     }
428     LOG_INFO("Received Identity Address Information");
429     auto iapacketview = std::get<IdentityAddressInformationView>(iapacket);
430     identity_address = hci::AddressWithType(iapacketview.GetBdAddr(), iapacketview.GetAddrType() == AddrType::PUBLIC
431                                                                           ? hci::AddressType::PUBLIC_DEVICE_ADDRESS
432                                                                           : hci::AddressType::RANDOM_DEVICE_ADDRESS);
433   }
434 
435   if (keys_i_receive & KeyMaskSign) {
436     auto packet = WaitSigningInformation();
437     if (std::holds_alternative<PairingFailure>(packet)) {
438       LOG_ERROR(" Was expecting Signing Information but did not receive!");
439       return std::get<PairingFailure>(packet);
440     }
441 
442     LOG_INFO("Received Signing Information");
443     signature_key = std::get<SigningInformationView>(packet).GetSignatureKey();
444   }
445 
446   return DistributedKeys{.remote_ltk = ltk,
447                          .remote_ediv = ediv,
448                          .remote_rand = rand,
449                          .remote_identity_address = identity_address,
450                          .remote_irk = irk,
451                          .remote_signature_key = signature_key};
452 }
453 
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)454 void PairingHandlerLe::SendKeys(const InitialInformations& i, const uint8_t& keys_i_send, Octet16 ltk, uint16_t ediv,
455                                 std::array<uint8_t, 8> rand, Octet16 irk, Address identity_address,
456                                 AddrType identity_addres_type, Octet16 signature_key) {
457   if (keys_i_send & KeyMaskEnc) {
458     LOG_INFO("Sending Encryption Information");
459     SendL2capPacket(i, EncryptionInformationBuilder::Create(ltk));
460     LOG_INFO("Sending Central Identification");
461     SendL2capPacket(i, CentralIdentificationBuilder::Create(ediv, rand));
462   }
463 
464   if (keys_i_send & KeyMaskId) {
465     LOG_INFO("Sending Identity Information");
466     SendL2capPacket(i, IdentityInformationBuilder::Create(irk));
467     LOG_INFO("Sending Identity Address Information");
468     SendL2capPacket(i, IdentityAddressInformationBuilder::Create(identity_addres_type, identity_address));
469   }
470 
471   if (keys_i_send & KeyMaskSign) {
472     LOG_INFO("Sending Signing Information");
473     SendL2capPacket(i, SigningInformationBuilder::Create(signature_key));
474   }
475 }
476 
477 }  // namespace security
478 }  // namespace bluetooth