• 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 includes definitions for Thread security material generation.
32  */
33 
34 #ifndef KEY_MANAGER_HPP_
35 #define KEY_MANAGER_HPP_
36 
37 #include "openthread-core-config.h"
38 
39 #include <stdint.h>
40 
41 #include <openthread/dataset.h>
42 #include <openthread/platform/crypto.h>
43 
44 #include "common/as_core_type.hpp"
45 #include "common/clearable.hpp"
46 #include "common/encoding.hpp"
47 #include "common/equatable.hpp"
48 #include "common/locator.hpp"
49 #include "common/non_copyable.hpp"
50 #include "common/random.hpp"
51 #include "common/timer.hpp"
52 #include "crypto/hmac_sha256.hpp"
53 #include "mac/mac_types.hpp"
54 #include "thread/mle_types.hpp"
55 
56 namespace ot {
57 
58 /**
59  * @addtogroup core-security
60  *
61  * @brief
62  *   This module includes definitions for Thread security material generation.
63  *
64  * @{
65  */
66 
67 /**
68  * This class represents Security Policy Rotation and Flags.
69  *
70  */
71 class SecurityPolicy : public otSecurityPolicy, public Equatable<SecurityPolicy>
72 {
73 public:
74     /**
75      * Offset between the Thread Version and the Version-threshold valid for Routing.
76      *
77      */
78     static constexpr uint8_t kVersionThresholdOffsetVersion = 3;
79 
80     static constexpr uint16_t kMinKeyRotationTime     = 1;   ///< The minimum Key Rotation Time in hours.
81     static constexpr uint16_t kDefaultKeyRotationTime = 672; ///< Default Key Rotation Time (in unit of hours).
82 
83     /**
84      * This constructor initializes the object with default Key Rotation Time
85      * and Security Policy Flags.
86      *
87      */
SecurityPolicy(void)88     SecurityPolicy(void) { SetToDefault(); }
89 
90     /**
91      * This method sets the Security Policy to default values.
92      *
93      */
94     void SetToDefault(void);
95 
96     /**
97      * This method sets the Security Policy Flags.
98      *
99      * @param[in]  aFlags        The Security Policy Flags.
100      * @param[in]  aFlagsLength  The length of the Security Policy Flags, 1 byte for
101      *                           Thread 1.1 devices, and 2 bytes for Thread 1.2 or higher.
102      *
103      */
104     void SetFlags(const uint8_t *aFlags, uint8_t aFlagsLength);
105 
106     /**
107      * This method returns the Security Policy Flags.
108      *
109      * @param[out] aFlags        A pointer to the Security Policy Flags buffer.
110      * @param[in]  aFlagsLength  The length of the Security Policy Flags buffer.
111      *
112      */
113     void GetFlags(uint8_t *aFlags, uint8_t aFlagsLength) const;
114 
115 private:
116     static constexpr uint8_t kDefaultFlags                   = 0xff;
117     static constexpr uint8_t kObtainNetworkKeyMask           = 1 << 7;
118     static constexpr uint8_t kNativeCommissioningMask        = 1 << 6;
119     static constexpr uint8_t kRoutersMask                    = 1 << 5;
120     static constexpr uint8_t kExternalCommissioningMask      = 1 << 4;
121     static constexpr uint8_t kBeaconsMask                    = 1 << 3;
122     static constexpr uint8_t kCommercialCommissioningMask    = 1 << 2;
123     static constexpr uint8_t kAutonomousEnrollmentMask       = 1 << 1;
124     static constexpr uint8_t kNetworkKeyProvisioningMask     = 1 << 0;
125     static constexpr uint8_t kTobleLinkMask                  = 1 << 7;
126     static constexpr uint8_t kNonCcmRoutersMask              = 1 << 6;
127     static constexpr uint8_t kReservedMask                   = 0x38;
128     static constexpr uint8_t kVersionThresholdForRoutingMask = 0x07;
129 
130     void SetToDefaultFlags(void);
131 };
132 
133 /**
134  * This class represents a Thread Network Key.
135  *
136  */
137 OT_TOOL_PACKED_BEGIN
138 class NetworkKey : public otNetworkKey, public Equatable<NetworkKey>, public Clearable<NetworkKey>
139 {
140 public:
141     static constexpr uint8_t kSize = OT_NETWORK_KEY_SIZE; ///< Size of the Thread Network Key (in bytes).
142 
143 #if !OPENTHREAD_RADIO
144     /**
145      * This method generates a cryptographically secure random sequence to populate the Thread Network Key.
146      *
147      * @retval kErrorNone     Successfully generated a random Thread Network Key.
148      * @retval kErrorFailed   Failed to generate random sequence.
149      *
150      */
GenerateRandom(void)151     Error GenerateRandom(void) { return Random::Crypto::FillBuffer(m8, sizeof(m8)); }
152 #endif
153 
154 } OT_TOOL_PACKED_END;
155 
156 #if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
157 /**
158  * Provides a representation for Network Key reference.
159  *
160  */
161 typedef otNetworkKeyRef NetworkKeyRef;
162 #endif
163 
164 /**
165  * This class represents a Thread Pre-Shared Key for the Commissioner (PSKc).
166  *
167  */
168 OT_TOOL_PACKED_BEGIN
169 class Pskc : public otPskc, public Equatable<Pskc>, public Clearable<Pskc>
170 {
171 public:
172     static constexpr uint8_t kSize = OT_PSKC_MAX_SIZE; ///< Size (number of bytes) of the PSKc.
173 
174 #if !OPENTHREAD_RADIO
175     /**
176      * This method generates a cryptographically secure random sequence to populate the Thread PSKc.
177      *
178      * @retval kErrorNone  Successfully generated a random Thread PSKc.
179      *
180      */
GenerateRandom(void)181     Error GenerateRandom(void) { return Random::Crypto::FillBuffer(m8, sizeof(m8)); }
182 #endif
183 } OT_TOOL_PACKED_END;
184 
185 #if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
186 /**
187  * Provides a representation for Network Key reference.
188  *
189  */
190 typedef otPskcRef PskcRef;
191 #endif
192 
193 /**
194  *
195  * This class represents a Key Encryption Key (KEK).
196  *
197  */
198 typedef Mac::Key Kek;
199 
200 /**
201  *
202  * This class represents a Key Material for Key Encryption Key (KEK).
203  *
204  */
205 typedef Mac::KeyMaterial KekKeyMaterial;
206 
207 /**
208  * This class defines Thread Key Manager.
209  *
210  */
211 class KeyManager : public InstanceLocator, private NonCopyable
212 {
213 public:
214     /**
215      * This constructor initializes the object.
216      *
217      * @param[in]  aInstance     A reference to the OpenThread instance.
218      *
219      */
220     explicit KeyManager(Instance &aInstance);
221 
222     /**
223      * This method starts KeyManager rotation timer and sets guard timer to initial value.
224      *
225      */
226     void Start(void);
227 
228     /**
229      * This method stops KeyManager timers.
230      *
231      */
232     void Stop(void);
233 
234     /**
235      * This method gets the Thread Network Key.
236      *
237      * @param[out] aNetworkKey   A reference to a `NetworkKey` to output the Thread Network Key.
238      *
239      */
240     void GetNetworkKey(NetworkKey &aNetworkKey) const;
241 
242     /**
243      * This method sets the Thread Network Key.
244      *
245      * @param[in]  aNetworkKey        A Thread Network Key.
246      *
247      */
248     void SetNetworkKey(const NetworkKey &aNetworkKey);
249 
250 #if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
251     /**
252      * This method returns a Key Ref to Thread Network Key.
253      *
254      * @returns A key reference to the Thread Network Key.
255      *
256      */
GetNetworkKeyRef(void)257     NetworkKeyRef GetNetworkKeyRef(void) { return mNetworkKeyRef; }
258 
259     /**
260      * This method sets the Thread Network Key using Key Reference.
261      *
262      * @param[in]  aKeyRef        Reference to Thread Network Key.
263      *
264      */
265     void SetNetworkKeyRef(NetworkKeyRef aKeyRef);
266 #endif
267 
268     /**
269      * This method indicates whether the PSKc is configured.
270      *
271      * A value of all zeros indicates that the PSKc is not configured.
272      *
273      * @retval TRUE  if the PSKc is configured.
274      * @retval FALSE if the PSKc is not not configured.
275      *
276      */
IsPskcSet(void) const277     bool IsPskcSet(void) const { return mIsPskcSet; }
278 
279     /**
280      * This method gets the PKSc.
281      *
282      * @param[out] aPskc  A reference to a `Pskc` to return the PSKc.
283      *
284      */
285     void GetPskc(Pskc &aPskc) const;
286 
287     /**
288      * This method sets the PSKc.
289      *
290      * @param[in]  aPskc    A reference to the PSKc.
291      *
292      */
293     void SetPskc(const Pskc &aPskc);
294 
295 #if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
296     /**
297      * This method returns a Key Ref to PSKc.
298      *
299      * @returns A key reference to the PSKc.
300      *
301      */
GetPskcRef(void)302     const PskcRef &GetPskcRef(void) { return mPskcRef; }
303 
304     /**
305      * This method sets the PSKc as a Key reference.
306      *
307      * @param[in]  aPskc    A reference to the PSKc.
308      *
309      */
310     void SetPskcRef(PskcRef aKeyRef);
311 #endif
312 
313     /**
314      * This method returns the current key sequence value.
315      *
316      * @returns The current key sequence value.
317      *
318      */
GetCurrentKeySequence(void) const319     uint32_t GetCurrentKeySequence(void) const { return mKeySequence; }
320 
321     /**
322      * This method sets the current key sequence value.
323      *
324      * @param[in]  aKeySequence  The key sequence value.
325      *
326      */
327     void SetCurrentKeySequence(uint32_t aKeySequence);
328 
329 #if OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE
330     /**
331      * This method returns the current MAC key for TREL radio link.
332      *
333      * @returns The current TREL MAC key.
334      *
335      */
GetCurrentTrelMacKey(void) const336     const Mac::KeyMaterial &GetCurrentTrelMacKey(void) const { return mTrelKey; }
337 
338     /**
339      * This method returns a temporary MAC key for TREL radio link computed from the given key sequence.
340      *
341      * @param[in]  aKeySequence  The key sequence value.
342      *
343      * @returns The temporary TREL MAC key.
344      *
345      */
346     const Mac::KeyMaterial &GetTemporaryTrelMacKey(uint32_t aKeySequence);
347 #endif
348 
349     /**
350      * This method returns the current MLE key Material.
351      *
352      * @returns The current MLE key.
353      *
354      */
GetCurrentMleKey(void) const355     const Mle::KeyMaterial &GetCurrentMleKey(void) const { return mMleKey; }
356 
357     /**
358      * This method returns a temporary MLE key Material computed from the given key sequence.
359      *
360      * @param[in]  aKeySequence  The key sequence value.
361      *
362      * @returns The temporary MLE key.
363      *
364      */
365     const Mle::KeyMaterial &GetTemporaryMleKey(uint32_t aKeySequence);
366 
367 #if OPENTHREAD_CONFIG_RADIO_LINK_IEEE_802_15_4_ENABLE
368     /**
369      * This method returns the current MAC Frame Counter value for 15.4 radio link.
370      *
371      * @returns The current MAC Frame Counter value.
372      *
373      */
Get154MacFrameCounter(void) const374     uint32_t Get154MacFrameCounter(void) const { return mMacFrameCounters.Get154(); }
375 #endif
376 
377 #if OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE
378     /**
379      * This method returns the current MAC Frame Counter value for TREL radio link.
380      *
381      * @returns The current MAC Frame Counter value for TREL radio link.
382      *
383      */
GetTrelMacFrameCounter(void) const384     uint32_t GetTrelMacFrameCounter(void) const { return mMacFrameCounters.GetTrel(); }
385 
386     /**
387      * This method increments the current MAC Frame Counter value for TREL radio link.
388      *
389      */
390     void IncrementTrelMacFrameCounter(void);
391 #endif
392 
393     /**
394      * This method gets the maximum MAC Frame Counter among all supported radio links.
395      *
396      * @return The maximum MAC frame Counter among all supported radio links.
397      *
398      */
GetMaximumMacFrameCounter(void) const399     uint32_t GetMaximumMacFrameCounter(void) const { return mMacFrameCounters.GetMaximum(); }
400 
401     /**
402      * This method sets the current MAC Frame Counter value for all radio links.
403      *
404      * @param[in]  aMacFrameCounter  The MAC Frame Counter value.
405      *
406      */
407     void SetAllMacFrameCounters(uint32_t aMacFrameCounter);
408 
409     /**
410      * This method sets the MAC Frame Counter value which is stored in non-volatile memory.
411      *
412      * @param[in]  aStoredMacFrameCounter  The stored MAC Frame Counter value.
413      *
414      */
SetStoredMacFrameCounter(uint32_t aStoredMacFrameCounter)415     void SetStoredMacFrameCounter(uint32_t aStoredMacFrameCounter) { mStoredMacFrameCounter = aStoredMacFrameCounter; }
416 
417     /**
418      * This method returns the current MLE Frame Counter value.
419      *
420      * @returns The current MLE Frame Counter value.
421      *
422      */
GetMleFrameCounter(void) const423     uint32_t GetMleFrameCounter(void) const { return mMleFrameCounter; }
424 
425     /**
426      * This method sets the current MLE Frame Counter value.
427      *
428      * @param[in]  aMleFrameCounter  The MLE Frame Counter value.
429      *
430      */
SetMleFrameCounter(uint32_t aMleFrameCounter)431     void SetMleFrameCounter(uint32_t aMleFrameCounter) { mMleFrameCounter = aMleFrameCounter; }
432 
433     /**
434      * This method sets the MLE Frame Counter value which is stored in non-volatile memory.
435      *
436      * @param[in]  aStoredMleFrameCounter  The stored MLE Frame Counter value.
437      *
438      */
SetStoredMleFrameCounter(uint32_t aStoredMleFrameCounter)439     void SetStoredMleFrameCounter(uint32_t aStoredMleFrameCounter) { mStoredMleFrameCounter = aStoredMleFrameCounter; }
440 
441     /**
442      * This method increments the current MLE Frame Counter value.
443      *
444      */
445     void IncrementMleFrameCounter(void);
446 
447     /**
448      * This method returns the KEK as `KekKeyMaterail`
449      *
450      * @returns The KEK as `KekKeyMaterial`.
451      *
452      */
GetKek(void) const453     const KekKeyMaterial &GetKek(void) const { return mKek; }
454 
455     /**
456      * This method retrieves the KEK as literal `Kek` key.
457      *
458      * @param[out] aKek  A reference to a `Kek` to output the retrieved KEK.
459      *
460      */
ExtractKek(Kek & aKek)461     void ExtractKek(Kek &aKek) { mKek.ExtractKey(aKek); }
462 
463     /**
464      * This method sets the KEK.
465      *
466      * @param[in]  aKek  A KEK.
467      *
468      */
469     void SetKek(const Kek &aKek);
470 
471     /**
472      * This method sets the KEK.
473      *
474      * @param[in]  aKekBytes  A pointer to the KEK bytes.
475      *
476      */
SetKek(const uint8_t * aKekBytes)477     void SetKek(const uint8_t *aKekBytes) { SetKek(*reinterpret_cast<const Kek *>(aKekBytes)); }
478 
479     /**
480      * This method returns the current KEK Frame Counter value.
481      *
482      * @returns The current KEK Frame Counter value.
483      *
484      */
GetKekFrameCounter(void) const485     uint32_t GetKekFrameCounter(void) const { return mKekFrameCounter; }
486 
487     /**
488      * This method increments the current KEK Frame Counter value.
489      *
490      */
IncrementKekFrameCounter(void)491     void IncrementKekFrameCounter(void) { mKekFrameCounter++; }
492 
493     /**
494      * This method returns the KeySwitchGuardTime.
495      *
496      * The KeySwitchGuardTime is the time interval during which key rotation procedure is prevented.
497      *
498      * @returns The KeySwitchGuardTime value in hours.
499      *
500      */
GetKeySwitchGuardTime(void) const501     uint32_t GetKeySwitchGuardTime(void) const { return mKeySwitchGuardTime; }
502 
503     /**
504      * This method sets the KeySwitchGuardTime.
505      *
506      * The KeySwitchGuardTime is the time interval during which key rotation procedure is prevented.
507      *
508      * @param[in]  aKeySwitchGuardTime  The KeySwitchGuardTime value in hours.
509      *
510      */
SetKeySwitchGuardTime(uint32_t aKeySwitchGuardTime)511     void SetKeySwitchGuardTime(uint32_t aKeySwitchGuardTime) { mKeySwitchGuardTime = aKeySwitchGuardTime; }
512 
513     /**
514      * This method returns the Security Policy.
515      *
516      * The Security Policy specifies Key Rotation Time and network administrator preferences
517      * for which security-related operations are allowed or disallowed.
518      *
519      * @returns The SecurityPolicy.
520      *
521      */
GetSecurityPolicy(void) const522     const SecurityPolicy &GetSecurityPolicy(void) const { return mSecurityPolicy; }
523 
524     /**
525      * This method sets the Security Policy.
526      *
527      * The Security Policy specifies Key Rotation Time and network administrator preferences
528      * for which security-related operations are allowed or disallowed.
529      *
530      * @param[in]  aSecurityPolicy  The Security Policy.
531      *
532      */
533     void SetSecurityPolicy(const SecurityPolicy &aSecurityPolicy);
534 
535     /**
536      * This method updates the MAC keys and MLE key.
537      *
538      */
539     void UpdateKeyMaterial(void);
540 
541     /**
542      * This method handles MAC frame counter changes (callback from `SubMac` for 15.4 security frame change).
543      *
544      * This is called to indicate the @p aMacFrameCounter value is now used.
545      *
546      * @param[in]  aMacFrameCounter  The 15.4 link MAC frame counter value.
547      *
548      */
549     void MacFrameCounterUsed(uint32_t aMacFrameCounter);
550 
551 private:
552     static constexpr uint32_t kDefaultKeySwitchGuardTime = 624;
553     static constexpr uint32_t kOneHourIntervalInMsec     = 3600u * 1000u;
554     static constexpr bool     kExportableMacKeys         = OPENTHREAD_CONFIG_PLATFORM_MAC_KEYS_EXPORTABLE_ENABLE;
555 
556     OT_TOOL_PACKED_BEGIN
557     struct Keys
558     {
559         Mle::Key mMleKey;
560         Mac::Key mMacKey;
561     } OT_TOOL_PACKED_END;
562 
563     union HashKeys
564     {
565         Crypto::HmacSha256::Hash mHash;
566         Keys                     mKeys;
567 
GetMleKey(void) const568         const Mle::Key &GetMleKey(void) const { return mKeys.mMleKey; }
GetMacKey(void) const569         const Mac::Key &GetMacKey(void) const { return mKeys.mMacKey; }
570     };
571 
572     void ComputeKeys(uint32_t aKeySequence, HashKeys &aHashKeys);
573 
574 #if OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE
575     void ComputeTrelKey(uint32_t aKeySequence, Mac::Key &aKey);
576 #endif
577 
578     void        StartKeyRotationTimer(void);
579     static void HandleKeyRotationTimer(Timer &aTimer);
580     void        HandleKeyRotationTimer(void);
581 
582 #if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
583     void StoreNetworkKey(const NetworkKey &aNetworkKey, bool aOverWriteExisting);
584     void StorePskc(const Pskc &aPskc);
585 #endif
586 
587     void ResetFrameCounters(void);
588 
589     static const uint8_t kThreadString[];
590 
591 #if OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE
592     static const uint8_t kHkdfExtractSaltString[];
593     static const uint8_t kTrelInfoString[];
594 #endif
595 
596 #if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
597     NetworkKeyRef mNetworkKeyRef;
598 #else
599     NetworkKey mNetworkKey;
600 #endif
601 
602     uint32_t         mKeySequence;
603     Mle::KeyMaterial mMleKey;
604     Mle::KeyMaterial mTemporaryMleKey;
605 
606 #if OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE
607     Mac::KeyMaterial mTrelKey;
608     Mac::KeyMaterial mTemporaryTrelKey;
609 #endif
610 
611     Mac::LinkFrameCounters mMacFrameCounters;
612     uint32_t               mMleFrameCounter;
613     uint32_t               mStoredMacFrameCounter;
614     uint32_t               mStoredMleFrameCounter;
615 
616     uint32_t   mHoursSinceKeyRotation;
617     uint32_t   mKeySwitchGuardTime;
618     bool       mKeySwitchGuardEnabled;
619     TimerMilli mKeyRotationTimer;
620 
621 #if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
622     PskcRef mPskcRef;
623 #else
624     Pskc       mPskc;
625 #endif
626 
627     KekKeyMaterial mKek;
628     uint32_t       mKekFrameCounter;
629 
630     SecurityPolicy mSecurityPolicy;
631     bool           mIsPskcSet : 1;
632 };
633 
634 /**
635  * @}
636  */
637 
638 DefineCoreType(otSecurityPolicy, SecurityPolicy);
639 DefineCoreType(otNetworkKey, NetworkKey);
640 DefineCoreType(otPskc, Pskc);
641 
642 } // namespace ot
643 
644 #endif // KEY_MANAGER_HPP_
645