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 #include <openthread/platform/crypto.h> 43 44 #include "common/as_core_type.hpp" 45 #include "common/clearable.hpp" 46 #include "common/encoding.hpp" 47 #include "common/equatable.hpp" 48 #include "common/locator.hpp" 49 #include "common/non_copyable.hpp" 50 #include "common/random.hpp" 51 #include "common/timer.hpp" 52 #include "crypto/hmac_sha256.hpp" 53 #include "mac/mac_types.hpp" 54 #include "thread/mle_types.hpp" 55 56 namespace ot { 57 58 /** 59 * @addtogroup core-security 60 * 61 * @brief 62 * This module includes definitions for Thread security material generation. 63 * 64 * @{ 65 */ 66 67 /** 68 * This class represents Security Policy Rotation and Flags. 69 * 70 */ 71 class SecurityPolicy : public otSecurityPolicy, public Equatable<SecurityPolicy> 72 { 73 public: 74 /** 75 * Offset between the Thread Version and the Version-threshold valid for Routing. 76 * 77 */ 78 static constexpr uint8_t kVersionThresholdOffsetVersion = 3; 79 80 static constexpr uint16_t kMinKeyRotationTime = 1; ///< The minimum Key Rotation Time in hours. 81 static constexpr uint16_t kDefaultKeyRotationTime = 672; ///< Default Key Rotation Time (in unit of hours). 82 83 /** 84 * This constructor initializes the object with default Key Rotation Time 85 * and Security Policy Flags. 86 * 87 */ SecurityPolicy(void)88 SecurityPolicy(void) { SetToDefault(); } 89 90 /** 91 * This method sets the Security Policy to default values. 92 * 93 */ 94 void SetToDefault(void); 95 96 /** 97 * This method sets the Security Policy Flags. 98 * 99 * @param[in] aFlags The Security Policy Flags. 100 * @param[in] aFlagsLength The length of the Security Policy Flags, 1 byte for 101 * Thread 1.1 devices, and 2 bytes for Thread 1.2 or higher. 102 * 103 */ 104 void SetFlags(const uint8_t *aFlags, uint8_t aFlagsLength); 105 106 /** 107 * This method returns the Security Policy Flags. 108 * 109 * @param[out] aFlags A pointer to the Security Policy Flags buffer. 110 * @param[in] aFlagsLength The length of the Security Policy Flags buffer. 111 * 112 */ 113 void GetFlags(uint8_t *aFlags, uint8_t aFlagsLength) const; 114 115 private: 116 static constexpr uint8_t kDefaultFlags = 0xff; 117 static constexpr uint8_t kObtainNetworkKeyMask = 1 << 7; 118 static constexpr uint8_t kNativeCommissioningMask = 1 << 6; 119 static constexpr uint8_t kRoutersMask = 1 << 5; 120 static constexpr uint8_t kExternalCommissioningMask = 1 << 4; 121 static constexpr uint8_t kBeaconsMask = 1 << 3; 122 static constexpr uint8_t kCommercialCommissioningMask = 1 << 2; 123 static constexpr uint8_t kAutonomousEnrollmentMask = 1 << 1; 124 static constexpr uint8_t kNetworkKeyProvisioningMask = 1 << 0; 125 static constexpr uint8_t kTobleLinkMask = 1 << 7; 126 static constexpr uint8_t kNonCcmRoutersMask = 1 << 6; 127 static constexpr uint8_t kReservedMask = 0x38; 128 static constexpr uint8_t kVersionThresholdForRoutingMask = 0x07; 129 130 void SetToDefaultFlags(void); 131 }; 132 133 /** 134 * This class represents a Thread Network Key. 135 * 136 */ 137 OT_TOOL_PACKED_BEGIN 138 class NetworkKey : public otNetworkKey, public Equatable<NetworkKey>, public Clearable<NetworkKey> 139 { 140 public: 141 static constexpr uint8_t kSize = OT_NETWORK_KEY_SIZE; ///< Size of the Thread Network Key (in bytes). 142 143 #if !OPENTHREAD_RADIO 144 /** 145 * This method generates a cryptographically secure random sequence to populate the Thread Network Key. 146 * 147 * @retval kErrorNone Successfully generated a random Thread Network Key. 148 * @retval kErrorFailed Failed to generate random sequence. 149 * 150 */ GenerateRandom(void)151 Error GenerateRandom(void) { return Random::Crypto::FillBuffer(m8, sizeof(m8)); } 152 #endif 153 154 } OT_TOOL_PACKED_END; 155 156 #if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE 157 /** 158 * Provides a representation for Network Key reference. 159 * 160 */ 161 typedef otNetworkKeyRef NetworkKeyRef; 162 #endif 163 164 /** 165 * This class represents a Thread Pre-Shared Key for the Commissioner (PSKc). 166 * 167 */ 168 OT_TOOL_PACKED_BEGIN 169 class Pskc : public otPskc, public Equatable<Pskc>, public Clearable<Pskc> 170 { 171 public: 172 static constexpr uint8_t kSize = OT_PSKC_MAX_SIZE; ///< Size (number of bytes) of the PSKc. 173 174 #if !OPENTHREAD_RADIO 175 /** 176 * This method generates a cryptographically secure random sequence to populate the Thread PSKc. 177 * 178 * @retval kErrorNone Successfully generated a random Thread PSKc. 179 * 180 */ GenerateRandom(void)181 Error GenerateRandom(void) { return Random::Crypto::FillBuffer(m8, sizeof(m8)); } 182 #endif 183 } OT_TOOL_PACKED_END; 184 185 #if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE 186 /** 187 * Provides a representation for Network Key reference. 188 * 189 */ 190 typedef otPskcRef PskcRef; 191 #endif 192 193 /** 194 * 195 * This class represents a Key Encryption Key (KEK). 196 * 197 */ 198 typedef Mac::Key Kek; 199 200 /** 201 * 202 * This class represents a Key Material for Key Encryption Key (KEK). 203 * 204 */ 205 typedef Mac::KeyMaterial KekKeyMaterial; 206 207 /** 208 * This class defines Thread Key Manager. 209 * 210 */ 211 class KeyManager : public InstanceLocator, private NonCopyable 212 { 213 public: 214 /** 215 * This constructor initializes the object. 216 * 217 * @param[in] aInstance A reference to the OpenThread instance. 218 * 219 */ 220 explicit KeyManager(Instance &aInstance); 221 222 /** 223 * This method starts KeyManager rotation timer and sets guard timer to initial value. 224 * 225 */ 226 void Start(void); 227 228 /** 229 * This method stops KeyManager timers. 230 * 231 */ 232 void Stop(void); 233 234 /** 235 * This method gets the Thread Network Key. 236 * 237 * @param[out] aNetworkKey A reference to a `NetworkKey` to output the Thread Network Key. 238 * 239 */ 240 void GetNetworkKey(NetworkKey &aNetworkKey) const; 241 242 /** 243 * This method sets the Thread Network Key. 244 * 245 * @param[in] aNetworkKey A Thread Network Key. 246 * 247 */ 248 void SetNetworkKey(const NetworkKey &aNetworkKey); 249 250 #if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE 251 /** 252 * This method returns a Key Ref to Thread Network Key. 253 * 254 * @returns A key reference to the Thread Network Key. 255 * 256 */ GetNetworkKeyRef(void) const257 NetworkKeyRef GetNetworkKeyRef(void) const { return mNetworkKeyRef; } 258 259 /** 260 * This method sets the Thread Network Key using Key Reference. 261 * 262 * @param[in] aKeyRef Reference to Thread Network Key. 263 * 264 */ 265 void SetNetworkKeyRef(NetworkKeyRef aKeyRef); 266 #endif 267 268 /** 269 * This method indicates whether the PSKc is configured. 270 * 271 * A value of all zeros indicates that the PSKc is not configured. 272 * 273 * @retval TRUE if the PSKc is configured. 274 * @retval FALSE if the PSKc is not not configured. 275 * 276 */ IsPskcSet(void) const277 bool IsPskcSet(void) const { return mIsPskcSet; } 278 279 /** 280 * This method gets the PKSc. 281 * 282 * @param[out] aPskc A reference to a `Pskc` to return the PSKc. 283 * 284 */ 285 void GetPskc(Pskc &aPskc) const; 286 287 /** 288 * This method sets the PSKc. 289 * 290 * @param[in] aPskc A reference to the PSKc. 291 * 292 */ 293 void SetPskc(const Pskc &aPskc); 294 295 #if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE 296 /** 297 * This method returns a Key Ref to PSKc. 298 * 299 * @returns A key reference to the PSKc. 300 * 301 */ GetPskcRef(void) const302 const PskcRef &GetPskcRef(void) const { return mPskcRef; } 303 304 /** 305 * This method sets the PSKc as a Key reference. 306 * 307 * @param[in] aPskc A reference to the PSKc. 308 * 309 */ 310 void SetPskcRef(PskcRef aKeyRef); 311 #endif 312 313 /** 314 * This method returns the current key sequence value. 315 * 316 * @returns The current key sequence value. 317 * 318 */ GetCurrentKeySequence(void) const319 uint32_t GetCurrentKeySequence(void) const { return mKeySequence; } 320 321 /** 322 * This method sets the current key sequence value. 323 * 324 * @param[in] aKeySequence The key sequence value. 325 * 326 */ 327 void SetCurrentKeySequence(uint32_t aKeySequence); 328 329 #if OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE 330 /** 331 * This method returns the current MAC key for TREL radio link. 332 * 333 * @returns The current TREL MAC key. 334 * 335 */ GetCurrentTrelMacKey(void) const336 const Mac::KeyMaterial &GetCurrentTrelMacKey(void) const { return mTrelKey; } 337 338 /** 339 * This method returns a temporary MAC key for TREL radio link computed from the given key sequence. 340 * 341 * @param[in] aKeySequence The key sequence value. 342 * 343 * @returns The temporary TREL MAC key. 344 * 345 */ 346 const Mac::KeyMaterial &GetTemporaryTrelMacKey(uint32_t aKeySequence); 347 #endif 348 349 /** 350 * This method returns the current MLE key Material. 351 * 352 * @returns The current MLE key. 353 * 354 */ GetCurrentMleKey(void) const355 const Mle::KeyMaterial &GetCurrentMleKey(void) const { return mMleKey; } 356 357 /** 358 * This method returns a temporary MLE key Material computed from the given key sequence. 359 * 360 * @param[in] aKeySequence The key sequence value. 361 * 362 * @returns The temporary MLE key. 363 * 364 */ 365 const Mle::KeyMaterial &GetTemporaryMleKey(uint32_t aKeySequence); 366 367 #if OPENTHREAD_CONFIG_RADIO_LINK_IEEE_802_15_4_ENABLE 368 /** 369 * This method returns the current MAC Frame Counter value for 15.4 radio link. 370 * 371 * @returns The current MAC Frame Counter value. 372 * 373 */ Get154MacFrameCounter(void) const374 uint32_t Get154MacFrameCounter(void) const { return mMacFrameCounters.Get154(); } 375 #endif 376 377 #if OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE 378 /** 379 * This method returns the current MAC Frame Counter value for TREL radio link. 380 * 381 * @returns The current MAC Frame Counter value for TREL radio link. 382 * 383 */ GetTrelMacFrameCounter(void) const384 uint32_t GetTrelMacFrameCounter(void) const { return mMacFrameCounters.GetTrel(); } 385 386 /** 387 * This method increments the current MAC Frame Counter value for TREL radio link. 388 * 389 */ 390 void IncrementTrelMacFrameCounter(void); 391 #endif 392 393 /** 394 * This method gets the maximum MAC Frame Counter among all supported radio links. 395 * 396 * @return The maximum MAC frame Counter among all supported radio links. 397 * 398 */ GetMaximumMacFrameCounter(void) const399 uint32_t GetMaximumMacFrameCounter(void) const { return mMacFrameCounters.GetMaximum(); } 400 401 /** 402 * This method sets the current MAC Frame Counter value for all radio links. 403 * 404 * @param[in] aFrameCounter The MAC Frame Counter value. 405 * @param[in] aSetIfLarger If `true`, set only if the new value @p aFrameCounter is larger than current value. 406 * If `false`, set the new value independent of the current value. 407 408 */ 409 void SetAllMacFrameCounters(uint32_t aFrameCounter, bool aSetIfLarger); 410 411 /** 412 * This method sets the MAC Frame Counter value which is stored in non-volatile memory. 413 * 414 * @param[in] aStoredMacFrameCounter The stored MAC Frame Counter value. 415 * 416 */ SetStoredMacFrameCounter(uint32_t aStoredMacFrameCounter)417 void SetStoredMacFrameCounter(uint32_t aStoredMacFrameCounter) { mStoredMacFrameCounter = aStoredMacFrameCounter; } 418 419 /** 420 * This method returns the current MLE Frame Counter value. 421 * 422 * @returns The current MLE Frame Counter value. 423 * 424 */ GetMleFrameCounter(void) const425 uint32_t GetMleFrameCounter(void) const { return mMleFrameCounter; } 426 427 /** 428 * This method sets the current MLE Frame Counter value. 429 * 430 * @param[in] aMleFrameCounter The MLE Frame Counter value. 431 * 432 */ SetMleFrameCounter(uint32_t aMleFrameCounter)433 void SetMleFrameCounter(uint32_t aMleFrameCounter) { mMleFrameCounter = aMleFrameCounter; } 434 435 /** 436 * This method sets the MLE Frame Counter value which is stored in non-volatile memory. 437 * 438 * @param[in] aStoredMleFrameCounter The stored MLE Frame Counter value. 439 * 440 */ SetStoredMleFrameCounter(uint32_t aStoredMleFrameCounter)441 void SetStoredMleFrameCounter(uint32_t aStoredMleFrameCounter) { mStoredMleFrameCounter = aStoredMleFrameCounter; } 442 443 /** 444 * This method increments the current MLE Frame Counter value. 445 * 446 */ 447 void IncrementMleFrameCounter(void); 448 449 /** 450 * This method returns the KEK as `KekKeyMaterial` 451 * 452 * @returns The KEK as `KekKeyMaterial`. 453 * 454 */ GetKek(void) const455 const KekKeyMaterial &GetKek(void) const { return mKek; } 456 457 /** 458 * This method retrieves the KEK as literal `Kek` key. 459 * 460 * @param[out] aKek A reference to a `Kek` to output the retrieved KEK. 461 * 462 */ ExtractKek(Kek & aKek)463 void ExtractKek(Kek &aKek) { mKek.ExtractKey(aKek); } 464 465 /** 466 * This method sets the KEK. 467 * 468 * @param[in] aKek A KEK. 469 * 470 */ 471 void SetKek(const Kek &aKek); 472 473 /** 474 * This method sets the KEK. 475 * 476 * @param[in] aKekBytes A pointer to the KEK bytes. 477 * 478 */ SetKek(const uint8_t * aKekBytes)479 void SetKek(const uint8_t *aKekBytes) { SetKek(*reinterpret_cast<const Kek *>(aKekBytes)); } 480 481 /** 482 * This method returns the current KEK Frame Counter value. 483 * 484 * @returns The current KEK Frame Counter value. 485 * 486 */ GetKekFrameCounter(void) const487 uint32_t GetKekFrameCounter(void) const { return mKekFrameCounter; } 488 489 /** 490 * This method increments the current KEK Frame Counter value. 491 * 492 */ IncrementKekFrameCounter(void)493 void IncrementKekFrameCounter(void) { mKekFrameCounter++; } 494 495 /** 496 * This method returns the KeySwitchGuardTime. 497 * 498 * The KeySwitchGuardTime is the time interval during which key rotation procedure is prevented. 499 * 500 * @returns The KeySwitchGuardTime value in hours. 501 * 502 */ GetKeySwitchGuardTime(void) const503 uint32_t GetKeySwitchGuardTime(void) const { return mKeySwitchGuardTime; } 504 505 /** 506 * This method sets the KeySwitchGuardTime. 507 * 508 * The KeySwitchGuardTime is the time interval during which key rotation procedure is prevented. 509 * 510 * @param[in] aKeySwitchGuardTime The KeySwitchGuardTime value in hours. 511 * 512 */ SetKeySwitchGuardTime(uint32_t aKeySwitchGuardTime)513 void SetKeySwitchGuardTime(uint32_t aKeySwitchGuardTime) { mKeySwitchGuardTime = aKeySwitchGuardTime; } 514 515 /** 516 * This method returns the Security Policy. 517 * 518 * The Security Policy specifies Key Rotation Time and network administrator preferences 519 * for which security-related operations are allowed or disallowed. 520 * 521 * @returns The SecurityPolicy. 522 * 523 */ GetSecurityPolicy(void) const524 const SecurityPolicy &GetSecurityPolicy(void) const { return mSecurityPolicy; } 525 526 /** 527 * This method sets the Security Policy. 528 * 529 * The Security Policy specifies Key Rotation Time and network administrator preferences 530 * for which security-related operations are allowed or disallowed. 531 * 532 * @param[in] aSecurityPolicy The Security Policy. 533 * 534 */ 535 void SetSecurityPolicy(const SecurityPolicy &aSecurityPolicy); 536 537 /** 538 * This method updates the MAC keys and MLE key. 539 * 540 */ 541 void UpdateKeyMaterial(void); 542 543 /** 544 * This method handles MAC frame counter changes (callback from `SubMac` for 15.4 security frame change). 545 * 546 * This is called to indicate the @p aMacFrameCounter value is now used. 547 * 548 * @param[in] aMacFrameCounter The 15.4 link MAC frame counter value. 549 * 550 */ 551 void MacFrameCounterUsed(uint32_t aMacFrameCounter); 552 553 #if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE 554 /** 555 * This method destroys all the volatile mac keys stored in PSA ITS. 556 * 557 */ 558 void DestroyTemporaryKeys(void); 559 560 /** 561 * This method destroys all the persistent keys stored in PSA ITS. 562 * 563 */ 564 void DestroyPersistentKeys(void); 565 #endif 566 567 private: 568 static constexpr uint32_t kDefaultKeySwitchGuardTime = 624; 569 static constexpr uint32_t kOneHourIntervalInMsec = 3600u * 1000u; 570 static constexpr bool kExportableMacKeys = OPENTHREAD_CONFIG_PLATFORM_MAC_KEYS_EXPORTABLE_ENABLE; 571 572 OT_TOOL_PACKED_BEGIN 573 struct Keys 574 { 575 Mle::Key mMleKey; 576 Mac::Key mMacKey; 577 } OT_TOOL_PACKED_END; 578 579 union HashKeys 580 { 581 Crypto::HmacSha256::Hash mHash; 582 Keys mKeys; 583 GetMleKey(void) const584 const Mle::Key &GetMleKey(void) const { return mKeys.mMleKey; } GetMacKey(void) const585 const Mac::Key &GetMacKey(void) const { return mKeys.mMacKey; } 586 }; 587 588 void ComputeKeys(uint32_t aKeySequence, HashKeys &aHashKeys) const; 589 590 #if OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE 591 void ComputeTrelKey(uint32_t aKeySequence, Mac::Key &aKey) const; 592 #endif 593 594 void StartKeyRotationTimer(void); 595 void HandleKeyRotationTimer(void); 596 597 #if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE 598 void StoreNetworkKey(const NetworkKey &aNetworkKey, bool aOverWriteExisting); 599 void StorePskc(const Pskc &aPskc); 600 #endif 601 602 void ResetFrameCounters(void); 603 604 using RotationTimer = TimerMilliIn<KeyManager, &KeyManager::HandleKeyRotationTimer>; 605 606 static const uint8_t kThreadString[]; 607 608 #if OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE 609 static const uint8_t kHkdfExtractSaltString[]; 610 static const uint8_t kTrelInfoString[]; 611 #endif 612 613 #if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE 614 NetworkKeyRef mNetworkKeyRef; 615 #else 616 NetworkKey mNetworkKey; 617 #endif 618 619 uint32_t mKeySequence; 620 Mle::KeyMaterial mMleKey; 621 Mle::KeyMaterial mTemporaryMleKey; 622 623 #if OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE 624 Mac::KeyMaterial mTrelKey; 625 Mac::KeyMaterial mTemporaryTrelKey; 626 #endif 627 628 Mac::LinkFrameCounters mMacFrameCounters; 629 uint32_t mMleFrameCounter; 630 uint32_t mStoredMacFrameCounter; 631 uint32_t mStoredMleFrameCounter; 632 633 uint32_t mHoursSinceKeyRotation; 634 uint32_t mKeySwitchGuardTime; 635 bool mKeySwitchGuardEnabled; 636 RotationTimer mKeyRotationTimer; 637 638 #if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE 639 PskcRef mPskcRef; 640 #else 641 Pskc mPskc; 642 #endif 643 644 KekKeyMaterial mKek; 645 uint32_t mKekFrameCounter; 646 647 SecurityPolicy mSecurityPolicy; 648 bool mIsPskcSet : 1; 649 }; 650 651 /** 652 * @} 653 */ 654 655 DefineCoreType(otSecurityPolicy, SecurityPolicy); 656 DefineCoreType(otNetworkKey, NetworkKey); 657 DefineCoreType(otPskc, Pskc); 658 659 } // namespace ot 660 661 #endif // KEY_MANAGER_HPP_ 662