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