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