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