1 /*
2 * FIPS-180-1 compliant SHA-1 implementation
3 *
4 * Copyright (C) 2006-2015, 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 SHA1 with HW services based on mbed TLS API
21 */
22 /*
23 * The SHA-1 standard was published by NIST in 1993.
24 *
25 * http://www.itl.nist.gov/fipspubs/fip180-1.htm
26 */
27
28 /* Includes ------------------------------------------------------------------*/
29 #include "mbedtls/sha1.h"
30
31 #if defined(MBEDTLS_SHA1_C)
32 #if defined(MBEDTLS_SHA1_ALT)
33 #include <string.h>
34 #include "mbedtls/platform.h"
35 #include "mbedtls/platform_util.h"
36
37
38 /* Private typedef -----------------------------------------------------------*/
39 /* Private define ------------------------------------------------------------*/
40 #define ST_SHA1_TIMEOUT ((uint32_t) 3)
41
42 /* Parameter validation macros - mbedtls/platform_util.h has deprecated them */
43 #define SHA1_VALIDATE_RET( cond ) do { } while(0)
44 #define SHA1_VALIDATE( cond ) do { } while(0)
45
46 /* Private variables ---------------------------------------------------------*/
47 /* Private function prototypes -----------------------------------------------*/
48 /* Private functions ---------------------------------------------------------*/
49
50 /* Implementation that should never be optimized out by the compiler */
mbedtls_zeroize(void * v,size_t n)51 static void mbedtls_zeroize(void *v, size_t n)
52 {
53 volatile unsigned char *p = (unsigned char *)v;
54 while (n--)
55 {
56 *p++ = 0;
57 }
58 }
59
mbedtls_sha1_init(mbedtls_sha1_context * ctx)60 void mbedtls_sha1_init(mbedtls_sha1_context *ctx)
61 {
62 SHA1_VALIDATE( ctx != NULL );
63
64 mbedtls_zeroize(ctx, sizeof(mbedtls_sha1_context));
65
66 /* Enable HASH clock */
67 __HAL_RCC_HASH_CLK_ENABLE();
68 }
69
mbedtls_sha1_free(mbedtls_sha1_context * ctx)70 void mbedtls_sha1_free(mbedtls_sha1_context *ctx)
71 {
72 if (ctx == NULL)
73 {
74 return;
75 }
76 mbedtls_zeroize(ctx, sizeof(mbedtls_sha1_context));
77 }
78
mbedtls_sha1_clone(mbedtls_sha1_context * dst,const mbedtls_sha1_context * src)79 void mbedtls_sha1_clone(mbedtls_sha1_context *dst,
80 const mbedtls_sha1_context *src)
81 {
82 SHA1_VALIDATE( dst != NULL );
83 SHA1_VALIDATE( src != NULL );
84
85 *dst = *src;
86 }
87
mbedtls_sha1_starts_ret(mbedtls_sha1_context * ctx)88 int mbedtls_sha1_starts_ret(mbedtls_sha1_context *ctx)
89 {
90 SHA1_VALIDATE_RET( ctx != NULL );
91
92 /* HASH Configuration */
93 if (HAL_HASH_DeInit(&ctx->hhash) != HAL_OK)
94 {
95 return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
96 }
97 ctx->hhash.Init.DataType = HASH_DATATYPE_8B;
98 if (HAL_HASH_Init(&ctx->hhash) != HAL_OK)
99 {
100 return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
101 }
102
103 /* first block on 17 words */
104 ctx->first = ST_SHA1_EXTRA_BYTES;
105
106 ctx->sbuf_len = 0;
107
108 /* save hw context */
109 HAL_HASH_ContextSaving(&ctx->hhash, ctx->ctx_save_regs);
110
111 return 0;
112 }
113
mbedtls_internal_sha1_process(mbedtls_sha1_context * ctx,const unsigned char data[ST_SHA1_BLOCK_SIZE])114 int mbedtls_internal_sha1_process( mbedtls_sha1_context *ctx, const unsigned char data[ST_SHA1_BLOCK_SIZE] )
115 {
116 SHA1_VALIDATE_RET( ctx != NULL );
117 SHA1_VALIDATE_RET( (const unsigned char *)data != NULL );
118
119 /* restore hw context */
120 HAL_HASH_ContextRestoring(&ctx->hhash, ctx->ctx_save_regs);
121
122 if (HAL_HASH_SHA1_Accmlt(&ctx->hhash, (uint8_t *) data, ST_SHA1_BLOCK_SIZE) != 0)
123 {
124 return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
125 }
126
127 /* save hw context */
128 HAL_HASH_ContextSaving(&ctx->hhash, ctx->ctx_save_regs);
129
130 return 0;
131 }
132
mbedtls_sha1_update_ret(mbedtls_sha1_context * ctx,const unsigned char * input,size_t ilen)133 int mbedtls_sha1_update_ret(mbedtls_sha1_context *ctx, const unsigned char *input, size_t ilen)
134 {
135 size_t currentlen = ilen;
136
137 SHA1_VALIDATE_RET( ctx != NULL );
138 SHA1_VALIDATE_RET( ilen == 0 || input != NULL );
139
140 /* restore hw context */
141 HAL_HASH_ContextRestoring(&ctx->hhash, ctx->ctx_save_regs);
142
143 if (currentlen < (ST_SHA1_BLOCK_SIZE + ctx->first - ctx->sbuf_len))
144 {
145 /* only store input data in context buffer */
146 memcpy(ctx->sbuf + ctx->sbuf_len, input, currentlen);
147 ctx->sbuf_len += currentlen;
148 }
149 else
150 {
151 /* fill context buffer until ST_SHA1_BLOCK_SIZE bytes, and process it */
152 memcpy(ctx->sbuf + ctx->sbuf_len, input, (ST_SHA1_BLOCK_SIZE + ctx->first - ctx->sbuf_len));
153 currentlen -= (ST_SHA1_BLOCK_SIZE + ctx->first - ctx->sbuf_len);
154
155 if (HAL_HASH_SHA1_Accmlt(&ctx->hhash, (uint8_t *)(ctx->sbuf), ST_SHA1_BLOCK_SIZE + ctx->first) != 0)
156 {
157 return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
158 }
159
160 /* Process following input data with size multiple of ST_SHA1_BLOCK_SIZE bytes */
161 size_t iter = currentlen / ST_SHA1_BLOCK_SIZE;
162 if (iter != 0)
163 {
164 if (HAL_HASH_SHA1_Accmlt(&ctx->hhash, (uint8_t *)(input + ST_SHA1_BLOCK_SIZE + ctx->first - ctx->sbuf_len), (iter * ST_SHA1_BLOCK_SIZE)) != 0)
165 {
166 return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
167 }
168 }
169
170 /* following blocks on 16 words */
171 ctx->first = 0;
172
173 /* Store only the remaining input data up to (ST_SHA1_BLOCK_SIZE - 1) bytes */
174 ctx->sbuf_len = currentlen % ST_SHA1_BLOCK_SIZE;
175 if (ctx->sbuf_len != 0)
176 {
177 memcpy(ctx->sbuf, input + ilen - ctx->sbuf_len, ctx->sbuf_len);
178 }
179 }
180
181 /* save hw context */
182 HAL_HASH_ContextSaving(&ctx->hhash, ctx->ctx_save_regs);
183
184 return 0;
185 }
186
mbedtls_sha1_finish_ret(mbedtls_sha1_context * ctx,unsigned char output[32])187 int mbedtls_sha1_finish_ret(mbedtls_sha1_context *ctx, unsigned char output[32])
188 {
189 SHA1_VALIDATE_RET( ctx != NULL );
190 SHA1_VALIDATE_RET( (unsigned char *)output != NULL );
191
192 /* restore hw context */
193 HAL_HASH_ContextRestoring(&ctx->hhash, ctx->ctx_save_regs);
194
195 /* Last accumulation for pending bytes in sbuf_len, then trig processing and get digest */
196 if (HAL_HASH_SHA1_Accmlt_End(&ctx->hhash, ctx->sbuf, ctx->sbuf_len, output, ST_SHA1_TIMEOUT) != 0)
197 {
198 return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
199 }
200
201 ctx->sbuf_len = 0;
202
203 return 0;
204 }
205
206 #endif /* MBEDTLS_SHA1_ALT*/
207 #endif /* MBEDTLS_SHA1_C */
208