1 /* 2 * Copyright (c) 2016, The OpenThread Authors. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 3. Neither the name of the copyright holder nor the 13 * names of its contributors may be used to endorse or promote products 14 * derived from this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 * POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29 /** 30 * @file 31 * This file includes definitions for Thread security material generation. 32 */ 33 34 #ifndef KEY_MANAGER_HPP_ 35 #define KEY_MANAGER_HPP_ 36 37 #include "openthread-core-config.h" 38 39 #include <stdint.h> 40 41 #include <openthread/dataset.h> 42 43 #include "common/clearable.hpp" 44 #include "common/encoding.hpp" 45 #include "common/equatable.hpp" 46 #include "common/locator.hpp" 47 #include "common/non_copyable.hpp" 48 #include "common/random.hpp" 49 #include "common/timer.hpp" 50 #include "crypto/hmac_sha256.hpp" 51 #include "mac/mac_types.hpp" 52 #include "thread/mle_types.hpp" 53 54 namespace ot { 55 56 /** 57 * @addtogroup core-security 58 * 59 * @brief 60 * This module includes definitions for Thread security material generation. 61 * 62 * @{ 63 */ 64 65 /** 66 * This class represents Security Policy Rotation and Flags. 67 * 68 */ 69 class SecurityPolicy : public otSecurityPolicy, public Equatable<SecurityPolicy> 70 { 71 public: 72 /** 73 * Offset between the Thread Version and the Version-threshold valid for Routing. 74 * 75 */ 76 static constexpr uint8_t kVersionThresholdOffsetVersion = 3; 77 78 static constexpr uint16_t kMinKeyRotationTime = 1; ///< The minimum Key Rotation Time in hours. 79 static constexpr uint16_t kDefaultKeyRotationTime = 672; ///< Default Key Rotation Time (in unit of hours). 80 81 /** 82 * This constructor initializes the object with default Key Rotation Time 83 * and Security Policy Flags. 84 * 85 */ SecurityPolicy(void)86 SecurityPolicy(void) { SetToDefault(); } 87 88 /** 89 * This method sets the Security Policy to default values. 90 * 91 */ 92 void SetToDefault(void); 93 94 /** 95 * This method sets the Security Policy Flags. 96 * 97 * @param[in] aFlags The Security Policy Flags. 98 * @param[in] aFlagsLength The length of the Security Policy Flags, 1 byte for 99 * Thread 1.1 devices, and 2 bytes for Thread 1.2 or higher. 100 * 101 */ 102 void SetFlags(const uint8_t *aFlags, uint8_t aFlagsLength); 103 104 /** 105 * This method returns the Security Policy Flags. 106 * 107 * @param[out] aFlags A pointer to the Security Policy Flags buffer. 108 * @param[in] aFlagsLength The length of the Security Policy Flags buffer. 109 * 110 */ 111 void GetFlags(uint8_t *aFlags, uint8_t aFlagsLength) const; 112 113 private: 114 static constexpr uint8_t kDefaultFlags = 0xff; 115 static constexpr uint8_t kObtainNetworkKeyMask = 1 << 7; 116 static constexpr uint8_t kNativeCommissioningMask = 1 << 6; 117 static constexpr uint8_t kRoutersMask = 1 << 5; 118 static constexpr uint8_t kExternalCommissioningMask = 1 << 4; 119 static constexpr uint8_t kBeaconsMask = 1 << 3; 120 static constexpr uint8_t kCommercialCommissioningMask = 1 << 2; 121 static constexpr uint8_t kAutonomousEnrollmentMask = 1 << 1; 122 static constexpr uint8_t kNetworkKeyProvisioningMask = 1 << 0; 123 static constexpr uint8_t kTobleLinkMask = 1 << 7; 124 static constexpr uint8_t kNonCcmRoutersMask = 1 << 6; 125 static constexpr uint8_t kReservedMask = 0x38; 126 static constexpr uint8_t kVersionThresholdForRoutingMask = 0x07; 127 128 void SetToDefaultFlags(void); 129 }; 130 131 /** 132 * This class represents a Thread Network Key. 133 * 134 */ 135 OT_TOOL_PACKED_BEGIN 136 class NetworkKey : public otNetworkKey, public Equatable<NetworkKey> 137 { 138 public: 139 #if !OPENTHREAD_RADIO 140 /** 141 * This method generates a cryptographically secure random sequence to populate the Thread Network Key. 142 * 143 * @retval kErrorNone Successfully generated a random Thread Network Key. 144 * @retval kErrorFailed Failed to generate random sequence. 145 * 146 */ GenerateRandom(void)147 Error GenerateRandom(void) { return Random::Crypto::FillBuffer(m8, sizeof(m8)); } 148 #endif 149 } OT_TOOL_PACKED_END; 150 151 /** 152 * This class represents a Thread Pre-Shared Key for the Commissioner (PSKc). 153 * 154 */ 155 OT_TOOL_PACKED_BEGIN 156 class Pskc : public otPskc, public Equatable<Pskc>, public Clearable<Pskc> 157 { 158 public: 159 #if !OPENTHREAD_RADIO 160 /** 161 * This method generates a cryptographically secure random sequence to populate the Thread PSKc. 162 * 163 * @retval kErrorNone Successfully generated a random Thread PSKc. 164 * 165 */ GenerateRandom(void)166 Error GenerateRandom(void) { return Random::Crypto::FillBuffer(m8, sizeof(Pskc)); } 167 #endif 168 169 } OT_TOOL_PACKED_END; 170 171 /** 172 * 173 * This class represents a Key Encryption Key (KEK). 174 * 175 */ 176 typedef Mac::Key Kek; 177 178 /** 179 * This class defines Thread Key Manager. 180 * 181 */ 182 class KeyManager : public InstanceLocator, private NonCopyable 183 { 184 public: 185 /** 186 * This constructor initializes the object. 187 * 188 * @param[in] aInstance A reference to the OpenThread instance. 189 * 190 */ 191 explicit KeyManager(Instance &aInstance); 192 193 /** 194 * This method starts KeyManager rotation timer and sets guard timer to initial value. 195 * 196 */ 197 void Start(void); 198 199 /** 200 * This method stops KeyManager timers. 201 * 202 */ 203 void Stop(void); 204 205 /** 206 * This method returns the Thread Network Key. 207 * 208 * @returns The Thread Network Key. 209 * 210 */ GetNetworkKey(void) const211 const NetworkKey &GetNetworkKey(void) const { return mNetworkKey; } 212 213 /** 214 * This method sets the Thread Network Key. 215 * 216 * @param[in] aKey A Thread Network Key. 217 * 218 * @retval kErrorNone Successfully set the Thread Network Key. 219 * @retval kErrorInvalidArgs The @p aKeyLength value was invalid. 220 * 221 */ 222 Error SetNetworkKey(const NetworkKey &aKey); 223 224 #if OPENTHREAD_FTD || OPENTHREAD_MTD 225 /** 226 * This method indicates whether the PSKc is configured. 227 * 228 * A value of all zeros indicates that the PSKc is not configured. 229 * 230 * @retval TRUE if the PSKc is configured. 231 * @retval FALSE if the PSKc is not not configured. 232 * 233 */ IsPskcSet(void) const234 bool IsPskcSet(void) const { return mIsPskcSet; } 235 236 /** 237 * This method returns a pointer to the PSKc. 238 * 239 * @returns A reference to the PSKc. 240 * 241 */ GetPskc(void) const242 const Pskc &GetPskc(void) const { return mPskc; } 243 244 /** 245 * This method sets the PSKc. 246 * 247 * @param[in] aPskc A reference to the PSKc. 248 * 249 */ 250 void SetPskc(const Pskc &aPskc); 251 #endif 252 253 /** 254 * This method returns the current key sequence value. 255 * 256 * @returns The current key sequence value. 257 * 258 */ GetCurrentKeySequence(void) const259 uint32_t GetCurrentKeySequence(void) const { return mKeySequence; } 260 261 /** 262 * This method sets the current key sequence value. 263 * 264 * @param[in] aKeySequence The key sequence value. 265 * 266 */ 267 void SetCurrentKeySequence(uint32_t aKeySequence); 268 269 #if OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE 270 /** 271 * This method returns the current MAC key for TREL radio link. 272 * 273 * @returns The current TREL MAC key. 274 * 275 */ GetCurrentTrelMacKey(void) const276 const Mac::Key &GetCurrentTrelMacKey(void) const { return mTrelKey; } 277 278 /** 279 * This method returns a temporary MAC key for TREL radio link computed from the given key sequence. 280 * 281 * @param[in] aKeySequence The key sequence value. 282 * 283 * @returns The temporary TREL MAC key. 284 * 285 */ 286 const Mac::Key &GetTemporaryTrelMacKey(uint32_t aKeySequence); 287 #endif 288 289 /** 290 * This method returns the current MLE key. 291 * 292 * @returns The current MLE key. 293 * 294 */ GetCurrentMleKey(void) const295 const Mle::Key &GetCurrentMleKey(void) const { return mMleKey; } 296 297 /** 298 * This method returns a temporary MLE key computed from the given key sequence. 299 * 300 * @param[in] aKeySequence The key sequence value. 301 * 302 * @returns The temporary MLE key. 303 * 304 */ 305 const Mle::Key &GetTemporaryMleKey(uint32_t aKeySequence); 306 307 #if OPENTHREAD_CONFIG_RADIO_LINK_IEEE_802_15_4_ENABLE 308 /** 309 * This method returns the current MAC Frame Counter value for 15.4 radio link. 310 * 311 * @returns The current MAC Frame Counter value. 312 * 313 */ Get154MacFrameCounter(void) const314 uint32_t Get154MacFrameCounter(void) const { return mMacFrameCounters.Get154(); } 315 #endif 316 317 #if OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE 318 /** 319 * This method returns the current MAC Frame Counter value for TREL radio link. 320 * 321 * @returns The current MAC Frame Counter value for TREL radio link. 322 * 323 */ GetTrelMacFrameCounter(void) const324 uint32_t GetTrelMacFrameCounter(void) const { return mMacFrameCounters.GetTrel(); } 325 326 /** 327 * This method increments the current MAC Frame Counter value for TREL radio link. 328 * 329 */ 330 void IncrementTrelMacFrameCounter(void); 331 #endif 332 333 /** 334 * This method gets the maximum MAC Frame Counter among all supported radio links. 335 * 336 * @return The maximum MAC frame Counter among all supported radio links. 337 * 338 */ GetMaximumMacFrameCounter(void) const339 uint32_t GetMaximumMacFrameCounter(void) const { return mMacFrameCounters.GetMaximum(); } 340 341 /** 342 * This method sets the current MAC Frame Counter value for all radio links. 343 * 344 * @param[in] aMacFrameCounter The MAC Frame Counter value. 345 * 346 */ 347 void SetAllMacFrameCounters(uint32_t aMacFrameCounter); 348 349 /** 350 * This method sets the MAC Frame Counter value which is stored in non-volatile memory. 351 * 352 * @param[in] aStoredMacFrameCounter The stored MAC Frame Counter value. 353 * 354 */ SetStoredMacFrameCounter(uint32_t aStoredMacFrameCounter)355 void SetStoredMacFrameCounter(uint32_t aStoredMacFrameCounter) { mStoredMacFrameCounter = aStoredMacFrameCounter; } 356 357 /** 358 * This method returns the current MLE Frame Counter value. 359 * 360 * @returns The current MLE Frame Counter value. 361 * 362 */ GetMleFrameCounter(void) const363 uint32_t GetMleFrameCounter(void) const { return mMleFrameCounter; } 364 365 /** 366 * This method sets the current MLE Frame Counter value. 367 * 368 * @param[in] aMleFrameCounter The MLE Frame Counter value. 369 * 370 */ SetMleFrameCounter(uint32_t aMleFrameCounter)371 void SetMleFrameCounter(uint32_t aMleFrameCounter) { mMleFrameCounter = aMleFrameCounter; } 372 373 /** 374 * This method sets the MLE Frame Counter value which is stored in non-volatile memory. 375 * 376 * @param[in] aStoredMleFrameCounter The stored MLE Frame Counter value. 377 * 378 */ SetStoredMleFrameCounter(uint32_t aStoredMleFrameCounter)379 void SetStoredMleFrameCounter(uint32_t aStoredMleFrameCounter) { mStoredMleFrameCounter = aStoredMleFrameCounter; } 380 381 /** 382 * This method increments the current MLE Frame Counter value. 383 * 384 */ 385 void IncrementMleFrameCounter(void); 386 387 /** 388 * This method returns the KEK. 389 * 390 * @returns A pointer to the KEK. 391 * 392 */ GetKek(void) const393 const Kek &GetKek(void) const { return mKek; } 394 395 /** 396 * This method sets the KEK. 397 * 398 * @param[in] aKek A KEK. 399 * 400 */ 401 void SetKek(const Kek &aKek); 402 403 /** 404 * This method sets the KEK. 405 * 406 * @param[in] aKek A pointer to the KEK. 407 * 408 */ 409 void SetKek(const uint8_t *aKek); 410 411 /** 412 * This method returns the current KEK Frame Counter value. 413 * 414 * @returns The current KEK Frame Counter value. 415 * 416 */ GetKekFrameCounter(void) const417 uint32_t GetKekFrameCounter(void) const { return mKekFrameCounter; } 418 419 /** 420 * This method increments the current KEK Frame Counter value. 421 * 422 */ IncrementKekFrameCounter(void)423 void IncrementKekFrameCounter(void) { mKekFrameCounter++; } 424 425 /** 426 * This method returns the KeySwitchGuardTime. 427 * 428 * The KeySwitchGuardTime is the time interval during which key rotation procedure is prevented. 429 * 430 * @returns The KeySwitchGuardTime value in hours. 431 * 432 */ GetKeySwitchGuardTime(void) const433 uint32_t GetKeySwitchGuardTime(void) const { return mKeySwitchGuardTime; } 434 435 /** 436 * This method sets the KeySwitchGuardTime. 437 * 438 * The KeySwitchGuardTime is the time interval during which key rotation procedure is prevented. 439 * 440 * @param[in] aKeySwitchGuardTime The KeySwitchGuardTime value in hours. 441 * 442 */ SetKeySwitchGuardTime(uint32_t aKeySwitchGuardTime)443 void SetKeySwitchGuardTime(uint32_t aKeySwitchGuardTime) { mKeySwitchGuardTime = aKeySwitchGuardTime; } 444 445 /** 446 * This method returns the Security Policy. 447 * 448 * The Security Policy specifies Key Rotation Time and network administrator preferences 449 * for which security-related operations are allowed or disallowed. 450 * 451 * @returns The SecurityPolicy. 452 * 453 */ GetSecurityPolicy(void) const454 const SecurityPolicy &GetSecurityPolicy(void) const { return mSecurityPolicy; } 455 456 /** 457 * This method sets the Security Policy. 458 * 459 * The Security Policy specifies Key Rotation Time and network administrator preferences 460 * for which security-related operations are allowed or disallowed. 461 * 462 * @param[in] aSecurityPolicy The Security Policy. 463 * 464 */ 465 void SetSecurityPolicy(const SecurityPolicy &aSecurityPolicy); 466 467 /** 468 * This method updates the MAC keys and MLE key. 469 * 470 */ 471 void UpdateKeyMaterial(void); 472 473 /** 474 * This method handles MAC frame counter change (callback from `SubMac` for 15.4 security frame change) 475 * 476 * @param[in] aMacFrameCounter The 15.4 link MAC frame counter value. 477 * 478 */ 479 void MacFrameCounterUpdated(uint32_t aMacFrameCounter); 480 481 private: 482 static constexpr uint32_t kDefaultKeySwitchGuardTime = 624; 483 static constexpr uint32_t kOneHourIntervalInMsec = 3600u * 1000u; 484 485 OT_TOOL_PACKED_BEGIN 486 struct Keys 487 { 488 Mle::Key mMleKey; 489 Mac::Key mMacKey; 490 } OT_TOOL_PACKED_END; 491 492 union HashKeys 493 { 494 Crypto::HmacSha256::Hash mHash; 495 Keys mKeys; 496 }; 497 498 void ComputeKeys(uint32_t aKeySequence, HashKeys &aHashKeys); 499 500 #if OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE 501 void ComputeTrelKey(uint32_t aKeySequence, Mac::Key &aTrelKey); 502 #endif 503 504 void StartKeyRotationTimer(void); 505 static void HandleKeyRotationTimer(Timer &aTimer); 506 void HandleKeyRotationTimer(void); 507 508 static const uint8_t kThreadString[]; 509 510 #if OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE 511 static const uint8_t kHkdfExtractSaltString[]; 512 static const uint8_t kTrelInfoString[]; 513 #endif 514 515 NetworkKey mNetworkKey; 516 517 uint32_t mKeySequence; 518 Mle::Key mMleKey; 519 Mle::Key mTemporaryMleKey; 520 521 #if OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE 522 Mac::Key mTrelKey; 523 Mac::Key mTemporaryTrelKey; 524 #endif 525 526 Mac::LinkFrameCounters mMacFrameCounters; 527 uint32_t mMleFrameCounter; 528 uint32_t mStoredMacFrameCounter; 529 uint32_t mStoredMleFrameCounter; 530 531 uint32_t mHoursSinceKeyRotation; 532 uint32_t mKeySwitchGuardTime; 533 bool mKeySwitchGuardEnabled; 534 TimerMilli mKeyRotationTimer; 535 536 #if OPENTHREAD_MTD || OPENTHREAD_FTD 537 Pskc mPskc; 538 #endif 539 Kek mKek; 540 uint32_t mKekFrameCounter; 541 542 SecurityPolicy mSecurityPolicy; 543 bool mIsPskcSet : 1; 544 }; 545 546 /** 547 * @} 548 */ 549 550 } // namespace ot 551 552 #endif // KEY_MANAGER_HPP_ 553