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 #pragma once
16 #include <lib/fit/function.h>
17 
18 #include <cstdint>
19 
20 #include "pw_bluetooth_sapphire/internal/host/common/weak_self.h"
21 #include "pw_bluetooth_sapphire/internal/host/sm/pairing_channel.h"
22 #include "pw_bluetooth_sapphire/internal/host/sm/pairing_phase.h"
23 #include "pw_bluetooth_sapphire/internal/host/sm/sc_stage_1.h"
24 #include "pw_bluetooth_sapphire/internal/host/sm/smp.h"
25 
26 namespace bt::sm {
27 // ScStage1Passkey encapsulates Stage 1 of LE Secure Connections Pairing Phase
28 // 2, which takes care of authentication using the Passkey Entry method as in
29 // V5.0 Vol. 3 Part H 2.3.5.6.3.
30 //
31 // This class is not thread safe and is meant to be accessed on the thread it
32 // was created on. All callbacks will be run by the default dispatcher of a
33 // ScStage1Passkey's creation thread.
34 class ScStage1Passkey final : public ScStage1 {
35  public:
36   ScStage1Passkey(PairingPhase::Listener::WeakPtr listener,
37                   Role role,
38                   UInt256 local_pub_key_x,
39                   UInt256 peer_pub_key_x,
40                   PairingMethod method,
41                   PairingChannel::WeakPtr sm_chan,
42                   Stage1CompleteCallback on_complete);
43   void Run() override;
44   void OnPairingConfirm(PairingConfirmValue confirm) override;
45   void OnPairingRandom(PairingRandomValue rand) override;
46 
47  private:
48   // For SC passkey entry, each bit of the passkey is exchanged and confirmed
49   // one-by-one. Calling this function clears variables from the previous
50   // exchange (if necessary) and starts the next.
51   void StartBitExchange();
52 
53   // Functions that handle sending/receiving SMP messages in the exchange of a
54   // bit of the passkey.
55   void SendPairingConfirm();
56   void SendPairingRandom();
57 
58   // Called after SMP messages have been exchanged & verified for a given bit of
59   // the passkey. Ends stage 1 after all bits are exchanged, or calls
60   // StartBitExchange if there are still more bits.
61   void FinishBitExchange();
62 
63   PairingPhase::Listener::WeakPtr listener_;
64   Role role_;
65   UInt256 local_public_key_x_;
66   UInt256 peer_public_key_x_;
67   PairingMethod method_;
68 
69   // This member is set when the PairingPhase::Listener request for the Passkey
70   // completes.
71   std::optional<uint32_t> passkey_;
72   size_t passkey_bit_location_;
73 
74   PairingConfirmValue local_confirm_;
75   bool sent_local_confirm_;
76   // The presence of |peer_confirm_| signals if we've received the peer's
77   // Pairing Random message.
78   std::optional<PairingConfirmValue> peer_confirm_;
79 
80   PairingRandomValue local_rand_;
81   bool sent_local_rand_;
82   // The presence of |peer_rand_| signals if we've received the peer's Pairing
83   // Random message.
84   std::optional<PairingRandomValue> peer_rand_;
85 
86   PairingChannel::WeakPtr sm_chan_;
87   Stage1CompleteCallback on_complete_;
88   WeakSelf<ScStage1Passkey> weak_self_;
89 };
90 }  // namespace bt::sm
91