![]() |
|
|||
File indexing completed on 2025-05-11 08:23:00
0001 /* 0002 * Copyright 2018-2021 NXP 0003 * All rights reserved. 0004 * 0005 * 0006 * SPDX-License-Identifier: BSD-3-Clause 0007 */ 0008 0009 #ifndef _PUF_H_ 0010 #define _PUF_H_ 0011 0012 #include <stddef.h> 0013 #include <stdint.h> 0014 0015 #include "fsl_common.h" 0016 0017 /******************************************************************************* 0018 * Definitions 0019 *******************************************************************************/ 0020 0021 /*! 0022 * @addtogroup puf_driver 0023 * @{ 0024 */ 0025 /*! @name Driver version */ 0026 /*@{*/ 0027 /*! @brief PUF driver version. Version 2.1.6. 0028 * 0029 * Current version: 2.1.6 0030 * 0031 * Change log: 0032 * - 2.0.0 0033 * - Initial version. 0034 * - 2.0.1 0035 * - Fixed puf_wait_usec function optimization issue. 0036 * - 2.0.2 0037 * - Add PUF configuration structure and support for PUF SRAM controller. 0038 * Remove magic constants. 0039 * - 2.0.3 0040 * - Fix MISRA C-2012 issue. 0041 * - 2.1.0 0042 * - Align driver with PUF SRAM controller registers on LPCXpresso55s16. 0043 * - Update initizalition logic . 0044 * - 2.1.1 0045 * - Fix ARMGCC build warning . 0046 * - 2.1.2 0047 * - Update: Add automatic big to little endian swap for user 0048 * (pre-shared) keys destinated to secret hardware bus (PUF key index 0). 0049 * - 2.1.3 0050 * - Fix MISRA C-2012 issue. 0051 * - 2.1.4 0052 * - Replace register uint32_t ticksCount with volatile uint32_t ticksCount in puf_wait_usec() to prevent optimization 0053 * out delay loop. 0054 * - 2.1.5 0055 * - Use common SDK delay in puf_wait_usec() 0056 * - 2.1.6 0057 * - Changed wait time in PUF_Init(), when initialization fails it will try PUF_Powercycle() with shorter time. If 0058 * this shorter time will also fail, initialization will be tried with worst case time as before. 0059 */ 0060 #define FSL_PUF_DRIVER_VERSION (MAKE_VERSION(2, 1, 6)) 0061 /*@}*/ 0062 0063 typedef enum _puf_key_index_register 0064 { 0065 kPUF_KeyIndex_00 = 0x00U, 0066 kPUF_KeyIndex_01 = 0x01U, 0067 kPUF_KeyIndex_02 = 0x02U, 0068 kPUF_KeyIndex_03 = 0x03U, 0069 kPUF_KeyIndex_04 = 0x04U, 0070 kPUF_KeyIndex_05 = 0x05U, 0071 kPUF_KeyIndex_06 = 0x06U, 0072 kPUF_KeyIndex_07 = 0x07U, 0073 kPUF_KeyIndex_08 = 0x08U, 0074 kPUF_KeyIndex_09 = 0x09U, 0075 kPUF_KeyIndex_10 = 0x0AU, 0076 kPUF_KeyIndex_11 = 0x0BU, 0077 kPUF_KeyIndex_12 = 0x0CU, 0078 kPUF_KeyIndex_13 = 0x0DU, 0079 kPUF_KeyIndex_14 = 0x0EU, 0080 kPUF_KeyIndex_15 = 0x0FU, 0081 } puf_key_index_register_t; 0082 0083 typedef enum _puf_min_max 0084 { 0085 kPUF_KeySizeMin = 8u, 0086 kPUF_KeySizeMax = 512u, 0087 kPUF_KeyIndexMax = kPUF_KeyIndex_15, 0088 } puf_min_max_t; 0089 0090 /*! @brief PUF key slot. */ 0091 typedef enum _puf_key_slot 0092 { 0093 kPUF_KeySlot0 = 0U, /*!< PUF key slot 0 */ 0094 kPUF_KeySlot1 = 1U, /*!< PUF key slot 1 */ 0095 #if defined(PUF_KEYMASK_COUNT) && (PUF_KEYMASK_COUNT > 2) 0096 kPUF_KeySlot2 = 2U, /*!< PUF key slot 2 */ 0097 kPUF_KeySlot3 = 3U, /*!< PUF key slot 3 */ 0098 #endif 0099 } puf_key_slot_t; 0100 0101 typedef struct 0102 { 0103 uint32_t dischargeTimeMsec; 0104 uint32_t coreClockFrequencyHz; 0105 #if defined(FSL_FEATURE_PUF_HAS_SRAM_CTRL) && (FSL_FEATURE_PUF_HAS_SRAM_CTRL > 0) 0106 /* LPCXpresso55s16 */ 0107 PUF_SRAM_CTRL_Type *puf_sram_base; 0108 uint8_t CKGATING; 0109 #endif /* FSL_FEATURE_PUF_HAS_SRAM_CTRL */ 0110 } puf_config_t; 0111 /*! @brief Get Key Code size in bytes from key size in bytes at compile time. */ 0112 #define PUF_GET_KEY_CODE_SIZE_FOR_KEY_SIZE(x) ((160u + (((((x) << 3) + 255u) >> 8) << 8)) >> 3) 0113 #define PUF_MIN_KEY_CODE_SIZE PUF_GET_KEY_CODE_SIZE_FOR_KEY_SIZE(8UL) 0114 #define PUF_ACTIVATION_CODE_SIZE 1192U 0115 #define KEYSTORE_PUF_DISCHARGE_TIME_FIRST_TRY_MS 50 0116 #define KEYSTORE_PUF_DISCHARGE_TIME_MAX_MS 400 0117 0118 /*! PUF status return codes. */ 0119 enum 0120 { 0121 kStatus_EnrollNotAllowed = MAKE_STATUS(kStatusGroup_PUF, 1), 0122 kStatus_StartNotAllowed = MAKE_STATUS(kStatusGroup_PUF, 2) 0123 }; 0124 0125 /*! @} */ 0126 /******************************************************************************* 0127 * API 0128 *******************************************************************************/ 0129 0130 #if defined(__cplusplus) 0131 extern "C" { 0132 #endif /* __cplusplus */ 0133 0134 /*! 0135 * @brief Sets the default configuration of PUF 0136 * 0137 * This function initialize PUF config structure to default values. 0138 * 0139 * @param conf PUF configuration structure 0140 */ 0141 void PUF_GetDefaultConfig(puf_config_t *conf); 0142 0143 /*! 0144 * @brief Initialize PUF 0145 * 0146 * This function enables power to PUF block and waits until the block initializes. 0147 * 0148 * @param base PUF peripheral base address 0149 * @param conf PUF configuration structure 0150 * @return Status of the init operation 0151 */ 0152 status_t PUF_Init(PUF_Type *base, puf_config_t *conf); 0153 0154 /*! 0155 * @brief Denitialize PUF 0156 * 0157 * This function disables power to PUF SRAM and peripheral clock. 0158 * 0159 * @param base PUF peripheral base address 0160 * @param conf PUF configuration structure 0161 */ 0162 void PUF_Deinit(PUF_Type *base, puf_config_t *conf); 0163 0164 /*! 0165 * @brief Enroll PUF 0166 * 0167 * This function derives a digital fingerprint, generates the corresponding Activation Code (AC) 0168 * and returns it to be stored in an NVM or a file. This step needs to be 0169 * performed only once for each device. This function may be permanently disallowed by a fuse. 0170 * 0171 * @param base PUF peripheral base address 0172 * @param[out] activationCode Word aligned address of the resulting activation code. 0173 * @param activationCodeSize Size of the activationCode buffer in bytes. Shall be 1192 bytes. 0174 * @return Status of enroll operation. 0175 */ 0176 status_t PUF_Enroll(PUF_Type *base, uint8_t *activationCode, size_t activationCodeSize); 0177 0178 /*! 0179 * @brief Start PUF 0180 * 0181 * The Activation Code generated during the Enroll operation is used to 0182 * reconstruct the digital fingerprint. This needs to be done after every power-up 0183 * and reset. 0184 * 0185 * @param base PUF peripheral base address 0186 * @param activationCode Word aligned address of the input activation code. 0187 * @param activationCodeSize Size of the activationCode buffer in bytes. Shall be 1192 bytes. 0188 * @return Status of start operation. 0189 */ 0190 status_t PUF_Start(PUF_Type *base, const uint8_t *activationCode, size_t activationCodeSize); 0191 0192 /*! 0193 * @brief Set intrinsic key 0194 * 0195 * The digital fingerprint generated during the Enroll/Start 0196 * operations is used to generate a Key Code (KC) that defines a unique intrinsic 0197 * key. This KC is returned to be stored in an NVM or a file. This operation 0198 * needs to be done only once for each intrinsic key. 0199 * Each time a Set Intrinsic Key operation is executed a new unique key is 0200 * generated. 0201 * 0202 * @param base PUF peripheral base address 0203 * @param keyIndex PUF key index register 0204 * @param keySize Size of the intrinsic key to generate in bytes. 0205 * @param[out] keyCode Word aligned address of the resulting key code. 0206 * @param keyCodeSize Size of the keyCode buffer in bytes. Shall be PUF_GET_KEY_CODE_SIZE_FOR_KEY_SIZE(keySize). 0207 * @return Status of set intrinsic key operation. 0208 */ 0209 status_t PUF_SetIntrinsicKey( 0210 PUF_Type *base, puf_key_index_register_t keyIndex, size_t keySize, uint8_t *keyCode, size_t keyCodeSize); 0211 0212 /*! 0213 * @brief Set user key 0214 * 0215 * The digital fingerprint generated during the Enroll/Start 0216 * operations and a user key (UK) provided as input are used to 0217 * generate a Key Code (KC). This KC is sent returned to be stored 0218 * in an NVM or a file. This operation needs to be done only once for each user key. 0219 * 0220 * @param base PUF peripheral base address 0221 * @param keyIndex PUF key index register 0222 * @param userKey Word aligned address of input user key. 0223 * @param userKeySize Size of the input user key in bytes. 0224 * @param[out] keyCode Word aligned address of the resulting key code. 0225 * @param keyCodeSize Size of the keyCode buffer in bytes. Shall be PUF_GET_KEY_CODE_SIZE_FOR_KEY_SIZE(userKeySize). 0226 * @return Status of set user key operation. 0227 */ 0228 status_t PUF_SetUserKey(PUF_Type *base, 0229 puf_key_index_register_t keyIndex, 0230 const uint8_t *userKey, 0231 size_t userKeySize, 0232 uint8_t *keyCode, 0233 size_t keyCodeSize); 0234 0235 /*! 0236 * @brief Reconstruct key from a key code 0237 * 0238 * The digital fingerprint generated during the Start operation and the KC 0239 * generated during a Set Key operation (Set intrinsic key or Set user key) are used to retrieve a stored key. This 0240 * operation needs to be done every time a key is needed. 0241 * This function accepts only Key Codes created for PUF index registers kPUF_KeyIndex_01 to kPUF_KeyIndex_15. 0242 * 0243 * @param base PUF peripheral base address 0244 * @param keyCode Word aligned address of the input key code. 0245 * @param keyCodeSize Size of the keyCode buffer in bytes. Shall be PUF_GET_KEY_CODE_SIZE_FOR_KEY_SIZE(keySize). 0246 * @param[out] key Word aligned address of output key. 0247 * @param keySize Size of the output key in bytes. 0248 * @return Status of get key operation. 0249 */ 0250 status_t PUF_GetKey(PUF_Type *base, const uint8_t *keyCode, size_t keyCodeSize, uint8_t *key, size_t keySize); 0251 0252 /*! 0253 * @brief Reconstruct hw bus key from a key code 0254 * 0255 * The digital fingerprint generated during the Start operation and the KC 0256 * generated during a Set Key operation (Set intrinsic key or Set user key) are used to retrieve a stored key. This 0257 * operation needs to be done every time a key is needed. 0258 * This function accepts only Key Codes created for PUF index register kPUF_KeyIndex_00. 0259 * Such a key is output directly to a dedicated hardware bus. The reconstructed key is not exposed to system memory. 0260 * 0261 * @param base PUF peripheral base address 0262 * @param keyCode Word aligned address of the input key code. 0263 * @param keyCodeSize Size of the keyCode buffer in bytes. Shall be PUF_GET_KEY_CODE_SIZE_FOR_KEY_SIZE(keySize). 0264 * @param keySlot key slot to output on hw bus. Parameter is ignored on devices with less than two key slots. 0265 * @param keyMask key masking value. Shall be random for each POR/reset. Value does not have to be cryptographicaly 0266 * secure. 0267 * @return Status of get key operation. 0268 */ 0269 status_t PUF_GetHwKey( 0270 PUF_Type *base, const uint8_t *keyCode, size_t keyCodeSize, puf_key_slot_t keySlot, uint32_t keyMask); 0271 0272 /*! 0273 * @brief Zeroize PUF 0274 * 0275 * This function clears all PUF internal logic and puts the PUF to error state. 0276 * 0277 * @param base PUF peripheral base address 0278 * @return Status of the zeroize operation. 0279 */ 0280 status_t PUF_Zeroize(PUF_Type *base); 0281 0282 /*! 0283 * @brief Checks if Get Key operation is allowed. 0284 * 0285 * This function returns true if get key operation is allowed. 0286 * 0287 * @param base PUF peripheral base address 0288 * @return true if get key operation is allowed 0289 */ 0290 bool PUF_IsGetKeyAllowed(PUF_Type *base); 0291 0292 #if defined(PUF_CFG_BLOCKKEYOUTPUT_MASK) && PUF_CFG_BLOCKKEYOUTPUT_MASK 0293 static inline void PUF_BlockSetKey(PUF_Type *base) 0294 { 0295 base->CFG |= PUF_CFG_BLOCKKEYOUTPUT_MASK; /* block set key */ 0296 } 0297 #endif /* PUF_CFG_BLOCKKEYOUTPUT_MASK */ 0298 0299 #if defined(PUF_CFG_PUF_BLOCK_SET_KEY_MASK) && PUF_CFG_PUF_BLOCK_SET_KEY_MASK 0300 static inline void PUF_BlockSetKey(PUF_Type *base) 0301 { 0302 base->CFG |= PUF_CFG_PUF_BLOCK_SET_KEY_MASK; /* block set key */ 0303 } 0304 #endif /* PUF_CFG_PUF_BLOCK_SET_KEY_MASK */ 0305 0306 #if defined(PUF_CFG_BLOCKENROLL_SETKEY_MASK) && PUF_CFG_BLOCKENROLL_SETKEY_MASK 0307 static inline void PUF_BlockEnroll(PUF_Type *base) 0308 { 0309 base->CFG |= PUF_CFG_BLOCKENROLL_SETKEY_MASK; /* block enroll */ 0310 } 0311 #endif /* PUF_CFG_BLOCKENROLL_SETKEY_MASK */ 0312 0313 #if defined(PUF_CFG_PUF_BLOCK_ENROLL_MASK) && PUF_CFG_PUF_BLOCK_ENROLL_MASK 0314 static inline void PUF_BlockEnroll(PUF_Type *base) 0315 { 0316 base->CFG |= PUF_CFG_PUF_BLOCK_ENROLL_MASK; /* block enroll */ 0317 } 0318 #endif /* PUF_CFG_PUF_BLOCK_ENROLL_MASK */ 0319 0320 /*! 0321 * @brief Powercycle PUF 0322 * 0323 * This function make powercycle. 0324 * 0325 * @param base PUF peripheral base address 0326 * @param conf PUF configuration structure 0327 * @return Status of the powercycle operation. 0328 */ 0329 status_t PUF_PowerCycle(PUF_Type *base, puf_config_t *conf); 0330 0331 #if defined(__cplusplus) 0332 } 0333 #endif /* __cplusplus */ 0334 0335 #endif /* _PUF_H_ */
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
![]() ![]() |