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