1 /*
2  *  FIPS-180-2 compliant SHA-256 implementation
3  *
4  *  Copyright (C) 2006-2021, ARM Limited, All Rights Reserved
5  *  Copyright (C) 2019, STMicroelectronics, All Rights Reserved
6  *  SPDX-License-Identifier: Apache-2.0
7  *
8  *  Licensed under the Apache License, Version 2.0 (the "License"); you may
9  *  not use this file except in compliance with the License.
10  *  You may obtain a copy of the License at
11  *
12  *  http://www.apache.org/licenses/LICENSE-2.0
13  *
14  *  Unless required by applicable law or agreed to in writing, software
15  *  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
16  *  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  *  See the License for the specific language governing permissions and
18  *  limitations under the License.
19  *
20  *  This file implements STMicroelectronics SHA256 with HW services based on mbed TLS API
21  */
22 /*
23  *  The SHA-256 Secure Hash Standard was published by NIST in 2002.
24  *
25  *  http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf
26  */
27 
28 /* Includes ------------------------------------------------------------------*/
29 #include "mbedtls/sha256.h"
30 #include "mbedtls/error.h"
31 
32 #if defined(MBEDTLS_SHA256_C)
33 #if defined(MBEDTLS_SHA256_ALT)
34 #include <string.h>
35 #include "mbedtls/platform.h"
36 #include "mbedtls/platform_util.h"
37 
38 
39 /* Private typedef -----------------------------------------------------------*/
40 /* Private define ------------------------------------------------------------*/
41 #define ST_SHA256_TIMEOUT     ((uint32_t) 3)
42 
43 /* Parameter validation macros - mbedtls/platform_util.h has deprecated them */
44 #define SHA256_VALIDATE_RET( cond ) do { } while(0)
45 #define SHA256_VALIDATE( cond ) do { } while(0)
46 
47 /* Private variables ---------------------------------------------------------*/
48 /* Private function prototypes -----------------------------------------------*/
49 /* Private functions ---------------------------------------------------------*/
50 
51 /* Implementation that should never be optimized out by the compiler */
mbedtls_zeroize(void * v,size_t n)52 static void mbedtls_zeroize(void *v, size_t n)
53 {
54     volatile unsigned char *p = (unsigned char *)v;
55     while (n--)
56     {
57         *p++ = 0;
58     }
59 }
60 
mbedtls_sha256_init(mbedtls_sha256_context * ctx)61 void mbedtls_sha256_init(mbedtls_sha256_context *ctx)
62 {
63     SHA256_VALIDATE( ctx != NULL );
64 
65     mbedtls_zeroize(ctx, sizeof(mbedtls_sha256_context));
66 
67     /* Enable HASH clock */
68     __HAL_RCC_HASH_CLK_ENABLE();
69 }
70 
mbedtls_sha256_free(mbedtls_sha256_context * ctx)71 void mbedtls_sha256_free(mbedtls_sha256_context *ctx)
72 {
73     if (ctx == NULL)
74     {
75         return;
76     }
77     mbedtls_zeroize(ctx, sizeof(mbedtls_sha256_context));
78 }
79 
mbedtls_sha256_clone(mbedtls_sha256_context * dst,const mbedtls_sha256_context * src)80 void mbedtls_sha256_clone(mbedtls_sha256_context *dst,
81                           const mbedtls_sha256_context *src)
82 {
83     SHA256_VALIDATE( dst != NULL );
84     SHA256_VALIDATE( src != NULL );
85 
86     *dst = *src;
87 }
88 
mbedtls_sha256_starts(mbedtls_sha256_context * ctx,int is224)89 int mbedtls_sha256_starts(mbedtls_sha256_context *ctx, int is224)
90 {
91     SHA256_VALIDATE_RET( ctx != NULL );
92     SHA256_VALIDATE_RET( is224 == 0 || is224 == 1 );
93 
94     /* HASH Configuration */
95     if (HAL_HASH_DeInit(&ctx->hhash) != HAL_OK)
96     {
97         return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
98     }
99     ctx->hhash.Init.DataType = HASH_DATATYPE_8B;
100     if (HAL_HASH_Init(&ctx->hhash) != HAL_OK)
101     {
102         return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
103     }
104 
105     ctx->MBEDTLS_PRIVATE(is224) = is224;
106 
107     /* first block on 17 words */
108     ctx->first = ST_SHA256_EXTRA_BYTES;
109 
110     ctx->sbuf_len = 0;
111 
112 #ifdef ST_HW_CONTEXT_SAVING
113     /* save hw context */
114     HAL_HASH_ContextSaving(&ctx->hhash, ctx->ctx_save_regs);
115 #endif /* ST_HW_CONTEXT_SAVING */
116 
117     return 0;
118 }
119 
mbedtls_internal_sha256_process(mbedtls_sha256_context * ctx,const unsigned char data[ST_SHA256_BLOCK_SIZE])120 int mbedtls_internal_sha256_process( mbedtls_sha256_context *ctx, const unsigned char data[ST_SHA256_BLOCK_SIZE] )
121 {
122     SHA256_VALIDATE_RET( ctx != NULL );
123     SHA256_VALIDATE_RET( (const unsigned char *)data != NULL );
124 
125 #ifdef ST_HW_CONTEXT_SAVING
126     /* restore hw context */
127     HAL_HASH_ContextRestoring(&ctx->hhash, ctx->ctx_save_regs);
128 #endif /* ST_HW_CONTEXT_SAVING */
129 
130     if (ctx->MBEDTLS_PRIVATE(is224) == 0) {
131         if (HAL_HASHEx_SHA256_Accmlt(&ctx->hhash, (uint8_t *) data, ST_SHA256_BLOCK_SIZE) != 0) {
132             return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
133         }
134     } else {
135         if (HAL_HASHEx_SHA224_Accmlt(&ctx->hhash, (uint8_t *) data, ST_SHA256_BLOCK_SIZE) != 0) {
136             return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
137         }
138     }
139 
140 #ifdef ST_HW_CONTEXT_SAVING
141     /* save hw context */
142     HAL_HASH_ContextSaving(&ctx->hhash, ctx->ctx_save_regs);
143 #endif /* ST_HW_CONTEXT_SAVING */
144 
145     return 0;
146 }
147 
mbedtls_sha256_update(mbedtls_sha256_context * ctx,const unsigned char * input,size_t ilen)148 int mbedtls_sha256_update(mbedtls_sha256_context *ctx, const unsigned char *input, size_t ilen)
149 {
150     size_t currentlen = ilen;
151 
152     SHA256_VALIDATE_RET( ctx != NULL );
153     SHA256_VALIDATE_RET( ilen == 0 || input != NULL );
154 
155 #ifdef ST_HW_CONTEXT_SAVING
156     /* restore hw context */
157     HAL_HASH_ContextRestoring(&ctx->hhash, ctx->ctx_save_regs);
158 #endif /* ST_HW_CONTEXT_SAVING */
159 
160     if (currentlen < (ST_SHA256_BLOCK_SIZE + ctx->first - ctx->sbuf_len))
161     {
162         /* only store input data in context buffer */
163         memcpy(ctx->sbuf + ctx->sbuf_len, input, currentlen);
164         ctx->sbuf_len += currentlen;
165     }
166     else
167     {
168         /* fill context buffer until ST_SHA256_BLOCK_SIZE bytes, and process it */
169         memcpy(ctx->sbuf + ctx->sbuf_len, input, (ST_SHA256_BLOCK_SIZE + ctx->first - ctx->sbuf_len));
170         currentlen -= (ST_SHA256_BLOCK_SIZE + ctx->first - ctx->sbuf_len);
171 
172         if (ctx->MBEDTLS_PRIVATE(is224) == 0)
173         {
174             if (HAL_HASHEx_SHA256_Accmlt(&ctx->hhash, (uint8_t *)(ctx->sbuf), ST_SHA256_BLOCK_SIZE + ctx->first) != 0)
175             {
176                 return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
177             }
178         }
179         else
180         {
181             if (HAL_HASHEx_SHA224_Accmlt(&ctx->hhash, (uint8_t *)(ctx->sbuf), ST_SHA256_BLOCK_SIZE + ctx->first) != 0)
182             {
183                 return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
184             }
185         }
186 
187         /* Process following input data with size multiple of ST_SHA256_BLOCK_SIZE bytes */
188         size_t iter = currentlen / ST_SHA256_BLOCK_SIZE;
189         if (iter != 0)
190         {
191             if (ctx->MBEDTLS_PRIVATE(is224) == 0)
192             {
193                 if (HAL_HASHEx_SHA256_Accmlt(&ctx->hhash, (uint8_t *)(input + ST_SHA256_BLOCK_SIZE + ctx->first - ctx->sbuf_len), (iter * ST_SHA256_BLOCK_SIZE)) != 0)
194                 {
195                     return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
196                 }
197             }
198             else
199             {
200                 if (HAL_HASHEx_SHA224_Accmlt(&ctx->hhash, (uint8_t *)(input + ST_SHA256_BLOCK_SIZE + ctx->first - ctx->sbuf_len), (iter * ST_SHA256_BLOCK_SIZE)) != 0)
201                 {
202                     return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
203                 }
204             }
205         }
206 
207         /* following blocks on 16 words */
208         ctx->first = 0;
209 
210         /* Store only the remaining input data up to (ST_SHA256_BLOCK_SIZE - 1) bytes */
211         ctx->sbuf_len = currentlen % ST_SHA256_BLOCK_SIZE;
212         if (ctx->sbuf_len != 0)
213         {
214             memcpy(ctx->sbuf, input + ilen - ctx->sbuf_len, ctx->sbuf_len);
215         }
216     }
217 
218 #ifdef ST_HW_CONTEXT_SAVING
219     /* save hw context */
220     HAL_HASH_ContextSaving(&ctx->hhash, ctx->ctx_save_regs);
221 #endif /* ST_HW_CONTEXT_SAVING */
222     return 0;
223 }
224 
mbedtls_sha256_finish(mbedtls_sha256_context * ctx,unsigned char output[32])225 int mbedtls_sha256_finish(mbedtls_sha256_context *ctx, unsigned char output[32])
226 {
227     SHA256_VALIDATE_RET( ctx != NULL );
228     SHA256_VALIDATE_RET( (unsigned char *)output != NULL );
229 
230 #ifdef ST_HW_CONTEXT_SAVING
231     /* restore hw context */
232     HAL_HASH_ContextRestoring(&ctx->hhash, ctx->ctx_save_regs);
233 #endif /* ST_HW_CONTEXT_SAVING */
234 
235     /* Last accumulation for pending bytes in sbuf_len, then trig processing and get digest */
236     if (ctx->MBEDTLS_PRIVATE(is224) == 0)
237     {
238         if (HAL_HASHEx_SHA256_Accmlt_End(&ctx->hhash, ctx->sbuf, ctx->sbuf_len, output, ST_SHA256_TIMEOUT) != 0)
239         {
240             return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
241         }
242     }
243     else
244     {
245         if (HAL_HASHEx_SHA224_Accmlt_End(&ctx->hhash, ctx->sbuf, ctx->sbuf_len, output, ST_SHA256_TIMEOUT) != 0)
246         {
247             return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
248         }
249     }
250 
251     ctx->sbuf_len = 0;
252 
253     return 0;
254 }
255 
256 #endif /* MBEDTLS_SHA256_ALT*/
257 #endif /* MBEDTLS_SHA256_C */
258