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