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 implements Thread security material generation.
32 */
33
34 #include "key_manager.hpp"
35
36 #include "common/code_utils.hpp"
37 #include "common/encoding.hpp"
38 #include "common/locator_getters.hpp"
39 #include "common/log.hpp"
40 #include "common/timer.hpp"
41 #include "crypto/hkdf_sha256.hpp"
42 #include "crypto/storage.hpp"
43 #include "instance/instance.hpp"
44 #include "thread/mle_router.hpp"
45 #include "thread/thread_netif.hpp"
46
47 namespace ot {
48
49 RegisterLogModule("KeyManager");
50
51 const uint8_t KeyManager::kThreadString[] = {
52 'T', 'h', 'r', 'e', 'a', 'd',
53 };
54
55 #if OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE
56 const uint8_t KeyManager::kHkdfExtractSaltString[] = {'T', 'h', 'r', 'e', 'a', 'd', 'S', 'e', 'q', 'u', 'e', 'n',
57 'c', 'e', 'M', 'a', 's', 't', 'e', 'r', 'K', 'e', 'y'};
58
59 const uint8_t KeyManager::kTrelInfoString[] = {'T', 'h', 'r', 'e', 'a', 'd', 'O', 'v', 'e',
60 'r', 'I', 'n', 'f', 'r', 'a', 'K', 'e', 'y'};
61 #endif
62
63 //---------------------------------------------------------------------------------------------------------------------
64 // SecurityPolicy
65
SetToDefault(void)66 void SecurityPolicy::SetToDefault(void)
67 {
68 Clear();
69 mRotationTime = kDefaultKeyRotationTime;
70 SetToDefaultFlags();
71 }
72
SetToDefaultFlags(void)73 void SecurityPolicy::SetToDefaultFlags(void)
74 {
75 mObtainNetworkKeyEnabled = true;
76 mNativeCommissioningEnabled = true;
77 mRoutersEnabled = true;
78 mExternalCommissioningEnabled = true;
79 mCommercialCommissioningEnabled = false;
80 mAutonomousEnrollmentEnabled = false;
81 mNetworkKeyProvisioningEnabled = false;
82 mTobleLinkEnabled = true;
83 mNonCcmRoutersEnabled = false;
84 mVersionThresholdForRouting = 0;
85 }
86
SetFlags(const uint8_t * aFlags,uint8_t aFlagsLength)87 void SecurityPolicy::SetFlags(const uint8_t *aFlags, uint8_t aFlagsLength)
88 {
89 OT_ASSERT(aFlagsLength > 0);
90
91 SetToDefaultFlags();
92
93 mObtainNetworkKeyEnabled = aFlags[0] & kObtainNetworkKeyMask;
94 mNativeCommissioningEnabled = aFlags[0] & kNativeCommissioningMask;
95 mRoutersEnabled = aFlags[0] & kRoutersMask;
96 mExternalCommissioningEnabled = aFlags[0] & kExternalCommissioningMask;
97 mCommercialCommissioningEnabled = (aFlags[0] & kCommercialCommissioningMask) == 0;
98 mAutonomousEnrollmentEnabled = (aFlags[0] & kAutonomousEnrollmentMask) == 0;
99 mNetworkKeyProvisioningEnabled = (aFlags[0] & kNetworkKeyProvisioningMask) == 0;
100
101 VerifyOrExit(aFlagsLength > sizeof(aFlags[0]));
102 mTobleLinkEnabled = aFlags[1] & kTobleLinkMask;
103 mNonCcmRoutersEnabled = (aFlags[1] & kNonCcmRoutersMask) == 0;
104 mVersionThresholdForRouting = aFlags[1] & kVersionThresholdForRoutingMask;
105
106 exit:
107 return;
108 }
109
GetFlags(uint8_t * aFlags,uint8_t aFlagsLength) const110 void SecurityPolicy::GetFlags(uint8_t *aFlags, uint8_t aFlagsLength) const
111 {
112 OT_ASSERT(aFlagsLength > 0);
113
114 memset(aFlags, 0, aFlagsLength);
115
116 if (mObtainNetworkKeyEnabled)
117 {
118 aFlags[0] |= kObtainNetworkKeyMask;
119 }
120
121 if (mNativeCommissioningEnabled)
122 {
123 aFlags[0] |= kNativeCommissioningMask;
124 }
125
126 if (mRoutersEnabled)
127 {
128 aFlags[0] |= kRoutersMask;
129 }
130
131 if (mExternalCommissioningEnabled)
132 {
133 aFlags[0] |= kExternalCommissioningMask;
134 }
135
136 if (!mCommercialCommissioningEnabled)
137 {
138 aFlags[0] |= kCommercialCommissioningMask;
139 }
140
141 if (!mAutonomousEnrollmentEnabled)
142 {
143 aFlags[0] |= kAutonomousEnrollmentMask;
144 }
145
146 if (!mNetworkKeyProvisioningEnabled)
147 {
148 aFlags[0] |= kNetworkKeyProvisioningMask;
149 }
150
151 VerifyOrExit(aFlagsLength > sizeof(aFlags[0]));
152
153 if (mTobleLinkEnabled)
154 {
155 aFlags[1] |= kTobleLinkMask;
156 }
157
158 if (!mNonCcmRoutersEnabled)
159 {
160 aFlags[1] |= kNonCcmRoutersMask;
161 }
162
163 aFlags[1] |= kReservedMask;
164 aFlags[1] |= mVersionThresholdForRouting;
165
166 exit:
167 return;
168 }
169
170 //---------------------------------------------------------------------------------------------------------------------
171 // KeyManager
172
KeyManager(Instance & aInstance)173 KeyManager::KeyManager(Instance &aInstance)
174 : InstanceLocator(aInstance)
175 , mKeySequence(0)
176 , mMleFrameCounter(0)
177 , mStoredMacFrameCounter(0)
178 , mStoredMleFrameCounter(0)
179 , mHoursSinceKeyRotation(0)
180 , mKeySwitchGuardTime(kDefaultKeySwitchGuardTime)
181 , mKeySwitchGuardTimer(0)
182 , mKeyRotationTimer(aInstance)
183 , mKekFrameCounter(0)
184 , mIsPskcSet(false)
185 {
186 otPlatCryptoInit();
187
188 #if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
189 {
190 NetworkKey networkKey;
191
192 mNetworkKeyRef = Crypto::Storage::kInvalidKeyRef;
193 mPskcRef = Crypto::Storage::kInvalidKeyRef;
194
195 IgnoreError(networkKey.GenerateRandom());
196 StoreNetworkKey(networkKey, /* aOverWriteExisting */ false);
197 }
198 #else
199 IgnoreError(mNetworkKey.GenerateRandom());
200 mPskc.Clear();
201 #endif
202
203 mMacFrameCounters.Reset();
204 }
205
Start(void)206 void KeyManager::Start(void)
207 {
208 mKeySwitchGuardTimer = 0;
209 ResetKeyRotationTimer();
210 }
211
Stop(void)212 void KeyManager::Stop(void) { mKeyRotationTimer.Stop(); }
213
SetPskc(const Pskc & aPskc)214 void KeyManager::SetPskc(const Pskc &aPskc)
215 {
216 #if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
217 if (Crypto::Storage::IsKeyRefValid(mPskcRef))
218 {
219 Pskc pskc;
220
221 GetPskc(pskc);
222 VerifyOrExit(aPskc != pskc, Get<Notifier>().SignalIfFirst(kEventPskcChanged));
223 }
224
225 StorePskc(aPskc);
226 Get<Notifier>().Signal(kEventPskcChanged);
227 #else
228 SuccessOrExit(Get<Notifier>().Update(mPskc, aPskc, kEventPskcChanged));
229 #endif
230
231 exit:
232 mIsPskcSet = true;
233 }
234
ResetFrameCounters(void)235 void KeyManager::ResetFrameCounters(void)
236 {
237 Router *parent;
238
239 // reset parent frame counters
240 parent = &Get<Mle::MleRouter>().GetParent();
241 parent->SetKeySequence(0);
242 parent->GetLinkFrameCounters().Reset();
243 parent->SetLinkAckFrameCounter(0);
244 parent->SetMleFrameCounter(0);
245
246 #if OPENTHREAD_FTD
247 // reset router frame counters
248 for (Router &router : Get<RouterTable>())
249 {
250 router.SetKeySequence(0);
251 router.GetLinkFrameCounters().Reset();
252 router.SetLinkAckFrameCounter(0);
253 router.SetMleFrameCounter(0);
254 }
255
256 // reset child frame counters
257 for (Child &child : Get<ChildTable>().Iterate(Child::kInStateAnyExceptInvalid))
258 {
259 child.SetKeySequence(0);
260 child.GetLinkFrameCounters().Reset();
261 child.SetLinkAckFrameCounter(0);
262 child.SetMleFrameCounter(0);
263 }
264 #endif
265 }
266
SetNetworkKey(const NetworkKey & aNetworkKey)267 void KeyManager::SetNetworkKey(const NetworkKey &aNetworkKey)
268 {
269 #if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
270 if (Crypto::Storage::IsKeyRefValid(mNetworkKeyRef))
271 {
272 NetworkKey networkKey;
273
274 GetNetworkKey(networkKey);
275 VerifyOrExit(networkKey != aNetworkKey, Get<Notifier>().SignalIfFirst(kEventNetworkKeyChanged));
276 }
277
278 StoreNetworkKey(aNetworkKey, /* aOverWriteExisting */ true);
279 Get<Notifier>().Signal(kEventNetworkKeyChanged);
280 #else
281 SuccessOrExit(Get<Notifier>().Update(mNetworkKey, aNetworkKey, kEventNetworkKeyChanged));
282 #endif
283
284 Get<Notifier>().Signal(kEventThreadKeySeqCounterChanged);
285
286 mKeySequence = 0;
287 UpdateKeyMaterial();
288 ResetFrameCounters();
289
290 exit:
291 return;
292 }
293
ComputeKeys(uint32_t aKeySequence,HashKeys & aHashKeys) const294 void KeyManager::ComputeKeys(uint32_t aKeySequence, HashKeys &aHashKeys) const
295 {
296 Crypto::HmacSha256 hmac;
297 uint8_t keySequenceBytes[sizeof(uint32_t)];
298 Crypto::Key cryptoKey;
299
300 #if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
301 cryptoKey.SetAsKeyRef(mNetworkKeyRef);
302 #else
303 cryptoKey.Set(mNetworkKey.m8, NetworkKey::kSize);
304 #endif
305
306 hmac.Start(cryptoKey);
307
308 BigEndian::WriteUint32(aKeySequence, keySequenceBytes);
309 hmac.Update(keySequenceBytes);
310 hmac.Update(kThreadString);
311
312 hmac.Finish(aHashKeys.mHash);
313 }
314
315 #if OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE
ComputeTrelKey(uint32_t aKeySequence,Mac::Key & aKey) const316 void KeyManager::ComputeTrelKey(uint32_t aKeySequence, Mac::Key &aKey) const
317 {
318 Crypto::HkdfSha256 hkdf;
319 uint8_t salt[sizeof(uint32_t) + sizeof(kHkdfExtractSaltString)];
320 Crypto::Key cryptoKey;
321
322 #if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
323 cryptoKey.SetAsKeyRef(mNetworkKeyRef);
324 #else
325 cryptoKey.Set(mNetworkKey.m8, NetworkKey::kSize);
326 #endif
327
328 BigEndian::WriteUint32(aKeySequence, salt);
329 memcpy(salt + sizeof(uint32_t), kHkdfExtractSaltString, sizeof(kHkdfExtractSaltString));
330
331 hkdf.Extract(salt, sizeof(salt), cryptoKey);
332 hkdf.Expand(kTrelInfoString, sizeof(kTrelInfoString), aKey.m8, Mac::Key::kSize);
333 }
334 #endif
335
UpdateKeyMaterial(void)336 void KeyManager::UpdateKeyMaterial(void)
337 {
338 HashKeys hashKeys;
339
340 ComputeKeys(mKeySequence, hashKeys);
341
342 mMleKey.SetFrom(hashKeys.GetMleKey());
343
344 #if OPENTHREAD_CONFIG_RADIO_LINK_IEEE_802_15_4_ENABLE
345 {
346 Mac::KeyMaterial curKey;
347 Mac::KeyMaterial prevKey;
348 Mac::KeyMaterial nextKey;
349
350 curKey.SetFrom(hashKeys.GetMacKey(), kExportableMacKeys);
351
352 ComputeKeys(mKeySequence - 1, hashKeys);
353 prevKey.SetFrom(hashKeys.GetMacKey(), kExportableMacKeys);
354
355 ComputeKeys(mKeySequence + 1, hashKeys);
356 nextKey.SetFrom(hashKeys.GetMacKey(), kExportableMacKeys);
357
358 Get<Mac::SubMac>().SetMacKey(Mac::Frame::kKeyIdMode1, (mKeySequence & 0x7f) + 1, prevKey, curKey, nextKey);
359 }
360 #endif
361
362 #if OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE
363 {
364 Mac::Key key;
365
366 ComputeTrelKey(mKeySequence, key);
367 mTrelKey.SetFrom(key);
368 }
369 #endif
370 }
371
SetCurrentKeySequence(uint32_t aKeySequence,KeySeqUpdateFlags aFlags)372 void KeyManager::SetCurrentKeySequence(uint32_t aKeySequence, KeySeqUpdateFlags aFlags)
373 {
374 VerifyOrExit(aKeySequence != mKeySequence, Get<Notifier>().SignalIfFirst(kEventThreadKeySeqCounterChanged));
375
376 if (aFlags & kApplySwitchGuard)
377 {
378 VerifyOrExit(mKeySwitchGuardTimer == 0);
379 }
380
381 mKeySequence = aKeySequence;
382 UpdateKeyMaterial();
383
384 SetAllMacFrameCounters(0, /* aSetIfLarger */ false);
385 mMleFrameCounter = 0;
386
387 ResetKeyRotationTimer();
388
389 if (aFlags & kResetGuardTimer)
390 {
391 mKeySwitchGuardTimer = mKeySwitchGuardTime;
392 }
393
394 Get<Notifier>().Signal(kEventThreadKeySeqCounterChanged);
395
396 exit:
397 return;
398 }
399
GetTemporaryMleKey(uint32_t aKeySequence)400 const Mle::KeyMaterial &KeyManager::GetTemporaryMleKey(uint32_t aKeySequence)
401 {
402 HashKeys hashKeys;
403
404 ComputeKeys(aKeySequence, hashKeys);
405 mTemporaryMleKey.SetFrom(hashKeys.GetMleKey());
406
407 return mTemporaryMleKey;
408 }
409
410 #if OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE
GetTemporaryTrelMacKey(uint32_t aKeySequence)411 const Mac::KeyMaterial &KeyManager::GetTemporaryTrelMacKey(uint32_t aKeySequence)
412 {
413 Mac::Key key;
414
415 ComputeTrelKey(aKeySequence, key);
416 mTemporaryTrelKey.SetFrom(key);
417
418 return mTemporaryTrelKey;
419 }
420 #endif
421
SetAllMacFrameCounters(uint32_t aFrameCounter,bool aSetIfLarger)422 void KeyManager::SetAllMacFrameCounters(uint32_t aFrameCounter, bool aSetIfLarger)
423 {
424 mMacFrameCounters.SetAll(aFrameCounter);
425
426 #if OPENTHREAD_CONFIG_RADIO_LINK_IEEE_802_15_4_ENABLE
427 Get<Mac::SubMac>().SetFrameCounter(aFrameCounter, aSetIfLarger);
428 #else
429 OT_UNUSED_VARIABLE(aSetIfLarger);
430 #endif
431 }
432
433 #if OPENTHREAD_CONFIG_RADIO_LINK_IEEE_802_15_4_ENABLE
MacFrameCounterUsed(uint32_t aMacFrameCounter)434 void KeyManager::MacFrameCounterUsed(uint32_t aMacFrameCounter)
435 {
436 // This is callback from `SubMac` to indicate that a frame
437 // counter value is used for tx. We ensure to handle it
438 // even if it is called out of order.
439
440 VerifyOrExit(mMacFrameCounters.Get154() <= aMacFrameCounter);
441
442 mMacFrameCounters.Set154(aMacFrameCounter + 1);
443
444 if (mMacFrameCounters.Get154() >= mStoredMacFrameCounter)
445 {
446 IgnoreError(Get<Mle::MleRouter>().Store());
447 }
448
449 exit:
450 return;
451 }
452 #else
MacFrameCounterUsed(uint32_t)453 void KeyManager::MacFrameCounterUsed(uint32_t) {}
454 #endif
455
456 #if OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE
IncrementTrelMacFrameCounter(void)457 void KeyManager::IncrementTrelMacFrameCounter(void)
458 {
459 mMacFrameCounters.IncrementTrel();
460
461 if (mMacFrameCounters.GetTrel() >= mStoredMacFrameCounter)
462 {
463 IgnoreError(Get<Mle::MleRouter>().Store());
464 }
465 }
466 #endif
467
IncrementMleFrameCounter(void)468 void KeyManager::IncrementMleFrameCounter(void)
469 {
470 mMleFrameCounter++;
471
472 if (mMleFrameCounter >= mStoredMleFrameCounter)
473 {
474 IgnoreError(Get<Mle::MleRouter>().Store());
475 }
476 }
477
SetKek(const Kek & aKek)478 void KeyManager::SetKek(const Kek &aKek)
479 {
480 mKek.SetFrom(aKek, /* aIsExportable */ true);
481 mKekFrameCounter = 0;
482 }
483
SetSecurityPolicy(const SecurityPolicy & aSecurityPolicy)484 void KeyManager::SetSecurityPolicy(const SecurityPolicy &aSecurityPolicy)
485 {
486 SecurityPolicy newPolicy = aSecurityPolicy;
487
488 if (newPolicy.mRotationTime < SecurityPolicy::kMinKeyRotationTime)
489 {
490 newPolicy.mRotationTime = SecurityPolicy::kMinKeyRotationTime;
491 LogNote("Key Rotation Time in SecurityPolicy is set to min allowed value of %u", newPolicy.mRotationTime);
492 }
493
494 if (newPolicy.mRotationTime != mSecurityPolicy.mRotationTime)
495 {
496 uint32_t newGuardTime = newPolicy.mRotationTime;
497
498 // Calculations are done using a `uint32_t` variable to prevent
499 // potential overflow.
500
501 newGuardTime *= kKeySwitchGuardTimePercentage;
502 newGuardTime /= 100;
503
504 mKeySwitchGuardTime = static_cast<uint16_t>(newGuardTime);
505 }
506
507 IgnoreError(Get<Notifier>().Update(mSecurityPolicy, newPolicy, kEventSecurityPolicyChanged));
508
509 CheckForKeyRotation();
510 }
511
ResetKeyRotationTimer(void)512 void KeyManager::ResetKeyRotationTimer(void)
513 {
514 mHoursSinceKeyRotation = 0;
515 mKeyRotationTimer.Start(Time::kOneHourInMsec);
516 }
517
HandleKeyRotationTimer(void)518 void KeyManager::HandleKeyRotationTimer(void)
519 {
520 mKeyRotationTimer.Start(Time::kOneHourInMsec);
521
522 mHoursSinceKeyRotation++;
523
524 if (mKeySwitchGuardTimer > 0)
525 {
526 mKeySwitchGuardTimer--;
527 }
528
529 CheckForKeyRotation();
530 }
531
CheckForKeyRotation(void)532 void KeyManager::CheckForKeyRotation(void)
533 {
534 if (mHoursSinceKeyRotation >= mSecurityPolicy.mRotationTime)
535 {
536 SetCurrentKeySequence(mKeySequence + 1, kForceUpdate | kResetGuardTimer);
537 }
538 }
539
GetNetworkKey(NetworkKey & aNetworkKey) const540 void KeyManager::GetNetworkKey(NetworkKey &aNetworkKey) const
541 {
542 #if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
543 if (Crypto::Storage::HasKey(mNetworkKeyRef))
544 {
545 size_t keyLen;
546
547 SuccessOrAssert(Crypto::Storage::ExportKey(mNetworkKeyRef, aNetworkKey.m8, NetworkKey::kSize, keyLen));
548 OT_ASSERT(keyLen == NetworkKey::kSize);
549 }
550 else
551 {
552 aNetworkKey.Clear();
553 }
554 #else
555 aNetworkKey = mNetworkKey;
556 #endif
557 }
558
GetPskc(Pskc & aPskc) const559 void KeyManager::GetPskc(Pskc &aPskc) const
560 {
561 #if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
562 if (Crypto::Storage::HasKey(mPskcRef))
563 {
564 size_t keyLen;
565
566 SuccessOrAssert(Crypto::Storage::ExportKey(mPskcRef, aPskc.m8, Pskc::kSize, keyLen));
567 OT_ASSERT(keyLen == Pskc::kSize);
568 }
569 else
570 {
571 aPskc.Clear();
572 }
573 #else
574 aPskc = mPskc;
575 #endif
576 }
577
578 #if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
579
StoreNetworkKey(const NetworkKey & aNetworkKey,bool aOverWriteExisting)580 void KeyManager::StoreNetworkKey(const NetworkKey &aNetworkKey, bool aOverWriteExisting)
581 {
582 NetworkKeyRef keyRef;
583
584 keyRef = Crypto::Storage::kNetworkKeyRef;
585
586 if (!aOverWriteExisting)
587 {
588 // Check if there is already a network key stored in ITS. If
589 // stored, and we are not overwriting the existing key,
590 // return without doing anything.
591 if (Crypto::Storage::HasKey(keyRef))
592 {
593 ExitNow();
594 }
595 }
596
597 Crypto::Storage::DestroyKey(keyRef);
598
599 SuccessOrAssert(Crypto::Storage::ImportKey(keyRef, Crypto::Storage::kKeyTypeHmac,
600 Crypto::Storage::kKeyAlgorithmHmacSha256,
601 Crypto::Storage::kUsageSignHash | Crypto::Storage::kUsageExport,
602 Crypto::Storage::kTypePersistent, aNetworkKey.m8, NetworkKey::kSize));
603
604 exit:
605 if (mNetworkKeyRef != keyRef)
606 {
607 Crypto::Storage::DestroyKey(mNetworkKeyRef);
608 }
609
610 mNetworkKeyRef = keyRef;
611 }
612
StorePskc(const Pskc & aPskc)613 void KeyManager::StorePskc(const Pskc &aPskc)
614 {
615 PskcRef keyRef = Crypto::Storage::kPskcRef;
616
617 Crypto::Storage::DestroyKey(keyRef);
618
619 SuccessOrAssert(Crypto::Storage::ImportKey(keyRef, Crypto::Storage::kKeyTypeRaw,
620 Crypto::Storage::kKeyAlgorithmVendor, Crypto::Storage::kUsageExport,
621 Crypto::Storage::kTypePersistent, aPskc.m8, Pskc::kSize));
622
623 if (mPskcRef != keyRef)
624 {
625 Crypto::Storage::DestroyKey(mPskcRef);
626 }
627
628 mPskcRef = keyRef;
629 }
630
SetPskcRef(PskcRef aKeyRef)631 void KeyManager::SetPskcRef(PskcRef aKeyRef)
632 {
633 VerifyOrExit(mPskcRef != aKeyRef, Get<Notifier>().SignalIfFirst(kEventPskcChanged));
634
635 Crypto::Storage::DestroyKey(mPskcRef);
636
637 mPskcRef = aKeyRef;
638 Get<Notifier>().Signal(kEventPskcChanged);
639
640 exit:
641 mIsPskcSet = true;
642 }
643
SetNetworkKeyRef(otNetworkKeyRef aKeyRef)644 void KeyManager::SetNetworkKeyRef(otNetworkKeyRef aKeyRef)
645 {
646 VerifyOrExit(mNetworkKeyRef != aKeyRef, Get<Notifier>().SignalIfFirst(kEventNetworkKeyChanged));
647
648 Crypto::Storage::DestroyKey(mNetworkKeyRef);
649
650 mNetworkKeyRef = aKeyRef;
651 Get<Notifier>().Signal(kEventNetworkKeyChanged);
652 Get<Notifier>().Signal(kEventThreadKeySeqCounterChanged);
653 mKeySequence = 0;
654 UpdateKeyMaterial();
655 ResetFrameCounters();
656
657 exit:
658 return;
659 }
660
DestroyTemporaryKeys(void)661 void KeyManager::DestroyTemporaryKeys(void)
662 {
663 mMleKey.Clear();
664 mKek.Clear();
665 Get<Mac::SubMac>().ClearMacKeys();
666 Get<Mac::Mac>().ClearMode2Key();
667 }
668
DestroyPersistentKeys(void)669 void KeyManager::DestroyPersistentKeys(void) { Crypto::Storage::DestroyPersistentKeys(); }
670 #endif // OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
671
672 } // namespace ot
673