1 /*
2 * Copyright (c) 2001-2021, Arm Limited and Contributors. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7 #include "hash_driver.h"
8 #include "cc_pal_mem.h"
9 #include "cc_pal_log.h"
10 #include "sha1_alt.h"
11 #include "sha256_alt.h"
12
13 /* CC312 DMA limits the amount of data can be hashed at once. */
14 #define MAX_HASH_CHUNK_SIZE 0xffff
15
16 /*
17 In CC312, DMA (i.e. for hash module input ) needs access to physical and continues memory.
18 In order to assure the DMA can access the residue data saved in the hashCtx, it is being to copied to a local
19 stack variable.
20 In case memory is guaranteed to be DMAable, this copy can be removed, and hashCtx->prevData can be used.
21 */
mbedtls_hashUpdate(void * pHashUserCtx,uint8_t * pDataIn,size_t dataInSize)22 static uint32_t mbedtls_hashUpdate(void *pHashUserCtx,
23 uint8_t *pDataIn,
24 size_t dataInSize)
25 {
26 uint32_t rc = 0;
27 HashContext_t *pHashCtx = NULL;
28 size_t bytesToAdd = 0;
29 uint32_t localPrevDataIn[HASH_SHA512_BLOCK_SIZE_IN_WORDS];
30 CCBuffInfo_t inBuffInfo;
31
32 pHashCtx = (HashContext_t *)pHashUserCtx;
33 // If pHashCtx->prevDataInSize > 0, fill it with with the current data
34 bytesToAdd = CC_MIN(((pHashCtx->blockSizeInBytes - pHashCtx->prevDataInSize) % pHashCtx->blockSizeInBytes), dataInSize);
35 if (bytesToAdd > 0) {
36 /* add the data to the remaining buffer */
37 CC_PalMemCopy(&(((uint8_t *)(pHashCtx->prevDataIn))[pHashCtx->prevDataInSize]), pDataIn, bytesToAdd);
38 pHashCtx->prevDataInSize += bytesToAdd;
39 pDataIn += bytesToAdd;
40 dataInSize -= bytesToAdd;
41 }
42
43 // If the remaining buffer is full, process the block (else, the remaining buffer will be processed in the next update or finish) */
44 if (pHashCtx->prevDataInSize == pHashCtx->blockSizeInBytes) {
45 /* Copy prevDataIn to stack, in order to ensure continues and physical memory access.
46 That way, DMA will be able to access the data on any platform.*/
47 CC_PalMemCopy(localPrevDataIn, pHashCtx->prevDataIn, CC_MIN(HASH_SHA512_BLOCK_SIZE_IN_WORDS*sizeof(uint32_t), pHashCtx->prevDataInSize));
48
49 rc = SetDataBuffersInfo((uint8_t*)localPrevDataIn, pHashCtx->blockSizeInBytes, &inBuffInfo,
50 NULL, 0, NULL);
51 if (rc != 0) {
52 CC_PAL_LOG_ERR("illegal data buffers\n");
53 return rc;
54 }
55
56 rc = ProcessHashDrv(pHashCtx, &inBuffInfo, pHashCtx->blockSizeInBytes);
57 if (rc != CC_OK) {
58 CC_PAL_LOG_ERR( "ProcessHashDrv failed, ret = %d\n", rc );
59 return rc;
60 }
61 pHashCtx->prevDataInSize = 0;
62 }
63
64 // Process all the blocks that remain in the data
65 bytesToAdd = (dataInSize / pHashCtx->blockSizeInBytes) * pHashCtx->blockSizeInBytes;
66 if (bytesToAdd > 0) {
67
68 rc = SetDataBuffersInfo(pDataIn, bytesToAdd, &inBuffInfo,
69 NULL, 0, NULL);
70 if (rc != 0) {
71 CC_PAL_LOG_ERR("illegal data buffers\n");
72 return rc;
73 }
74
75 rc = ProcessHashDrv(pHashCtx, &inBuffInfo, bytesToAdd);
76 if (rc != CC_OK) {
77 CC_PAL_LOG_ERR( "ProcessHashDrv failed, ret = %d\n", rc );
78 return rc;
79 }
80 pDataIn += bytesToAdd;
81 dataInSize -= bytesToAdd;
82 }
83
84 // Copy the remaining partial block to prevDataIn */
85 bytesToAdd = dataInSize;
86 if (bytesToAdd > 0) {
87 CC_PalMemCopy((uint8_t *)&((pHashCtx->prevDataIn)[pHashCtx->prevDataInSize]), pDataIn, bytesToAdd);
88 pHashCtx->prevDataInSize += bytesToAdd;
89 }
90 return CC_OK;
91 }
92
mbedtls_sha_process_internal(void * ctx,const unsigned char * data)93 int mbedtls_sha_process_internal( void *ctx, const unsigned char *data )
94 {
95 int ret;
96
97 if ( NULL == ctx )
98 {
99 CC_PAL_LOG_ERR( "ctx is NULL\n" );
100 return( 1 );
101 }
102 if ( NULL == data )
103 {
104 CC_PAL_LOG_ERR( "data is NULL\n" );
105 return( 1 );
106 }
107 ret = mbedtls_hashUpdate(ctx, (uint8_t *)data, HASH_BLOCK_SIZE_IN_BYTES);
108 if( CC_OK != ret)
109 {
110 CC_PAL_LOG_ERR("mbedtls_hashUpdate failed, ret = %d\n", ret);
111 return( 1 );
112 }
113
114 return( 0 );
115 }
116
mbedtls_sha_starts_internal(void * ctx,hashMode_t mode)117 int mbedtls_sha_starts_internal( void *ctx, hashMode_t mode )
118 {
119 int ret;
120 HashContext_t *pHashCtx = NULL;
121
122 if( NULL == ctx )
123 {
124 CC_PAL_LOG_ERR( "ctx is NULL\n" );
125 return( 1 );
126 }
127
128 pHashCtx = (HashContext_t *)ctx;
129 CC_PalMemSetZero(ctx, sizeof( HashContext_t ) );
130 pHashCtx->mode = mode;
131 pHashCtx->blockSizeInBytes = HASH_BLOCK_SIZE_IN_BYTES;
132 ret = InitHashDrv(pHashCtx);
133 if(ret != 0)
134 {
135 return( 1 );
136 }
137 else
138 {
139 return( 0 );
140 }
141 }
142
mbedtls_sha_finish_internal(void * ctx)143 int mbedtls_sha_finish_internal( void *ctx )
144 {
145 uint32_t localPrevDataIn[HASH_SHA512_BLOCK_SIZE_IN_WORDS];
146 size_t dataInSize = 0;
147 drvError_t drvRc = HASH_DRV_OK;
148 HashContext_t *pHashCtx = NULL;
149 CCBuffInfo_t inBuffInfo;
150
151 pHashCtx = (HashContext_t *)ctx;
152 if (pHashCtx->prevDataInSize != 0) {
153 /* Copy prevDataIn to stack, in order to ensure continues and physical memory access.
154 That way, DMA will be able to access the data on any platform.*/
155 CC_PalMemCopy(localPrevDataIn, pHashCtx->prevDataIn, CC_MIN(HASH_SHA512_BLOCK_SIZE_IN_WORDS*sizeof(uint32_t), pHashCtx->prevDataInSize));
156 dataInSize = pHashCtx->prevDataInSize;
157 }
158 pHashCtx->isLastBlockProcessed = 1;
159
160 drvRc = SetDataBuffersInfo((uint8_t*)localPrevDataIn, dataInSize, &inBuffInfo,
161 NULL, 0, NULL);
162 if (drvRc != 0) {
163 CC_PAL_LOG_ERR("illegal data buffers\n");
164 return( 1 );
165 }
166
167 drvRc = ProcessHashDrv(pHashCtx, &inBuffInfo, dataInSize);
168 if (drvRc != HASH_DRV_OK){
169 CC_PAL_LOG_ERR( "ProcessHashDrv failed, ret = %d\n", drvRc );
170 return( 1 );
171 }
172 drvRc = FinishHashDrv(pHashCtx);
173 if (drvRc != HASH_DRV_OK) {
174 CC_PAL_LOG_ERR( "FinishHashDrv failed, ret = %d\n", drvRc );
175 return( 1 );
176 }
177 pHashCtx->prevDataInSize = 0;
178
179 return( 0 );
180 }
181
mbedtls_sha_update_internal(void * ctx,const unsigned char * input,size_t ilen)182 int mbedtls_sha_update_internal( void *ctx, const unsigned char *input, size_t ilen )
183 {
184 int ret = 1;
185
186 if (NULL == ctx){
187 CC_PAL_LOG_ERR( "ctx is NULL\n" );
188 return( 1 );
189 }
190
191 if (0 == ilen){
192 /* This is a valid situation, no need to call hashUpdate.
193 HashFinish will produce the result. */
194 return( 0 );
195 }
196
197 //if len not zero, but pointer is NULL
198 if (NULL == input){
199 CC_PAL_LOG_ERR( "input is NULL\n" );
200 //printf("TEST12, hash err = 1\n");
201 return( 1 );
202 }
203
204 while (ilen > MAX_HASH_CHUNK_SIZE) {
205 ret = mbedtls_hashUpdate(ctx, (uint8_t *)input, MAX_HASH_CHUNK_SIZE);
206
207 ilen -= MAX_HASH_CHUNK_SIZE;
208 input += MAX_HASH_CHUNK_SIZE;
209
210 if (CC_OK != ret) {
211 CC_PAL_LOG_ERR("mbedtls_hashUpdate failed, ret = %d\n", ret);
212 return( 1 );
213 }
214 }
215
216 ret = mbedtls_hashUpdate(ctx, (uint8_t *)input, ilen);
217 if (CC_OK != ret) {
218 CC_PAL_LOG_ERR("mbedtls_hashUpdate failed, ret = %d\n", ret);
219 return( 1 );
220 }
221
222 return( 0 );
223 }
224
225
226