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