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 "cc_pal_mutex.h"
8 #include "cc_pal_abort.h"
9 #include "cc_pal_mem.h"
10 #include "hash_driver.h"
11 #include "driver_defs.h"
12 #include "cc_hal.h"
13 #include "cc_hal_plat.h"
14 #include "cc_regs.h"
15 #include "dx_crys_kernel.h"
16 #include "cc_common.h"
17 #include "cc_common_math.h"
18 #include "hash_driver_ext_dma.h"
19 #include "cc_util_pm.h"
20 
21 extern CC_PalMutex CCSymCryptoMutex;
22 
23 
24 /* initial HASH values */
25 static const uint32_t HASH_LARVAL_SHA1[] = {0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0};
26 static const uint32_t HASH_LARVAL_SHA224[] = {0xc1059ed8, 0x367cd507, 0x3070dd17, 0xf70e5939, 0xffc00b31, 0x68581511, 0x64f98fa7, 0xbefa4fa4};
27 static const uint32_t HASH_LARVAL_SHA256[] = {0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19};
28 
29 
30 /**********************************************************************************************/
31 /************************ Private Functions ***************************************************/
32 /**********************************************************************************************/
33 
UpdateHashFinishExtDma(hashMode_t mode,uint32_t * digest)34 static void UpdateHashFinishExtDma(hashMode_t mode, uint32_t *digest)
35 {
36     /* read and store the hash data registers */
37     switch(mode) {
38     case HASH_SHA224:
39     case HASH_SHA256:
40         digest[7] = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, HASH_H7));
41         digest[6] = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, HASH_H6));
42         digest[5] = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, HASH_H5));
43         /* fall-thru */
44     case HASH_SHA1:
45         digest[4] = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, HASH_H4));
46         digest[3] = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, HASH_H3));
47         digest[2] = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, HASH_H2));
48         digest[1] = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, HASH_H1));
49         digest[0] = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, HASH_H0));
50     default:
51         break;
52     }
53 }
54 
55 /**********************************************************************************************/
56 /************************              Public Functions          ******************************/
57 /**********************************************************************************************/
58 
InitHashExtDma(hashMode_t mode,uint32_t dataSize)59 drvError_t InitHashExtDma(hashMode_t mode, uint32_t dataSize)
60 {
61     uint32_t hashCtrl = 0;
62     uint32_t digest[MAX_DIGEST_SIZE_WORDS] = {0};
63     drvError_t drvRc = HASH_DRV_OK;
64     int rc;
65     uint32_t irrVal = 0;
66 
67     /* lock mutex for more aes hw operation */
68     drvRc = CC_PalMutexLock(&CCSymCryptoMutex, CC_INFINITE);
69     if (drvRc != 0) {
70         CC_PalAbort("Fail to acquire mutex\n");
71     }
72 
73     /* increase CC counter at the beginning of each operation */
74     drvRc = CC_IS_WAKE;
75     if (drvRc != 0) {
76         CC_PalAbort("Fail to increase PM counter\n");
77     }
78 
79     /* make sure sym engines are ready to use */
80     CC_HAL_WAIT_ON_CRYPTO_BUSY();
81     /* verify hash valid mode */
82     switch(mode) {
83     case HASH_SHA1:
84         hashCtrl |= HW_HASH_CTL_SHA1_VAL;
85         CC_PalMemCopy((uint8_t *)digest, (uint8_t *)&HASH_LARVAL_SHA1, SHA1_DIGEST_SIZE_IN_BYTES );
86         break;
87     case HASH_SHA224:
88         hashCtrl |= HW_HASH_CTL_SHA256_VAL;
89         CC_PalMemCopy((uint8_t *)digest, (uint8_t *)&HASH_LARVAL_SHA224, SHA256_DIGEST_SIZE_IN_BYTES );
90         break;
91     case HASH_SHA256:
92         hashCtrl |= HW_HASH_CTL_SHA256_VAL;
93         CC_PalMemCopy((uint8_t *)digest, (uint8_t *)&HASH_LARVAL_SHA256, SHA256_DIGEST_SIZE_IN_BYTES );
94         break;
95     default:
96         drvRc = HASH_DRV_ILLEGAL_OPERATION_MODE_ERROR;
97         goto end;
98     }
99 
100 
101     /* clear all interrupts before starting the engine */
102     CC_HalClearInterruptBit(0xFFFFFFFFUL);
103 
104     /* mask dma interrupts which are not required */
105     irrVal = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, HOST_IMR));
106     CC_REG_FLD_SET(HOST_RGF, HOST_IMR, SRAM_TO_DIN_MASK, irrVal, 1);
107     CC_REG_FLD_SET(HOST_RGF, HOST_IMR, DOUT_TO_SRAM_MASK, irrVal, 1);
108     CC_REG_FLD_SET(HOST_RGF, HOST_IMR, MEM_TO_DIN_MASK, irrVal, 1);
109     CC_REG_FLD_SET(HOST_RGF, HOST_IMR, DOUT_TO_MEM_MASK, irrVal, 1);
110     CC_REG_FLD_SET(HOST_RGF, HOST_IMR, SYM_DMA_COMPLETED_MASK, irrVal, 1);
111     CC_HalMaskInterrupt(irrVal);
112 
113     /* enable clock */
114     CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, HASH_CLK_ENABLE) ,SET_CLOCK_ENABLE);
115     CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, DMA_CLK_ENABLE) ,SET_CLOCK_ENABLE);
116 
117     /* configure CC to hash */
118     CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, CRYPTO_CTL) ,CONFIG_HASH_MODE_VAL);
119 
120     CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, HASH_PAD_EN) ,1);
121 
122     CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, HASH_SEL_AES_MAC), 0);
123 
124     /* load the current length of message being processed */
125     CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, HASH_CUR_LEN_0), 0);
126     CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, HASH_CUR_LEN_1), 0);
127 
128     CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, HASH_CONTROL) ,hashCtrl);
129 
130     /* initializing the init HASH values from context */
131     switch(mode) {
132     case HASH_SHA224:
133     case HASH_SHA256:
134         CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, HASH_H7) ,digest[7]);
135         CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, HASH_H6) ,digest[6]);
136         CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, HASH_H5) ,digest[5]);
137         /* fall-thru */
138     case HASH_SHA1:
139         CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, HASH_H4) ,digest[4]);
140         CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, HASH_H3) ,digest[3]);
141         CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, HASH_H2) ,digest[2]);
142         CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, HASH_H1) ,digest[1]);
143         CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, HASH_H0) ,digest[0]);
144         break;
145     default:
146         drvRc = HASH_DRV_ILLEGAL_OPERATION_MODE_ERROR;
147         goto end;
148     }
149     if (dataSize == 0) {
150         /* use DO_PAD to complete padding of previous operation */
151         CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, HASH_PAD_CFG) ,4);
152 
153     } else {
154         CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AUTO_HW_PADDING) ,1);
155     }
156 
157     CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, DIN_CPU_DATA_SIZE) , dataSize);
158 
159 
160     return HASH_DRV_OK;
161 end:
162     rc = terminateHashExtDma();
163     if (rc != 0) {
164         CC_PalAbort("Failed to terminateHashExtDma \n");
165     }
166 
167     return drvRc;
168 }
169 
170 
FinishHashExtDma(hashMode_t mode,uint32_t * digest)171 drvError_t FinishHashExtDma(hashMode_t mode, uint32_t * digest)
172 {
173 
174     int i;
175     drvError_t rc = AES_DRV_OK;
176 
177     UpdateHashFinishExtDma(mode, digest);
178     /* reverse the bytes */
179     for ( i = 0 ; i < MAX_DIGEST_SIZE_WORDS ; i++ ) {
180         digest[i] = CC_COMMON_REVERSE32(digest[i]);
181     }
182 
183     /* reset to default values */
184     CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, HASH_PAD_EN) ,1);
185 
186     CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AUTO_HW_PADDING) ,0);
187 
188     CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, HASH_PAD_CFG) ,0);
189 
190 
191     rc = terminateHashExtDma();
192     if (rc != 0) {
193         CC_PalAbort("Failed to terminateHashExtDma \n");
194     }
195 
196     return HASH_DRV_OK;
197 }
198 
terminateHashExtDma(void)199 drvError_t terminateHashExtDma(void)
200 {
201     drvError_t rc = AES_DRV_OK;
202 
203     CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, HASH_CLK_ENABLE) ,SET_CLOCK_DISABLE);
204     CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, DMA_CLK_ENABLE) ,SET_CLOCK_DISABLE);
205 
206     /* decrease CC counter at the end of each operation */
207     rc = CC_IS_IDLE;
208     if (rc != 0) {
209         CC_PalAbort("Fail to decrease PM counter\n");
210     }
211 
212     /* unlock mutex for more aes hw operation */
213     rc = CC_PalMutexUnlock(&CCSymCryptoMutex);
214     if (rc != 0) {
215         CC_PalAbort("Fail to unlock mutex\n");
216     }
217     return rc;
218 }
219