1 /*
2 * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7 #include <stdint.h>
8 #include <stddef.h>
9
10 #include "dx_nvm.h"
11 #include "secureboot_general_hwdefs.h"
12 #include "secureboot_stage_defs.h"
13 #include "bsv_error.h"
14 #include "bsv_otp_api.h"
15 #include "cc_otp_defs.h"
16
17 #ifdef CC_SB_SUPPORT_SB_RT
18 #include "driver_defs.h"
19 #include "cc_pal_buff_attr.h"
20 #include "cc_error.h"
21 #endif
22
23 /**********************************************************************************************/
24 /************************ Private declarations ************************************************/
25 /**********************************************************************************************/
26
LoadBsvAesKey(unsigned long hwBaseAddress,CCBsvKeyType_t keyType,uint32_t * pUserKey,size_t userKeySize)27 static CCError_t LoadBsvAesKey(unsigned long hwBaseAddress,
28 CCBsvKeyType_t keyType,
29 uint32_t *pUserKey,
30 size_t userKeySize)
31 {
32 CCError_t error = CC_OK;
33 uint32_t isKeyInUse = 0;
34
35 switch (keyType) {
36
37 case CC_BSV_HUK_KEY:
38 /* validate HUK key */
39 CC_BSV_IS_OTP_HUK_ERROR(hwBaseAddress, error);
40 if (error) {
41 error = CC_BSV_ILLEGAL_HUK_VALUE_ERR;
42 }
43 break;
44
45 case CC_BSV_RTL_KEY:
46 break;
47
48 case CC_BSV_PROV_KEY:
49 /* check if key in use */
50 CC_BSV_IS_KCP_IN_USE(hwBaseAddress, isKeyInUse, error);
51 if ( (error) || (isKeyInUse != CC_TRUE) ) {
52 error = CC_BSV_ILLEGAL_KCP_VALUE_ERR;
53 break;
54 }
55
56 /* validate provisioning key */
57 CC_BSV_IS_OTP_KCP_ERROR(hwBaseAddress, error);
58 if (error) {
59 error = CC_BSV_ILLEGAL_KCP_VALUE_ERR;
60 }
61 break;
62
63 case CC_BSV_CE_KEY:
64 /* check if key in use */
65 CC_BSV_IS_KCE_IN_USE(hwBaseAddress, isKeyInUse, error);
66 if ( (error) || (isKeyInUse != CC_TRUE) ) {
67 error = CC_BSV_ILLEGAL_KCE_VALUE_ERR;
68 break;
69 }
70
71 /* validate code encryption key */
72 CC_BSV_IS_OTP_KCE_ERROR(hwBaseAddress, error);
73 if (error) {
74 error = CC_BSV_ILLEGAL_KCE_VALUE_ERR;
75 }
76 break;
77
78 case CC_BSV_ICV_PROV_KEY:
79 /* check if key in use */
80 CC_BSV_IS_KPICV_IN_USE(hwBaseAddress, isKeyInUse, error);
81 if ( (error) || (isKeyInUse != CC_TRUE) ) {
82 error = CC_BSV_ILLEGAL_KPICV_VALUE_ERR;
83 break;
84 }
85
86 /* validate provisioning key */
87 CC_BSV_IS_OTP_KPICV_ERROR(hwBaseAddress, error);
88 if (error) {
89 error = CC_BSV_ILLEGAL_KPICV_VALUE_ERR;
90 }
91 break;
92
93 case CC_BSV_ICV_CE_KEY:
94 /* check if key in use */
95 CC_BSV_IS_KCEICV_IN_USE(hwBaseAddress, isKeyInUse, error);
96 if ( (error) || (isKeyInUse != CC_TRUE) ) {
97 error = CC_BSV_ILLEGAL_KCEICV_VALUE_ERR;
98 break;
99 }
100
101 /* validate provisioning key */
102 CC_BSV_IS_OTP_KCEICV_ERROR(hwBaseAddress, error);
103 if (error) {
104 error = CC_BSV_ILLEGAL_KCEICV_VALUE_ERR;
105 }
106 break;
107
108 case CC_BSV_USER_KEY:
109 /* load user key */
110 SB_HAL_WRITE_REGISTER(SB_REG_ADDR(hwBaseAddress, AES_KEY_0_0) ,pUserKey[0]);
111 SB_HAL_WRITE_REGISTER(SB_REG_ADDR(hwBaseAddress, AES_KEY_0_1) ,pUserKey[1]);
112 SB_HAL_WRITE_REGISTER(SB_REG_ADDR(hwBaseAddress, AES_KEY_0_2) ,pUserKey[2]);
113 SB_HAL_WRITE_REGISTER(SB_REG_ADDR(hwBaseAddress, AES_KEY_0_3) ,pUserKey[3]);
114
115 if(userKeySize == CC_BSV_256BITS_KEY_SIZE_IN_BYTES) {
116 SB_HAL_WRITE_REGISTER(SB_REG_ADDR(hwBaseAddress, AES_KEY_0_4) ,pUserKey[4]);
117 SB_HAL_WRITE_REGISTER(SB_REG_ADDR(hwBaseAddress, AES_KEY_0_5) ,pUserKey[5]);
118 SB_HAL_WRITE_REGISTER(SB_REG_ADDR(hwBaseAddress, AES_KEY_0_6) ,pUserKey[6]);
119 SB_HAL_WRITE_REGISTER(SB_REG_ADDR(hwBaseAddress, AES_KEY_0_7) ,pUserKey[7]);
120 }
121 break;
122
123 default:
124 /* NOTE: KCE and KCEICV are not supported for CMAC KDF */
125 error = CC_BSV_INVALID_KEY_TYPE_ERROR;
126 break;
127 }
128
129 /* load secret key (HUK / KRTL / KCP / KPICV) */
130 if ( (error==CC_OK) && (keyType!=CC_BSV_USER_KEY)) {
131 SB_HAL_WRITE_REGISTER(SB_REG_ADDR(hwBaseAddress, HOST_CRYPTOKEY_SEL) ,keyType);
132 SB_HAL_WRITE_REGISTER(SB_REG_ADDR(hwBaseAddress, AES_SK) ,0x1);
133 }
134
135 return error;
136 }
137
138
LoadBsvAesIVState(unsigned long hwBaseAddress)139 static void LoadBsvAesIVState(unsigned long hwBaseAddress)
140 {
141 /* write the initial counter value according to mode */
142 SB_HAL_WRITE_REGISTER(SB_REG_ADDR(hwBaseAddress, AES_IV_0_0) ,0);
143 SB_HAL_WRITE_REGISTER(SB_REG_ADDR(hwBaseAddress, AES_IV_0_1) ,0);
144 SB_HAL_WRITE_REGISTER(SB_REG_ADDR(hwBaseAddress, AES_IV_0_2) ,0);
145 SB_HAL_WRITE_REGISTER(SB_REG_ADDR(hwBaseAddress, AES_IV_0_3) ,0);
146
147 return;
148 }
149
150
LoadBsvAesCtrState(unsigned long hwBaseAddress,uint32_t * pCtrStateBuf)151 static void LoadBsvAesCtrState(unsigned long hwBaseAddress, uint32_t *pCtrStateBuf)
152 {
153 /* write the initial counter value according to mode */
154 SB_HAL_WRITE_REGISTER(SB_REG_ADDR(hwBaseAddress, AES_CTR_0_0) ,pCtrStateBuf[0]);
155 SB_HAL_WRITE_REGISTER(SB_REG_ADDR(hwBaseAddress, AES_CTR_0_1) ,pCtrStateBuf[1]);
156 SB_HAL_WRITE_REGISTER(SB_REG_ADDR(hwBaseAddress, AES_CTR_0_2) ,pCtrStateBuf[2]);
157 SB_HAL_WRITE_REGISTER(SB_REG_ADDR(hwBaseAddress, AES_CTR_0_3) ,pCtrStateBuf[3]);
158
159 return;
160 }
161
162
163 /**********************************************************************************************/
164 /************************ Public Functions ******************************/
165 /**********************************************************************************************/
166
InitBsvAes(unsigned long hwBaseAddress)167 void InitBsvAes(unsigned long hwBaseAddress)
168 {
169 uint32_t regVal = 0;
170
171 /* enable clocks */
172 SB_HAL_WRITE_REGISTER(SB_REG_ADDR(hwBaseAddress, AES_CLK_ENABLE) ,CC_BSV_CLOCK_ENABLE);
173 SB_HAL_WRITE_REGISTER(SB_REG_ADDR(hwBaseAddress, DMA_CLK_ENABLE) ,CC_BSV_CLOCK_ENABLE);
174
175 /* make sure sym engines are ready to use */
176 CC_BSV_WAIT_ON_CRYPTO_BUSY();
177
178 /* clear all interrupts before starting the engine */
179 SB_HalClearInterruptBit(hwBaseAddress, 0xFFFFFFFFUL);
180
181 /* mask dma interrupts which are not required */
182 CC_REG_FLD_SET(HOST_RGF, HOST_IMR, SRAM_TO_DIN_MASK, regVal, CC_TRUE);
183 CC_REG_FLD_SET(HOST_RGF, HOST_IMR, DOUT_TO_SRAM_MASK, regVal, CC_TRUE);
184 CC_REG_FLD_SET(HOST_RGF, HOST_IMR, MEM_TO_DIN_MASK, regVal, CC_TRUE);
185 CC_REG_FLD_SET(HOST_RGF, HOST_IMR, DOUT_TO_MEM_MASK, regVal, CC_TRUE);
186 SB_HalMaskInterrupt(hwBaseAddress, regVal);
187
188 /* configure CC to AES */
189 SB_HAL_WRITE_REGISTER(SB_REG_ADDR(hwBaseAddress, CRYPTO_CTL) ,BSV_CRYPTO_AES);
190
191 /* zero AES_REMAINING_BYTES */
192 SB_HAL_WRITE_REGISTER(SB_REG_ADDR(hwBaseAddress, AES_REMAINING_BYTES) ,0);
193
194 return;
195 }
196
197
FreeBsvAes(unsigned long hwBaseAddress)198 void FreeBsvAes(unsigned long hwBaseAddress)
199 {
200 /* disable clocks */
201 SB_HAL_WRITE_REGISTER(SB_REG_ADDR(hwBaseAddress, AES_CLK_ENABLE) ,CC_BSV_CLOCK_DISABLE);
202 SB_HAL_WRITE_REGISTER(SB_REG_ADDR(hwBaseAddress, DMA_CLK_ENABLE) ,CC_BSV_CLOCK_DISABLE);
203
204 return;
205 }
206
207
ProcessBsvAes(unsigned long hwBaseAddress,bsvAesMode_t mode,CCBsvKeyType_t keyType,uint32_t * pUserKey,size_t userKeySize,uint32_t * pCtrStateBuf,uint32_t inputDataAddr,uint32_t outputDataAddr,uint32_t dataSize,uint8_t isLoadIv)208 CCError_t ProcessBsvAes(unsigned long hwBaseAddress,
209 bsvAesMode_t mode,
210 CCBsvKeyType_t keyType,
211 uint32_t *pUserKey,
212 size_t userKeySize,
213 uint32_t *pCtrStateBuf,
214 uint32_t inputDataAddr,
215 uint32_t outputDataAddr,
216 uint32_t dataSize,
217 uint8_t isLoadIv)
218 {
219 CCError_t error = CC_OK;
220 uint32_t irrVal = 0;
221 uint32_t aesCtrl = 0;
222
223 #ifdef CC_SB_SUPPORT_SB_RT
224 drvError_t drvRet = CC_OK;
225 uint8_t buffNs = 0;
226 uint32_t regVal = 0;
227 #endif
228
229 /* set AES configuration word */
230 CC_REG_FLD_SET(HOST_RGF, AES_CONTROL, DEC_KEY0, aesCtrl, BSV_AES_DIRECTION_ENCRYPT);
231 CC_REG_FLD_SET(HOST_RGF, AES_CONTROL, MODE_KEY0, aesCtrl, mode);
232 if ( (keyType == CC_BSV_HUK_KEY) ||
233 ((keyType == CC_BSV_USER_KEY) && (userKeySize == CC_BSV_256BITS_KEY_SIZE_IN_BYTES)) ){
234 /* 256b keys: HUK, user key */
235 CC_REG_FLD_SET(HOST_RGF, AES_CONTROL, NK_KEY0, aesCtrl, BSV_AES_KEY_SIZE_256BITS);
236 } else {
237 /* 128b keys: RTL, KCP, KCE, KPICV, KCEICV, user key */
238 CC_REG_FLD_SET(HOST_RGF, AES_CONTROL, NK_KEY0, aesCtrl, BSV_AES_KEY_SIZE_128BITS);
239 }
240 SB_HAL_WRITE_REGISTER(SB_REG_ADDR(hwBaseAddress, AES_CONTROL) ,aesCtrl);
241
242 /* load AES key */
243 error = LoadBsvAesKey(hwBaseAddress, keyType, pUserKey, userKeySize);
244 if(error != CC_OK) {
245 FreeBsvAes(hwBaseAddress);
246 return error;
247 }
248
249 if(mode == BSV_AES_CIPHER_CTR) {
250 if (isLoadIv == CC_TRUE){
251 /* load ctr regs */
252 LoadBsvAesCtrState(hwBaseAddress, pCtrStateBuf);
253 }
254
255
256 #ifdef CC_SB_SUPPORT_SB_RT
257 /* Need to verify the outputDataAddr memory type and configure CC's AHBM accordingly */
258 drvRet = CC_PalDataBufferAttrGet((uint8_t*)outputDataAddr, dataSize, OUTPUT_DATA_BUFFER, &buffNs);
259 if (drvRet != CC_OK){
260 FreeBsvAes(hwBaseAddress);
261 return CC_FATAL_ERROR;
262 }
263 /* set it in regVal just if we have an output */
264 CC_REG_FLD_SET(HOST_RGF, AHBM_HNONSEC, AHB_WRITE_HNONSEC, regVal, buffNs);
265
266 #endif
267 /* configure destination address in case of ctr */
268 SB_HAL_WRITE_REGISTER(SB_REG_ADDR(hwBaseAddress, DST_LLI_WORD0) ,outputDataAddr);
269 SB_HAL_WRITE_REGISTER(SB_REG_ADDR(hwBaseAddress, DST_LLI_WORD1) ,dataSize);
270
271 } else {
272 /* case CMAC */
273 if (isLoadIv == CC_TRUE){
274 /* load iv length */
275 LoadBsvAesIVState(hwBaseAddress);
276 /* initiate CMAC sub-keys calculation */
277 SB_HAL_WRITE_REGISTER(SB_REG_ADDR(hwBaseAddress, AES_CMAC_INIT) ,CC_TRUE);
278 }
279
280 /* set the remaining bytes */
281 SB_HAL_WRITE_REGISTER(SB_REG_ADDR(hwBaseAddress, AES_REMAINING_BYTES) ,dataSize);
282 }
283
284
285 /* if data size is 0, only set HW reg to 1 */
286 if(dataSize == 0)
287 SB_HAL_WRITE_REGISTER(SB_REG_ADDR(hwBaseAddress, AES_CMAC_SIZE0_KICK) ,CC_TRUE);
288 else {
289
290 #ifdef CC_SB_SUPPORT_SB_RT
291 /* Need to verify the outputDataAddr memory type and configure CC's AHBM accordingly */
292 drvRet = CC_PalDataBufferAttrGet((uint8_t*)inputDataAddr, dataSize, INPUT_DATA_BUFFER, &buffNs);
293 if (drvRet != CC_OK){
294 FreeBsvAes(hwBaseAddress);
295 return CC_FATAL_ERROR;
296 }
297 /* if we had and output regVal already contains the output attribute */
298 CC_REG_FLD_SET(HOST_RGF, AHBM_HNONSEC, AHB_READ_HNONSEC, regVal, buffNs);
299 SB_HAL_WRITE_REGISTER(SB_REG_ADDR(hwBaseAddress, AHBM_HNONSEC) ,regVal);
300
301 #endif
302
303 /* configure source address and size */
304 SB_HAL_WRITE_REGISTER(SB_REG_ADDR(hwBaseAddress, SRC_LLI_WORD0) ,inputDataAddr);
305 SB_HAL_WRITE_REGISTER(SB_REG_ADDR(hwBaseAddress, SRC_LLI_WORD1) ,dataSize);
306
307 /* set dma completion bit in irr */
308 CC_REG_FLD_SET(HOST_RGF, HOST_IRR, SYM_DMA_COMPLETED, irrVal, 1);
309 error = SB_HalWaitInterrupt(hwBaseAddress, irrVal);
310 if(error != CC_OK) {
311 FreeBsvAes(hwBaseAddress);
312 }
313 }
314
315 return error;
316 }
317
318
FinishBsvAes(unsigned long hwBaseAddress,bsvAesMode_t mode,CCBsvCmacResult_t cmacResBuf)319 void FinishBsvAes(unsigned long hwBaseAddress,
320 bsvAesMode_t mode,
321 CCBsvCmacResult_t cmacResBuf)
322 {
323
324 if(mode == BSV_AES_CIPHER_CMAC) {
325 /* read and store the hash data registers */
326 SB_HAL_READ_REGISTER(SB_REG_ADDR(hwBaseAddress, AES_IV_0_0), cmacResBuf[0]);
327 SB_HAL_READ_REGISTER(SB_REG_ADDR(hwBaseAddress, AES_IV_0_1), cmacResBuf[1]);
328 SB_HAL_READ_REGISTER(SB_REG_ADDR(hwBaseAddress, AES_IV_0_2), cmacResBuf[2]);
329 SB_HAL_READ_REGISTER(SB_REG_ADDR(hwBaseAddress, AES_IV_0_3), cmacResBuf[3]);
330 }
331
332 FreeBsvAes(hwBaseAddress);
333
334 return;
335
336 }
337
338
339
340