1 /*
2 * Copyright 2017-2018,2023 NXP
3 * All rights reserved.
4 *
5 *
6 * SPDX-License-Identifier: BSD-3-Clause
7 */
8
9 #ifndef _PUF_V3_H_
10 #define _PUF_V3_H_
11
12 #include <stddef.h>
13 #include <stdint.h>
14
15 #include "fsl_common.h"
16
17 /*******************************************************************************
18 * Definitions
19 ******************************************************************************/
20 /*!
21 * @addtogroup puf_v3_driver
22 * @{
23 */
24 /*! @name Driver version */
25 /*! @{ */
26 /*! @brief PUFv3 driver version. Version 2.0.3.
27 *
28 * Current version: 2.0.3
29 *
30 * Change log:
31 * - 2.0.3
32 * - Update for various PUF CTRL wrapper
33 * - 2.0.2
34 * - Fix MISRA issue in driver.
35 * - 2.0.1
36 * - Fix PUF initialization issue and update driver to reflect SoC header changes.
37 * - 2.0.0
38 * - Initial version.
39 */
40 #define FSL_PUF_V3_DRIVER_VERSION (MAKE_VERSION(2, 0, 3))
41 /*! @} */
42
43 #define kPUF_EndianLittle (0x0u)
44 #define kPUF_EndianBig (0x1u)
45 typedef uint32_t puf_endianness_t;
46
47 #define kPUF_KeyDestRegister (0x1u)
48 #define kPUF_KeyDestKeyBus (0x2u)
49 #define kPUF_KeyDestInvalid (0x3u)
50 typedef uint32_t puf_key_dest_t;
51
52 #define kPUF_KeyAllowRegister (0x1u)
53 #define kPUF_KeyAllowKeyBus (0x2u)
54 #define kPUF_KeyAllowAll (0x3u)
55 typedef uint32_t puf_key_scope_t;
56
57 #define kPUF_ResultOK (0x0u)
58 #define kPUF_AcNotForThisProductPhase1 (0xf0u)
59 #define kPUF_AcNotForThisProductPhase2 (0xf1u)
60 #define kPUF_AcCorruptedPhase1 (0xf2u)
61 #define kPUF_AcCorruptedPhase2 (0xf3u)
62 #define kPUF_AcAuthFailedPhase1 (0xf4u)
63 #define kPUF_AcAuthFailedPhase2 (0xf5u)
64 #define kPUF_QualityVerificationFail (0xf6u)
65 #define kPUF_ContextIncorrect (0xf7u)
66 #define kPUF_DestinationNotAllowed (0xf8u)
67 #define kPUF_Failure (0xFFu)
68 typedef uint32_t puf_result_code_t;
69
70 #define kPUF_NonsecureUser (0xCu) /* b1100 */
71 #define kPUF_NonsecurePrivilege (0x9u) /* b1001 */
72 #define kPUF_SecureUser (0x6u) /* b0110 */
73 #define kPUF_SecurePrivilege (0x3u) /* b0011 */
74 typedef uint32_t puf_sec_level_t;
75
76 typedef struct
77 {
78 puf_endianness_t dataEndianness;
79 uint8_t CKGATING;
80 } puf_config_t;
81
82 typedef struct
83 {
84 puf_key_scope_t keyScopeStarted;
85 puf_key_scope_t keyScopeEnrolled;
86 uint32_t userCtx0;
87 uint32_t userCtx1;
88 } puf_key_ctx_t;
89
90 #define PUF_ACTIVATION_CODE_SIZE (size_t)(FSL_FEATURE_PUF_ACTIVATION_CODE_SIZE)
91 #define PUF_GET_KEY_CODE_SIZE_FOR_KEY_SIZE(x) ((0x34u + (x)) + 0x10u * ((x) / 0x32u))
92 #define SEC_LOCK_PATTERN 0xAC50u
93
94 enum
95 {
96 kStatus_PUF_OperationNotAllowed = MAKE_STATUS(kStatusGroup_PUF, 0xA5),
97 kStatus_PUF_AcNotForThisProductPhase1 = MAKE_STATUS(kStatusGroup_PUF, kPUF_AcNotForThisProductPhase1),
98 kStatus_PUF_AcNotForThisProductPhase2 = MAKE_STATUS(kStatusGroup_PUF, kPUF_AcNotForThisProductPhase2),
99 kStatus_PUF_AcCorruptedPhase1 = MAKE_STATUS(kStatusGroup_PUF, kPUF_AcCorruptedPhase1),
100 kStatus_PUF_AcCorruptedPhase2 = MAKE_STATUS(kStatusGroup_PUF, kPUF_AcCorruptedPhase2),
101 kStatus_PUF_AcAuthFailedPhase1 = MAKE_STATUS(kStatusGroup_PUF, kPUF_AcAuthFailedPhase1),
102 kStatus_PUF_NBOOT_AcAuthFailedPhase2 = MAKE_STATUS(kStatusGroup_PUF, kPUF_AcAuthFailedPhase2),
103 kStatus_PUF_QualityVerificationFail = MAKE_STATUS(kStatusGroup_PUF, kPUF_QualityVerificationFail),
104 kStatus_PUF_ContextIncorrect = MAKE_STATUS(kStatusGroup_PUF, kPUF_ContextIncorrect),
105 kStatus_PUF_DestinationNotAllowed = MAKE_STATUS(kStatusGroup_PUF, kPUF_DestinationNotAllowed),
106 kStatus_PUF_Failure = MAKE_STATUS(kStatusGroup_PUF, kPUF_Failure),
107 };
108
109 /*******************************************************************************
110 * API
111 *******************************************************************************/
112 #if defined(__cplusplus)
113 extern "C" {
114 #endif /* __cplusplus */
115
116 /*!
117 * brief Sets the default configuration of PUF
118 *
119 * This function initialize PUF config structure to default values.
120 *
121 * @param conf PUF configuration structure
122 */
123 void PUF_GetDefaultConfig(puf_config_t *conf);
124
125 /*!
126 * brief Initialize PUF
127 *
128 * This function enables power to PUF block and waits until the block initializes.
129 *
130 * @param conf PUF configuration structure
131 * @return Status of the init operation
132 */
133 status_t PUF_Init(PUF_Type *base, puf_config_t *conf);
134
135 /*!
136 * brief Denitialize PUF
137 *
138 * This function disables power to PUF SRAM and peripheral clock.
139 *
140 * @param base PUF peripheral base address
141 * @param conf PUF configuration structure
142 */
143 void PUF_Deinit(PUF_Type *base, puf_config_t *conf);
144
145 /*!
146 * brief Enroll PUF
147 *
148 * This function derives a digital fingerprint, generates the corresponding Activation Code (AC)
149 * and returns it to be stored in an NVM or a file. This step needs to be
150 * performed only once for each device. This function may be permanently disallowed by a fuse.
151 *
152 * @param base PUF peripheral base address
153 * @param[out] activationCode Word aligned address of the resulting activation code.
154 * @param activationCodeSize Size of the activationCode buffer in bytes. Shall be FSL_FEATURE_PUF_ACTIVATION_CODE_SIZE
155 * bytes.
156 * @param score Value of the PUF Score that was obtained during the enroll operation.
157 * @return Status of enroll operation.
158 */
159 status_t PUF_Enroll(PUF_Type *base, uint8_t *activationCode, size_t activationCodeSize, uint8_t *score);
160
161 /*!
162 * brief Start PUF
163 *
164 * The Activation Code generated during the Enroll operation is used to
165 * reconstruct the digital fingerprint. This needs to be done after every power-up
166 * and reset.
167 *
168 * @param base PUF peripheral base address
169 * @param[in] activationCode Word aligned address of the input activation code.
170 * @param activationCodeSize Size of the activationCode buffer in bytes. Shall be FSL_FEATURE_PUF_ACTIVATION_CODE_SIZE
171 * bytes.
172 * @param score Value of the PUF Score that was obtained during the start operation.
173 * return Status of start operation.
174 */
175 status_t PUF_Start(PUF_Type *base, const uint8_t *activationCode, size_t activationCodeSize, uint8_t *score);
176
177 /*!
178 * brief Stop PUF
179 *
180 * The Stop operation removes all key material from PUF flipflops and PUF SRAM, and sets
181 * PUF to the Stopped state.
182 *
183 * @param base PUF peripheral base address
184 * @return Status of stop operation.
185 */
186 status_t PUF_Stop(PUF_Type *base);
187
188 /*!
189 * brief PUF Get Key
190 *
191 * The Get Key operation derives a key from the intrinsic PUF key and externally provided context.
192 *
193 * @param base PUF peripheral base address
194 * @param keyCtx PUF key context struct
195 * @param keyDest output destination of the derived PUF key
196 * @param[out] key Word aligned address of output key (only used when kPUF_KeyDestRegister).
197 * @param keySize Size of the derived key in bytes.
198 * @return Status of get key operation.
199 */
200 status_t PUF_GetKey(PUF_Type *base, puf_key_ctx_t *keyCtx, puf_key_dest_t keyDest, uint8_t *key, size_t keySize);
201
202 /*!
203 * brief PUF Wrap generated random
204 *
205 * The Wrap Generated Random operation wraps a random key into a Key Code (KC).
206 *
207 * @param base PUF peripheral base address
208 * @param keyCtx PUF key context struct
209 * @param keySize Size of the key to be generated in bytes.
210 * @param[out] keyCode Word aligned address of the resulting key code.
211 * @param keyCodeSize Size of the output keycode in bytes.
212 * @return Status of wrap generated random operation.
213 */
214 status_t PUF_WrapGeneratedRandom(
215 PUF_Type *base, puf_key_ctx_t *keyCtx, size_t keySize, uint8_t *keyCode, size_t keyCodeSize);
216
217 /*!
218 * brief PUF Wrap user key
219 *
220 * The Wrap operation wraps a user defined key into a Key Code (KC).
221 *
222 * @param base PUF peripheral base address
223 * @param keyCtx PUF key context struct.
224 * @param userKey Word aligned address of input user key.
225 * @param userKeySize Size of the key to be wrapped in bytes.
226 * @param[out] keyCode Word aligned address of the resulting key code.
227 * @param keyCodeSize Size of the output keycode in bytes.
228 * @return Status of wrap operation.
229 */
230 status_t PUF_Wrap(
231 PUF_Type *base, puf_key_ctx_t *keyCtx, uint8_t *userKey, size_t userKeySize, uint8_t *keyCode, size_t keyCodeSize);
232
233 /*!
234 * brief PUF Unwrap user key
235 *
236 * The unwrap operation unwraps the key from a previously created Key Code (KC)
237 *
238 * @param base PUF peripheral base address
239 * @param keyDest output destination of the unwraped PUF key
240 * @param[in] keyCode Word aligned address of the input key code.
241 * @param keyCodeSize Size of the input keycode in bytes.
242 * @param key Word aligned address of output key (only used when kPUF_KeyDestRegister).
243 * @param keySize Size of the key to be generated in bytes.
244 * @return Status of unwrap operation.
245 */
246 status_t PUF_Unwrap(
247 PUF_Type *base, puf_key_dest_t keyDest, uint8_t *keyCode, size_t keyCodeSize, uint8_t *key, size_t keySize);
248
249 /*!
250 * brief Generate Random
251 *
252 * The Generate Random operation outputs the requested amount of random data as specified in a
253 * provided context.
254 *
255 * @param base PUF peripheral base address
256 * @param size Size of random data to be genarated in bytes.
257 * @return Status of generate random operation.
258 */
259 status_t PUF_GenerateRandom(PUF_Type *base, uint8_t *data, size_t size);
260
261 /*!
262 * brief Zeroize PUF
263 *
264 * This function clears all PUF internal logic and puts the PUF to zeroized state.
265 *
266 * @param base PUF peripheral base address
267 * @return Status of the zeroize operation.
268 */
269 status_t PUF_Zeroize(PUF_Type *base);
270
271 /*!
272 * brief Test PUF
273 *
274 * With the Test PUF operation, diagnostics about the PUF quality is collected and presented in a PUF
275 * score.
276 *
277 * @param base PUF peripheral base address
278 * @param score Value of the PUF Score that was obtained during the enroll operation.
279 * @return Status of the test operation.
280 */
281 status_t PUF_Test(PUF_Type *base, uint8_t *score);
282
283 /*!
284 * @brief Blocks specified PUF commands
285 *
286 * This function blocks PUF commands specified by mask parameter.
287 *
288 * @param base PUF peripheral base address
289 * @param mask Mask of parameters which should be blocked until power-cycle.
290 * @return Status of the test operation.
291 */
PUF_BlockCommand(PUF_Type * base,uint32_t mask)292 static inline void PUF_BlockCommand(PUF_Type *base, uint32_t mask)
293 {
294 base->CONFIG |= mask;
295 }
296
297 /*!
298 * brief Set lock of PUF operation
299 *
300 * Lock the security level of PUF block until key generate, wrap or unwrap operation is completed.
301 * Note: Only security level defined in SEC_LOCK register can use PUFv3 or change its security level.
302 * Default setting after leaving ROM is Secure-Privilege
303 *
304 * @param base PUF peripheral base address
305 * @param securityLevel Security level of PUF block.
306 * @return Status of the test operation.
307 */
308 status_t PUF_SetLock(PUF_Type *base, puf_sec_level_t securityLevel);
309
310 /*!
311 * brief Set App Context mask
312 *
313 * This function sets Application defined context mask used in conjunction with key user context 2.
314 * Whenever bit in this register is 1, corresponding bit in user context 2 provided
315 * during key code creation should be zero only.
316 *
317 * This register is only modifiable by task running at secure-privilege level.
318 *
319 * @param base PUF peripheral base address
320 * @param appCtxMask Value of the Application defined context mask.
321 * @return Status of the test operation.
322 */
323 status_t PUF_SetCtxMask(PUF_Type *base, uint32_t appCtxMask);
324
325 #if defined(__cplusplus)
326 }
327 #endif /* __cplusplus */
328
329 #endif /* _PUF_H_ */
330