fsl_bee.c 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303
  1. /*
  2. * Copyright 2017, 2019 NXP
  3. * All rights reserved.
  4. *
  5. *
  6. * SPDX-License-Identifier: BSD-3-Clause
  7. */
  8. #include "fsl_bee.h"
  9. /*******************************************************************************
  10. * Definitions
  11. ******************************************************************************/
  12. /* Component ID definition, used by tools. */
  13. #ifndef FSL_COMPONENT_ID
  14. #define FSL_COMPONENT_ID "platform.drivers.bee"
  15. #endif
  16. /*******************************************************************************
  17. * Variables
  18. ******************************************************************************/
  19. /*******************************************************************************
  20. * Code
  21. ******************************************************************************/
  22. static void aligned_memcpy(void *dst, const void *src, size_t size)
  23. {
  24. register uint32_t *to32 = (uint32_t *)(uint32_t *)dst;
  25. register const uint32_t *from32 = (const uint32_t *)(const uint32_t *)src;
  26. while (size >= sizeof(uint32_t))
  27. {
  28. *to32 = *from32;
  29. size -= sizeof(uint32_t);
  30. to32++;
  31. from32++;
  32. }
  33. }
  34. /*!
  35. * brief Resets BEE module to factory default values.
  36. *
  37. * This function performs hardware reset of BEE module. Attributes and keys from software for both regions are cleared.
  38. *
  39. * param base BEE peripheral address.
  40. */
  41. void BEE_Init(BEE_Type *base)
  42. {
  43. #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
  44. CLOCK_EnableClock(kCLOCK_Bee);
  45. #endif
  46. base->CTRL = BEE_CTRL_CTRL_SFTRST_N_MASK | BEE_CTRL_CTRL_CLK_EN_MASK;
  47. }
  48. /*!
  49. * brief Resets BEE module, clears keys for both regions and disables clock to the BEE.
  50. *
  51. * This function performs hardware reset of BEE module and disables clocks. Attributes and keys from software for both
  52. * regions are cleared.
  53. *
  54. * param base BEE peripheral address.
  55. */
  56. void BEE_Deinit(BEE_Type *base)
  57. {
  58. base->CTRL &=
  59. ~(BEE_CTRL_BEE_ENABLE_MASK | BEE_CTRL_CTRL_SFTRST_N_MASK | BEE_CTRL_CTRL_CLK_EN_MASK | BEE_CTRL_KEY_VALID_MASK);
  60. #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
  61. CLOCK_DisableClock(kCLOCK_Bee);
  62. #endif
  63. }
  64. /*!
  65. * brief Loads default values to the BEE region configuration structure.
  66. *
  67. * Loads default values to the BEE region configuration structure. The default values are as follows:
  68. * code
  69. * config->region0Mode = kBEE_AesCtrMode;
  70. * config->region1Mode = kBEE_AesCtrMode;
  71. * config->region0AddrOffset = 0U;
  72. * config->region1AddrOffset = 0U;
  73. * config->region0SecLevel = kBEE_SecurityLevel3;
  74. * config->region1SecLevel = kBEE_SecurityLevel3;
  75. * config->region1Bot = 0U;
  76. * config->region1Top = 0U;
  77. * config->accessPermission = kBEE_AccessProtDisabled;
  78. * config->endianSwapEn = kBEE_EndianSwapEnabled;
  79. * endcode
  80. *
  81. * param config Configuration structure for BEE peripheral.
  82. */
  83. void BEE_GetDefaultConfig(bee_region_config_t *config)
  84. {
  85. assert(config);
  86. /* Initializes the configure structure to zero. */
  87. (void)memset(config, 0, sizeof(*config));
  88. config->region0Mode = kBEE_AesCtrMode;
  89. config->region1Mode = kBEE_AesCtrMode;
  90. config->region0AddrOffset = 0U;
  91. config->region1AddrOffset = 0U;
  92. config->region0SecLevel = kBEE_SecurityLevel3;
  93. config->region1SecLevel = kBEE_SecurityLevel3;
  94. config->region1Bot = 0U;
  95. config->region1Top = 0U;
  96. config->accessPermission = kBEE_AccessProtDisabled;
  97. config->endianSwapEn = kBEE_EndianSwapEnabled;
  98. }
  99. /*!
  100. * brief Sets BEE configuration.
  101. *
  102. * This function sets BEE peripheral and BEE region settings accorging to given configuration structure.
  103. *
  104. * param base BEE peripheral address.
  105. * param config Configuration structure for BEE.
  106. */
  107. void BEE_SetConfig(BEE_Type *base, const bee_region_config_t *config)
  108. {
  109. uint32_t beeCtrlVal;
  110. bool reenable = false;
  111. /* Wait until BEE is in idle state */
  112. while (0U == (BEE_GetStatusFlags(base) & (uint32_t)kBEE_IdleFlag))
  113. {
  114. }
  115. /* Disable BEE before region configuration in case it is enabled. */
  116. if ((base->CTRL & BEE_CTRL_BEE_ENABLE_MASK) != 0U)
  117. {
  118. BEE_Disable(base);
  119. reenable = true;
  120. }
  121. /* Preserve CTRL bit values that are not set by this function */
  122. beeCtrlVal = base->CTRL & 0xFFFF0037U;
  123. /* Set variable according to configuration */
  124. beeCtrlVal |= BEE_CTRL_AC_PROT_EN(config->accessPermission) | BEE_CTRL_LITTLE_ENDIAN(config->endianSwapEn) |
  125. BEE_CTRL_SECURITY_LEVEL_R0(config->region0SecLevel) | BEE_CTRL_CTRL_AES_MODE_R0(config->region0Mode) |
  126. BEE_CTRL_SECURITY_LEVEL_R1(config->region1SecLevel) | BEE_CTRL_CTRL_AES_MODE_R1(config->region1Mode);
  127. /* Load values to registers */
  128. base->CTRL = beeCtrlVal;
  129. base->ADDR_OFFSET0 = config->region0AddrOffset;
  130. base->ADDR_OFFSET1 = config->region1AddrOffset;
  131. base->REGION1_BOT = config->region1Bot;
  132. base->REGION1_TOP = config->region1Top;
  133. /* Reenable BEE if it was enabled before. */
  134. if (reenable)
  135. {
  136. BEE_Enable(base);
  137. }
  138. }
  139. /*!
  140. * brief Loads the AES key for selected region into BEE key registers.
  141. *
  142. * This function loads given AES key to BEE register for the given region.
  143. * The key must be 32-bit aligned and stored in little-endian format.
  144. *
  145. * Please note, that eFuse BEE_KEYx_SEL must be set accordingly to be able to load and use key loaded in BEE registers.
  146. * Otherwise, key cannot loaded and BEE will use key from OTPMK or SW_GP2.
  147. *
  148. * param base BEE peripheral address.
  149. * param region Selection of the BEE region to be configured.
  150. * param key AES key (in little-endian format).
  151. * param keySize Size of AES key.
  152. */
  153. status_t BEE_SetRegionKey(BEE_Type *base, bee_region_t region, const uint8_t *key, size_t keySize)
  154. {
  155. bool redisable = false;
  156. /* Key must be 32-bit aligned */
  157. if ((0U != ((uintptr_t)key & 0x3u)) || (keySize != 16U))
  158. {
  159. return kStatus_InvalidArgument;
  160. }
  161. /* Wait until BEE is in idle state */
  162. while (0U == (BEE_GetStatusFlags(base) & (uint32_t)kBEE_IdleFlag))
  163. {
  164. }
  165. /* Clear KEY_VALID bit before new key is loaded */
  166. base->CTRL &= ~BEE_CTRL_KEY_VALID_MASK;
  167. /* Write key registers, key is stored in little-endian format in memory */
  168. aligned_memcpy((uint32_t *)(uint32_t)&base->AES_KEY0_W0, key, keySize);
  169. /* Enable BEE before key configuration. */
  170. if (0U == (base->CTRL & BEE_CTRL_BEE_ENABLE_MASK))
  171. {
  172. BEE_Enable(base);
  173. redisable = true;
  174. }
  175. if (region == kBEE_Region0)
  176. {
  177. base->CTRL &= ~BEE_CTRL_KEY_REGION_SEL_MASK;
  178. }
  179. else if (region == kBEE_Region1)
  180. {
  181. base->CTRL |= BEE_CTRL_KEY_REGION_SEL_MASK;
  182. }
  183. else
  184. {
  185. return kStatus_InvalidArgument;
  186. }
  187. /* Set KEY_VALID bit to trigger key loading */
  188. base->CTRL |= BEE_CTRL_KEY_VALID_MASK;
  189. /* Wait until key is ready */
  190. while (0U == (base->CTRL & BEE_CTRL_KEY_VALID_MASK))
  191. {
  192. }
  193. /* Redisable BEE if it was disabled before this function call. */
  194. if (redisable)
  195. {
  196. BEE_Disable(base);
  197. }
  198. return kStatus_Success;
  199. }
  200. /*!
  201. * brief Loads the nonce for selected region into BEE nonce registers.
  202. *
  203. * This function loads given nonce(only AES CTR mode) to BEE register for the given region.
  204. * The nonce must be 32-bit aligned and stored in little-endian format.
  205. *
  206. * param base BEE peripheral address.
  207. * param region Selection of the BEE region to be configured.
  208. * param nonce AES nonce (in little-endian format).
  209. * param nonceSize Size of AES nonce.
  210. */
  211. status_t BEE_SetRegionNonce(BEE_Type *base, bee_region_t region, const uint8_t *nonce, size_t nonceSize)
  212. {
  213. /* Nonce must be 32-bit aligned */
  214. if ((0U != ((uintptr_t)nonce & 0x3u)) || (nonceSize != 16U))
  215. {
  216. return kStatus_InvalidArgument;
  217. }
  218. /* Wait until BEE is in idle state */
  219. while (0U == (BEE_GetStatusFlags(base) & (uint32_t)kBEE_IdleFlag))
  220. {
  221. }
  222. /* Write nonce registers, nonce is stored in little-endian format in memory */
  223. if (region == kBEE_Region0)
  224. {
  225. aligned_memcpy((uint32_t *)(uint32_t)&base->CTR_NONCE0_W0, nonce, nonceSize);
  226. }
  227. else if (region == kBEE_Region1)
  228. {
  229. aligned_memcpy((uint32_t *)(uint32_t)&base->CTR_NONCE1_W0, nonce, nonceSize);
  230. }
  231. else
  232. {
  233. return kStatus_InvalidArgument;
  234. }
  235. return kStatus_Success;
  236. }
  237. /*!
  238. * brief Gets the BEE status flags.
  239. *
  240. * This function returns status of BEE peripheral.
  241. *
  242. * param base BEE peripheral address.
  243. *
  244. * return The status flags. This is the logical OR of members of the
  245. * enumeration ::bee_status_flags_t
  246. */
  247. uint32_t BEE_GetStatusFlags(BEE_Type *base)
  248. {
  249. return base->STATUS;
  250. }
  251. /*!
  252. * brief Clears the BEE status flags.
  253. *
  254. * param base BEE peripheral base address.
  255. * param mask The status flags to clear. This is a logical OR of members of the
  256. * enumeration ::bee_status_flags_t
  257. */
  258. void BEE_ClearStatusFlags(BEE_Type *base, uint32_t mask)
  259. {
  260. /* w1c */
  261. base->STATUS |= mask;
  262. }