xref: /aosp_15_r20/external/pigweed/pw_bluetooth_sapphire/public/pw_bluetooth_sapphire/internal/host/sm/smp.h (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 #pragma once
16 #include <pw_chrono/system_clock.h>
17 
18 #include <cstdint>
19 
20 #include "pw_bluetooth_sapphire/internal/host/common/device_address.h"
21 #include "pw_bluetooth_sapphire/internal/host/common/uint128.h"
22 
23 // This file defines constants that are used by the Security Manager Protocol
24 // (SMP) that operates over the L2CAP SMP channel.
25 
26 namespace bt::sm {
27 
28 // Core Spec v5.3, Vol 3, Part H, 3.2
29 constexpr uint16_t kNoSecureConnectionsMtu = 23;
30 constexpr uint16_t kLeSecureConnectionsMtu = 65;
31 
32 // SMP Timeout in seconds (Core Spec v5.3, Vol 3, Part H, 3.4)
33 constexpr pw::chrono::SystemClock::duration kPairingTimeout =
34     std::chrono::seconds(30);
35 
36 // The supported encryption key sizes (Core Spec v5.3, Vol 3, Part H, 2.3.4).
37 constexpr uint8_t kMinEncryptionKeySize = 7;
38 constexpr uint8_t kMaxEncryptionKeySize = 16;
39 
40 // These are the sample ltk and random from (Core Spec v5.3, Vol 6, Part C, 1),
41 // they are declared so that SecurityManager can reject any peers using them and
42 // inclusive-language: disable
43 // prevent a mitm.
44 constexpr UInt128 kSpecSampleLtk = {0xBF,
45                                     0x01,
46                                     0xFB,
47                                     0x9D,
48                                     0x4E,
49                                     0xF3,
50                                     0xBC,
51                                     0x36,
52                                     0xD8,
53                                     0x74,
54                                     0xF5,
55                                     0x39,
56                                     0x41,
57                                     0x38,
58                                     0x68,
59                                     0x4C};
60 constexpr uint64_t kSpecSampleRandom = 0xABCDEF1234567890;
61 
62 // The field that identifies the type of a command.
63 using Code = uint8_t;
64 
65 struct Header {
66   Code code;
67 } __attribute__((packed));
68 
69 // Supported pairing methods.
70 enum class PairingMethod {
71   // Unauthenticated
72   kJustWorks,
73 
74   // Local host inputs passkey. Authenticated.
75   kPasskeyEntryInput,
76 
77   // Local host displays passkey. Authenticated.
78   kPasskeyEntryDisplay,
79 
80   // Authenticated, LE Secure Connections only.
81   kNumericComparison,
82 
83   // Authenticated depending on OOB mechanism
84   kOutOfBand,
85 };
86 
87 enum class IOCapability : uint8_t {
88   kDisplayOnly = 0x00,
89   kDisplayYesNo = 0x01,
90   kKeyboardOnly = 0x02,
91   kNoInputNoOutput = 0x03,
92   kKeyboardDisplay = 0x04,
93 };
94 
95 enum class OOBDataFlag : uint8_t {
96   kNotPresent = 0x00,
97   kPresent = 0x01,
98 };
99 
100 // Possible values that can be assigned to the "AuthReq" bit field (Core Spec
101 // v5.3, Vol 3, Part H, Figure 3.3).
102 enum AuthReq : uint8_t {
103   // Indicates that bonding is requested.
104   kBondingFlag = (1 << 0),
105 
106   // Indicates whether Man-in-the-middle protection is required.
107   kMITM = (1 << 2),
108 
109   // Indicates whether Secure Connections is supported.
110   kSC = (1 << 3),
111 
112   // Indicates whether Keypress notifications should be generated for the
113   // Passkey Entry protocol.
114   kKeypress = (1 << 4),
115 
116   // Indicates whether cross-transport key generation is supported for Secure
117   // Connections.
118   kCT2 = (1 << 5),
119 };
120 using AuthReqField = uint8_t;
121 
122 // Possible values for the Key Distribution/Generation fields (Core Spec v5.3,
123 // Vol 3, Part H, Figure 3.11)
124 enum KeyDistGen : uint8_t {
125   // LE: Indicates that the LTK will be distributed using the "Encryption
126   // Information" command in LE legacy pairing. Ignored in LE Secure
127   // Connections.
128   //
129   // BR/EDR: Indicates that the LTK will be derived from the BR/EDR Link Key.
130   kEncKey = (1 << 0),
131 
132   // Indicates that the IRK will be distributed using the "Identity Information"
133   // command and the Identity Address using the "Identity Address Information"
134   // command.
135   kIdKey = (1 << 1),
136 
137   // Indicates that the CSRK will be distributed using the "Signing Information"
138   // command.
139   kSignKey = (1 << 2),
140 
141   // LE: Indicates that the BR/EDR Link Key will be derived from the LTK.
142   // Ignored if LE Secure Connections isn't supported.
143   //
144   // BR/EDR: Reserved for future use.
145   kLinkKey = (1 << 3),
146 };
147 using KeyDistGenField = uint8_t;
148 
149 // Possible failure reason codes used in the "Pairing Failed" command.
150 // (Core Spec v5.3, Vol 3, Part H, 3.5.5, Table 3.7).
151 enum class ErrorCode : uint8_t {
152   // User input of passkey failed, e.g. due to cancelation.
153   kPasskeyEntryFailed = 0x01,
154 
155   // OOB data is not available.
156   kOOBNotAvailable = 0x02,
157 
158   // Authentication requirements cannot be met due to IO capabilities.
159   kAuthenticationRequirements = 0x03,
160 
161   // The confirm value does not match what was calculated.
162   kConfirmValueFailed = 0x04,
163 
164   // Pairing is not supported.
165   kPairingNotSupported = 0x05,
166 
167   // The resultant encryption key size is insufficient given local security
168   // requirements.
169   kEncryptionKeySize = 0x06,
170 
171   // An SMP command is not supported.
172   kCommandNotSupported = 0x07,
173 
174   // Pairing failed due to an unspecified reason.
175   kUnspecifiedReason = 0x08,
176 
177   // Pairing/authentication procedure is disallowed because too little time has
178   // elapsed since the last pairing/security request.
179   kRepeatedAttempts = 0x09,
180 
181   // SMP command parameters were invalid.
182   kInvalidParameters = 0x0A,
183 
184   // Indicates to the remote device that the DHKey Check value received doesn't
185   // match the one calculated locally.
186   kDHKeyCheckFailed = 0x0B,
187 
188   // Indicates that the confirm values in the numeric comparison protocol do not
189   // match.
190   kNumericComparisonFailed = 0x0C,
191 
192   // Indicates that pairing over the LE transport failed due to a concurrent
193   // pairing request over the BR/EDR transport.
194   kBREDRPairingInProgress = 0x0D,
195 
196   // Indicates that the BR/EDR Link Key generated on the BR/EDR transport cannot
197   // be used to derive keys for the LE transport.
198   kCrossTransportKeyDerivationNotAllowed = 0x0E,
199 };
200 
201 // Possible keypress notification types used in the "Keypress Notification"
202 // command (Core Spec v5.3, Vol 3, Part H, 3.5.8).
203 enum class KeypressNotificationType : uint8_t {
204   kStarted = 0,
205   kDigitEntered = 1,
206   kDigitErased = 2,
207   kCleared = 3,
208   kCompleted = 4,
209 };
210 
211 // Possible address types used in the "Identity Address Information" command
212 // (Core Spec v5.3, Vol 3, Part H, 3.6.5).
213 enum class AddressType : uint8_t {
214   kPublic = 0x00,
215   kStaticRandom = 0x01,
216 };
217 
218 // ========== SMP PDUs ========
219 constexpr Code kInvalidCode = 0x00;
220 
221 // ======================================
222 // Pairing Request (Core Spec v5.3, Vol 3, Part H, 3.5.1)
223 constexpr Code kPairingRequest = 0x01;
224 struct PairingRequestParams {
225   // The local I/O capability.
226   IOCapability io_capability;
227 
228   // Whether or not OOB authentication data is available.
229   OOBDataFlag oob_data_flag;
230 
231   // The requested security properties (Core Spec v5.3, Vol 3, Part H, 2.3.1).
232   AuthReqField auth_req;
233 
234   // Maximum encryption key size supported. Valid values are 7-16.
235   uint8_t max_encryption_key_size;
236 
237   // The keys that the initiator requests to distribute/generate.
238   KeyDistGenField initiator_key_dist_gen;
239 
240   // The keys that the responder requests to distribute/generate.
241   KeyDistGenField responder_key_dist_gen;
242 } __attribute__((packed));
243 
244 // =======================================
245 // Pairing Response (Core Spec v5.3, Vol 3, Part H, 3.5.2)
246 constexpr Code kPairingResponse = 0x02;
247 using PairingResponseParams = PairingRequestParams;
248 
249 // ======================================
250 // Pairing Confirm (Core Spec v5.3, Vol 3, Part H, 3.5.3)
251 constexpr Code kPairingConfirm = 0x03;
252 using PairingConfirmValue = UInt128;
253 
254 // =====================================
255 // Pairing Random (Core Spec v5.3, Vol 3, Part H, 3.5.4)
256 constexpr Code kPairingRandom = 0x04;
257 using PairingRandomValue = UInt128;
258 
259 // =====================================
260 // Pairing Failed (Core Spec v5.3, Vol 3, Part H, 3.5.5)
261 constexpr Code kPairingFailed = 0x05;
262 using PairingFailedParams = ErrorCode;
263 
264 // =============================================
265 // Encryption Information (LE Legacy Pairing only; Core Spec v5.3, Vol 3,
266 // Part H, 3.6.2)
267 constexpr Code kEncryptionInformation = 0x06;
268 using EncryptionInformationParams = UInt128;
269 
270 // ====================================================================
271 // Central Identification (LE Legacy Pairing only; Core Spec v5.3, Vol 3,
272 // Part H, 3.6.3)
273 constexpr Code kCentralIdentification = 0x07;
274 struct CentralIdentificationParams {
275   uint16_t ediv;
276   uint64_t rand;
277 } __attribute__((packed));
278 
279 // ===========================================
280 // Identity Information (Core Spec v5.3, Vol 3, Part H, 3.6.4)
281 constexpr Code kIdentityInformation = 0x08;
282 using IRK = UInt128;
283 
284 // ===================================================
285 // Identity Address Information (Core Spec v5.3, Vol 3, Part H, 3.6.5)
286 constexpr Code kIdentityAddressInformation = 0x09;
287 struct IdentityAddressInformationParams {
288   AddressType type;
289   DeviceAddressBytes bd_addr;
290 } __attribute__((packed));
291 
292 // ==========================================
293 // Signing Information (Core Spec v5.3, Vol 3, Part H, 3.6.6)
294 constexpr Code kSigningInformation = 0x0A;
295 using CSRK = UInt128;
296 
297 // =======================================
298 // Security Request (Core Spec v5.3, Vol 3, Part H, 3.6.7)
299 constexpr Code kSecurityRequest = 0x0B;
300 
301 // See enum AuthReq for parameters.
302 
303 // ==================================================================
304 // Pairing Public Key (Secure Connections only; Core Spec v5.3, Vol 3, Part H,
305 // 3.5.6)
306 constexpr Code kPairingPublicKey = 0x0C;
307 struct PairingPublicKeyParams {
308   uint8_t x[32];
309   uint8_t y[32];
310 } __attribute__((packed));
311 
312 // ======================================================================
313 // Pairing DHKey Check (LE Secure Connections only; Core Spec v5.3, Vol 3,
314 // Part H, 3.5.7)
315 constexpr Code kPairingDHKeyCheck = 0x0D;
316 using PairingDHKeyCheckValueE = UInt128;
317 
318 // ============================================
319 // Keypress Notification (Core Spec v5.3, Vol 3, Part H, 3.5.8)
320 constexpr Code kKeypressNotification = 0x0E;
321 
322 // See enum KeypressNotificationType above for parameters.
323 
324 }  // namespace bt::sm
325