• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/instance.hpp"
39 #include "common/locator_getters.hpp"
40 #include "common/log.hpp"
41 #include "common/timer.hpp"
42 #include "crypto/hkdf_sha256.hpp"
43 #include "crypto/storage.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, KeyManager::HandleKeyRotationTimer)
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)
206 {
207     mKeyRotationTimer.Stop();
208 }
209 
SetPskc(const Pskc & aPskc)210 void KeyManager::SetPskc(const Pskc &aPskc)
211 {
212 #if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
213     if (Crypto::Storage::IsKeyRefValid(mPskcRef))
214     {
215         Pskc pskc;
216 
217         GetPskc(pskc);
218         VerifyOrExit(aPskc != pskc, Get<Notifier>().SignalIfFirst(kEventPskcChanged));
219     }
220 
221     StorePskc(aPskc);
222     Get<Notifier>().Signal(kEventPskcChanged);
223 #else
224     SuccessOrExit(Get<Notifier>().Update(mPskc, aPskc, kEventPskcChanged));
225 #endif
226 
227 exit:
228     mIsPskcSet = true;
229 }
230 
ResetFrameCounters(void)231 void KeyManager::ResetFrameCounters(void)
232 {
233     Router *parent;
234 
235     // reset parent frame counters
236     parent = &Get<Mle::MleRouter>().GetParent();
237     parent->SetKeySequence(0);
238     parent->GetLinkFrameCounters().Reset();
239     parent->SetLinkAckFrameCounter(0);
240     parent->SetMleFrameCounter(0);
241 
242 #if OPENTHREAD_FTD
243     // reset router frame counters
244     for (Router &router : Get<RouterTable>().Iterate())
245     {
246         router.SetKeySequence(0);
247         router.GetLinkFrameCounters().Reset();
248         router.SetLinkAckFrameCounter(0);
249         router.SetMleFrameCounter(0);
250     }
251 
252     // reset child frame counters
253     for (Child &child : Get<ChildTable>().Iterate(Child::kInStateAnyExceptInvalid))
254     {
255         child.SetKeySequence(0);
256         child.GetLinkFrameCounters().Reset();
257         child.SetLinkAckFrameCounter(0);
258         child.SetMleFrameCounter(0);
259     }
260 #endif
261 }
262 
SetNetworkKey(const NetworkKey & aNetworkKey)263 void KeyManager::SetNetworkKey(const NetworkKey &aNetworkKey)
264 {
265 #if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
266     if (Crypto::Storage::IsKeyRefValid(mNetworkKeyRef))
267     {
268         NetworkKey networkKey;
269 
270         GetNetworkKey(networkKey);
271         VerifyOrExit(networkKey != aNetworkKey, Get<Notifier>().SignalIfFirst(kEventNetworkKeyChanged));
272     }
273 
274     StoreNetworkKey(aNetworkKey, /* aOverWriteExisting */ true);
275     Get<Notifier>().Signal(kEventNetworkKeyChanged);
276 #else
277     SuccessOrExit(Get<Notifier>().Update(mNetworkKey, aNetworkKey, kEventNetworkKeyChanged));
278 #endif
279 
280     Get<Notifier>().Signal(kEventThreadKeySeqCounterChanged);
281 
282     mKeySequence = 0;
283     UpdateKeyMaterial();
284     ResetFrameCounters();
285 
286 exit:
287     return;
288 }
289 
ComputeKeys(uint32_t aKeySequence,HashKeys & aHashKeys)290 void KeyManager::ComputeKeys(uint32_t aKeySequence, HashKeys &aHashKeys)
291 {
292     Crypto::HmacSha256 hmac;
293     uint8_t            keySequenceBytes[sizeof(uint32_t)];
294     Crypto::Key        cryptoKey;
295 
296 #if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
297     cryptoKey.SetAsKeyRef(mNetworkKeyRef);
298 #else
299     cryptoKey.Set(mNetworkKey.m8, NetworkKey::kSize);
300 #endif
301 
302     hmac.Start(cryptoKey);
303 
304     Encoding::BigEndian::WriteUint32(aKeySequence, keySequenceBytes);
305     hmac.Update(keySequenceBytes);
306     hmac.Update(kThreadString);
307 
308     hmac.Finish(aHashKeys.mHash);
309 }
310 
311 #if OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE
ComputeTrelKey(uint32_t aKeySequence,Mac::Key & aKey)312 void KeyManager::ComputeTrelKey(uint32_t aKeySequence, Mac::Key &aKey)
313 {
314     Crypto::HkdfSha256 hkdf;
315     uint8_t            salt[sizeof(uint32_t) + sizeof(kHkdfExtractSaltString)];
316     Crypto::Key        cryptoKey;
317 
318 #if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
319     cryptoKey.SetAsKeyRef(mNetworkKeyRef);
320 #else
321     cryptoKey.Set(mNetworkKey.m8, NetworkKey::kSize);
322 #endif
323 
324     Encoding::BigEndian::WriteUint32(aKeySequence, salt);
325     memcpy(salt + sizeof(uint32_t), kHkdfExtractSaltString, sizeof(kHkdfExtractSaltString));
326 
327     hkdf.Extract(salt, sizeof(salt), cryptoKey);
328     hkdf.Expand(kTrelInfoString, sizeof(kTrelInfoString), aKey.m8, Mac::Key::kSize);
329 }
330 #endif
331 
UpdateKeyMaterial(void)332 void KeyManager::UpdateKeyMaterial(void)
333 {
334     HashKeys hashKeys;
335 
336     ComputeKeys(mKeySequence, hashKeys);
337 
338     mMleKey.SetFrom(hashKeys.GetMleKey());
339 
340 #if OPENTHREAD_CONFIG_RADIO_LINK_IEEE_802_15_4_ENABLE
341     {
342         Mac::KeyMaterial curKey;
343         Mac::KeyMaterial prevKey;
344         Mac::KeyMaterial nextKey;
345 
346         curKey.SetFrom(hashKeys.GetMacKey(), kExportableMacKeys);
347 
348         ComputeKeys(mKeySequence - 1, hashKeys);
349         prevKey.SetFrom(hashKeys.GetMacKey(), kExportableMacKeys);
350 
351         ComputeKeys(mKeySequence + 1, hashKeys);
352         nextKey.SetFrom(hashKeys.GetMacKey(), kExportableMacKeys);
353 
354         Get<Mac::SubMac>().SetMacKey(Mac::Frame::kKeyIdMode1, (mKeySequence & 0x7f) + 1, prevKey, curKey, nextKey);
355     }
356 #endif
357 
358 #if OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE
359     {
360         Mac::Key key;
361 
362         ComputeTrelKey(mKeySequence, key);
363         mTrelKey.SetFrom(key);
364     }
365 #endif
366 }
367 
SetCurrentKeySequence(uint32_t aKeySequence)368 void KeyManager::SetCurrentKeySequence(uint32_t aKeySequence)
369 {
370     VerifyOrExit(aKeySequence != mKeySequence, Get<Notifier>().SignalIfFirst(kEventThreadKeySeqCounterChanged));
371 
372     if ((aKeySequence == (mKeySequence + 1)) && mKeyRotationTimer.IsRunning())
373     {
374         if (mKeySwitchGuardEnabled)
375         {
376             // Check if the guard timer has expired if key rotation is requested.
377             VerifyOrExit(mHoursSinceKeyRotation >= mKeySwitchGuardTime);
378             StartKeyRotationTimer();
379         }
380 
381         mKeySwitchGuardEnabled = true;
382     }
383 
384     mKeySequence = aKeySequence;
385     UpdateKeyMaterial();
386 
387     SetAllMacFrameCounters(0);
388     mMleFrameCounter = 0;
389 
390     Get<Notifier>().Signal(kEventThreadKeySeqCounterChanged);
391 
392 exit:
393     return;
394 }
395 
GetTemporaryMleKey(uint32_t aKeySequence)396 const Mle::KeyMaterial &KeyManager::GetTemporaryMleKey(uint32_t aKeySequence)
397 {
398     HashKeys hashKeys;
399 
400     ComputeKeys(aKeySequence, hashKeys);
401     mTemporaryMleKey.SetFrom(hashKeys.GetMleKey());
402 
403     return mTemporaryMleKey;
404 }
405 
406 #if OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE
GetTemporaryTrelMacKey(uint32_t aKeySequence)407 const Mac::KeyMaterial &KeyManager::GetTemporaryTrelMacKey(uint32_t aKeySequence)
408 {
409     Mac::Key key;
410 
411     ComputeTrelKey(aKeySequence, key);
412     mTemporaryTrelKey.SetFrom(key);
413 
414     return mTemporaryTrelKey;
415 }
416 #endif
417 
SetAllMacFrameCounters(uint32_t aMacFrameCounter)418 void KeyManager::SetAllMacFrameCounters(uint32_t aMacFrameCounter)
419 {
420     mMacFrameCounters.SetAll(aMacFrameCounter);
421 
422 #if OPENTHREAD_CONFIG_RADIO_LINK_IEEE_802_15_4_ENABLE
423     Get<Mac::SubMac>().SetFrameCounter(aMacFrameCounter);
424 #endif
425 }
426 
427 #if OPENTHREAD_CONFIG_RADIO_LINK_IEEE_802_15_4_ENABLE
MacFrameCounterUsed(uint32_t aMacFrameCounter)428 void KeyManager::MacFrameCounterUsed(uint32_t aMacFrameCounter)
429 {
430     // This is callback from `SubMac` to indicate that a frame
431     // counter value is used for tx. We ensure to handle it
432     // even if it is called out of order.
433 
434     VerifyOrExit(mMacFrameCounters.Get154() <= aMacFrameCounter);
435 
436     mMacFrameCounters.Set154(aMacFrameCounter + 1);
437 
438     if (mMacFrameCounters.Get154() >= mStoredMacFrameCounter)
439     {
440         IgnoreError(Get<Mle::MleRouter>().Store());
441     }
442 
443 exit:
444     return;
445 }
446 #else
MacFrameCounterUsed(uint32_t)447 void KeyManager::MacFrameCounterUsed(uint32_t)
448 {
449 }
450 #endif
451 
452 #if OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE
IncrementTrelMacFrameCounter(void)453 void KeyManager::IncrementTrelMacFrameCounter(void)
454 {
455     mMacFrameCounters.IncrementTrel();
456 
457     if (mMacFrameCounters.GetTrel() >= mStoredMacFrameCounter)
458     {
459         IgnoreError(Get<Mle::MleRouter>().Store());
460     }
461 }
462 #endif
463 
IncrementMleFrameCounter(void)464 void KeyManager::IncrementMleFrameCounter(void)
465 {
466     mMleFrameCounter++;
467 
468     if (mMleFrameCounter >= mStoredMleFrameCounter)
469     {
470         IgnoreError(Get<Mle::MleRouter>().Store());
471     }
472 }
473 
SetKek(const Kek & aKek)474 void KeyManager::SetKek(const Kek &aKek)
475 {
476     mKek.SetFrom(aKek, /* aIsExportable */ true);
477     mKekFrameCounter = 0;
478 }
479 
SetSecurityPolicy(const SecurityPolicy & aSecurityPolicy)480 void KeyManager::SetSecurityPolicy(const SecurityPolicy &aSecurityPolicy)
481 {
482     if (aSecurityPolicy.mRotationTime < SecurityPolicy::kMinKeyRotationTime)
483     {
484         LogNote("Key Rotation Time too small: %d", aSecurityPolicy.mRotationTime);
485         ExitNow();
486     }
487 
488     IgnoreError(Get<Notifier>().Update(mSecurityPolicy, aSecurityPolicy, kEventSecurityPolicyChanged));
489 
490 exit:
491     return;
492 }
493 
StartKeyRotationTimer(void)494 void KeyManager::StartKeyRotationTimer(void)
495 {
496     mHoursSinceKeyRotation = 0;
497     mKeyRotationTimer.Start(kOneHourIntervalInMsec);
498 }
499 
HandleKeyRotationTimer(Timer & aTimer)500 void KeyManager::HandleKeyRotationTimer(Timer &aTimer)
501 {
502     aTimer.Get<KeyManager>().HandleKeyRotationTimer();
503 }
504 
HandleKeyRotationTimer(void)505 void KeyManager::HandleKeyRotationTimer(void)
506 {
507     mHoursSinceKeyRotation++;
508 
509     // Order of operations below is important. We should restart the timer (from
510     // last fire time for one hour interval) before potentially calling
511     // `SetCurrentKeySequence()`. `SetCurrentKeySequence()` uses the fact that
512     // timer is running to decide to check for the guard time and to reset the
513     // rotation timer (and the `mHoursSinceKeyRotation`) if it updates the key
514     // sequence.
515 
516     mKeyRotationTimer.StartAt(mKeyRotationTimer.GetFireTime(), kOneHourIntervalInMsec);
517 
518     if (mHoursSinceKeyRotation >= mSecurityPolicy.mRotationTime)
519     {
520         SetCurrentKeySequence(mKeySequence + 1);
521     }
522 }
523 
GetNetworkKey(NetworkKey & aNetworkKey) const524 void KeyManager::GetNetworkKey(NetworkKey &aNetworkKey) const
525 {
526 #if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
527     if (Crypto::Storage::IsKeyRefValid(mNetworkKeyRef))
528     {
529         size_t keyLen;
530 
531         SuccessOrAssert(Crypto::Storage::ExportKey(mNetworkKeyRef, aNetworkKey.m8, NetworkKey::kSize, keyLen));
532         OT_ASSERT(keyLen == NetworkKey::kSize);
533     }
534     else
535     {
536         aNetworkKey.Clear();
537     }
538 #else
539     aNetworkKey = mNetworkKey;
540 #endif
541 }
542 
GetPskc(Pskc & aPskc) const543 void KeyManager::GetPskc(Pskc &aPskc) const
544 {
545 #if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
546     if (Crypto::Storage::IsKeyRefValid(mPskcRef))
547     {
548         size_t keyLen;
549 
550         SuccessOrAssert(Crypto::Storage::ExportKey(mPskcRef, aPskc.m8, Pskc::kSize, keyLen));
551         OT_ASSERT(keyLen == Pskc::kSize);
552     }
553     else
554     {
555         aPskc.Clear();
556     }
557 #else
558     aPskc = mPskc;
559 #endif
560 }
561 
562 #if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
563 
StoreNetworkKey(const NetworkKey & aNetworkKey,bool aOverWriteExisting)564 void KeyManager::StoreNetworkKey(const NetworkKey &aNetworkKey, bool aOverWriteExisting)
565 {
566     NetworkKeyRef keyRef;
567 
568     keyRef = Crypto::Storage::kNetworkKeyRef;
569 
570     if (!aOverWriteExisting)
571     {
572         // Check if there is already a network key stored in ITS. If
573         // stored, and we are not overwriting the existing key,
574         // return without doing anything.
575         if (Crypto::Storage::HasKey(keyRef))
576         {
577             ExitNow();
578         }
579     }
580 
581     Crypto::Storage::DestroyKey(keyRef);
582 
583     SuccessOrAssert(Crypto::Storage::ImportKey(keyRef, Crypto::Storage::kKeyTypeHmac,
584                                                Crypto::Storage::kKeyAlgorithmHmacSha256,
585                                                Crypto::Storage::kUsageSignHash | Crypto::Storage::kUsageExport,
586                                                Crypto::Storage::kTypePersistent, aNetworkKey.m8, NetworkKey::kSize));
587 
588 exit:
589     if (mNetworkKeyRef != keyRef)
590     {
591         Crypto::Storage::DestroyKey(mNetworkKeyRef);
592     }
593 
594     mNetworkKeyRef = keyRef;
595 }
596 
StorePskc(const Pskc & aPskc)597 void KeyManager::StorePskc(const Pskc &aPskc)
598 {
599     PskcRef keyRef = Crypto::Storage::kPskcRef;
600 
601     Crypto::Storage::DestroyKey(keyRef);
602 
603     SuccessOrAssert(Crypto::Storage::ImportKey(keyRef, Crypto::Storage::kKeyTypeRaw,
604                                                Crypto::Storage::kKeyAlgorithmVendor, Crypto::Storage::kUsageExport,
605                                                Crypto::Storage::kTypePersistent, aPskc.m8, Pskc::kSize));
606 
607     if (mPskcRef != keyRef)
608     {
609         Crypto::Storage::DestroyKey(mPskcRef);
610     }
611 
612     mPskcRef = keyRef;
613 }
614 
SetPskcRef(PskcRef aKeyRef)615 void KeyManager::SetPskcRef(PskcRef aKeyRef)
616 {
617     VerifyOrExit(mPskcRef != aKeyRef, Get<Notifier>().SignalIfFirst(kEventPskcChanged));
618 
619     Crypto::Storage::DestroyKey(mPskcRef);
620 
621     mPskcRef = aKeyRef;
622     Get<Notifier>().Signal(kEventPskcChanged);
623 
624 exit:
625     mIsPskcSet = true;
626 }
627 
SetNetworkKeyRef(otNetworkKeyRef aKeyRef)628 void KeyManager::SetNetworkKeyRef(otNetworkKeyRef aKeyRef)
629 {
630     VerifyOrExit(mNetworkKeyRef != aKeyRef, Get<Notifier>().SignalIfFirst(kEventNetworkKeyChanged));
631 
632     Crypto::Storage::DestroyKey(mNetworkKeyRef);
633 
634     mNetworkKeyRef = aKeyRef;
635     Get<Notifier>().Signal(kEventNetworkKeyChanged);
636     Get<Notifier>().Signal(kEventThreadKeySeqCounterChanged);
637     mKeySequence = 0;
638     UpdateKeyMaterial();
639     ResetFrameCounters();
640 
641 exit:
642     return;
643 }
644 
645 #endif // OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
646 
647 } // namespace ot
648