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 
43 #include "common/clearable.hpp"
44 #include "common/encoding.hpp"
45 #include "common/equatable.hpp"
46 #include "common/locator.hpp"
47 #include "common/non_copyable.hpp"
48 #include "common/random.hpp"
49 #include "common/timer.hpp"
50 #include "crypto/hmac_sha256.hpp"
51 #include "mac/mac_types.hpp"
52 #include "thread/mle_types.hpp"
53 
54 namespace ot {
55 
56 /**
57  * @addtogroup core-security
58  *
59  * @brief
60  *   This module includes definitions for Thread security material generation.
61  *
62  * @{
63  */
64 
65 /**
66  * This class represents Security Policy Rotation and Flags.
67  *
68  */
69 class SecurityPolicy : public otSecurityPolicy, public Equatable<SecurityPolicy>
70 {
71 public:
72     /**
73      * Offset between the Thread Version and the Version-threshold valid for Routing.
74      *
75      */
76     static constexpr uint8_t kVersionThresholdOffsetVersion = 3;
77 
78     static constexpr uint16_t kMinKeyRotationTime     = 1;   ///< The minimum Key Rotation Time in hours.
79     static constexpr uint16_t kDefaultKeyRotationTime = 672; ///< Default Key Rotation Time (in unit of hours).
80 
81     /**
82      * This constructor initializes the object with default Key Rotation Time
83      * and Security Policy Flags.
84      *
85      */
SecurityPolicy(void)86     SecurityPolicy(void) { SetToDefault(); }
87 
88     /**
89      * This method sets the Security Policy to default values.
90      *
91      */
92     void SetToDefault(void);
93 
94     /**
95      * This method sets the Security Policy Flags.
96      *
97      * @param[in]  aFlags        The Security Policy Flags.
98      * @param[in]  aFlagsLength  The length of the Security Policy Flags, 1 byte for
99      *                           Thread 1.1 devices, and 2 bytes for Thread 1.2 or higher.
100      *
101      */
102     void SetFlags(const uint8_t *aFlags, uint8_t aFlagsLength);
103 
104     /**
105      * This method returns the Security Policy Flags.
106      *
107      * @param[out] aFlags        A pointer to the Security Policy Flags buffer.
108      * @param[in]  aFlagsLength  The length of the Security Policy Flags buffer.
109      *
110      */
111     void GetFlags(uint8_t *aFlags, uint8_t aFlagsLength) const;
112 
113 private:
114     static constexpr uint8_t kDefaultFlags                   = 0xff;
115     static constexpr uint8_t kObtainNetworkKeyMask           = 1 << 7;
116     static constexpr uint8_t kNativeCommissioningMask        = 1 << 6;
117     static constexpr uint8_t kRoutersMask                    = 1 << 5;
118     static constexpr uint8_t kExternalCommissioningMask      = 1 << 4;
119     static constexpr uint8_t kBeaconsMask                    = 1 << 3;
120     static constexpr uint8_t kCommercialCommissioningMask    = 1 << 2;
121     static constexpr uint8_t kAutonomousEnrollmentMask       = 1 << 1;
122     static constexpr uint8_t kNetworkKeyProvisioningMask     = 1 << 0;
123     static constexpr uint8_t kTobleLinkMask                  = 1 << 7;
124     static constexpr uint8_t kNonCcmRoutersMask              = 1 << 6;
125     static constexpr uint8_t kReservedMask                   = 0x38;
126     static constexpr uint8_t kVersionThresholdForRoutingMask = 0x07;
127 
128     void SetToDefaultFlags(void);
129 };
130 
131 /**
132  * This class represents a Thread Network Key.
133  *
134  */
135 OT_TOOL_PACKED_BEGIN
136 class NetworkKey : public otNetworkKey, public Equatable<NetworkKey>
137 {
138 public:
139 #if !OPENTHREAD_RADIO
140     /**
141      * This method generates a cryptographically secure random sequence to populate the Thread Network Key.
142      *
143      * @retval kErrorNone     Successfully generated a random Thread Network Key.
144      * @retval kErrorFailed   Failed to generate random sequence.
145      *
146      */
GenerateRandom(void)147     Error GenerateRandom(void) { return Random::Crypto::FillBuffer(m8, sizeof(m8)); }
148 #endif
149 } OT_TOOL_PACKED_END;
150 
151 /**
152  * This class represents a Thread Pre-Shared Key for the Commissioner (PSKc).
153  *
154  */
155 OT_TOOL_PACKED_BEGIN
156 class Pskc : public otPskc, public Equatable<Pskc>, public Clearable<Pskc>
157 {
158 public:
159 #if !OPENTHREAD_RADIO
160     /**
161      * This method generates a cryptographically secure random sequence to populate the Thread PSKc.
162      *
163      * @retval kErrorNone  Successfully generated a random Thread PSKc.
164      *
165      */
GenerateRandom(void)166     Error GenerateRandom(void) { return Random::Crypto::FillBuffer(m8, sizeof(Pskc)); }
167 #endif
168 
169 } OT_TOOL_PACKED_END;
170 
171 /**
172  *
173  * This class represents a Key Encryption Key (KEK).
174  *
175  */
176 typedef Mac::Key Kek;
177 
178 /**
179  * This class defines Thread Key Manager.
180  *
181  */
182 class KeyManager : public InstanceLocator, private NonCopyable
183 {
184 public:
185     /**
186      * This constructor initializes the object.
187      *
188      * @param[in]  aInstance     A reference to the OpenThread instance.
189      *
190      */
191     explicit KeyManager(Instance &aInstance);
192 
193     /**
194      * This method starts KeyManager rotation timer and sets guard timer to initial value.
195      *
196      */
197     void Start(void);
198 
199     /**
200      * This method stops KeyManager timers.
201      *
202      */
203     void Stop(void);
204 
205     /**
206      * This method returns the Thread Network Key.
207      *
208      * @returns The Thread Network Key.
209      *
210      */
GetNetworkKey(void) const211     const NetworkKey &GetNetworkKey(void) const { return mNetworkKey; }
212 
213     /**
214      * This method sets the Thread Network Key.
215      *
216      * @param[in]  aKey        A Thread Network Key.
217      *
218      * @retval kErrorNone         Successfully set the Thread Network Key.
219      * @retval kErrorInvalidArgs  The @p aKeyLength value was invalid.
220      *
221      */
222     Error SetNetworkKey(const NetworkKey &aKey);
223 
224 #if OPENTHREAD_FTD || OPENTHREAD_MTD
225     /**
226      * This method indicates whether the PSKc is configured.
227      *
228      * A value of all zeros indicates that the PSKc is not configured.
229      *
230      * @retval TRUE  if the PSKc is configured.
231      * @retval FALSE if the PSKc is not not configured.
232      *
233      */
IsPskcSet(void) const234     bool IsPskcSet(void) const { return mIsPskcSet; }
235 
236     /**
237      * This method returns a pointer to the PSKc.
238      *
239      * @returns A reference to the PSKc.
240      *
241      */
GetPskc(void) const242     const Pskc &GetPskc(void) const { return mPskc; }
243 
244     /**
245      * This method sets the PSKc.
246      *
247      * @param[in]  aPskc    A reference to the PSKc.
248      *
249      */
250     void SetPskc(const Pskc &aPskc);
251 #endif
252 
253     /**
254      * This method returns the current key sequence value.
255      *
256      * @returns The current key sequence value.
257      *
258      */
GetCurrentKeySequence(void) const259     uint32_t GetCurrentKeySequence(void) const { return mKeySequence; }
260 
261     /**
262      * This method sets the current key sequence value.
263      *
264      * @param[in]  aKeySequence  The key sequence value.
265      *
266      */
267     void SetCurrentKeySequence(uint32_t aKeySequence);
268 
269 #if OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE
270     /**
271      * This method returns the current MAC key for TREL radio link.
272      *
273      * @returns The current TREL MAC key.
274      *
275      */
GetCurrentTrelMacKey(void) const276     const Mac::Key &GetCurrentTrelMacKey(void) const { return mTrelKey; }
277 
278     /**
279      * This method returns a temporary MAC key for TREL radio link computed from the given key sequence.
280      *
281      * @param[in]  aKeySequence  The key sequence value.
282      *
283      * @returns The temporary TREL MAC key.
284      *
285      */
286     const Mac::Key &GetTemporaryTrelMacKey(uint32_t aKeySequence);
287 #endif
288 
289     /**
290      * This method returns the current MLE key.
291      *
292      * @returns The current MLE key.
293      *
294      */
GetCurrentMleKey(void) const295     const Mle::Key &GetCurrentMleKey(void) const { return mMleKey; }
296 
297     /**
298      * This method returns a temporary MLE key computed from the given key sequence.
299      *
300      * @param[in]  aKeySequence  The key sequence value.
301      *
302      * @returns The temporary MLE key.
303      *
304      */
305     const Mle::Key &GetTemporaryMleKey(uint32_t aKeySequence);
306 
307 #if OPENTHREAD_CONFIG_RADIO_LINK_IEEE_802_15_4_ENABLE
308     /**
309      * This method returns the current MAC Frame Counter value for 15.4 radio link.
310      *
311      * @returns The current MAC Frame Counter value.
312      *
313      */
Get154MacFrameCounter(void) const314     uint32_t Get154MacFrameCounter(void) const { return mMacFrameCounters.Get154(); }
315 #endif
316 
317 #if OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE
318     /**
319      * This method returns the current MAC Frame Counter value for TREL radio link.
320      *
321      * @returns The current MAC Frame Counter value for TREL radio link.
322      *
323      */
GetTrelMacFrameCounter(void) const324     uint32_t GetTrelMacFrameCounter(void) const { return mMacFrameCounters.GetTrel(); }
325 
326     /**
327      * This method increments the current MAC Frame Counter value for TREL radio link.
328      *
329      */
330     void IncrementTrelMacFrameCounter(void);
331 #endif
332 
333     /**
334      * This method gets the maximum MAC Frame Counter among all supported radio links.
335      *
336      * @return The maximum MAC frame Counter among all supported radio links.
337      *
338      */
GetMaximumMacFrameCounter(void) const339     uint32_t GetMaximumMacFrameCounter(void) const { return mMacFrameCounters.GetMaximum(); }
340 
341     /**
342      * This method sets the current MAC Frame Counter value for all radio links.
343      *
344      * @param[in]  aMacFrameCounter  The MAC Frame Counter value.
345      *
346      */
347     void SetAllMacFrameCounters(uint32_t aMacFrameCounter);
348 
349     /**
350      * This method sets the MAC Frame Counter value which is stored in non-volatile memory.
351      *
352      * @param[in]  aStoredMacFrameCounter  The stored MAC Frame Counter value.
353      *
354      */
SetStoredMacFrameCounter(uint32_t aStoredMacFrameCounter)355     void SetStoredMacFrameCounter(uint32_t aStoredMacFrameCounter) { mStoredMacFrameCounter = aStoredMacFrameCounter; }
356 
357     /**
358      * This method returns the current MLE Frame Counter value.
359      *
360      * @returns The current MLE Frame Counter value.
361      *
362      */
GetMleFrameCounter(void) const363     uint32_t GetMleFrameCounter(void) const { return mMleFrameCounter; }
364 
365     /**
366      * This method sets the current MLE Frame Counter value.
367      *
368      * @param[in]  aMleFrameCounter  The MLE Frame Counter value.
369      *
370      */
SetMleFrameCounter(uint32_t aMleFrameCounter)371     void SetMleFrameCounter(uint32_t aMleFrameCounter) { mMleFrameCounter = aMleFrameCounter; }
372 
373     /**
374      * This method sets the MLE Frame Counter value which is stored in non-volatile memory.
375      *
376      * @param[in]  aStoredMleFrameCounter  The stored MLE Frame Counter value.
377      *
378      */
SetStoredMleFrameCounter(uint32_t aStoredMleFrameCounter)379     void SetStoredMleFrameCounter(uint32_t aStoredMleFrameCounter) { mStoredMleFrameCounter = aStoredMleFrameCounter; }
380 
381     /**
382      * This method increments the current MLE Frame Counter value.
383      *
384      */
385     void IncrementMleFrameCounter(void);
386 
387     /**
388      * This method returns the KEK.
389      *
390      * @returns A pointer to the KEK.
391      *
392      */
GetKek(void) const393     const Kek &GetKek(void) const { return mKek; }
394 
395     /**
396      * This method sets the KEK.
397      *
398      * @param[in]  aKek  A KEK.
399      *
400      */
401     void SetKek(const Kek &aKek);
402 
403     /**
404      * This method sets the KEK.
405      *
406      * @param[in]  aKek  A pointer to the KEK.
407      *
408      */
409     void SetKek(const uint8_t *aKek);
410 
411     /**
412      * This method returns the current KEK Frame Counter value.
413      *
414      * @returns The current KEK Frame Counter value.
415      *
416      */
GetKekFrameCounter(void) const417     uint32_t GetKekFrameCounter(void) const { return mKekFrameCounter; }
418 
419     /**
420      * This method increments the current KEK Frame Counter value.
421      *
422      */
IncrementKekFrameCounter(void)423     void IncrementKekFrameCounter(void) { mKekFrameCounter++; }
424 
425     /**
426      * This method returns the KeySwitchGuardTime.
427      *
428      * The KeySwitchGuardTime is the time interval during which key rotation procedure is prevented.
429      *
430      * @returns The KeySwitchGuardTime value in hours.
431      *
432      */
GetKeySwitchGuardTime(void) const433     uint32_t GetKeySwitchGuardTime(void) const { return mKeySwitchGuardTime; }
434 
435     /**
436      * This method sets the KeySwitchGuardTime.
437      *
438      * The KeySwitchGuardTime is the time interval during which key rotation procedure is prevented.
439      *
440      * @param[in]  aKeySwitchGuardTime  The KeySwitchGuardTime value in hours.
441      *
442      */
SetKeySwitchGuardTime(uint32_t aKeySwitchGuardTime)443     void SetKeySwitchGuardTime(uint32_t aKeySwitchGuardTime) { mKeySwitchGuardTime = aKeySwitchGuardTime; }
444 
445     /**
446      * This method returns the Security Policy.
447      *
448      * The Security Policy specifies Key Rotation Time and network administrator preferences
449      * for which security-related operations are allowed or disallowed.
450      *
451      * @returns The SecurityPolicy.
452      *
453      */
GetSecurityPolicy(void) const454     const SecurityPolicy &GetSecurityPolicy(void) const { return mSecurityPolicy; }
455 
456     /**
457      * This method sets the Security Policy.
458      *
459      * The Security Policy specifies Key Rotation Time and network administrator preferences
460      * for which security-related operations are allowed or disallowed.
461      *
462      * @param[in]  aSecurityPolicy  The Security Policy.
463      *
464      */
465     void SetSecurityPolicy(const SecurityPolicy &aSecurityPolicy);
466 
467     /**
468      * This method updates the MAC keys and MLE key.
469      *
470      */
471     void UpdateKeyMaterial(void);
472 
473     /**
474      * This method handles MAC frame counter change (callback from `SubMac` for 15.4 security frame change)
475      *
476      * @param[in]  aMacFrameCounter  The 15.4 link MAC frame counter value.
477      *
478      */
479     void MacFrameCounterUpdated(uint32_t aMacFrameCounter);
480 
481 private:
482     static constexpr uint32_t kDefaultKeySwitchGuardTime = 624;
483     static constexpr uint32_t kOneHourIntervalInMsec     = 3600u * 1000u;
484 
485     OT_TOOL_PACKED_BEGIN
486     struct Keys
487     {
488         Mle::Key mMleKey;
489         Mac::Key mMacKey;
490     } OT_TOOL_PACKED_END;
491 
492     union HashKeys
493     {
494         Crypto::HmacSha256::Hash mHash;
495         Keys                     mKeys;
496     };
497 
498     void ComputeKeys(uint32_t aKeySequence, HashKeys &aHashKeys);
499 
500 #if OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE
501     void ComputeTrelKey(uint32_t aKeySequence, Mac::Key &aTrelKey);
502 #endif
503 
504     void        StartKeyRotationTimer(void);
505     static void HandleKeyRotationTimer(Timer &aTimer);
506     void        HandleKeyRotationTimer(void);
507 
508     static const uint8_t kThreadString[];
509 
510 #if OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE
511     static const uint8_t kHkdfExtractSaltString[];
512     static const uint8_t kTrelInfoString[];
513 #endif
514 
515     NetworkKey mNetworkKey;
516 
517     uint32_t mKeySequence;
518     Mle::Key mMleKey;
519     Mle::Key mTemporaryMleKey;
520 
521 #if OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE
522     Mac::Key mTrelKey;
523     Mac::Key mTemporaryTrelKey;
524 #endif
525 
526     Mac::LinkFrameCounters mMacFrameCounters;
527     uint32_t               mMleFrameCounter;
528     uint32_t               mStoredMacFrameCounter;
529     uint32_t               mStoredMleFrameCounter;
530 
531     uint32_t   mHoursSinceKeyRotation;
532     uint32_t   mKeySwitchGuardTime;
533     bool       mKeySwitchGuardEnabled;
534     TimerMilli mKeyRotationTimer;
535 
536 #if OPENTHREAD_MTD || OPENTHREAD_FTD
537     Pskc mPskc;
538 #endif
539     Kek      mKek;
540     uint32_t mKekFrameCounter;
541 
542     SecurityPolicy mSecurityPolicy;
543     bool           mIsPskcSet : 1;
544 };
545 
546 /**
547  * @}
548  */
549 
550 } // namespace ot
551 
552 #endif // KEY_MANAGER_HPP_
553