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