Mistake on this page?
Report an issue in GitHub or email us
DeviceKey.h
1 /* mbed Microcontroller Library
2  * Copyright (c) 2018 ARM Limited
3  * SPDX-License-Identifier: Apache-2.0
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 #ifndef MBED_DEVICEKEY_H
18 #define MBED_DEVICEKEY_H
19 
20 #include "stddef.h"
21 #include "stdint.h"
22 #include "platform/NonCopyable.h"
23 
24 #define DEVICEKEY_ENABLED 1
25 
26 // Whole class is not supported if entropy is not enabled
27 // Flash device is required as Device Key is currently depending on it
28 #if !DEVICE_FLASH || !defined(COMPONENT_FLASHIAP)
29 #undef DEVICEKEY_ENABLED
30 #define DEVICEKEY_ENABLED 0
31 #endif
32 
33 #if (DEVICEKEY_ENABLED) || defined(DOXYGEN_ONLY)
34 
35 namespace mbed {
36 /** \addtogroup device-security Device Key
37  * \ingroup mbed-os-public
38  * @{
39  */
40 
41 
42 #define DEVICE_KEY_16BYTE 16
43 #define DEVICE_KEY_32BYTE 32
44 
45 enum DeviceKeyStatus {
46  DEVICEKEY_SUCCESS = 0,
47  DEVICEKEY_INVALID_KEY_SIZE = -1,
48  DEVICEKEY_INVALID_KEY_TYPE = -2,
49  DEVICEKEY_SAVE_FAILED = -3,
50  DEVICEKEY_ALREADY_EXIST = -4,
51  DEVICEKEY_NOT_FOUND = -5,
52  DEVICEKEY_READ_FAILED = -6,
53  DEVICEKEY_KVSTORE_UNPREDICTED_ERROR = -7,
54  DEVICEKEY_ERR_CMAC_GENERIC_FAILURE = -8,
55  DEVICEKEY_BUFFER_TOO_SMALL = -9,
56  DEVICEKEY_NO_KEY_INJECTED = -10,
57  DEVICEKEY_INVALID_PARAM = -11,
58  DEVICEKEY_GENERATE_RANDOM_ERROR = -12,
59 };
60 
61 /** Use this singleton if you need to derive a new key from the device root of trust.
62  *
63  * @note Synchronization level: Thread safe
64  * @ingroup device-key
65  */
66 /**
67  * \defgroup device-security_DeviceKey DeviceKey class
68  * \addtogroup device-security
69  * @{
70  */
71 class DeviceKey : private mbed::NonCopyable<DeviceKey> {
72 public:
73 
74  /**
75  * @brief As a singleton, return the single instance of the class.
76  * Reason for this class being a singleton is the following:
77  * - Ease of use for users of this class not having to coordinate instantiations.
78  * - Lazy instantiation of internal data (which we can't achieve with simple static classes).
79  *
80  * @returns Singleton instance reference.
81  */
83  {
84  // Use this implementation of singleton (Meyer's) rather than the one that allocates
85  // the instance on the heap, as it ensures destruction at program end (preventing warnings
86  // from memory checking tools, such as valgrind).
87  static DeviceKey instance;
88  return instance;
89  }
90 
91  ~DeviceKey();
92 
93  /** Derive a new key based on the salt string.
94  * @param isalt Input buffer used to create the new key. Same input always generates the same key
95  * @param isalt_size Size of the data in salt buffer.
96  * @param output Buffer to receive the derived key. Size must be 16 bytes or 32 bytes
97  * according to the ikey_type parameter
98  * @param ikey_type Type of the required key. Must be 16 bytes or 32 bytes.
99  * @return 0 on success, negative error code on failure
100  */
101  int generate_derived_key(const unsigned char *isalt, size_t isalt_size, unsigned char *output, uint16_t ikey_type);
102 
103  /** Set a device key into the KVStore. If entropy support is missing, call this method
104  * before calling device_key_derived_key. This method should be called only once!
105  * @param value Input buffer contain the key.
106  * @param isize Size of the supplied key. Must be 16 bytes or 32 bytes.
107  * @return 0 on success, negative error code on failure
108  */
109  int device_inject_root_of_trust(uint32_t *value, size_t isize);
110  /** Generate Root of Trust.
111  * Uses TRNG or various other entropy sources to generate random device key and
112  * inject it into device's KVStore. Device Key can only be generated once.
113  *
114  * @param key_size Size of key in bytes to generate. Must be 16 bytes or 32 bytes. Default is 16 bytes.
115  *
116  * @return DEVICEKEY_SUCCESS, when device key successfully generated and injected.
117  * @return DEVICEKEY_ALREADY_EXIST, if the key has already been written.
118  * @return DEVICEKEY_GENERATE_RANDOM_ERROR if this device does not contain entropy sources and cannot generate a key.
119  * @return DEVICEKEY_INVALID_KEY_SIZE if key_size is not 32 or 16 bytes.
120  * @return error codes on other failures.
121  */
122  int generate_root_of_trust(size_t key_size = DEVICE_KEY_16BYTE);
123 
124 private:
125  // Private constructor, as class is a singleton
126  DeviceKey();
127 
128  /** Read a device key from the KVStore
129  * @param output Buffer for the returned key.
130  * @param size Input: The size of the output buffer.
131  * Output: The actual size of the written data
132  * @return 0 on success, negative error code on failure
133  */
134  int read_key_from_kvstore(uint32_t *output, size_t &size);
135 
136  /** Set a device key into the KVStore
137  * @param input Input buffer contain the key.
138  * @param isize The size of the input buffer.
139  * @return 0 on success, negative error code on failure
140  */
141  int write_key_to_kvstore(uint32_t *input, size_t isize);
142 
143  /** Get a derived key base on a salt string. The methods implements Section 5.1
144  * in NIST SP 800-108, Recommendation for Key Derivation Using Pseudorandom Functions
145  * @param ikey_buff Input buffer holding the ROT key
146  * @param ikey_size Size of the input key. Must be 16 bytes or 32 bytes.
147  * @param isalt Input buffer contain some string.
148  * @param isalt_size Size of the supplied input string.
149  * @param output Buffer for the derived key result.
150  * @param ikey_type The requested key size. Must be 16 bytes or 32 bytes.
151  * @return 0 on success, negative error code on failure
152  */
153  int get_derived_key(uint32_t *ikey_buff, size_t ikey_size, const unsigned char *isalt, size_t isalt_size,
154  unsigned char *output, uint32_t ikey_type);
155 
156 };
157 
158 /** @}*/
159 /** @}*/
160 
161 }
162 
163 #endif
164 #endif
165 
static DeviceKey & get_instance()
As a singleton, return the single instance of the class.
Definition: DeviceKey.h:82
int device_inject_root_of_trust(uint32_t *value, size_t isize)
Set a device key into the KVStore.
int generate_derived_key(const unsigned char *isalt, size_t isalt_size, unsigned char *output, uint16_t ikey_type)
Derive a new key based on the salt string.
Prevents generation of copy constructor and copy assignment operator in derived classes.
Definition: NonCopyable.h:162
int generate_root_of_trust(size_t key_size=16)
Generate Root of Trust.
Definition: ATHandler.h:46
Important Information for this Arm website

This site uses cookies to store information on your computer. By continuing to use our site, you consent to our cookies. If you are not happy with the use of these cookies, please review our Cookie Policy to learn how they can be disabled. By disabling cookies, some features of the site will not work.