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 "cc_pal_mutex.h"
11 #include "cc_pal_abort.h"
12 #include "cc_pal_mem.h"
13 #include "hash_driver.h"
14 #include "driver_defs.h"
15 #include "cc_hal.h"
16 #include "cc_hal_plat.h"
17 #include "cc_sram_map.h"
18 #include "cc_regs.h"
19 #include "dx_crys_kernel.h"
20
21 #include "cc_common.h"
22 #include "cc_common_math.h"
23
24 #include "cc_util_pm.h"
25
26 extern CC_PalMutex CCSymCryptoMutex;
27
28 /**********************************************************************************************/
29 /************************ Private Functions ***************************************************/
30 /**********************************************************************************************/
31
UpdateHashFinish(HashContext_t * hashCtx)32 static void UpdateHashFinish(HashContext_t *hashCtx)
33 {
34 /* read and store the hash data registers */
35 switch(hashCtx->mode) {
36 case HASH_SHA224:
37 case HASH_SHA256:
38 hashCtx->digest[7] = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, HASH_H7));
39 hashCtx->digest[6] = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, HASH_H6));
40 hashCtx->digest[5] = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, HASH_H5));
41 /* Fall-through. */
42 case HASH_SHA1:
43 hashCtx->digest[4] = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, HASH_H4));
44 hashCtx->digest[3] = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, HASH_H3));
45 hashCtx->digest[2] = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, HASH_H2));
46 hashCtx->digest[1] = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, HASH_H1));
47 hashCtx->digest[0] = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, HASH_H0));
48 default:
49 break;
50 }
51
52 /* read and store the current length of message that was processed */
53 hashCtx->totalDataSizeProcessed[0] = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, HASH_CUR_LEN_0));
54 hashCtx->totalDataSizeProcessed[1] = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, HASH_CUR_LEN_1));
55
56 return;
57 }
58
59 /* initial HASH values */
60 static const uint32_t HASH_LARVAL_SHA1[] = {0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0};
61 static const uint32_t HASH_LARVAL_SHA224[] = {0xc1059ed8, 0x367cd507, 0x3070dd17, 0xf70e5939, 0xffc00b31, 0x68581511, 0x64f98fa7, 0xbefa4fa4};
62 static const uint32_t HASH_LARVAL_SHA256[] = {0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19};
63
64
65 /**********************************************************************************************/
66 /************************ Public Functions ******************************/
67 /**********************************************************************************************/
68
InitHashDrv(void * pCtx)69 drvError_t InitHashDrv(void *pCtx)
70 {
71 HashContext_t *hashCtx;
72
73 /* verify user context pointer */
74 if ( pCtx == NULL ) {
75 return HASH_DRV_INVALID_USER_CONTEXT_POINTER_ERROR;
76 }
77 hashCtx = (HashContext_t *)pCtx;
78
79 /* verify hash valid mode */
80 switch (hashCtx->mode) {
81 case HASH_SHA1:
82 CC_PalMemCopy((uint8_t *)&hashCtx->digest, (uint8_t *)&HASH_LARVAL_SHA1, SHA1_DIGEST_SIZE_IN_BYTES );
83 break;
84 case HASH_SHA224:
85 CC_PalMemCopy((uint8_t *)&hashCtx->digest, (uint8_t *)&HASH_LARVAL_SHA224, SHA256_DIGEST_SIZE_IN_BYTES );
86 break;
87 case HASH_SHA256:
88 CC_PalMemCopy((uint8_t *)&hashCtx->digest, (uint8_t *)&HASH_LARVAL_SHA256, SHA256_DIGEST_SIZE_IN_BYTES );
89 break;
90 default:
91 return HASH_DRV_ILLEGAL_OPERATION_MODE_ERROR;
92 }
93
94 return HASH_DRV_OK;
95 }
96
97
ProcessHashDrv(void * pCtx,CCBuffInfo_t * pInputBuffInfo,uint32_t dataInSize)98 drvError_t ProcessHashDrv( void *pCtx,
99 CCBuffInfo_t *pInputBuffInfo,
100 uint32_t dataInSize)
101 {
102 uint32_t irrVal = 0;
103 drvError_t drvRc = HASH_DRV_OK;
104 uint32_t hashCtrl = 0;
105 HashContext_t *hashCtx;
106 uint32_t regVal = 0;
107 uint32_t inputDataAddr;
108
109 /* check input parameters */
110 if (pInputBuffInfo == NULL) {
111 return HASH_DRV_INVALID_USER_DATA_BUFF_POINTER_ERROR;
112 }
113
114 /* verify user context pointer */
115 if ( pCtx == NULL ) {
116 return HASH_DRV_INVALID_USER_CONTEXT_POINTER_ERROR;
117 }
118 hashCtx = (HashContext_t *)pCtx;
119
120 /* verify hash valid mode */
121 switch(hashCtx->mode) {
122 case HASH_SHA1:
123 hashCtrl |= HW_HASH_CTL_SHA1_VAL;
124 break;
125 case HASH_SHA224:
126 case HASH_SHA256:
127 hashCtrl |= HW_HASH_CTL_SHA256_VAL;
128 break;
129 default:
130 return HASH_DRV_ILLEGAL_OPERATION_MODE_ERROR;
131 }
132
133 /* lock mutex for more aes hw operation */
134 drvRc = CC_PalMutexLock(&CCSymCryptoMutex, CC_INFINITE);
135 if (drvRc != 0) {
136 CC_PalAbort("Fail to acquire mutex\n");
137 }
138
139 /* increase CC counter at the beginning of each operation */
140 drvRc = CC_IS_WAKE;
141 if (drvRc != 0) {
142 CC_PalAbort("Fail to increase PM counter\n");
143 }
144
145 /* make sure sym engines are ready to use */
146 CC_HAL_WAIT_ON_CRYPTO_BUSY();
147
148 /* clear all interrupts before starting the engine */
149 CC_HalClearInterruptBit(0xFFFFFFFFUL);
150
151 /* mask dma interrupts which are not required */
152 irrVal = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, HOST_IMR));
153 CC_REG_FLD_SET(HOST_RGF, HOST_IMR, SRAM_TO_DIN_MASK, irrVal, 1);
154 CC_REG_FLD_SET(HOST_RGF, HOST_IMR, DOUT_TO_SRAM_MASK, irrVal, 1);
155 CC_REG_FLD_SET(HOST_RGF, HOST_IMR, MEM_TO_DIN_MASK, irrVal, 1);
156 CC_REG_FLD_SET(HOST_RGF, HOST_IMR, DOUT_TO_MEM_MASK, irrVal, 1);
157 CC_REG_FLD_SET(HOST_RGF, HOST_IMR, SYM_DMA_COMPLETED_MASK, irrVal, 0);
158 CC_HalMaskInterrupt(irrVal);
159
160 /* enable clock */
161 CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, HASH_CLK_ENABLE) ,SET_CLOCK_ENABLE);
162 CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, DMA_CLK_ENABLE) ,SET_CLOCK_ENABLE);
163
164 /* configure CC to hash */
165 CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, CRYPTO_CTL) ,CONFIG_HASH_MODE_VAL);
166
167 CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, HASH_PAD_EN) ,1);
168
169 CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, HASH_SEL_AES_MAC), 0);
170
171 /* load the current length of message being processed */
172 CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, HASH_CUR_LEN_0), hashCtx->totalDataSizeProcessed[0]);
173 CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, HASH_CUR_LEN_1), hashCtx->totalDataSizeProcessed[1]);
174
175 CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, HASH_CONTROL) ,hashCtrl);
176
177 /* initializing the init HASH values from context */
178 switch(hashCtx->mode) {
179 case HASH_SHA224:
180 case HASH_SHA256:
181 CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, HASH_H7) ,hashCtx->digest[7]);
182 CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, HASH_H6) ,hashCtx->digest[6]);
183 CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, HASH_H5) ,hashCtx->digest[5]);
184 /* Fall-through. */
185 case HASH_SHA1:
186 CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, HASH_H4) ,hashCtx->digest[4]);
187 CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, HASH_H3) ,hashCtx->digest[3]);
188 CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, HASH_H2) ,hashCtx->digest[2]);
189 CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, HASH_H1) ,hashCtx->digest[1]);
190 CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, HASH_H0) ,hashCtx->digest[0]);
191 default:
192 break;
193 }
194
195 if (dataInSize == 0) {
196 /* use DO_PAD to complete padding of previous operation */
197 CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, HASH_PAD_CFG) ,4);
198
199 } else {
200 /* use HW padding (NA for zero bytes) for last block */
201 if (hashCtx->isLastBlockProcessed == 1){
202 CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AUTO_HW_PADDING) ,1);
203 }
204
205 inputDataAddr = pInputBuffInfo->dataBuffAddr;
206
207 /* configure the HW with the correct data buffer attributes (secure/non-secure) */
208 CC_REG_FLD_SET(HOST_RGF, AHBM_HNONSEC, AHB_READ_HNONSEC, regVal, pInputBuffInfo->dataBuffNs);
209 CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AHBM_HNONSEC) ,regVal);
210
211 /* configure source address and size */
212 CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, SRC_LLI_WORD0) ,inputDataAddr);
213 CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, SRC_LLI_WORD1) ,dataInSize);
214
215 /* set dma completion bit in irr */
216 irrVal = 0;
217 CC_REG_FLD_SET(HOST_RGF, HOST_IRR, SYM_DMA_COMPLETED, irrVal, 1);
218 drvRc = CC_HalWaitInterrupt(irrVal);
219 /* Note: Hash operation should be completed also in case of error! */
220 /* drvRc will be tested later, and hash results will be cleared */
221 }
222
223 /* finishing the update operation */
224 UpdateHashFinish(hashCtx);
225
226 /* reset to default values in case of operation completion */
227 CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, HASH_PAD_EN) ,1);
228
229 CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AUTO_HW_PADDING) ,0);
230
231 CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, HASH_PAD_CFG) ,0);
232
233 /* disable the HASH clock in the end of the process */
234 CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, HASH_CLK_ENABLE) ,SET_CLOCK_DISABLE);
235 CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, DMA_CLK_ENABLE) ,SET_CLOCK_DISABLE);
236
237 if (drvRc != HASH_DRV_OK) {
238 /* Clear buffer results in case of error */
239 CC_PalMemSetZero((uint8_t*)hashCtx->digest, MAX_DIGEST_SIZE_WORDS);
240 }
241
242 /* decrease CC counter at the end of each operation */
243 if (CC_IS_IDLE != 0) {
244 CC_PalAbort("Fail to decrease PM counter\n");
245 }
246
247 /* release mutex */
248 if (CC_PalMutexUnlock(&CCSymCryptoMutex) != 0) {
249 CC_PalAbort("Fail to release mutex\n");
250 }
251
252 return drvRc;
253 }
254
255
FinishHashDrv(void * pCtx)256 drvError_t FinishHashDrv(void *pCtx)
257 {
258
259 HashContext_t *hashCtx;
260 int i;
261
262 /* verify user context pointer */
263 if ( pCtx == NULL ) {
264 return HASH_DRV_INVALID_USER_CONTEXT_POINTER_ERROR;
265 }
266 hashCtx = (HashContext_t *)pCtx;
267
268 /* reverse the bytes */
269 for ( i = 0 ; i < MAX_DIGEST_SIZE_WORDS ; i++ )
270 hashCtx->digest[i] = CC_COMMON_REVERSE32(hashCtx->digest[i]);
271
272 return HASH_DRV_OK;
273
274 }
275
276
277
278