• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2023 The Pigweed Authors
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License"); you may not
4 // use this file except in compliance with the License. You may obtain a copy of
5 // the License at
6 //
7 //     https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12 // License for the specific language governing permissions and limitations under
13 // the License.
14 
15 #include "pw_bluetooth_sapphire/internal/host/sm/phase_3.h"
16 
17 #include <pw_assert/check.h>
18 #include <pw_bytes/endian.h>
19 
20 #include <optional>
21 #include <type_traits>
22 
23 #include "lib/fit/function.h"
24 #include "pw_bluetooth_sapphire/internal/host/common/device_address.h"
25 #include "pw_bluetooth_sapphire/internal/host/common/log.h"
26 #include "pw_bluetooth_sapphire/internal/host/common/random.h"
27 #include "pw_bluetooth_sapphire/internal/host/hci/connection.h"
28 #include "pw_bluetooth_sapphire/internal/host/sm/packet.h"
29 #include "pw_bluetooth_sapphire/internal/host/sm/pairing_phase.h"
30 #include "pw_bluetooth_sapphire/internal/host/sm/smp.h"
31 #include "pw_bluetooth_sapphire/internal/host/sm/types.h"
32 #include "pw_bluetooth_sapphire/internal/host/sm/util.h"
33 
34 namespace bt::sm {
35 
Phase3(PairingChannel::WeakPtr chan,Listener::WeakPtr listener,Role role,PairingFeatures features,SecurityProperties le_sec,Phase3CompleteCallback on_complete)36 Phase3::Phase3(PairingChannel::WeakPtr chan,
37                Listener::WeakPtr listener,
38                Role role,
39                PairingFeatures features,
40                SecurityProperties le_sec,
41                Phase3CompleteCallback on_complete)
42     : PairingPhase(std::move(chan), std::move(listener), role),
43       features_(features),
44       le_sec_(le_sec),
45       obtained_remote_keys_(0),
46       sent_local_keys_(false),
47       on_complete_(std::move(on_complete)) {
48   // LTKs may not be distributed during Secure Connections.
49   PW_CHECK(!(features_.secure_connections &&
50              (ShouldSendLtk() || ShouldReceiveLtk())),
51            "Phase 3 may not distribute the LTK in Secure Connections pairing");
52 
53   PW_CHECK(
54       HasKeysToDistribute(features_, sm_chan().link_type() == LinkType::kACL));
55   // The link must be encrypted with at least an STK in order for Phase 3 to
56   // take place.
57   PW_CHECK(le_sec.level() != SecurityLevel::kNoSecurity);
58   SetPairingChannelHandler(*this);
59 }
60 
Start()61 void Phase3::Start() {
62   PW_CHECK(!has_failed());
63   PW_CHECK(!KeyExchangeComplete());
64 
65   if (role() == Role::kInitiator && !RequestedKeysObtained()) {
66     bt_log(DEBUG, "sm", "waiting to receive keys from the responder");
67     return;
68   }
69 
70   if (!LocalKeysSent() && !SendLocalKeys()) {
71     bt_log(WARN, "sm", "unable to send local keys");
72     Abort(ErrorCode::kUnspecifiedReason);
73     return;
74   }
75   // If there are no keys left to exchange then we're done with pairing. This
76   // cannot be an else branch because the above call to SendLocalKeys could've
77   // completed pairing.
78   if (KeyExchangeComplete()) {
79     SignalComplete();
80   }
81 }
82 
OnEncryptionInformation(const EncryptionInformationParams & ltk)83 void Phase3::OnEncryptionInformation(const EncryptionInformationParams& ltk) {
84   // Only allowed on the LE transport.
85   if (sm_chan().link_type() != bt::LinkType::kLE) {
86     bt_log(
87         DEBUG, "sm", "\"Encryption Information\" over BR/EDR not supported!");
88     Abort(ErrorCode::kCommandNotSupported);
89     return;
90   }
91 
92   if (!ShouldReceiveLtk()) {
93     bt_log(WARN, "sm", "received unexpected LTK");
94     Abort(ErrorCode::kUnspecifiedReason);
95     return;
96   }
97 
98   // abort pairing if we received a second LTK from the peer.
99   if (peer_ltk_bytes_.has_value() || peer_ltk_.has_value()) {
100     bt_log(WARN, "sm", "already received LTK! aborting");
101     Abort(ErrorCode::kUnspecifiedReason);
102     return;
103   }
104 
105   // Abort pairing if the LTK is the sample LTK from the core spec
106   if (ltk == kSpecSampleLtk) {
107     bt_log(WARN, "sm", "LTK is sample from spec, not secure! aborting");
108     Abort(ErrorCode::kUnspecifiedReason);
109     return;
110   }
111 
112   // Check that the received key has 0s at all locations more significant than
113   // negotiated key_size
114   uint8_t key_size = features_.encryption_key_size;
115   PW_DCHECK(key_size <= ltk.size());
116   for (auto i = key_size; i < ltk.size(); i++) {
117     if (ltk[i] != 0) {
118       bt_log(WARN, "sm", "received LTK is larger than max keysize! aborting");
119       Abort(ErrorCode::kInvalidParameters);
120       return;
121     }
122   }
123 
124   PW_DCHECK(!(obtained_remote_keys_ & KeyDistGen::kEncKey));
125   peer_ltk_bytes_ = ltk;
126 
127   // Wait to receive EDiv and Rand
128 }
129 
OnCentralIdentification(const CentralIdentificationParams & params)130 void Phase3::OnCentralIdentification(
131     const CentralIdentificationParams& params) {
132   // Only allowed on the LE transport.
133   if (sm_chan().link_type() != bt::LinkType::kLE) {
134     bt_log(
135         DEBUG, "sm", "\"Central Identification\" over BR/EDR not supported!");
136     Abort(ErrorCode::kCommandNotSupported);
137     return;
138   }
139   uint16_t ediv =
140       pw::bytes::ConvertOrderFrom(cpp20::endian::little, params.ediv);
141   uint64_t random =
142       pw::bytes::ConvertOrderFrom(cpp20::endian::little, params.rand);
143 
144   if (!ShouldReceiveLtk()) {
145     bt_log(WARN, "sm", "received unexpected ediv/rand");
146     Abort(ErrorCode::kUnspecifiedReason);
147     return;
148   }
149 
150   // EDIV and Rand must be sent AFTER the LTK (Vol 3, Part H, 3.6.1).
151   if (!peer_ltk_bytes_.has_value()) {
152     bt_log(WARN, "sm", "received EDIV and Rand before LTK!");
153     Abort(ErrorCode::kUnspecifiedReason);
154     return;
155   }
156 
157   if (obtained_remote_keys_ & KeyDistGen::kEncKey) {
158     bt_log(WARN, "sm", "already received EDIV and Rand!");
159     Abort(ErrorCode::kUnspecifiedReason);
160     return;
161   }
162 
163   // Abort pairing if the Rand is the sample Rand from the core spec
164   if (random == kSpecSampleRandom) {
165     bt_log(WARN, "sm", "random is sample from core spec, not secure! aborting");
166     Abort(ErrorCode::kUnspecifiedReason);
167     return;
168   }
169 
170   // The security properties of the LTK are determined by the current link
171   // properties (i.e. the properties of the STK).
172   peer_ltk_ = LTK(le_sec_, hci_spec::LinkKey(*peer_ltk_bytes_, random, ediv));
173   obtained_remote_keys_ |= KeyDistGen::kEncKey;
174 
175   // "EncKey" received. Complete pairing if possible.
176   OnExpectedKeyReceived();
177 }
178 
OnIdentityInformation(const IRK & irk)179 void Phase3::OnIdentityInformation(const IRK& irk) {
180   if (!ShouldReceiveIdentity()) {
181     bt_log(WARN, "sm", "received unexpected IRK");
182     Abort(ErrorCode::kUnspecifiedReason);
183     return;
184   }
185 
186   // Abort if we receive an IRK more than once.
187   if (irk_.has_value()) {
188     bt_log(WARN, "sm", "already received IRK! aborting");
189     Abort(ErrorCode::kUnspecifiedReason);
190     return;
191   }
192 
193   PW_DCHECK(!(obtained_remote_keys_ & KeyDistGen::kIdKey));
194   irk_ = irk;
195 
196   // Wait to receive identity address
197 }
198 
OnIdentityAddressInformation(const IdentityAddressInformationParams & params)199 void Phase3::OnIdentityAddressInformation(
200     const IdentityAddressInformationParams& params) {
201   if (!ShouldReceiveIdentity()) {
202     bt_log(WARN, "sm", "received unexpected identity address");
203     Abort(ErrorCode::kUnspecifiedReason);
204     return;
205   }
206 
207   // The identity address must be sent after the IRK (Vol 3, Part H, 3.6.1).
208   if (!irk_.has_value()) {
209     bt_log(WARN, "sm", "received identity address before the IRK!");
210     Abort(ErrorCode::kUnspecifiedReason);
211     return;
212   }
213 
214   if (obtained_remote_keys_ & KeyDistGen::kIdKey) {
215     bt_log(WARN, "sm", "already received identity information!");
216     Abort(ErrorCode::kUnspecifiedReason);
217     return;
218   }
219   auto type = DeviceAddress::Type::kLERandom;
220   if (params.type != AddressType::kStaticRandom) {
221     if (params.type != AddressType::kPublic) {
222       bt_log(WARN,
223              "sm",
224              "received invalid bt address type: %d",
225              static_cast<int>(params.type));
226       Abort(ErrorCode::kInvalidParameters);
227       return;
228     }
229     type = DeviceAddress::Type::kLEPublic;
230   }
231   auto identity_address = DeviceAddress(type, params.bd_addr);
232   // Store the identity address and mark all identity info as received.
233   identity_address_ = identity_address;
234   obtained_remote_keys_ |= KeyDistGen::kIdKey;
235 
236   // "IdKey" received. Complete pairing if possible.
237   OnExpectedKeyReceived();
238 }
239 
OnExpectedKeyReceived()240 void Phase3::OnExpectedKeyReceived() {
241   if (!RequestedKeysObtained()) {
242     bt_log(DEBUG, "sm", "received one expected key, more keys pending");
243     return;
244   }
245 
246   if (role() == Role::kInitiator && !LocalKeysSent() && !SendLocalKeys()) {
247     bt_log(WARN, "sm", "unable to send local keys to peer");
248     Abort(ErrorCode::kUnspecifiedReason);
249     return;
250   }
251   // If we've received all the expected keys and sent the local keys, Phase 3 is
252   // complete
253   SignalComplete();
254 }
255 
SendLocalKeys()256 bool Phase3::SendLocalKeys() {
257   PW_DCHECK(!LocalKeysSent());
258 
259   if (ShouldSendLtk() && !SendEncryptionKey()) {
260     return false;
261   }
262 
263   if (ShouldSendIdentity() && !SendIdentityInfo()) {
264     return false;
265   }
266 
267   sent_local_keys_ = true;
268   return true;
269 }
270 
SendEncryptionKey()271 bool Phase3::SendEncryptionKey() {
272   PW_CHECK(!features_.secure_connections);
273 
274   // Only allowed on the LE transport.
275   if (sm_chan().link_type() != bt::LinkType::kLE) {
276     return false;
277   }
278 
279   // Generate a completely random value for LTK.
280   UInt128 ltk_bytes = Random<UInt128>();
281 
282   // Mask the ltk down to the maximum encryption key size.
283   uint8_t key_size = features_.encryption_key_size;
284   if (key_size < 16) {
285     MutableBufferView view(ltk_bytes.data() + key_size, 16 - key_size);
286     view.SetToZeros();
287   }
288 
289   // Generate completely random values for EDiv and Rand, use masked LTK.
290   // The LTK inherits the security properties of the STK currently encrypting
291   // the link.
292   local_ltk_ =
293       LTK(le_sec_,
294           hci_spec::LinkKey(ltk_bytes, Random<uint64_t>(), Random<uint16_t>()));
295 
296   // Send LTK
297   sm_chan().SendMessage(kEncryptionInformation, local_ltk_->key().value());
298   // Send EDiv & Rand
299   sm_chan().SendMessage(
300       kCentralIdentification,
301       CentralIdentificationParams{
302           .ediv = pw::bytes::ConvertOrderTo(cpp20::endian::little,
303                                             local_ltk_->key().ediv()),
304           .rand = pw::bytes::ConvertOrderTo(cpp20::endian::little,
305                                             local_ltk_->key().rand())});
306 
307   return true;
308 }
309 
SendIdentityInfo()310 bool Phase3::SendIdentityInfo() {
311   std::optional<IdentityInfo> maybe_id_info = listener()->OnIdentityRequest();
312   if (!maybe_id_info.has_value()) {
313     bt_log(DEBUG,
314            "sm",
315            "local identity information required but no longer "
316            "available; abort pairing");
317     return false;
318   }
319   auto id_info = *maybe_id_info;
320 
321   if (!id_info.address.IsStaticRandom() && !id_info.address.IsPublic()) {
322     bt_log(DEBUG, "sm", "identity address must be public or static random!");
323     return false;
324   }
325 
326   // Send IRK
327   sm_chan().SendMessage(kIdentityInformation, id_info.irk);
328   // Send identity address
329   sm_chan().SendMessage(
330       kIdentityAddressInformation,
331       IdentityAddressInformationParams{
332           .type = (id_info.address.IsStaticRandom() ? AddressType::kStaticRandom
333                                                     : AddressType::kPublic),
334           .bd_addr = id_info.address.value()});
335 
336   return true;
337 }
338 
SignalComplete()339 void Phase3::SignalComplete() {
340   PW_CHECK(KeyExchangeComplete());
341 
342   // The security properties of all keys are determined by the security
343   // properties of the link used to distribute them. This is already reflected
344   // by |le_sec_|.
345   PairingData pairing_data;
346   pairing_data.peer_ltk = peer_ltk_;
347   pairing_data.local_ltk = local_ltk_;
348 
349   if (irk_.has_value()) {
350     // If there is an IRK there must also be an identity address.
351     PW_CHECK(identity_address_.has_value());
352     pairing_data.irk = Key(le_sec_, *irk_);
353     pairing_data.identity_address = identity_address_;
354   }
355   on_complete_(pairing_data);
356 }
357 
OnRxBFrame(ByteBufferPtr sdu)358 void Phase3::OnRxBFrame(ByteBufferPtr sdu) {
359   auto maybe_reader = ValidPacketReader::ParseSdu(sdu);
360   if (maybe_reader.is_error()) {
361     Abort(maybe_reader.error_value());
362     return;
363   }
364   ValidPacketReader reader = maybe_reader.value();
365   Code smp_code = reader.code();
366 
367   switch (smp_code) {
368     case kPairingFailed:
369       OnFailure(Error(reader.payload<ErrorCode>()));
370       break;
371     case kEncryptionInformation:
372       OnEncryptionInformation(reader.payload<EncryptionInformationParams>());
373       break;
374     case kCentralIdentification:
375       OnCentralIdentification(reader.payload<CentralIdentificationParams>());
376       break;
377     case kIdentityInformation:
378       OnIdentityInformation(reader.payload<IRK>());
379       break;
380     case kIdentityAddressInformation:
381       OnIdentityAddressInformation(
382           reader.payload<IdentityAddressInformationParams>());
383       break;
384     default:
385       bt_log(INFO,
386              "sm",
387              "received unexpected code %d when in Pairing Phase 3",
388              smp_code);
389       Abort(ErrorCode::kUnspecifiedReason);
390   }
391 }
392 
RequestedKeysObtained() const393 bool Phase3::RequestedKeysObtained() const {
394   // DistributableKeys masks key fields that don't correspond to keys exchanged
395   // in Phase 3.
396   const KeyDistGenField kMaskedRemoteKeys =
397       DistributableKeys(features_.remote_key_distribution,
398                         sm_chan().link_type() == LinkType::kACL);
399   // Return true if we expect no keys from the remote. We keep track of received
400   // keys individually in `obtained_remote_keys` as they are received
401   // asynchronously from the peer.
402   return !kMaskedRemoteKeys || (kMaskedRemoteKeys == obtained_remote_keys_);
403 }
404 
LocalKeysSent() const405 bool Phase3::LocalKeysSent() const {
406   // DistributableKeys masks key fields that don't correspond to keys exchanged
407   // in Phase 3.
408   const KeyDistGenField kMaskedLocalKeys =
409       DistributableKeys(features_.local_key_distribution,
410                         sm_chan().link_type() == LinkType::kACL);
411   // Return true if we didn't agree to send any keys. We need only store a
412   // boolean to track whether we've sent the keys, as sending the keys to the
413   // peer occurs sequentially.
414   return !kMaskedLocalKeys || sent_local_keys_;
415 }
416 
ShouldReceiveLtk() const417 bool Phase3::ShouldReceiveLtk() const {
418   return static_cast<bool>(features_.remote_key_distribution &
419                            KeyDistGen::kEncKey) &&
420          sm_chan().link_type() == bt::LinkType::kLE;
421 }
422 
ShouldReceiveIdentity() const423 bool Phase3::ShouldReceiveIdentity() const {
424   return (features_.remote_key_distribution & KeyDistGen::kIdKey);
425 }
426 
ShouldSendLtk() const427 bool Phase3::ShouldSendLtk() const {
428   return static_cast<bool>(features_.local_key_distribution &
429                            KeyDistGen::kEncKey) &&
430          sm_chan().link_type() == bt::LinkType::kLE;
431 }
432 
ShouldSendIdentity() const433 bool Phase3::ShouldSendIdentity() const {
434   return (features_.local_key_distribution & KeyDistGen::kIdKey);
435 }
436 
437 }  // namespace bt::sm
438