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 "secureboot_general_hwdefs.h"
11 #include "secureboot_stage_defs.h"
12
13 #ifdef CC_SB_SUPPORT_SB_RT
14 #include "driver_defs.h"
15 #include "cc_pal_buff_attr.h"
16 #include "cc_error.h"
17 #endif
18
19 /**********************************************************************************************/
20 /************************ Private declarations ************************************************/
21 /**********************************************************************************************/
22
23 /* initial HASH values */
24 static const uint32_t BSV_HASH_SHA256[] = {0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19};
25
26
27 /**********************************************************************************************/
28 /************************ Public Functions ******************************/
29 /**********************************************************************************************/
30
InitBsvHash(unsigned long hwBaseAddress)31 void InitBsvHash(unsigned long hwBaseAddress)
32 {
33 uint32_t regVal = 0;
34
35 /* enable clocks */
36 SB_HAL_WRITE_REGISTER(SB_REG_ADDR(hwBaseAddress, HASH_CLK_ENABLE) ,CC_BSV_CLOCK_ENABLE);
37 SB_HAL_WRITE_REGISTER(SB_REG_ADDR(hwBaseAddress, DMA_CLK_ENABLE) ,CC_BSV_CLOCK_ENABLE);
38
39 /* make sure sym engines are ready to use */
40 CC_BSV_WAIT_ON_CRYPTO_BUSY();
41
42 /* clear all interrupts before starting the engine */
43 SB_HalClearInterruptBit(hwBaseAddress, 0xFFFFFFFFUL);
44
45 /* mask dma interrupts which are not required */
46 CC_REG_FLD_SET(HOST_RGF, HOST_IMR, SRAM_TO_DIN_MASK, regVal, CC_TRUE);
47 CC_REG_FLD_SET(HOST_RGF, HOST_IMR, DOUT_TO_SRAM_MASK, regVal, CC_TRUE);
48 CC_REG_FLD_SET(HOST_RGF, HOST_IMR, MEM_TO_DIN_MASK, regVal, CC_TRUE);
49 CC_REG_FLD_SET(HOST_RGF, HOST_IMR, DOUT_TO_MEM_MASK, regVal, CC_TRUE);
50 SB_HalMaskInterrupt(hwBaseAddress, regVal);
51
52 /* configure CC to hash */
53 SB_HAL_WRITE_REGISTER(SB_REG_ADDR(hwBaseAddress, CRYPTO_CTL) ,BSV_CRYPTO_HASH);
54 SB_HAL_WRITE_REGISTER(SB_REG_ADDR(hwBaseAddress, HASH_SEL_AES_MAC) ,0);
55
56 /* set hash operation mode */
57 SB_HAL_WRITE_REGISTER(SB_REG_ADDR(hwBaseAddress, HASH_CONTROL) ,BSV_HASH_CTL_SHA256_VAL);
58
59 /* enable HW padding */
60 SB_HAL_WRITE_REGISTER(SB_REG_ADDR(hwBaseAddress, HASH_PAD_EN) ,CC_TRUE);
61
62 /* load the current length of message being processed */
63 SB_HAL_WRITE_REGISTER(SB_REG_ADDR(hwBaseAddress, HASH_CUR_LEN_0), 0);
64 SB_HAL_WRITE_REGISTER(SB_REG_ADDR(hwBaseAddress, HASH_CUR_LEN_1), 0);
65
66 /* initializing the init HASH values from context */
67 SB_HAL_WRITE_REGISTER(SB_REG_ADDR(hwBaseAddress, HASH_H7) ,BSV_HASH_SHA256[7]);
68 SB_HAL_WRITE_REGISTER(SB_REG_ADDR(hwBaseAddress, HASH_H6) ,BSV_HASH_SHA256[6]);
69 SB_HAL_WRITE_REGISTER(SB_REG_ADDR(hwBaseAddress, HASH_H5) ,BSV_HASH_SHA256[5]);
70 SB_HAL_WRITE_REGISTER(SB_REG_ADDR(hwBaseAddress, HASH_H4) ,BSV_HASH_SHA256[4]);
71 SB_HAL_WRITE_REGISTER(SB_REG_ADDR(hwBaseAddress, HASH_H3) ,BSV_HASH_SHA256[3]);
72 SB_HAL_WRITE_REGISTER(SB_REG_ADDR(hwBaseAddress, HASH_H2) ,BSV_HASH_SHA256[2]);
73 SB_HAL_WRITE_REGISTER(SB_REG_ADDR(hwBaseAddress, HASH_H1) ,BSV_HASH_SHA256[1]);
74 SB_HAL_WRITE_REGISTER(SB_REG_ADDR(hwBaseAddress, HASH_H0) ,BSV_HASH_SHA256[0]);
75
76 /* do NOT use HW padding (to enable non-integrated operations) */
77 SB_HAL_WRITE_REGISTER(SB_REG_ADDR(hwBaseAddress, AUTO_HW_PADDING) ,CC_FALSE);
78
79 return;
80 }
81
82
FreeBsvHash(unsigned long hwBaseAddress)83 void FreeBsvHash(unsigned long hwBaseAddress)
84 {
85 /* reset to default values in case of operation completion */
86 SB_HAL_WRITE_REGISTER(SB_REG_ADDR(hwBaseAddress, AUTO_HW_PADDING) ,CC_FALSE);
87 SB_HAL_WRITE_REGISTER(SB_REG_ADDR(hwBaseAddress, HASH_PAD_CFG) ,CC_FALSE);
88
89 /* disable clocks */
90 SB_HAL_WRITE_REGISTER(SB_REG_ADDR(hwBaseAddress, HASH_CLK_ENABLE) ,CC_BSV_CLOCK_DISABLE);
91 SB_HAL_WRITE_REGISTER(SB_REG_ADDR(hwBaseAddress, DMA_CLK_ENABLE) ,CC_BSV_CLOCK_DISABLE);
92
93 return;
94 }
95
96
ProcessBsvHash(unsigned long hwBaseAddress,uint32_t inputDataAddr,uint32_t dataInSize)97 CCError_t ProcessBsvHash( unsigned long hwBaseAddress,
98 uint32_t inputDataAddr,
99 uint32_t dataInSize)
100 {
101 uint32_t irrVal = 0;
102 CCError_t error = CC_OK;
103 CCHashResult_t tempBuff;
104
105 #ifdef CC_SB_SUPPORT_SB_RT
106 drvError_t drvRet = CC_OK;
107 uint8_t buffNs = 0;
108 uint32_t regVal = 0;
109 #endif
110
111 if (dataInSize != 0) {
112
113 #ifdef CC_SB_SUPPORT_SB_RT
114 /* Need to verify the DataIn memory type and configure CC's AHBM accordingly */
115 drvRet = CC_PalDataBufferAttrGet((uint8_t*)inputDataAddr, dataInSize, INPUT_DATA_BUFFER, &buffNs);
116 if (drvRet != CC_OK){
117 FreeBsvHash(hwBaseAddress);
118 return CC_FATAL_ERROR;
119 }
120
121 CC_REG_FLD_SET(HOST_RGF, AHBM_HNONSEC, AHB_READ_HNONSEC, regVal, buffNs);
122 SB_HAL_WRITE_REGISTER(SB_REG_ADDR(hwBaseAddress, AHBM_HNONSEC) ,regVal);
123
124 #endif
125 /* configure source address and size */
126 SB_HAL_WRITE_REGISTER(SB_REG_ADDR(hwBaseAddress, SRC_LLI_WORD0) ,inputDataAddr);
127 SB_HAL_WRITE_REGISTER(SB_REG_ADDR(hwBaseAddress, SRC_LLI_WORD1) ,dataInSize);
128
129 /* set dma completion bit in irr */
130 CC_REG_FLD_SET(HOST_RGF, HOST_IRR, SYM_DMA_COMPLETED, irrVal, 1);
131 error = SB_HalWaitInterrupt(hwBaseAddress, irrVal);
132 if(error != CC_OK) {
133 /* Note: Hash operation should be completed also in case of error! */
134
135 /* Use DO_PAD to complete padding of full operation */
136 SB_HAL_WRITE_REGISTER(SB_REG_ADDR(hwBaseAddress, HASH_PAD_CFG) ,BSV_HASH_PAD_CFG_VAL);
137
138 /* Empty Hash HW registers */
139 SB_HAL_READ_REGISTER(SB_REG_ADDR(hwBaseAddress, HASH_H7), tempBuff[7]);
140 SB_HAL_READ_REGISTER(SB_REG_ADDR(hwBaseAddress, HASH_H6), tempBuff[6]);
141 SB_HAL_READ_REGISTER(SB_REG_ADDR(hwBaseAddress, HASH_H5), tempBuff[5]);
142 SB_HAL_READ_REGISTER(SB_REG_ADDR(hwBaseAddress, HASH_H4), tempBuff[4]);
143 SB_HAL_READ_REGISTER(SB_REG_ADDR(hwBaseAddress, HASH_H3), tempBuff[3]);
144 SB_HAL_READ_REGISTER(SB_REG_ADDR(hwBaseAddress, HASH_H2), tempBuff[2]);
145 SB_HAL_READ_REGISTER(SB_REG_ADDR(hwBaseAddress, HASH_H1), tempBuff[1]);
146 SB_HAL_READ_REGISTER(SB_REG_ADDR(hwBaseAddress, HASH_H0), tempBuff[0]);
147
148 /* Reset Hash temporary results */
149 UTIL_MemSet((uint8_t*)tempBuff, 0, sizeof(CCHashResult_t));
150
151 FreeBsvHash(hwBaseAddress);
152 }
153
154 }
155
156 return error;
157 }
158
159
FinishBsvHash(unsigned long hwBaseAddress,CCHashResult_t hashBuff)160 void FinishBsvHash(unsigned long hwBaseAddress, CCHashResult_t hashBuff)
161 {
162 int i;
163
164 /* use DO_PAD to complete padding of full operation */
165 SB_HAL_WRITE_REGISTER(SB_REG_ADDR(hwBaseAddress, HASH_PAD_CFG) ,BSV_HASH_PAD_CFG_VAL);
166
167 /* read and store the hash data registers */
168 SB_HAL_READ_REGISTER(SB_REG_ADDR(hwBaseAddress, HASH_H7), hashBuff[7]);
169 SB_HAL_READ_REGISTER(SB_REG_ADDR(hwBaseAddress, HASH_H6), hashBuff[6]);
170 SB_HAL_READ_REGISTER(SB_REG_ADDR(hwBaseAddress, HASH_H5), hashBuff[5]);
171 SB_HAL_READ_REGISTER(SB_REG_ADDR(hwBaseAddress, HASH_H4), hashBuff[4]);
172 SB_HAL_READ_REGISTER(SB_REG_ADDR(hwBaseAddress, HASH_H3), hashBuff[3]);
173 SB_HAL_READ_REGISTER(SB_REG_ADDR(hwBaseAddress, HASH_H2), hashBuff[2]);
174 SB_HAL_READ_REGISTER(SB_REG_ADDR(hwBaseAddress, HASH_H1), hashBuff[1]);
175 SB_HAL_READ_REGISTER(SB_REG_ADDR(hwBaseAddress, HASH_H0), hashBuff[0]);
176
177 /* reverse the bytes */
178 for ( i = 0 ; i < CC_BSV_SHA256_DIGEST_SIZE_IN_WORDS ; i++ ){
179 hashBuff[i] = UTIL_INVERSE_UINT32_BYTES(hashBuff[i]);
180 }
181
182 FreeBsvHash(hwBaseAddress);
183
184 return;
185
186 }
187
188
189
190