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