Mbed OS Reference
Loading...
Searching...
No Matches
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
29#undef DEVICEKEY_ENABLED
30#define DEVICEKEY_ENABLED 0
31#endif
32
33#if (DEVICEKEY_ENABLED) || defined(DOXYGEN_ONLY)
34
35namespace mbed {
36/** \addtogroup drivers-public-api
37 * @{
38 */
39
40
41#define DEVICE_KEY_16BYTE 16
42#define DEVICE_KEY_32BYTE 32
43
44enum DeviceKeyStatus {
45 DEVICEKEY_SUCCESS = 0,
46 DEVICEKEY_INVALID_KEY_SIZE = -1,
47 DEVICEKEY_INVALID_KEY_TYPE = -2,
48 DEVICEKEY_SAVE_FAILED = -3,
49 DEVICEKEY_ALREADY_EXIST = -4,
50 DEVICEKEY_NOT_FOUND = -5,
51 DEVICEKEY_READ_FAILED = -6,
52 DEVICEKEY_KVSTORE_UNPREDICTED_ERROR = -7,
53 DEVICEKEY_ERR_CMAC_GENERIC_FAILURE = -8,
54 DEVICEKEY_BUFFER_TOO_SMALL = -9,
55 DEVICEKEY_NO_KEY_INJECTED = -10,
56 DEVICEKEY_INVALID_PARAM = -11,
57 DEVICEKEY_GENERATE_RANDOM_ERROR = -12,
58};
59
60/** Use this singleton if you need to derive a new key from the device root of trust.
61 *
62 * @note Synchronization level: Thread safe
63 * @ingroup device-key
64 */
65/**
66 */
67class DeviceKey : private mbed::NonCopyable<DeviceKey> {
68public:
69
70 /**
71 * @brief As a singleton, return the single instance of the class.
72 * Reason for this class being a singleton is the following:
73 * - Ease of use for users of this class not having to coordinate instantiations.
74 * - Lazy instantiation of internal data (which we can't achieve with simple static classes).
75 *
76 * @returns Singleton instance reference.
77 */
79 {
80 // Use this implementation of singleton (Meyer's) rather than the one that allocates
81 // the instance on the heap, as it ensures destruction at program end (preventing warnings
82 // from memory checking tools, such as valgrind).
83 static DeviceKey instance;
84 return instance;
85 }
86
87 ~DeviceKey();
88
89 /** Derive a new key based on the salt string.
90 * @param isalt Input buffer used to create the new key. Same input always generates the same key
91 * @param isalt_size Size of the data in salt buffer.
92 * @param output Buffer to receive the derived key. Size must be 16 bytes or 32 bytes
93 * according to the ikey_type parameter
94 * @param ikey_type Type of the required key. Must be 16 bytes or 32 bytes.
95 * @return 0 on success, negative error code on failure
96 */
97 int generate_derived_key(const unsigned char *isalt, size_t isalt_size, unsigned char *output, uint16_t ikey_type);
98
99 /** Set a device key into the KVStore. If entropy support is missing, call this method
100 * before calling device_key_derived_key. This method should be called only once!
101 * @param value Input buffer contain the key.
102 * @param isize Size of the supplied key. Must be 16 bytes or 32 bytes.
103 * @return 0 on success, negative error code on failure
104 */
105 int device_inject_root_of_trust(uint32_t *value, size_t isize);
106 /** Generate Root of Trust.
107 * Uses TRNG or various other entropy sources to generate random device key and
108 * inject it into device's KVStore. Device Key can only be generated once.
109 *
110 * @param key_size Size of key in bytes to generate. Must be 16 bytes or 32 bytes. Default is 16 bytes.
111 *
112 * @return DEVICEKEY_SUCCESS, when device key successfully generated and injected.
113 * @return DEVICEKEY_ALREADY_EXIST, if the key has already been written.
114 * @return DEVICEKEY_GENERATE_RANDOM_ERROR if this device does not contain entropy sources and cannot generate a key.
115 * @return DEVICEKEY_INVALID_KEY_SIZE if key_size is not 32 or 16 bytes.
116 * @return error codes on other failures.
117 */
118 int generate_root_of_trust(size_t key_size = DEVICE_KEY_16BYTE);
119
120private:
121 // Private constructor, as class is a singleton
122 DeviceKey();
123
124 /** Read a device key from the KVStore
125 * @param output Buffer for the returned key.
126 * @param size Input: The size of the output buffer.
127 * Output: The actual size of the written data
128 * @return 0 on success, negative error code on failure
129 */
130 int read_key_from_kvstore(uint32_t *output, size_t &size);
131
132 /** Set a device key into the KVStore
133 * @param input Input buffer contain the key.
134 * @param isize The size of the input buffer.
135 * @return 0 on success, negative error code on failure
136 */
137 int write_key_to_kvstore(uint32_t *input, size_t isize);
138
139 /** Get a derived key base on a salt string. The methods implements Section 5.1
140 * in NIST SP 800-108, Recommendation for Key Derivation Using Pseudorandom Functions
141 * @param ikey_buff Input buffer holding the ROT key
142 * @param ikey_size Size of the input key. Must be 16 bytes or 32 bytes.
143 * @param isalt Input buffer contain some string.
144 * @param isalt_size Size of the supplied input string.
145 * @param output Buffer for the derived key result.
146 * @param ikey_type The requested key size. Must be 16 bytes or 32 bytes.
147 * @return 0 on success, negative error code on failure
148 */
149 int get_derived_key(uint32_t *ikey_buff, size_t ikey_size, const unsigned char *isalt, size_t isalt_size,
150 unsigned char *output, uint32_t ikey_type);
151
152};
153
154/** @}*/
155
156}
157
158#endif
159#endif
160
Use this singleton if you need to derive a new key from the device root of trust.
Definition: DeviceKey.h:67
int generate_root_of_trust(size_t key_size=16)
Generate Root of Trust.
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.
static DeviceKey & get_instance()
As a singleton, return the single instance of the class.
Definition: DeviceKey.h:78
int device_inject_root_of_trust(uint32_t *value, size_t isize)
Set a device key into the KVStore.
Prevents generation of copy constructor and copy assignment operator in derived classes.
Definition: NonCopyable.h:162