fsl_puf.h 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233
  1. /*
  2. * Copyright 2018 NXP
  3. * All rights reserved.
  4. *
  5. *
  6. * SPDX-License-Identifier: BSD-3-Clause
  7. */
  8. #ifndef _PUF_H_
  9. #define _PUF_H_
  10. #include <stddef.h>
  11. #include <stdint.h>
  12. #include "fsl_common.h"
  13. #define swap_bytes(in) __REV(in)
  14. typedef enum _puf_key_index_register
  15. {
  16. kPUF_KeyIndex_00 = 0x00U,
  17. kPUF_KeyIndex_01 = 0x01U,
  18. kPUF_KeyIndex_02 = 0x02U,
  19. kPUF_KeyIndex_03 = 0x03U,
  20. kPUF_KeyIndex_04 = 0x04U,
  21. kPUF_KeyIndex_05 = 0x05U,
  22. kPUF_KeyIndex_06 = 0x06U,
  23. kPUF_KeyIndex_07 = 0x07U,
  24. kPUF_KeyIndex_08 = 0x08U,
  25. kPUF_KeyIndex_09 = 0x09U,
  26. kPUF_KeyIndex_10 = 0x0AU,
  27. kPUF_KeyIndex_11 = 0x0BU,
  28. kPUF_KeyIndex_12 = 0x0CU,
  29. kPUF_KeyIndex_13 = 0x0DU,
  30. kPUF_KeyIndex_14 = 0x0EU,
  31. kPUF_KeyIndex_15 = 0x0FU,
  32. } puf_key_index_register_t;
  33. typedef enum _puf_min_max
  34. {
  35. kPUF_KeySizeMin = 8u,
  36. kPUF_KeySizeMax = 512u,
  37. kPUF_KeyIndexMax = kPUF_KeyIndex_15,
  38. } puf_min_max_t;
  39. typedef enum _puf_key_slot
  40. {
  41. kPUF_KeySlot0 = 0U, /*!< PUF key slot 0 */
  42. kPUF_KeySlot1 = 1U, /*!< PUF key slot 1 */
  43. #if defined(FSL_FEATURE_PUF_HAS_KEYSLOTS) && (FSL_FEATURE_PUF_HAS_KEYSLOTS > 2)
  44. kPUF_KeySlot2 = 2U, /*!< PUF key slot 2 */
  45. kPUF_KeySlot3 = 3U, /*!< PUF key slot 3 */
  46. #endif
  47. } puf_key_slot_t;
  48. /*! @brief Get Key Code size in bytes from key size in bytes at compile time. */
  49. #define PUF_GET_KEY_CODE_SIZE_FOR_KEY_SIZE(x) ((160u + ((((x << 3) + 255u) >> 8) << 8)) >> 3)
  50. #define PUF_MIN_KEY_CODE_SIZE PUF_GET_KEY_CODE_SIZE_FOR_KEY_SIZE(8)
  51. #define PUF_ACTIVATION_CODE_SIZE 1192
  52. /*******************************************************************************
  53. * API
  54. *******************************************************************************/
  55. #if defined(__cplusplus)
  56. extern "C" {
  57. #endif /* __cplusplus */
  58. /*!
  59. * @brief Initialize PUF
  60. *
  61. * This function enables power to PUF block and waits until the block initializes.
  62. *
  63. * @param base PUF peripheral base address
  64. * @param dischargeTimeMsec time in ms to wait for PUF SRAM to fully discharge
  65. * @param coreClockFrequencyHz core clock frequency in Hz
  66. * @return Status of the init operation
  67. */
  68. status_t PUF_Init(PUF_Type *base, uint32_t dischargeTimeMsec, uint32_t coreClockFrequencyHz);
  69. /*!
  70. * @brief Denitialize PUF
  71. *
  72. * This function disables power to PUF SRAM and peripheral clock.
  73. *
  74. * @param base PUF peripheral base address
  75. * @param dischargeTimeMsec time in ms to wait for PUF SRAM to fully discharge
  76. * @param coreClockFrequencyHz core clock frequency in Hz
  77. */
  78. void PUF_Deinit(PUF_Type *base, uint32_t dischargeTimeMsec, uint32_t coreClockFrequencyHz);
  79. /*!
  80. * @brief Enroll PUF
  81. *
  82. * This function derives a digital fingerprint, generates the corresponding Activation Code (AC)
  83. * and returns it to be stored in an NVM or a file. This step needs to be
  84. * performed only once for each device. This function may be permanently disallowed by a fuse.
  85. *
  86. * @param base PUF peripheral base address
  87. * @param[out] activationCode Word aligned address of the resulting activation code.
  88. * @param activationCodeSize Size of the activationCode buffer in bytes. Shall be 1192 bytes.
  89. * @return Status of enroll operation.
  90. */
  91. status_t PUF_Enroll(PUF_Type *base, uint8_t *activationCode, size_t activationCodeSize);
  92. /*!
  93. * @brief Start PUF
  94. *
  95. * The Activation Code generated during the Enroll operation is used to
  96. * reconstruct the digital fingerprint. This needs to be done after every power-up
  97. * and reset.
  98. *
  99. * @param base PUF peripheral base address
  100. * @param activationCode Word aligned address of the input activation code.
  101. * @param activationCodeSize Size of the activationCode buffer in bytes. Shall be 1192 bytes.
  102. * @return Status of start operation.
  103. */
  104. status_t PUF_Start(PUF_Type *base, const uint8_t *activationCode, size_t activationCodeSize);
  105. /*!
  106. * @brief Set intrinsic key
  107. *
  108. * The digital fingerprint generated during the Enroll/Start
  109. * operations is used to generate a Key Code (KC) that defines a unique intrinsic
  110. * key. This KC is returned to be stored in an NVM or a file. This operation
  111. * needs to be done only once for each intrinsic key.
  112. * Each time a Set Intrinsic Key operation is executed a new unique key is
  113. * generated.
  114. *
  115. * @param base PUF peripheral base address
  116. * @param keyIndex PUF key index register
  117. * @param keySize Size of the intrinsic key to generate in bytes.
  118. * @param[out] keyCode Word aligned address of the resulting key code.
  119. * @param keyCodeSize Size of the keyCode buffer in bytes. Shall be PUF_GET_KEY_CODE_SIZE_FOR_KEY_SIZE(keySize).
  120. * @return Status of set intrinsic key operation.
  121. */
  122. status_t PUF_SetIntrinsicKey(
  123. PUF_Type *base, puf_key_index_register_t keyIndex, size_t keySize, uint8_t *keyCode, size_t keyCodeSize);
  124. /*!
  125. * @brief Set user key
  126. *
  127. * The digital fingerprint generated during the Enroll/Start
  128. * operations and a user key (UK) provided as input are used to
  129. * generate a Key Code (KC). This KC is sent returned to be stored
  130. * in an NVM or a file. This operation needs to be done only once for each user key.
  131. *
  132. * @param base PUF peripheral base address
  133. * @param keyIndex PUF key index register
  134. * @param userKey Word aligned address of input user key.
  135. * @param userKeySize Size of the input user key in bytes.
  136. * @param[out] keyCode Word aligned address of the resulting key code.
  137. * @param keyCodeSize Size of the keyCode buffer in bytes. Shall be PUF_GET_KEY_CODE_SIZE_FOR_KEY_SIZE(userKeySize).
  138. * @return Status of set user key operation.
  139. */
  140. status_t PUF_SetUserKey(PUF_Type *base,
  141. puf_key_index_register_t keyIndex,
  142. const uint8_t *userKey,
  143. size_t userKeySize,
  144. uint8_t *keyCode,
  145. size_t keyCodeSize);
  146. /*!
  147. * @brief Reconstruct key from a key code
  148. *
  149. * The digital fingerprint generated during the Start operation and the KC
  150. * generated during a Set Key operation (Set intrinsic key or Set user key) are used to retrieve a stored key. This
  151. * operation needs to be done every time a key is needed.
  152. * This function accepts only Key Codes created for PUF index registers kPUF_KeyIndex_01 to kPUF_KeyIndex_15.
  153. *
  154. * @param base PUF peripheral base address
  155. * @param keyCode Word aligned address of the input key code.
  156. * @param keyCodeSize Size of the keyCode buffer in bytes. Shall be PUF_GET_KEY_CODE_SIZE_FOR_KEY_SIZE(keySize).
  157. * @param[out] key Word aligned address of output key.
  158. * @param keySize Size of the output key in bytes.
  159. * @return Status of get key operation.
  160. */
  161. status_t PUF_GetKey(PUF_Type *base, const uint8_t *keyCode, size_t keyCodeSize, uint8_t *key, size_t keySize);
  162. /*!
  163. * @brief Reconstruct hw bus key from a key code
  164. *
  165. * The digital fingerprint generated during the Start operation and the KC
  166. * generated during a Set Key operation (Set intrinsic key or Set user key) are used to retrieve a stored key. This
  167. * operation needs to be done every time a key is needed.
  168. * This function accepts only Key Codes created for PUF index register kPUF_KeyIndex_00.
  169. * Such a key is output directly to a dedicated hardware bus. The reconstructed key is not exposed to system memory.
  170. *
  171. * @param base PUF peripheral base address
  172. * @param keyCode Word aligned address of the input key code.
  173. * @param keyCodeSize Size of the keyCode buffer in bytes. Shall be PUF_GET_KEY_CODE_SIZE_FOR_KEY_SIZE(keySize).
  174. * @param keySlot key slot to output on hw bus. Parameter is ignored on devices with less than two key slots.
  175. * @param keyMask key masking value. Shall be random for each POR/reset. Value does not have to be cryptographicaly
  176. * secure.
  177. * @return Status of get key operation.
  178. */
  179. status_t PUF_GetHwKey(
  180. PUF_Type *base, const uint8_t *keyCode, size_t keyCodeSize, puf_key_slot_t keySlot, uint32_t keyMask);
  181. /*!
  182. * @brief Zeroize PUF
  183. *
  184. * This function clears all PUF internal logic and puts the PUF to error state.
  185. *
  186. * @param base PUF peripheral base address
  187. * @return Status of the zeroize operation.
  188. */
  189. status_t PUF_Zeroize(PUF_Type *base);
  190. /*!
  191. * @brief Checks if Get Key operation is allowed.
  192. *
  193. * This function returns true if get key operation is allowed.
  194. *
  195. * @param base PUF peripheral base address
  196. * @return true if get key operation is allowed
  197. */
  198. bool PUF_IsGetKeyAllowed(PUF_Type *base);
  199. static inline void PUF_BlockSetKey(PUF_Type *base)
  200. {
  201. base->CFG |= PUF_CFG_BLOCKKEYOUTPUT_MASK; /* block set key */
  202. }
  203. static inline void PUF_BlockEnroll(PUF_Type *base)
  204. {
  205. base->CFG |= PUF_CFG_BLOCKENROLL_SETKEY_MASK; /* block enroll */
  206. }
  207. #if defined(__cplusplus)
  208. }
  209. #endif /* __cplusplus */
  210. #endif /* _PUF_H_ */