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