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