1 /*
2 * SHA-256 implementation with hardware ESP32 support added.
3 * Uses mbedTLS software implementation for failover when concurrent
4 * SHA operations are in use.
5 *
6 * SPDX-FileCopyrightText: The Mbed TLS Contributors
7 *
8 * SPDX-License-Identifier: Apache-2.0
9 *
10 * SPDX-FileContributor: 2016-2023 Espressif Systems (Shanghai) CO LTD
11 */
12 /*
13 * The SHA-256 Secure Hash Standard was published by NIST in 2002.
14 *
15 * http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf
16 */
17
18 #include <mbedtls/build_info.h>
19
20 #if defined(MBEDTLS_SHA256_C) && defined(MBEDTLS_SHA256_ALT)
21
22 #include "mbedtls/sha256.h"
23
24 #include <string.h>
25
26 #if defined(MBEDTLS_SELF_TEST)
27 #if defined(MBEDTLS_PLATFORM_C)
28 #include "mbedtls/platform.h"
29 #else
30 #include <stdio.h>
31 #define mbedtls_printf printf
32 #endif /* MBEDTLS_PLATFORM_C */
33 #endif /* MBEDTLS_SELF_TEST */
34
35 #include "sha/sha_parallel_engine.h"
36
37 /* Implementation that should never be optimized out by the compiler */
mbedtls_zeroize(void * v,size_t n)38 static void mbedtls_zeroize( void *v, size_t n )
39 {
40 volatile unsigned char *p = v;
41 while ( n-- ) {
42 *p++ = 0;
43 }
44 }
45
46 /*
47 * 32-bit integer manipulation macros (big endian)
48 */
49 #ifndef GET_UINT32_BE
50 #define GET_UINT32_BE(n,b,i) \
51 do { \
52 (n) = ( (uint32_t) (b)[(i) ] << 24 ) \
53 | ( (uint32_t) (b)[(i) + 1] << 16 ) \
54 | ( (uint32_t) (b)[(i) + 2] << 8 ) \
55 | ( (uint32_t) (b)[(i) + 3] ); \
56 } while( 0 )
57 #endif
58
59 #ifndef PUT_UINT32_BE
60 #define PUT_UINT32_BE(n,b,i) \
61 do { \
62 (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \
63 (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \
64 (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \
65 (b)[(i) + 3] = (unsigned char) ( (n) ); \
66 } while( 0 )
67 #endif
68
mbedtls_sha256_init(mbedtls_sha256_context * ctx)69 void mbedtls_sha256_init( mbedtls_sha256_context *ctx )
70 {
71 memset( ctx, 0, sizeof( mbedtls_sha256_context ) );
72 }
73
mbedtls_sha256_free(mbedtls_sha256_context * ctx)74 void mbedtls_sha256_free( mbedtls_sha256_context *ctx )
75 {
76 if ( ctx == NULL ) {
77 return;
78 }
79
80 if (ctx->mode == ESP_MBEDTLS_SHA256_HARDWARE) {
81 esp_sha_unlock_engine(SHA2_256);
82 }
83 mbedtls_zeroize( ctx, sizeof( mbedtls_sha256_context ) );
84 }
85
mbedtls_sha256_clone(mbedtls_sha256_context * dst,const mbedtls_sha256_context * src)86 void mbedtls_sha256_clone( mbedtls_sha256_context *dst,
87 const mbedtls_sha256_context *src )
88 {
89 *dst = *src;
90
91 if (src->mode == ESP_MBEDTLS_SHA256_HARDWARE) {
92 /* Copy hardware digest state out to cloned state,
93 which will become a software digest.
94 */
95 esp_sha_read_digest_state(SHA2_256, dst->state);
96 dst->mode = ESP_MBEDTLS_SHA256_SOFTWARE;
97 }
98 }
99
100 /*
101 * SHA-256 context setup
102 */
mbedtls_sha256_starts(mbedtls_sha256_context * ctx,int is224)103 int mbedtls_sha256_starts( mbedtls_sha256_context *ctx, int is224 )
104 {
105 ctx->total[0] = 0;
106 ctx->total[1] = 0;
107
108 if ( is224 == 0 ) {
109 /* SHA-256 */
110 ctx->state[0] = 0x6A09E667;
111 ctx->state[1] = 0xBB67AE85;
112 ctx->state[2] = 0x3C6EF372;
113 ctx->state[3] = 0xA54FF53A;
114 ctx->state[4] = 0x510E527F;
115 ctx->state[5] = 0x9B05688C;
116 ctx->state[6] = 0x1F83D9AB;
117 ctx->state[7] = 0x5BE0CD19;
118 } else {
119 /* SHA-224 */
120 ctx->state[0] = 0xC1059ED8;
121 ctx->state[1] = 0x367CD507;
122 ctx->state[2] = 0x3070DD17;
123 ctx->state[3] = 0xF70E5939;
124 ctx->state[4] = 0xFFC00B31;
125 ctx->state[5] = 0x68581511;
126 ctx->state[6] = 0x64F98FA7;
127 ctx->state[7] = 0xBEFA4FA4;
128 }
129
130 ctx->is224 = is224;
131 if (ctx->mode == ESP_MBEDTLS_SHA256_HARDWARE) {
132 esp_sha_unlock_engine(SHA2_256);
133 }
134 ctx->mode = ESP_MBEDTLS_SHA256_UNUSED;
135 return 0;
136 }
137
138 static const uint32_t K[] = {
139 0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5,
140 0x3956C25B, 0x59F111F1, 0x923F82A4, 0xAB1C5ED5,
141 0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3,
142 0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174,
143 0xE49B69C1, 0xEFBE4786, 0x0FC19DC6, 0x240CA1CC,
144 0x2DE92C6F, 0x4A7484AA, 0x5CB0A9DC, 0x76F988DA,
145 0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7,
146 0xC6E00BF3, 0xD5A79147, 0x06CA6351, 0x14292967,
147 0x27B70A85, 0x2E1B2138, 0x4D2C6DFC, 0x53380D13,
148 0x650A7354, 0x766A0ABB, 0x81C2C92E, 0x92722C85,
149 0xA2BFE8A1, 0xA81A664B, 0xC24B8B70, 0xC76C51A3,
150 0xD192E819, 0xD6990624, 0xF40E3585, 0x106AA070,
151 0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5,
152 0x391C0CB3, 0x4ED8AA4A, 0x5B9CCA4F, 0x682E6FF3,
153 0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208,
154 0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2,
155 };
156
157 #define SHR(x,n) ((x & 0xFFFFFFFF) >> n)
158 #define ROTR(x,n) (SHR(x,n) | (x << (32 - n)))
159
160 #define S0(x) (ROTR(x, 7) ^ ROTR(x,18) ^ SHR(x, 3))
161 #define S1(x) (ROTR(x,17) ^ ROTR(x,19) ^ SHR(x,10))
162
163 #define S2(x) (ROTR(x, 2) ^ ROTR(x,13) ^ ROTR(x,22))
164 #define S3(x) (ROTR(x, 6) ^ ROTR(x,11) ^ ROTR(x,25))
165
166 #define F0(x,y,z) ((x & y) | (z & (x | y)))
167 #define F1(x,y,z) (z ^ (x & (y ^ z)))
168
169 #define R(t) \
170 ( \
171 W[t] = S1(W[t - 2]) + W[t - 7] + \
172 S0(W[t - 15]) + W[t - 16] \
173 )
174
175 #define P(a,b,c,d,e,f,g,h,x,K) \
176 { \
177 temp1 = h + S3(e) + F1(e,f,g) + K + x; \
178 temp2 = S2(a) + F0(a,b,c); \
179 d += temp1; h = temp1 + temp2; \
180 }
181
182
mbedtls_sha256_software_process(mbedtls_sha256_context * ctx,const unsigned char data[64])183 static void mbedtls_sha256_software_process( mbedtls_sha256_context *ctx, const unsigned char data[64] )
184 {
185 uint32_t temp1, temp2, W[64];
186 uint32_t A[8];
187 unsigned int i;
188
189 for ( i = 0; i < 8; i++ ) {
190 A[i] = ctx->state[i];
191 }
192
193 #if defined(MBEDTLS_SHA256_SMALLER)
194 for ( i = 0; i < 64; i++ ) {
195 if ( i < 16 ) {
196 GET_UINT32_BE( W[i], data, 4 * i );
197 } else {
198 R( i );
199 }
200
201 P( A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], W[i], K[i] );
202
203 temp1 = A[7]; A[7] = A[6]; A[6] = A[5]; A[5] = A[4]; A[4] = A[3];
204 A[3] = A[2]; A[2] = A[1]; A[1] = A[0]; A[0] = temp1;
205 }
206 #else /* MBEDTLS_SHA256_SMALLER */
207 for ( i = 0; i < 16; i++ ) {
208 GET_UINT32_BE( W[i], data, 4 * i );
209 }
210
211 for ( i = 0; i < 16; i += 8 ) {
212 P( A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], W[i + 0], K[i + 0] );
213 P( A[7], A[0], A[1], A[2], A[3], A[4], A[5], A[6], W[i + 1], K[i + 1] );
214 P( A[6], A[7], A[0], A[1], A[2], A[3], A[4], A[5], W[i + 2], K[i + 2] );
215 P( A[5], A[6], A[7], A[0], A[1], A[2], A[3], A[4], W[i + 3], K[i + 3] );
216 P( A[4], A[5], A[6], A[7], A[0], A[1], A[2], A[3], W[i + 4], K[i + 4] );
217 P( A[3], A[4], A[5], A[6], A[7], A[0], A[1], A[2], W[i + 5], K[i + 5] );
218 P( A[2], A[3], A[4], A[5], A[6], A[7], A[0], A[1], W[i + 6], K[i + 6] );
219 P( A[1], A[2], A[3], A[4], A[5], A[6], A[7], A[0], W[i + 7], K[i + 7] );
220 }
221
222 for ( i = 16; i < 64; i += 8 ) {
223 P( A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], R(i + 0), K[i + 0] );
224 P( A[7], A[0], A[1], A[2], A[3], A[4], A[5], A[6], R(i + 1), K[i + 1] );
225 P( A[6], A[7], A[0], A[1], A[2], A[3], A[4], A[5], R(i + 2), K[i + 2] );
226 P( A[5], A[6], A[7], A[0], A[1], A[2], A[3], A[4], R(i + 3), K[i + 3] );
227 P( A[4], A[5], A[6], A[7], A[0], A[1], A[2], A[3], R(i + 4), K[i + 4] );
228 P( A[3], A[4], A[5], A[6], A[7], A[0], A[1], A[2], R(i + 5), K[i + 5] );
229 P( A[2], A[3], A[4], A[5], A[6], A[7], A[0], A[1], R(i + 6), K[i + 6] );
230 P( A[1], A[2], A[3], A[4], A[5], A[6], A[7], A[0], R(i + 7), K[i + 7] );
231 }
232 #endif /* MBEDTLS_SHA256_SMALLER */
233
234 for ( i = 0; i < 8; i++ ) {
235 ctx->state[i] += A[i];
236 }
237 }
238
239
esp_internal_sha256_parallel_engine_process(mbedtls_sha256_context * ctx,const unsigned char data[64],bool read_digest)240 static int esp_internal_sha256_parallel_engine_process( mbedtls_sha256_context *ctx, const unsigned char data[64], bool read_digest )
241 {
242 bool first_block = false;
243
244 if (ctx->mode == ESP_MBEDTLS_SHA256_UNUSED) {
245 /* try to use hardware for this digest */
246 if (!ctx->is224 && esp_sha_try_lock_engine(SHA2_256)) {
247 ctx->mode = ESP_MBEDTLS_SHA256_HARDWARE;
248 first_block = true;
249 } else {
250 ctx->mode = ESP_MBEDTLS_SHA256_SOFTWARE;
251 }
252 }
253
254 if (ctx->mode == ESP_MBEDTLS_SHA256_HARDWARE) {
255 esp_sha_block(SHA2_256, data, first_block);
256 if (read_digest) {
257 esp_sha_read_digest_state(SHA2_256, ctx->state);
258 }
259 } else {
260 mbedtls_sha256_software_process(ctx, data);
261 }
262
263 return 0;
264 }
265
266
mbedtls_internal_sha256_process(mbedtls_sha256_context * ctx,const unsigned char data[64])267 int mbedtls_internal_sha256_process( mbedtls_sha256_context *ctx, const unsigned char data[64] )
268 {
269 return esp_internal_sha256_parallel_engine_process(ctx, data, true);
270 }
271
272
273 /*
274 * SHA-256 process buffer
275 */
mbedtls_sha256_update(mbedtls_sha256_context * ctx,const unsigned char * input,size_t ilen)276 int mbedtls_sha256_update( mbedtls_sha256_context *ctx, const unsigned char *input,
277 size_t ilen )
278 {
279 int ret = -1;
280 size_t fill;
281 uint32_t left;
282
283 if ( ilen == 0 ) {
284 return 0;
285 }
286
287 left = ctx->total[0] & 0x3F;
288 fill = 64 - left;
289
290 ctx->total[0] += (uint32_t) ilen;
291 ctx->total[0] &= 0xFFFFFFFF;
292
293 if ( ctx->total[0] < (uint32_t) ilen ) {
294 ctx->total[1]++;
295 }
296
297 if ( left && ilen >= fill ) {
298 memcpy( (void *) (ctx->buffer + left), input, fill );
299
300 if ( ( ret = esp_internal_sha256_parallel_engine_process( ctx, ctx->buffer, false ) ) != 0 ) {
301 return ret;
302 }
303
304 input += fill;
305 ilen -= fill;
306 left = 0;
307 }
308
309 while ( ilen >= 64 ) {
310 if ( ( ret = esp_internal_sha256_parallel_engine_process( ctx, input, false ) ) != 0 ) {
311 return ret;
312 }
313
314 input += 64;
315 ilen -= 64;
316 }
317
318 if (ctx->mode == ESP_MBEDTLS_SHA256_HARDWARE) {
319 esp_sha_read_digest_state(SHA2_256, ctx->state);
320 }
321
322 if ( ilen > 0 ) {
323 memcpy( (void *) (ctx->buffer + left), input, ilen );
324 }
325
326 return 0;
327 }
328
329 static const unsigned char sha256_padding[64] = {
330 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
331 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
332 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
333 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
334 };
335
336 /*
337 * SHA-256 final digest
338 */
mbedtls_sha256_finish(mbedtls_sha256_context * ctx,unsigned char * output)339 int mbedtls_sha256_finish( mbedtls_sha256_context *ctx, unsigned char *output )
340 {
341 int ret = -1;
342 uint32_t last, padn;
343 uint32_t high, low;
344 unsigned char msglen[8];
345
346 high = ( ctx->total[0] >> 29 )
347 | ( ctx->total[1] << 3 );
348 low = ( ctx->total[0] << 3 );
349
350 PUT_UINT32_BE( high, msglen, 0 );
351 PUT_UINT32_BE( low, msglen, 4 );
352
353 last = ctx->total[0] & 0x3F;
354 padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
355
356 if ( ( ret = mbedtls_sha256_update( ctx, sha256_padding, padn ) ) != 0 ) {
357 goto out;
358 }
359
360 if ( ( ret = mbedtls_sha256_update( ctx, msglen, 8 ) ) != 0 ) {
361 goto out;
362 }
363
364 /* if state is in hardware, read it out */
365 if (ctx->mode == ESP_MBEDTLS_SHA256_HARDWARE) {
366 esp_sha_read_digest_state(SHA2_256, ctx->state);
367 }
368
369 PUT_UINT32_BE( ctx->state[0], output, 0 );
370 PUT_UINT32_BE( ctx->state[1], output, 4 );
371 PUT_UINT32_BE( ctx->state[2], output, 8 );
372 PUT_UINT32_BE( ctx->state[3], output, 12 );
373 PUT_UINT32_BE( ctx->state[4], output, 16 );
374 PUT_UINT32_BE( ctx->state[5], output, 20 );
375 PUT_UINT32_BE( ctx->state[6], output, 24 );
376
377 if ( ctx->is224 == 0 ) {
378 PUT_UINT32_BE( ctx->state[7], output, 28 );
379 }
380
381 out:
382 if (ctx->mode == ESP_MBEDTLS_SHA256_HARDWARE) {
383 esp_sha_unlock_engine(SHA2_256);
384 ctx->mode = ESP_MBEDTLS_SHA256_SOFTWARE;
385 }
386
387 return ret;
388 }
389
390 #endif /* MBEDTLS_SHA256_C && MBEDTLS_SHA256_ALT */
391