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