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