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