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