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)257 NetworkKeyRef GetNetworkKeyRef(void) { 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)302 const PskcRef &GetPskcRef(void) { 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] aMacFrameCounter The MAC Frame Counter value. 405 * 406 */ 407 void SetAllMacFrameCounters(uint32_t aMacFrameCounter); 408 409 /** 410 * This method sets the MAC Frame Counter value which is stored in non-volatile memory. 411 * 412 * @param[in] aStoredMacFrameCounter The stored MAC Frame Counter value. 413 * 414 */ SetStoredMacFrameCounter(uint32_t aStoredMacFrameCounter)415 void SetStoredMacFrameCounter(uint32_t aStoredMacFrameCounter) { mStoredMacFrameCounter = aStoredMacFrameCounter; } 416 417 /** 418 * This method returns the current MLE Frame Counter value. 419 * 420 * @returns The current MLE Frame Counter value. 421 * 422 */ GetMleFrameCounter(void) const423 uint32_t GetMleFrameCounter(void) const { return mMleFrameCounter; } 424 425 /** 426 * This method sets the current MLE Frame Counter value. 427 * 428 * @param[in] aMleFrameCounter The MLE Frame Counter value. 429 * 430 */ SetMleFrameCounter(uint32_t aMleFrameCounter)431 void SetMleFrameCounter(uint32_t aMleFrameCounter) { mMleFrameCounter = aMleFrameCounter; } 432 433 /** 434 * This method sets the MLE Frame Counter value which is stored in non-volatile memory. 435 * 436 * @param[in] aStoredMleFrameCounter The stored MLE Frame Counter value. 437 * 438 */ SetStoredMleFrameCounter(uint32_t aStoredMleFrameCounter)439 void SetStoredMleFrameCounter(uint32_t aStoredMleFrameCounter) { mStoredMleFrameCounter = aStoredMleFrameCounter; } 440 441 /** 442 * This method increments the current MLE Frame Counter value. 443 * 444 */ 445 void IncrementMleFrameCounter(void); 446 447 /** 448 * This method returns the KEK as `KekKeyMaterail` 449 * 450 * @returns The KEK as `KekKeyMaterial`. 451 * 452 */ GetKek(void) const453 const KekKeyMaterial &GetKek(void) const { return mKek; } 454 455 /** 456 * This method retrieves the KEK as literal `Kek` key. 457 * 458 * @param[out] aKek A reference to a `Kek` to output the retrieved KEK. 459 * 460 */ ExtractKek(Kek & aKek)461 void ExtractKek(Kek &aKek) { mKek.ExtractKey(aKek); } 462 463 /** 464 * This method sets the KEK. 465 * 466 * @param[in] aKek A KEK. 467 * 468 */ 469 void SetKek(const Kek &aKek); 470 471 /** 472 * This method sets the KEK. 473 * 474 * @param[in] aKekBytes A pointer to the KEK bytes. 475 * 476 */ SetKek(const uint8_t * aKekBytes)477 void SetKek(const uint8_t *aKekBytes) { SetKek(*reinterpret_cast<const Kek *>(aKekBytes)); } 478 479 /** 480 * This method returns the current KEK Frame Counter value. 481 * 482 * @returns The current KEK Frame Counter value. 483 * 484 */ GetKekFrameCounter(void) const485 uint32_t GetKekFrameCounter(void) const { return mKekFrameCounter; } 486 487 /** 488 * This method increments the current KEK Frame Counter value. 489 * 490 */ IncrementKekFrameCounter(void)491 void IncrementKekFrameCounter(void) { mKekFrameCounter++; } 492 493 /** 494 * This method returns the KeySwitchGuardTime. 495 * 496 * The KeySwitchGuardTime is the time interval during which key rotation procedure is prevented. 497 * 498 * @returns The KeySwitchGuardTime value in hours. 499 * 500 */ GetKeySwitchGuardTime(void) const501 uint32_t GetKeySwitchGuardTime(void) const { return mKeySwitchGuardTime; } 502 503 /** 504 * This method sets the KeySwitchGuardTime. 505 * 506 * The KeySwitchGuardTime is the time interval during which key rotation procedure is prevented. 507 * 508 * @param[in] aKeySwitchGuardTime The KeySwitchGuardTime value in hours. 509 * 510 */ SetKeySwitchGuardTime(uint32_t aKeySwitchGuardTime)511 void SetKeySwitchGuardTime(uint32_t aKeySwitchGuardTime) { mKeySwitchGuardTime = aKeySwitchGuardTime; } 512 513 /** 514 * This method returns the Security Policy. 515 * 516 * The Security Policy specifies Key Rotation Time and network administrator preferences 517 * for which security-related operations are allowed or disallowed. 518 * 519 * @returns The SecurityPolicy. 520 * 521 */ GetSecurityPolicy(void) const522 const SecurityPolicy &GetSecurityPolicy(void) const { return mSecurityPolicy; } 523 524 /** 525 * This method sets the Security Policy. 526 * 527 * The Security Policy specifies Key Rotation Time and network administrator preferences 528 * for which security-related operations are allowed or disallowed. 529 * 530 * @param[in] aSecurityPolicy The Security Policy. 531 * 532 */ 533 void SetSecurityPolicy(const SecurityPolicy &aSecurityPolicy); 534 535 /** 536 * This method updates the MAC keys and MLE key. 537 * 538 */ 539 void UpdateKeyMaterial(void); 540 541 /** 542 * This method handles MAC frame counter changes (callback from `SubMac` for 15.4 security frame change). 543 * 544 * This is called to indicate the @p aMacFrameCounter value is now used. 545 * 546 * @param[in] aMacFrameCounter The 15.4 link MAC frame counter value. 547 * 548 */ 549 void MacFrameCounterUsed(uint32_t aMacFrameCounter); 550 551 private: 552 static constexpr uint32_t kDefaultKeySwitchGuardTime = 624; 553 static constexpr uint32_t kOneHourIntervalInMsec = 3600u * 1000u; 554 static constexpr bool kExportableMacKeys = OPENTHREAD_CONFIG_PLATFORM_MAC_KEYS_EXPORTABLE_ENABLE; 555 556 OT_TOOL_PACKED_BEGIN 557 struct Keys 558 { 559 Mle::Key mMleKey; 560 Mac::Key mMacKey; 561 } OT_TOOL_PACKED_END; 562 563 union HashKeys 564 { 565 Crypto::HmacSha256::Hash mHash; 566 Keys mKeys; 567 GetMleKey(void) const568 const Mle::Key &GetMleKey(void) const { return mKeys.mMleKey; } GetMacKey(void) const569 const Mac::Key &GetMacKey(void) const { return mKeys.mMacKey; } 570 }; 571 572 void ComputeKeys(uint32_t aKeySequence, HashKeys &aHashKeys); 573 574 #if OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE 575 void ComputeTrelKey(uint32_t aKeySequence, Mac::Key &aKey); 576 #endif 577 578 void StartKeyRotationTimer(void); 579 static void HandleKeyRotationTimer(Timer &aTimer); 580 void HandleKeyRotationTimer(void); 581 582 #if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE 583 void StoreNetworkKey(const NetworkKey &aNetworkKey, bool aOverWriteExisting); 584 void StorePskc(const Pskc &aPskc); 585 #endif 586 587 void ResetFrameCounters(void); 588 589 static const uint8_t kThreadString[]; 590 591 #if OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE 592 static const uint8_t kHkdfExtractSaltString[]; 593 static const uint8_t kTrelInfoString[]; 594 #endif 595 596 #if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE 597 NetworkKeyRef mNetworkKeyRef; 598 #else 599 NetworkKey mNetworkKey; 600 #endif 601 602 uint32_t mKeySequence; 603 Mle::KeyMaterial mMleKey; 604 Mle::KeyMaterial mTemporaryMleKey; 605 606 #if OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE 607 Mac::KeyMaterial mTrelKey; 608 Mac::KeyMaterial mTemporaryTrelKey; 609 #endif 610 611 Mac::LinkFrameCounters mMacFrameCounters; 612 uint32_t mMleFrameCounter; 613 uint32_t mStoredMacFrameCounter; 614 uint32_t mStoredMleFrameCounter; 615 616 uint32_t mHoursSinceKeyRotation; 617 uint32_t mKeySwitchGuardTime; 618 bool mKeySwitchGuardEnabled; 619 TimerMilli mKeyRotationTimer; 620 621 #if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE 622 PskcRef mPskcRef; 623 #else 624 Pskc mPskc; 625 #endif 626 627 KekKeyMaterial mKek; 628 uint32_t mKekFrameCounter; 629 630 SecurityPolicy mSecurityPolicy; 631 bool mIsPskcSet : 1; 632 }; 633 634 /** 635 * @} 636 */ 637 638 DefineCoreType(otSecurityPolicy, SecurityPolicy); 639 DefineCoreType(otNetworkKey, NetworkKey); 640 DefineCoreType(otPskc, Pskc); 641 642 } // namespace ot 643 644 #endif // KEY_MANAGER_HPP_ 645