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