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 #pragma once 20 21 #include <array> 22 #include <chrono> 23 #include <condition_variable> 24 #include <mutex> 25 #include <optional> 26 #include <queue> 27 #include <thread> 28 #include <variant> 29 30 #include "common/bind.h" 31 #include "crypto_toolbox/crypto_toolbox.h" 32 #include "hci/hci_packets.h" 33 #include "hci/le_security_interface.h" 34 #include "packet/packet_view.h" 35 #include "security/ecdh_keys.h" 36 #include "security/initial_informations.h" 37 #include "security/pairing_failure.h" 38 #include "security/smp_packets.h" 39 #include "security/ui.h" 40 41 // Code generated by PDL does not allow us ot do || and && operations on bits 42 // efficiently. Use those masks on fields requiring them until this is solved 43 constexpr uint8_t AuthReqMaskBondingFlag = 0x01; 44 constexpr uint8_t AuthReqMaskMitm = 0x04; 45 constexpr uint8_t AuthReqMaskSc = 0x08; 46 constexpr uint8_t AuthReqMaskKeypress = 0x10; 47 constexpr uint8_t AuthReqMaskCt2 = 0x20; 48 49 constexpr uint8_t KeyMaskEnc = 0x01; 50 constexpr uint8_t KeyMaskId = 0x02; 51 constexpr uint8_t KeyMaskSign = 0x04; 52 constexpr uint8_t KeyMaskLink = 0x08; 53 54 using bluetooth::hci::EncryptionChangeView; 55 using bluetooth::hci::EncryptionKeyRefreshCompleteView; 56 57 namespace bluetooth { 58 namespace security { 59 60 using crypto_toolbox::Octet16; 61 62 /* This class represents an event send from other subsystems into SMP Pairing Handler, 63 * i.e. user request from the UI, L2CAP or HCI interaction */ 64 class PairingEvent { 65 public: 66 enum TYPE { EXIT, L2CAP, HCI_EVENT, UI }; 67 TYPE type; 68 69 std::optional<CommandView> l2cap_packet; 70 71 std::optional<hci::EventPacketView> hci_event; 72 73 enum UI_ACTION_TYPE { PAIRING_ACCEPTED, CONFIRM_YESNO, PASSKEY }; 74 UI_ACTION_TYPE ui_action; 75 uint32_t ui_value; 76 PairingEvent(TYPE type)77 PairingEvent(TYPE type) : type(type) {} PairingEvent(CommandView l2cap_packet)78 PairingEvent(CommandView l2cap_packet) : type(L2CAP), l2cap_packet(l2cap_packet) {} PairingEvent(UI_ACTION_TYPE ui_action,uint32_t ui_value)79 PairingEvent(UI_ACTION_TYPE ui_action, uint32_t ui_value) : type(UI), ui_action(ui_action), ui_value(ui_value) {} PairingEvent(hci::EventPacketView hci_event)80 PairingEvent(hci::EventPacketView hci_event) : type(HCI_EVENT), hci_event(hci_event) {} 81 }; 82 83 constexpr int SMP_TIMEOUT = 30; 84 85 using CommandViewOrFailure = std::variant<CommandView, PairingFailure>; 86 using Phase1Result = std::pair<PairingRequestView /* pairning_request*/, PairingResponseView /* pairing_response */>; 87 using Phase1ResultOrFailure = std::variant<PairingFailure, Phase1Result>; 88 using KeyExchangeResult = 89 std::tuple<EcdhPublicKey /* PKa */, EcdhPublicKey /* PKb */, std::array<uint8_t, 32> /*dhkey*/>; 90 using Stage1Result = std::tuple<Octet16, Octet16, Octet16, Octet16>; 91 using Stage1ResultOrFailure = std::variant<PairingFailure, Stage1Result>; 92 using Stage2ResultOrFailure = std::variant<PairingFailure, Octet16 /* LTK */>; 93 using DistributedKeysOrFailure = std::variant<PairingFailure, DistributedKeys, std::monostate>; 94 95 using LegacyStage1Result = Octet16 /*TK*/; 96 using LegacyStage1ResultOrFailure = std::variant<PairingFailure, LegacyStage1Result>; 97 using StkOrFailure = std::variant<PairingFailure, Octet16 /* STK */>; 98 99 /* PairingHandlerLe takes care of the Pairing process. Pairing is strictly defined 100 * exchange of messages and UI interactions, divided into PHASES. 101 * 102 * Each PairingHandlerLe have a thread executing |PairingMain| method. Thread is 103 * blocked when waiting for UI/L2CAP/HCI interactions, and moves through all the 104 * phases. 105 */ 106 class PairingHandlerLe { 107 public: 108 // This is the phase of pairing as defined in BT Spec (with exception of 109 // accept prompt) 110 // * ACCEPT_PROMPT - we're waiting for the user to accept remotely initiated pairing 111 // * PHASE1 - feature exchange 112 // * PHASE2 - authentication 113 // * PHASE3 - key exchange 114 enum PAIRING_PHASE { ACCEPT_PROMPT, PHASE1, PHASE2, PHASE3 }; 115 PAIRING_PHASE phase; 116 117 // All the knowledge to initiate the pairing process must be passed into this function PairingHandlerLe(PAIRING_PHASE phase,InitialInformations informations)118 PairingHandlerLe(PAIRING_PHASE phase, InitialInformations informations) 119 : phase(phase), queue_guard(), thread_(&PairingHandlerLe::PairingMain, this, informations) {} 120 ~PairingHandlerLe()121 ~PairingHandlerLe() { 122 SendExitSignal(); 123 // we need ot check if thread is joinable, because tests call join form 124 // within WaitUntilPairingFinished 125 if (thread_.joinable()) thread_.join(); 126 } 127 128 void PairingMain(InitialInformations i); 129 130 Phase1ResultOrFailure ExchangePairingFeature(const InitialInformations& i); 131 SendL2capPacket(const InitialInformations & i,std::unique_ptr<bluetooth::security::CommandBuilder> command)132 void SendL2capPacket(const InitialInformations& i, std::unique_ptr<bluetooth::security::CommandBuilder> command) { 133 i.proper_l2cap_interface->Enqueue(std::move(command), i.l2cap_handler); 134 } 135 SendHciLeStartEncryption(const InitialInformations & i,uint16_t conn_handle,const std::array<uint8_t,8> & rand,const uint16_t & ediv,const Octet16 & ltk)136 void SendHciLeStartEncryption(const InitialInformations& i, uint16_t conn_handle, const std::array<uint8_t, 8>& rand, 137 const uint16_t& ediv, const Octet16& ltk) { 138 i.le_security_interface->EnqueueCommand(hci::LeStartEncryptionBuilder::Create(conn_handle, rand, ediv, ltk), 139 common::BindOnce([](hci::CommandStatusView) { 140 // TODO: handle command status. It's important - can show we are not 141 // connected any more. 142 143 // TODO: if anything useful must be done there, use some sort of proper 144 // handler, wait/notify, and execute on the handler thread 145 }), 146 i.l2cap_handler); 147 } 148 WaitEncryptionChanged()149 std::variant<PairingFailure, EncryptionChangeView, EncryptionKeyRefreshCompleteView> WaitEncryptionChanged() { 150 PairingEvent e = WaitForEvent(); 151 if (e.type != PairingEvent::HCI_EVENT) return PairingFailure("Was expecting HCI event but received something else"); 152 153 if (!e.hci_event->IsValid()) return PairingFailure("Received invalid HCI event"); 154 155 if (e.hci_event->GetEventCode() == hci::EventCode::ENCRYPTION_CHANGE) { 156 EncryptionChangeView enc_chg_packet = EncryptionChangeView::Create(*e.hci_event); 157 if (!enc_chg_packet.IsValid()) { 158 return PairingFailure("Invalid Encryption Change packet received"); 159 } 160 return enc_chg_packet; 161 } 162 163 if (e.hci_event->GetEventCode() == hci::EventCode::ENCRYPTION_KEY_REFRESH_COMPLETE) { 164 hci::EncryptionKeyRefreshCompleteView enc_packet = EncryptionKeyRefreshCompleteView::Create(*e.hci_event); 165 if (!enc_packet.IsValid()) { 166 return PairingFailure("Invalid Key Refresh packet received"); 167 } 168 return enc_packet; 169 } 170 171 return PairingFailure("Was expecting Encryption Change or Key Refresh Complete but received something else"); 172 } 173 IAmMaster(const InitialInformations & i)174 inline bool IAmMaster(const InitialInformations& i) { 175 return i.my_role == hci::Role::MASTER; 176 } 177 178 /* This function generates data that should be passed to remote device, except 179 the private key. */ GenerateOobData()180 static MyOobData GenerateOobData() { 181 MyOobData data; 182 std::tie(data.private_key, data.public_key) = GenerateECDHKeyPair(); 183 184 data.r = GenerateRandom<16>(); 185 data.c = crypto_toolbox::f4(data.public_key.x.data(), data.public_key.x.data(), data.r, 0); 186 return data; 187 } 188 189 std::variant<PairingFailure, KeyExchangeResult> ExchangePublicKeys(const InitialInformations& i, 190 OobDataFlag remote_have_oob_data); 191 192 Stage1ResultOrFailure DoSecureConnectionsStage1(const InitialInformations& i, const EcdhPublicKey& PKa, 193 const EcdhPublicKey& PKb, const PairingRequestView& pairing_request, 194 const PairingResponseView& pairing_response); 195 196 Stage1ResultOrFailure SecureConnectionsNumericComparison(const InitialInformations& i, const EcdhPublicKey& PKa, 197 const EcdhPublicKey& PKb); 198 199 Stage1ResultOrFailure SecureConnectionsJustWorks(const InitialInformations& i, const EcdhPublicKey& PKa, 200 const EcdhPublicKey& PKb); 201 202 Stage1ResultOrFailure SecureConnectionsPasskeyEntry(const InitialInformations& i, const EcdhPublicKey& PKa, 203 const EcdhPublicKey& PKb, IoCapability my_iocaps, 204 IoCapability remote_iocaps); 205 206 Stage1ResultOrFailure SecureConnectionsOutOfBand(const InitialInformations& i, const EcdhPublicKey& Pka, 207 const EcdhPublicKey& Pkb, OobDataFlag my_oob_flag, 208 OobDataFlag remote_oob_flag); 209 210 Stage2ResultOrFailure DoSecureConnectionsStage2(const InitialInformations& i, const EcdhPublicKey& PKa, 211 const EcdhPublicKey& PKb, const PairingRequestView& pairing_request, 212 const PairingResponseView& pairing_response, 213 const Stage1Result stage1result, 214 const std::array<uint8_t, 32>& dhkey); 215 216 DistributedKeysOrFailure DistributeKeys(const InitialInformations& i, const PairingResponseView& pairing_response, 217 bool isSecureConnections); 218 219 DistributedKeysOrFailure ReceiveKeys(const uint8_t& keys_i_receive); 220 221 LegacyStage1ResultOrFailure DoLegacyStage1(const InitialInformations& i, const PairingRequestView& pairing_request, 222 const PairingResponseView& pairing_response); 223 LegacyStage1ResultOrFailure LegacyOutOfBand(const InitialInformations& i); 224 LegacyStage1ResultOrFailure LegacyJustWorks(); 225 LegacyStage1ResultOrFailure LegacyPasskeyEntry(const InitialInformations& i, const IoCapability& my_iocaps, 226 const IoCapability& remote_iocaps); 227 StkOrFailure DoLegacyStage2(const InitialInformations& i, const PairingRequestView& pairing_request, 228 const PairingResponseView& pairing_response, const Octet16& tk); 229 230 void SendKeys(const InitialInformations& i, const uint8_t& keys_i_send, Octet16 ltk, uint16_t ediv, 231 std::array<uint8_t, 8> rand, Octet16 irk, Address identity_address, AddrType identity_addres_type, 232 Octet16 signature_key); 233 234 /* This can be called from any thread to immediately finish the pairing in progress. */ SendExitSignal()235 void SendExitSignal() { 236 { 237 std::unique_lock<std::mutex> lock(queue_guard); 238 queue.push(PairingEvent(PairingEvent::EXIT)); 239 } 240 pairing_thread_blocker_.notify_one(); 241 } 242 243 /* SMP Command received from remote device */ OnCommandView(CommandView packet)244 void OnCommandView(CommandView packet) { 245 { 246 std::unique_lock<std::mutex> lock(queue_guard); 247 queue.push(PairingEvent(std::move(packet))); 248 } 249 pairing_thread_blocker_.notify_one(); 250 } 251 252 /* SMP Command received from remote device */ OnHciEvent(hci::EventPacketView hci_event)253 void OnHciEvent(hci::EventPacketView hci_event) { 254 { 255 std::unique_lock<std::mutex> lock(queue_guard); 256 queue.push(PairingEvent(std::move(hci_event))); 257 } 258 pairing_thread_blocker_.notify_one(); 259 } 260 261 /* Interaction from user */ OnUiAction(PairingEvent::UI_ACTION_TYPE ui_action,uint32_t ui_value)262 void OnUiAction(PairingEvent::UI_ACTION_TYPE ui_action, uint32_t ui_value) { 263 { 264 std::unique_lock<std::mutex> lock(queue_guard); 265 queue.push(PairingEvent(ui_action, ui_value)); 266 } 267 pairing_thread_blocker_.notify_one(); 268 } 269 270 /* Blocks the pairing process until some external interaction, or timeout happens */ WaitForEvent()271 PairingEvent WaitForEvent() { 272 std::unique_lock<std::mutex> lock(queue_guard); 273 do { 274 if (!queue.empty()) { 275 PairingEvent e = queue.front(); 276 queue.pop(); 277 return e; 278 } 279 // This releases the lock while blocking. 280 if (pairing_thread_blocker_.wait_for(lock, std::chrono::seconds(SMP_TIMEOUT)) == std::cv_status::timeout) { 281 return PairingEvent(PairingEvent::EXIT); 282 } 283 284 } while (true); 285 } 286 WaitUiPairingAccept()287 std::optional<PairingEvent> WaitUiPairingAccept() { 288 PairingEvent e = WaitForEvent(); 289 if (e.type == PairingEvent::UI & e.ui_action == PairingEvent::PAIRING_ACCEPTED) { 290 return e; 291 } else { 292 return std::nullopt; 293 } 294 } 295 WaitUiConfirmYesNo()296 std::optional<PairingEvent> WaitUiConfirmYesNo() { 297 PairingEvent e = WaitForEvent(); 298 if (e.type == PairingEvent::UI & e.ui_action == PairingEvent::CONFIRM_YESNO) { 299 return e; 300 } else { 301 return std::nullopt; 302 } 303 } 304 WaitUiPasskey()305 std::optional<PairingEvent> WaitUiPasskey() { 306 PairingEvent e = WaitForEvent(); 307 if (e.type == PairingEvent::UI & e.ui_action == PairingEvent::PASSKEY) { 308 return e; 309 } else { 310 return std::nullopt; 311 } 312 } 313 314 template <Code C> 315 struct CodeToPacketView; 316 template <> 317 struct CodeToPacketView<Code::PAIRING_REQUEST> { 318 typedef PairingRequestView type; 319 }; 320 template <> 321 struct CodeToPacketView<Code::PAIRING_RESPONSE> { 322 typedef PairingResponseView type; 323 }; 324 template <> 325 struct CodeToPacketView<Code::PAIRING_CONFIRM> { 326 typedef PairingConfirmView type; 327 }; 328 template <> 329 struct CodeToPacketView<Code::PAIRING_RANDOM> { 330 typedef PairingRandomView type; 331 }; 332 template <> 333 struct CodeToPacketView<Code::PAIRING_FAILED> { 334 typedef PairingFailedView type; 335 }; 336 template <> 337 struct CodeToPacketView<Code::ENCRYPTION_INFORMATION> { 338 typedef EncryptionInformationView type; 339 }; 340 template <> 341 struct CodeToPacketView<Code::MASTER_IDENTIFICATION> { 342 typedef MasterIdentificationView type; 343 }; 344 template <> 345 struct CodeToPacketView<Code::IDENTITY_INFORMATION> { 346 typedef IdentityInformationView type; 347 }; 348 template <> 349 struct CodeToPacketView<Code::IDENTITY_ADDRESS_INFORMATION> { 350 typedef IdentityAddressInformationView type; 351 }; 352 template <> 353 struct CodeToPacketView<Code::SIGNING_INFORMATION> { 354 typedef SigningInformationView type; 355 }; 356 template <> 357 struct CodeToPacketView<Code::SECURITY_REQUEST> { 358 typedef SecurityRequestView type; 359 }; 360 template <> 361 struct CodeToPacketView<Code::PAIRING_PUBLIC_KEY> { 362 typedef PairingPublicKeyView type; 363 }; 364 template <> 365 struct CodeToPacketView<Code::PAIRING_DH_KEY_CHECK> { 366 typedef PairingDhKeyCheckView type; 367 }; 368 template <> 369 struct CodeToPacketView<Code::PAIRING_KEYPRESS_NOTIFICATION> { 370 typedef PairingKeypressNotificationView type; 371 }; 372 373 template <Code CODE> 374 std::variant<typename CodeToPacketView<CODE>::type, PairingFailure> WaitPacket() { 375 PairingEvent e = WaitForEvent(); 376 switch (e.type) { 377 case PairingEvent::EXIT: 378 return PairingFailure( 379 /*FROM_HERE,*/ "Was expecting L2CAP Packet " + CodeText(CODE) + ", but received EXIT instead"); 380 381 case PairingEvent::HCI_EVENT: 382 return PairingFailure( 383 /*FROM_HERE,*/ "Was expecting L2CAP Packet " + CodeText(CODE) + ", but received HCI_EVENT instead"); 384 385 case PairingEvent::UI: 386 return PairingFailure( 387 /*FROM_HERE,*/ "Was expecting L2CAP Packet " + CodeText(CODE) + ", but received UI instead"); 388 389 case PairingEvent::L2CAP: { 390 auto l2cap_packet = e.l2cap_packet.value(); 391 if (!l2cap_packet.IsValid()) { 392 return PairingFailure("Malformed L2CAP packet received!"); 393 } 394 395 const auto& received_code = l2cap_packet.GetCode(); 396 if (received_code != CODE) { 397 if (received_code == Code::PAIRING_FAILED) { 398 auto pkt = PairingFailedView::Create(l2cap_packet); 399 if (!pkt.IsValid()) return PairingFailure("Malformed " + CodeText(CODE) + " packet"); 400 return PairingFailure(/*FROM_HERE,*/ 401 "Was expecting " + CodeText(CODE) + ", but received PAIRING_FAILED instead", 402 pkt.GetReason()); 403 } 404 405 return PairingFailure(/*FROM_HERE,*/ 406 "Was expecting " + CodeText(CODE) + ", but received " + CodeText(received_code) + 407 " instead", 408 received_code); 409 } 410 411 auto pkt = CodeToPacketView<CODE>::type::Create(l2cap_packet); 412 if (!pkt.IsValid()) return PairingFailure("Malformed " + CodeText(CODE) + " packet"); 413 return pkt; 414 } 415 } 416 } 417 418 auto WaitPairingRequest() { 419 return WaitPacket<Code::PAIRING_REQUEST>(); 420 } 421 422 auto WaitPairingResponse() { 423 return WaitPacket<Code::PAIRING_RESPONSE>(); 424 } 425 426 auto WaitPairingConfirm() { 427 return WaitPacket<Code::PAIRING_CONFIRM>(); 428 } 429 430 auto WaitPairingRandom() { 431 return WaitPacket<Code::PAIRING_RANDOM>(); 432 } 433 434 auto WaitPairingPublicKey() { 435 return WaitPacket<Code::PAIRING_PUBLIC_KEY>(); 436 } 437 438 auto WaitPairingDHKeyCheck() { 439 return WaitPacket<Code::PAIRING_DH_KEY_CHECK>(); 440 } 441 442 auto WaitEncryptionInformationRequest() { 443 return WaitPacket<Code::ENCRYPTION_INFORMATION>(); 444 } 445 446 auto WaitEncryptionInformation() { 447 return WaitPacket<Code::ENCRYPTION_INFORMATION>(); 448 } 449 450 auto WaitMasterIdentification() { 451 return WaitPacket<Code::MASTER_IDENTIFICATION>(); 452 } 453 454 auto WaitIdentityInformation() { 455 return WaitPacket<Code::IDENTITY_INFORMATION>(); 456 } 457 458 auto WaitIdentityAddressInformation() { 459 return WaitPacket<Code::IDENTITY_ADDRESS_INFORMATION>(); 460 } 461 462 auto WaitSigningInformation() { 463 return WaitPacket<Code::SIGNING_INFORMATION>(); 464 } 465 466 template <size_t SIZE> 467 static std::array<uint8_t, SIZE> GenerateRandom() { 468 // TODO: We need a proper random number generator here. 469 // use current time as seed for random generator 470 std::srand(std::time(nullptr)); 471 std::array<uint8_t, SIZE> r; 472 for (size_t i = 0; i < SIZE; i++) r[i] = std::rand(); 473 return r; 474 } 475 476 uint32_t GenerateRandom() { 477 // TODO: We need a proper random number generator here. 478 // use current time as seed for random generator 479 std::srand(std::time(nullptr)); 480 return std::rand(); 481 } 482 483 /* This is just for test, never use in production code! */ 484 void WaitUntilPairingFinished() { 485 thread_.join(); 486 } 487 488 private: 489 std::condition_variable pairing_thread_blocker_; 490 491 std::mutex queue_guard; 492 std::queue<PairingEvent> queue; 493 494 std::thread thread_; 495 }; 496 } // namespace security 497 } // namespace bluetooth