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 using bluetooth::os::GenerateRandom;
24
25 namespace bluetooth {
26 namespace security {
27
ExchangePublicKeys(const InitialInformations & i,OobDataFlag remote_have_oob_data)28 std::variant<PairingFailure, KeyExchangeResult> PairingHandlerLe::ExchangePublicKeys(const InitialInformations& i,
29 OobDataFlag remote_have_oob_data) {
30 // Generate ECDH, or use one that was used for OOB data
31 const auto [private_key, public_key] = (remote_have_oob_data == OobDataFlag::NOT_PRESENT || !i.my_oob_data)
32 ? GenerateECDHKeyPair()
33 : std::make_pair(i.my_oob_data->private_key, i.my_oob_data->public_key);
34
35 LOG_INFO("Public key exchange start");
36 std::unique_ptr<PairingPublicKeyBuilder> myPublicKey = PairingPublicKeyBuilder::Create(public_key.x, public_key.y);
37
38 if (!ValidateECDHPoint(public_key)) {
39 LOG_ERROR("Can't validate my own public key!!!");
40 return PairingFailure("Can't validate my own public key");
41 }
42
43 if (IAmMaster(i)) {
44 // Send pairing public key
45 LOG_INFO("Master sends out public key");
46 SendL2capPacket(i, std::move(myPublicKey));
47 }
48
49 LOG_INFO(" Waiting for Public key...");
50 auto response = WaitPairingPublicKey();
51 LOG_INFO(" Received public key");
52 if (std::holds_alternative<PairingFailure>(response)) {
53 return std::get<PairingFailure>(response);
54 }
55
56 EcdhPublicKey remote_public_key;
57 auto ppkv = std::get<PairingPublicKeyView>(response);
58 remote_public_key.x = ppkv.GetPublicKeyX();
59 remote_public_key.y = ppkv.GetPublicKeyY();
60 LOG_INFO("Received Public key from remote");
61
62 // validate received public key
63 if (!ValidateECDHPoint(remote_public_key)) {
64 // TODO: Spec is unclear what should happend when the point is not on
65 // the correct curve: A device that detects an invalid public key from
66 // the peer at any point during the LE Secure Connections pairing
67 // process shall not use the resulting LTK, if any.
68 LOG_INFO("Can't validate remote public key");
69 return PairingFailure("Can't validate remote public key");
70 }
71
72 if (!IAmMaster(i)) {
73 LOG_INFO("Slave sends out public key");
74 // Send pairing public key
75 SendL2capPacket(i, std::move(myPublicKey));
76 }
77
78 LOG_INFO("Public key exchange finish");
79
80 std::array<uint8_t, 32> dhkey = ComputeDHKey(private_key, remote_public_key);
81
82 const EcdhPublicKey& PKa = IAmMaster(i) ? public_key : remote_public_key;
83 const EcdhPublicKey& PKb = IAmMaster(i) ? remote_public_key : public_key;
84
85 return KeyExchangeResult{PKa, PKb, dhkey};
86 }
87
DoSecureConnectionsStage1(const InitialInformations & i,const EcdhPublicKey & PKa,const EcdhPublicKey & PKb,const PairingRequestView & pairing_request,const PairingResponseView & pairing_response)88 Stage1ResultOrFailure PairingHandlerLe::DoSecureConnectionsStage1(const InitialInformations& i,
89 const EcdhPublicKey& PKa, const EcdhPublicKey& PKb,
90 const PairingRequestView& pairing_request,
91 const PairingResponseView& pairing_response) {
92 if (((pairing_request.GetAuthReq() & AuthReqMaskMitm) == 0) &&
93 ((pairing_response.GetAuthReq() & AuthReqMaskMitm) == 0)) {
94 // If both devices have not set MITM option, Just Works shall be used
95 return SecureConnectionsJustWorks(i, PKa, PKb);
96 }
97
98 if (pairing_request.GetOobDataFlag() == OobDataFlag::PRESENT ||
99 pairing_response.GetOobDataFlag() == OobDataFlag::PRESENT) {
100 OobDataFlag remote_oob_flag = IAmMaster(i) ? pairing_response.GetOobDataFlag() : pairing_request.GetOobDataFlag();
101 OobDataFlag my_oob_flag = IAmMaster(i) ? pairing_request.GetOobDataFlag() : pairing_response.GetOobDataFlag();
102 return SecureConnectionsOutOfBand(i, PKa, PKb, my_oob_flag, remote_oob_flag);
103 }
104
105 const auto& iom = pairing_request.GetIoCapability();
106 const auto& ios = pairing_response.GetIoCapability();
107
108 if ((iom == IoCapability::KEYBOARD_DISPLAY || iom == IoCapability::DISPLAY_YES_NO) &&
109 (ios == IoCapability::KEYBOARD_DISPLAY || ios == IoCapability::DISPLAY_YES_NO)) {
110 return SecureConnectionsNumericComparison(i, PKa, PKb);
111 }
112
113 if (iom == IoCapability::NO_INPUT_NO_OUTPUT || ios == IoCapability::NO_INPUT_NO_OUTPUT) {
114 return SecureConnectionsJustWorks(i, PKa, PKb);
115 }
116
117 if ((iom == IoCapability::DISPLAY_ONLY || iom == IoCapability::DISPLAY_YES_NO) &&
118 (ios == IoCapability::DISPLAY_ONLY || ios == IoCapability::DISPLAY_YES_NO)) {
119 return SecureConnectionsJustWorks(i, PKa, PKb);
120 }
121
122 IoCapability my_iocaps = IAmMaster(i) ? iom : ios;
123 IoCapability remote_iocaps = IAmMaster(i) ? ios : iom;
124 return SecureConnectionsPasskeyEntry(i, PKa, PKb, my_iocaps, remote_iocaps);
125 }
126
DoSecureConnectionsStage2(const InitialInformations & i,const EcdhPublicKey & PKa,const EcdhPublicKey & PKb,const PairingRequestView & pairing_request,const PairingResponseView & pairing_response,const Stage1Result stage1result,const std::array<uint8_t,32> & dhkey)127 Stage2ResultOrFailure PairingHandlerLe::DoSecureConnectionsStage2(const InitialInformations& i,
128 const EcdhPublicKey& PKa, const EcdhPublicKey& PKb,
129 const PairingRequestView& pairing_request,
130 const PairingResponseView& pairing_response,
131 const Stage1Result stage1result,
132 const std::array<uint8_t, 32>& dhkey) {
133 LOG_INFO("Authentication stage 2 started");
134
135 auto [Na, Nb, ra, rb] = stage1result;
136
137 // 2.3.5.6.5 Authentication stage 2 long term key calculation
138 uint8_t a[7];
139 uint8_t b[7];
140
141 if (IAmMaster(i)) {
142 memcpy(a, i.my_connection_address.GetAddress().data(), hci::Address::kLength);
143 a[6] = (uint8_t)i.my_connection_address.GetAddressType();
144 memcpy(b, i.remote_connection_address.GetAddress().data(), hci::Address::kLength);
145 b[6] = (uint8_t)i.remote_connection_address.GetAddressType();
146 } else {
147 memcpy(a, i.remote_connection_address.GetAddress().data(), hci::Address::kLength);
148 a[6] = (uint8_t)i.remote_connection_address.GetAddressType();
149 memcpy(b, i.my_connection_address.GetAddress().data(), hci::Address::kLength);
150 b[6] = (uint8_t)i.my_connection_address.GetAddressType();
151 }
152
153 Octet16 ltk, mac_key;
154 crypto_toolbox::f5((uint8_t*)dhkey.data(), Na, Nb, a, b, &mac_key, <k);
155
156 // DHKey exchange and check
157
158 std::array<uint8_t, 3> iocapA{static_cast<uint8_t>(pairing_request.GetIoCapability()),
159 static_cast<uint8_t>(pairing_request.GetOobDataFlag()), pairing_request.GetAuthReq()};
160 std::array<uint8_t, 3> iocapB{static_cast<uint8_t>(pairing_response.GetIoCapability()),
161 static_cast<uint8_t>(pairing_response.GetOobDataFlag()), pairing_response.GetAuthReq()};
162
163 // LOG(INFO) << +(IAmMaster(i)) << " LTK = " << base::HexEncode(ltk.data(), ltk.size());
164 // LOG(INFO) << +(IAmMaster(i)) << " MAC_KEY = " << base::HexEncode(mac_key.data(), mac_key.size());
165 // LOG(INFO) << +(IAmMaster(i)) << " Na = " << base::HexEncode(Na.data(), Na.size());
166 // LOG(INFO) << +(IAmMaster(i)) << " Nb = " << base::HexEncode(Nb.data(), Nb.size());
167 // LOG(INFO) << +(IAmMaster(i)) << " ra = " << base::HexEncode(ra.data(), ra.size());
168 // LOG(INFO) << +(IAmMaster(i)) << " rb = " << base::HexEncode(rb.data(), rb.size());
169 // LOG(INFO) << +(IAmMaster(i)) << " iocapA = " << base::HexEncode(iocapA.data(), iocapA.size());
170 // LOG(INFO) << +(IAmMaster(i)) << " iocapB = " << base::HexEncode(iocapB.data(), iocapB.size());
171 // LOG(INFO) << +(IAmMaster(i)) << " a = " << base::HexEncode(a, 7);
172 // LOG(INFO) << +(IAmMaster(i)) << " b = " << base::HexEncode(b, 7);
173
174 Octet16 Ea = crypto_toolbox::f6(mac_key, Na, Nb, rb, iocapA.data(), a, b);
175
176 Octet16 Eb = crypto_toolbox::f6(mac_key, Nb, Na, ra, iocapB.data(), b, a);
177
178 if (IAmMaster(i)) {
179 // send Pairing DHKey Check
180 SendL2capPacket(i, PairingDhKeyCheckBuilder::Create(Ea));
181
182 auto response = WaitPairingDHKeyCheck();
183 if (std::holds_alternative<PairingFailure>(response)) {
184 return std::get<PairingFailure>(response);
185 }
186
187 if (std::get<PairingDhKeyCheckView>(response).GetDhKeyCheck() != Eb) {
188 LOG_INFO("Ea != Eb, aborting!");
189 SendL2capPacket(i, PairingFailedBuilder::Create(PairingFailedReason::DHKEY_CHECK_FAILED));
190 return PairingFailure("Ea != Eb");
191 }
192 } else {
193 auto response = WaitPairingDHKeyCheck();
194 if (std::holds_alternative<PairingFailure>(response)) {
195 return std::get<PairingFailure>(response);
196 }
197
198 if (std::get<PairingDhKeyCheckView>(response).GetDhKeyCheck() != Ea) {
199 LOG_INFO("Ea != Eb, aborting!");
200 SendL2capPacket(i, PairingFailedBuilder::Create(PairingFailedReason::DHKEY_CHECK_FAILED));
201 return PairingFailure("Ea != Eb");
202 }
203
204 // send Pairing DHKey Check
205 SendL2capPacket(i, PairingDhKeyCheckBuilder::Create(Eb));
206 }
207
208 LOG_INFO("Authentication stage 2 (DHKey checks) finished");
209 return ltk;
210 }
211
SecureConnectionsOutOfBand(const InitialInformations & i,const EcdhPublicKey & Pka,const EcdhPublicKey & Pkb,OobDataFlag my_oob_flag,OobDataFlag remote_oob_flag)212 Stage1ResultOrFailure PairingHandlerLe::SecureConnectionsOutOfBand(const InitialInformations& i,
213 const EcdhPublicKey& Pka, const EcdhPublicKey& Pkb,
214 OobDataFlag my_oob_flag,
215 OobDataFlag remote_oob_flag) {
216 LOG_INFO("Out Of Band start");
217
218 Octet16 zeros{0};
219 Octet16 localR = (remote_oob_flag == OobDataFlag::PRESENT && i.my_oob_data) ? i.my_oob_data->r : zeros;
220 Octet16 remoteR;
221
222 if (my_oob_flag == OobDataFlag::NOT_PRESENT || (my_oob_flag == OobDataFlag::PRESENT && !i.remote_oob_data)) {
223 /* we have send the OOB data, but not received them. remote will check if
224 * C value is correct */
225 remoteR = zeros;
226 } else {
227 remoteR = i.remote_oob_data->le_sc_r;
228 Octet16 remoteC = i.remote_oob_data->le_sc_c;
229
230 Octet16 remoteC2;
231 if (IAmMaster(i)) {
232 remoteC2 = crypto_toolbox::f4((uint8_t*)Pkb.x.data(), (uint8_t*)Pkb.x.data(), remoteR, 0);
233 } else {
234 remoteC2 = crypto_toolbox::f4((uint8_t*)Pka.x.data(), (uint8_t*)Pka.x.data(), remoteR, 0);
235 }
236
237 if (remoteC2 != remoteC) {
238 LOG_ERROR("C_computed != C_from_remote, aborting!");
239 return PairingFailure("C_computed != C_from_remote, aborting");
240 }
241 }
242
243 Octet16 Na, Nb, ra, rb;
244 if (IAmMaster(i)) {
245 ra = localR;
246 rb = remoteR;
247 Na = GenerateRandom<16>();
248 // Send Pairing Random
249 SendL2capPacket(i, PairingRandomBuilder::Create(Na));
250
251 LOG_INFO("Master waits for Nb");
252 auto random = WaitPairingRandom();
253 if (std::holds_alternative<PairingFailure>(random)) {
254 return std::get<PairingFailure>(random);
255 }
256 Nb = std::get<PairingRandomView>(random).GetRandomValue();
257 } else {
258 ra = remoteR;
259 rb = localR;
260 Nb = GenerateRandom<16>();
261
262 LOG_INFO("Slave waits for random");
263 auto random = WaitPairingRandom();
264 if (std::holds_alternative<PairingFailure>(random)) {
265 return std::get<PairingFailure>(random);
266 }
267 Na = std::get<PairingRandomView>(random).GetRandomValue();
268
269 SendL2capPacket(i, PairingRandomBuilder::Create(Nb));
270 }
271
272 return Stage1Result{Na, Nb, ra, rb};
273 }
274
SecureConnectionsPasskeyEntry(const InitialInformations & i,const EcdhPublicKey & PKa,const EcdhPublicKey & PKb,IoCapability my_iocaps,IoCapability remote_iocaps)275 Stage1ResultOrFailure PairingHandlerLe::SecureConnectionsPasskeyEntry(const InitialInformations& i,
276 const EcdhPublicKey& PKa,
277 const EcdhPublicKey& PKb, IoCapability my_iocaps,
278 IoCapability remote_iocaps) {
279 LOG_INFO("Passkey Entry start");
280 Octet16 Na, Nb, ra{0}, rb{0};
281
282 uint32_t passkey;
283
284 if (my_iocaps == IoCapability::DISPLAY_ONLY || remote_iocaps == IoCapability::KEYBOARD_ONLY) {
285 // I display
286 passkey = GenerateRandom();
287 passkey &= 0x0fffff; /* maximum 20 significant bytes */
288 constexpr uint32_t PASSKEY_MAX = 999999;
289 while (passkey > PASSKEY_MAX) passkey >>= 1;
290
291 i.user_interface_handler->Post(common::BindOnce(&UI::DisplayPasskey, common::Unretained(i.user_interface),
292 i.remote_connection_address, i.remote_name, passkey));
293
294 } else if (my_iocaps == IoCapability::KEYBOARD_ONLY || remote_iocaps == IoCapability::DISPLAY_ONLY) {
295 i.user_interface_handler->Post(common::BindOnce(&UI::DisplayEnterPasskeyDialog,
296 common::Unretained(i.user_interface), i.remote_connection_address,
297 i.remote_name));
298 std::optional<PairingEvent> response = WaitUiPasskey();
299 if (!response) return PairingFailure("Passkey did not arrive!");
300
301 passkey = response->ui_value;
302
303 /*TODO: shall we send "Keypress Notification" after each key ? This would
304 * have impact on the SMP timeout*/
305
306 } else {
307 LOG(FATAL) << "THIS SHOULD NEVER HAPPEN";
308 return PairingFailure("FATAL!");
309 }
310
311 uint32_t bitmask = 0x01;
312 for (int loop = 0; loop < 20; loop++, bitmask <<= 1) {
313 LOG_INFO("Iteration no %d", loop);
314 bool bit_set = ((bitmask & passkey) != 0);
315 uint8_t ri = bit_set ? 0x81 : 0x80;
316
317 Octet16 Cai, Cbi, Nai, Nbi;
318 if (IAmMaster(i)) {
319 Nai = GenerateRandom<16>();
320
321 Cai = crypto_toolbox::f4((uint8_t*)PKa.x.data(), (uint8_t*)PKb.x.data(), Nai, ri);
322
323 // Send Pairing Confirm
324 LOG_INFO("Master sends Cai");
325 SendL2capPacket(i, PairingConfirmBuilder::Create(Cai));
326
327 LOG_INFO("Master waits for the Cbi");
328 auto confirm = WaitPairingConfirm();
329 if (std::holds_alternative<PairingFailure>(confirm)) {
330 return std::get<PairingFailure>(confirm);
331 }
332 Cbi = std::get<PairingConfirmView>(confirm).GetConfirmValue();
333
334 // Send Pairing Random
335 SendL2capPacket(i, PairingRandomBuilder::Create(Nai));
336
337 LOG_INFO("Master waits for Nbi");
338 auto random = WaitPairingRandom();
339 if (std::holds_alternative<PairingFailure>(random)) {
340 return std::get<PairingFailure>(random);
341 }
342 Nbi = std::get<PairingRandomView>(random).GetRandomValue();
343
344 Octet16 Cbi2 = crypto_toolbox::f4((uint8_t*)PKb.x.data(), (uint8_t*)PKa.x.data(), Nbi, ri);
345 if (Cbi != Cbi2) {
346 LOG_INFO("Cai != Cbi, aborting!");
347 SendL2capPacket(i, PairingFailedBuilder::Create(PairingFailedReason::CONFIRM_VALUE_FAILED));
348 return PairingFailure("Cai != Cbi");
349 }
350 } else {
351 Nbi = GenerateRandom<16>();
352 // Compute confirm
353 Cbi = crypto_toolbox::f4((uint8_t*)PKb.x.data(), (uint8_t*)PKa.x.data(), Nbi, ri);
354
355 LOG_INFO("Slave waits for the Cai");
356 auto confirm = WaitPairingConfirm();
357 if (std::holds_alternative<PairingFailure>(confirm)) {
358 return std::get<PairingFailure>(confirm);
359 }
360 Cai = std::get<PairingConfirmView>(confirm).GetConfirmValue();
361
362 // Send Pairing Confirm
363 LOG_INFO("Slave sends confirmation");
364 SendL2capPacket(i, PairingConfirmBuilder::Create(Cbi));
365
366 LOG_INFO("Slave waits for random");
367 auto random = WaitPairingRandom();
368 if (std::holds_alternative<PairingFailure>(random)) {
369 return std::get<PairingFailure>(random);
370 }
371 Nai = std::get<PairingRandomView>(random).GetRandomValue();
372
373 Octet16 Cai2 = crypto_toolbox::f4((uint8_t*)PKa.x.data(), (uint8_t*)PKb.x.data(), Nai, ri);
374 if (Cai != Cai2) {
375 LOG_INFO("Cai != Cai2, aborting!");
376 SendL2capPacket(i, PairingFailedBuilder::Create(PairingFailedReason::CONFIRM_VALUE_FAILED));
377 return PairingFailure("Cai != Cai2");
378 }
379
380 // Send Pairing Random
381 SendL2capPacket(i, PairingRandomBuilder::Create(Nbi));
382 }
383
384 if (loop == 19) {
385 Na = Nai;
386 Nb = Nbi;
387 }
388 }
389
390 ra[0] = (uint8_t)(passkey);
391 ra[1] = (uint8_t)(passkey >> 8);
392 ra[2] = (uint8_t)(passkey >> 16);
393 ra[3] = (uint8_t)(passkey >> 24);
394 rb = ra;
395
396 return Stage1Result{Na, Nb, ra, rb};
397 }
398
SecureConnectionsNumericComparison(const InitialInformations & i,const EcdhPublicKey & PKa,const EcdhPublicKey & PKb)399 Stage1ResultOrFailure PairingHandlerLe::SecureConnectionsNumericComparison(const InitialInformations& i,
400 const EcdhPublicKey& PKa,
401 const EcdhPublicKey& PKb) {
402 LOG_INFO("Numeric Comparison start");
403 Stage1ResultOrFailure result = SecureConnectionsJustWorks(i, PKa, PKb);
404 if (std::holds_alternative<PairingFailure>(result)) {
405 return std::get<PairingFailure>(result);
406 }
407
408 const auto [Na, Nb, ra, rb] = std::get<Stage1Result>(result);
409
410 uint32_t number_to_display = crypto_toolbox::g2((uint8_t*)PKa.x.data(), (uint8_t*)PKb.x.data(), Na, Nb);
411
412 i.user_interface_handler->Post(common::BindOnce(&UI::DisplayConfirmValue, common::Unretained(i.user_interface),
413 i.remote_connection_address, i.remote_name, number_to_display));
414
415 std::optional<PairingEvent> confirmyesno = WaitUiConfirmYesNo();
416 if (!confirmyesno || confirmyesno->ui_value == 0) {
417 LOG_INFO("Was expecting the user value confirm");
418 return PairingFailure("Was expecting the user value confirm");
419 }
420
421 return result;
422 }
423
SecureConnectionsJustWorks(const InitialInformations & i,const EcdhPublicKey & PKa,const EcdhPublicKey & PKb)424 Stage1ResultOrFailure PairingHandlerLe::SecureConnectionsJustWorks(const InitialInformations& i,
425 const EcdhPublicKey& PKa, const EcdhPublicKey& PKb) {
426 Octet16 Cb, Na, Nb, ra, rb;
427
428 ra = rb = {0};
429
430 if (IAmMaster(i)) {
431 Na = GenerateRandom<16>();
432 LOG_INFO("Master waits for confirmation");
433 auto confirm = WaitPairingConfirm();
434 if (std::holds_alternative<PairingFailure>(confirm)) {
435 return std::get<PairingFailure>(confirm);
436 }
437 Cb = std::get<PairingConfirmView>(confirm).GetConfirmValue();
438
439 // Send Pairing Random
440 SendL2capPacket(i, PairingRandomBuilder::Create(Na));
441
442 LOG_INFO("Master waits for Random");
443 auto random = WaitPairingRandom();
444 if (std::holds_alternative<PairingFailure>(random)) {
445 return std::get<PairingFailure>(random);
446 }
447 Nb = std::get<PairingRandomView>(random).GetRandomValue();
448
449 // Compute Cb locally
450 Octet16 Cb_local = crypto_toolbox::f4((uint8_t*)PKb.x.data(), (uint8_t*)PKa.x.data(), Nb, 0);
451
452 if (Cb_local != Cb) {
453 LOG_INFO("Cb_local != Cb, aborting!");
454 SendL2capPacket(i, PairingFailedBuilder::Create(PairingFailedReason::CONFIRM_VALUE_FAILED));
455 return PairingFailure("Cb_local != Cb");
456 }
457 } else {
458 Nb = GenerateRandom<16>();
459 // Compute confirm
460 Cb = crypto_toolbox::f4((uint8_t*)PKb.x.data(), (uint8_t*)PKa.x.data(), Nb, 0);
461
462 // Send Pairing Confirm
463 LOG_INFO("Slave sends confirmation");
464 SendL2capPacket(i, PairingConfirmBuilder::Create(Cb));
465
466 LOG_INFO("Slave waits for random");
467 auto random = WaitPairingRandom();
468 if (std::holds_alternative<PairingFailure>(random)) {
469 return std::get<PairingFailure>(random);
470 }
471 Na = std::get<PairingRandomView>(random).GetRandomValue();
472
473 // Send Pairing Random
474 SendL2capPacket(i, PairingRandomBuilder::Create(Nb));
475 }
476
477 return Stage1Result{Na, Nb, ra, rb};
478 }
479
480 } // namespace security
481 } // namespace bluetooth