1 /*
2  *  SHA-1 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-1 standard was published by NIST in 1993.
14  *
15  *  http://www.itl.nist.gov/fipspubs/fip180-1.htm
16  */
17 
18 #include <mbedtls/build_info.h>
19 
20 #if defined(MBEDTLS_SHA1_C) && defined(MBEDTLS_SHA1_ALT)
21 
22 #include "mbedtls/sha1.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 = (unsigned char *)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 {                                                       \
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 }
57 #endif
58 
59 #ifndef PUT_UINT32_BE
60 #define PUT_UINT32_BE(n,b,i)                            \
61 {                                                       \
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 }
67 #endif
68 
mbedtls_sha1_init(mbedtls_sha1_context * ctx)69 void mbedtls_sha1_init( mbedtls_sha1_context *ctx )
70 {
71     memset( ctx, 0, sizeof( mbedtls_sha1_context ) );
72 }
73 
mbedtls_sha1_free(mbedtls_sha1_context * ctx)74 void mbedtls_sha1_free( mbedtls_sha1_context *ctx )
75 {
76     if ( ctx == NULL ) {
77         return;
78     }
79 
80     if (ctx->mode == ESP_MBEDTLS_SHA1_HARDWARE) {
81         esp_sha_unlock_engine(SHA1);
82     }
83     mbedtls_zeroize( ctx, sizeof( mbedtls_sha1_context ) );
84 }
85 
mbedtls_sha1_clone(mbedtls_sha1_context * dst,const mbedtls_sha1_context * src)86 void mbedtls_sha1_clone( mbedtls_sha1_context *dst,
87                          const mbedtls_sha1_context *src )
88 {
89     *dst = *src;
90 
91     if (src->mode == ESP_MBEDTLS_SHA1_HARDWARE) {
92         /* Copy hardware digest state out to cloned state,
93            which will be a software digest.
94         */
95         esp_sha_read_digest_state(SHA1, dst->state);
96         dst->mode = ESP_MBEDTLS_SHA1_SOFTWARE;
97     }
98 }
99 
100 
101 /*
102  * SHA-1 context setup
103  */
mbedtls_sha1_starts(mbedtls_sha1_context * ctx)104 int mbedtls_sha1_starts( mbedtls_sha1_context *ctx )
105 {
106     ctx->total[0] = 0;
107     ctx->total[1] = 0;
108 
109     ctx->state[0] = 0x67452301;
110     ctx->state[1] = 0xEFCDAB89;
111     ctx->state[2] = 0x98BADCFE;
112     ctx->state[3] = 0x10325476;
113     ctx->state[4] = 0xC3D2E1F0;
114 
115     if (ctx->mode == ESP_MBEDTLS_SHA1_HARDWARE) {
116         esp_sha_unlock_engine(SHA1);
117     }
118     ctx->mode = ESP_MBEDTLS_SHA1_UNUSED;
119 
120     return 0;
121 }
122 
123 
mbedtls_sha1_software_process(mbedtls_sha1_context * ctx,const unsigned char data[64])124 static void mbedtls_sha1_software_process( mbedtls_sha1_context *ctx, const unsigned char data[64] )
125 {
126     uint32_t temp, W[16], A, B, C, D, E;
127 
128     GET_UINT32_BE( W[ 0], data,  0 );
129     GET_UINT32_BE( W[ 1], data,  4 );
130     GET_UINT32_BE( W[ 2], data,  8 );
131     GET_UINT32_BE( W[ 3], data, 12 );
132     GET_UINT32_BE( W[ 4], data, 16 );
133     GET_UINT32_BE( W[ 5], data, 20 );
134     GET_UINT32_BE( W[ 6], data, 24 );
135     GET_UINT32_BE( W[ 7], data, 28 );
136     GET_UINT32_BE( W[ 8], data, 32 );
137     GET_UINT32_BE( W[ 9], data, 36 );
138     GET_UINT32_BE( W[10], data, 40 );
139     GET_UINT32_BE( W[11], data, 44 );
140     GET_UINT32_BE( W[12], data, 48 );
141     GET_UINT32_BE( W[13], data, 52 );
142     GET_UINT32_BE( W[14], data, 56 );
143     GET_UINT32_BE( W[15], data, 60 );
144 
145 #define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
146 
147 #define R(t)                                            \
148 (                                                       \
149     temp = W[( t -  3 ) & 0x0F] ^ W[( t - 8 ) & 0x0F] ^ \
150            W[( t - 14 ) & 0x0F] ^ W[  t       & 0x0F],  \
151     ( W[t & 0x0F] = S(temp,1) )                         \
152 )
153 
154 #define P(a,b,c,d,e,x)                                  \
155 {                                                       \
156     e += S(a,5) + F(b,c,d) + K + x; b = S(b,30);        \
157 }
158 
159     A = ctx->state[0];
160     B = ctx->state[1];
161     C = ctx->state[2];
162     D = ctx->state[3];
163     E = ctx->state[4];
164 
165 #define F(x,y,z) (z ^ (x & (y ^ z)))
166 #define K 0x5A827999
167 
168     P( A, B, C, D, E, W[0]  );
169     P( E, A, B, C, D, W[1]  );
170     P( D, E, A, B, C, W[2]  );
171     P( C, D, E, A, B, W[3]  );
172     P( B, C, D, E, A, W[4]  );
173     P( A, B, C, D, E, W[5]  );
174     P( E, A, B, C, D, W[6]  );
175     P( D, E, A, B, C, W[7]  );
176     P( C, D, E, A, B, W[8]  );
177     P( B, C, D, E, A, W[9]  );
178     P( A, B, C, D, E, W[10] );
179     P( E, A, B, C, D, W[11] );
180     P( D, E, A, B, C, W[12] );
181     P( C, D, E, A, B, W[13] );
182     P( B, C, D, E, A, W[14] );
183     P( A, B, C, D, E, W[15] );
184     P( E, A, B, C, D, R(16) );
185     P( D, E, A, B, C, R(17) );
186     P( C, D, E, A, B, R(18) );
187     P( B, C, D, E, A, R(19) );
188 
189 #undef K
190 #undef F
191 
192 #define F(x,y,z) (x ^ y ^ z)
193 #define K 0x6ED9EBA1
194 
195     P( A, B, C, D, E, R(20) );
196     P( E, A, B, C, D, R(21) );
197     P( D, E, A, B, C, R(22) );
198     P( C, D, E, A, B, R(23) );
199     P( B, C, D, E, A, R(24) );
200     P( A, B, C, D, E, R(25) );
201     P( E, A, B, C, D, R(26) );
202     P( D, E, A, B, C, R(27) );
203     P( C, D, E, A, B, R(28) );
204     P( B, C, D, E, A, R(29) );
205     P( A, B, C, D, E, R(30) );
206     P( E, A, B, C, D, R(31) );
207     P( D, E, A, B, C, R(32) );
208     P( C, D, E, A, B, R(33) );
209     P( B, C, D, E, A, R(34) );
210     P( A, B, C, D, E, R(35) );
211     P( E, A, B, C, D, R(36) );
212     P( D, E, A, B, C, R(37) );
213     P( C, D, E, A, B, R(38) );
214     P( B, C, D, E, A, R(39) );
215 
216 #undef K
217 #undef F
218 
219 #define F(x,y,z) ((x & y) | (z & (x | y)))
220 #define K 0x8F1BBCDC
221 
222     P( A, B, C, D, E, R(40) );
223     P( E, A, B, C, D, R(41) );
224     P( D, E, A, B, C, R(42) );
225     P( C, D, E, A, B, R(43) );
226     P( B, C, D, E, A, R(44) );
227     P( A, B, C, D, E, R(45) );
228     P( E, A, B, C, D, R(46) );
229     P( D, E, A, B, C, R(47) );
230     P( C, D, E, A, B, R(48) );
231     P( B, C, D, E, A, R(49) );
232     P( A, B, C, D, E, R(50) );
233     P( E, A, B, C, D, R(51) );
234     P( D, E, A, B, C, R(52) );
235     P( C, D, E, A, B, R(53) );
236     P( B, C, D, E, A, R(54) );
237     P( A, B, C, D, E, R(55) );
238     P( E, A, B, C, D, R(56) );
239     P( D, E, A, B, C, R(57) );
240     P( C, D, E, A, B, R(58) );
241     P( B, C, D, E, A, R(59) );
242 
243 #undef K
244 #undef F
245 
246 #define F(x,y,z) (x ^ y ^ z)
247 #define K 0xCA62C1D6
248 
249     P( A, B, C, D, E, R(60) );
250     P( E, A, B, C, D, R(61) );
251     P( D, E, A, B, C, R(62) );
252     P( C, D, E, A, B, R(63) );
253     P( B, C, D, E, A, R(64) );
254     P( A, B, C, D, E, R(65) );
255     P( E, A, B, C, D, R(66) );
256     P( D, E, A, B, C, R(67) );
257     P( C, D, E, A, B, R(68) );
258     P( B, C, D, E, A, R(69) );
259     P( A, B, C, D, E, R(70) );
260     P( E, A, B, C, D, R(71) );
261     P( D, E, A, B, C, R(72) );
262     P( C, D, E, A, B, R(73) );
263     P( B, C, D, E, A, R(74) );
264     P( A, B, C, D, E, R(75) );
265     P( E, A, B, C, D, R(76) );
266     P( D, E, A, B, C, R(77) );
267     P( C, D, E, A, B, R(78) );
268     P( B, C, D, E, A, R(79) );
269 
270 #undef K
271 #undef F
272 
273     ctx->state[0] += A;
274     ctx->state[1] += B;
275     ctx->state[2] += C;
276     ctx->state[3] += D;
277     ctx->state[4] += E;
278 }
279 
280 
esp_internal_sha1_parallel_engine_process(mbedtls_sha1_context * ctx,const unsigned char data[64],bool read_digest)281 static int esp_internal_sha1_parallel_engine_process( mbedtls_sha1_context *ctx, const unsigned char data[64], bool read_digest )
282 {
283     bool first_block = false;
284 
285     if (ctx->mode == ESP_MBEDTLS_SHA1_UNUSED) {
286         /* try to use hardware for this digest */
287         if (esp_sha_try_lock_engine(SHA1)) {
288             ctx->mode = ESP_MBEDTLS_SHA1_HARDWARE;
289             first_block = true;
290         } else {
291             ctx->mode = ESP_MBEDTLS_SHA1_SOFTWARE;
292         }
293     }
294 
295     if (ctx->mode == ESP_MBEDTLS_SHA1_HARDWARE) {
296         esp_sha_block(SHA1, data, first_block);
297         if (read_digest) {
298             esp_sha_read_digest_state(SHA1, ctx->state);
299         }
300     } else {
301         mbedtls_sha1_software_process(ctx, data);
302     }
303 
304     return 0;
305 }
306 
307 
mbedtls_internal_sha1_process(mbedtls_sha1_context * ctx,const unsigned char data[64])308 int mbedtls_internal_sha1_process( mbedtls_sha1_context *ctx, const unsigned char data[64] )
309 {
310     return esp_internal_sha1_parallel_engine_process(ctx, data, true);
311 }
312 
313 
314 /*
315  * SHA-1 process buffer
316  */
mbedtls_sha1_update(mbedtls_sha1_context * ctx,const unsigned char * input,size_t ilen)317 int mbedtls_sha1_update( mbedtls_sha1_context *ctx, const unsigned char *input, size_t ilen )
318 {
319     int ret = -1;
320     size_t fill;
321     uint32_t left;
322 
323     if ( ilen == 0 ) {
324         return 0;
325     }
326 
327     left = ctx->total[0] & 0x3F;
328     fill = 64 - left;
329 
330     ctx->total[0] += (uint32_t) ilen;
331     ctx->total[0] &= 0xFFFFFFFF;
332 
333     if ( ctx->total[0] < (uint32_t) ilen ) {
334         ctx->total[1]++;
335     }
336 
337     if ( left && ilen >= fill ) {
338         memcpy( (void *) (ctx->buffer + left), input, fill );
339 
340         if ( ( ret = esp_internal_sha1_parallel_engine_process( ctx, ctx->buffer, false ) ) != 0 ) {
341             return ret;
342         }
343 
344         input += fill;
345         ilen  -= fill;
346         left = 0;
347     }
348 
349     while ( ilen >= 64 ) {
350         if ( ( ret = esp_internal_sha1_parallel_engine_process( ctx, input, false ) ) != 0 ) {
351             return ret;
352         }
353 
354         input += 64;
355         ilen  -= 64;
356     }
357 
358     if (ctx->mode == ESP_MBEDTLS_SHA1_HARDWARE) {
359         esp_sha_read_digest_state(SHA1, ctx->state);
360     }
361 
362     if ( ilen > 0 ) {
363         memcpy( (void *) (ctx->buffer + left), input, ilen );
364     }
365 
366     return 0;
367 }
368 
369 static const unsigned char sha1_padding[64] = {
370     0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
371     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
372     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
373     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
374 };
375 
376 /*
377 * SHA-1 final digest
378  */
mbedtls_sha1_finish(mbedtls_sha1_context * ctx,unsigned char output[20])379 int mbedtls_sha1_finish( mbedtls_sha1_context *ctx, unsigned char output[20] )
380 {
381     int ret = -1;
382     uint32_t last, padn;
383     uint32_t high, low;
384     unsigned char msglen[8];
385 
386     high = ( ctx->total[0] >> 29 )
387            | ( ctx->total[1] <<  3 );
388     low  = ( ctx->total[0] <<  3 );
389 
390     PUT_UINT32_BE( high, msglen, 0 );
391     PUT_UINT32_BE( low,  msglen, 4 );
392 
393     last = ctx->total[0] & 0x3F;
394     padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
395 
396     if ( ( ret = mbedtls_sha1_update( ctx, sha1_padding, padn ) ) != 0 ) {
397         goto out;
398     }
399     if ( ( ret = mbedtls_sha1_update( ctx, msglen, 8 ) ) != 0 ) {
400         goto out;
401     }
402 
403     /* if state is in hardware, read it out */
404     if (ctx->mode == ESP_MBEDTLS_SHA1_HARDWARE) {
405         esp_sha_read_digest_state(SHA1, ctx->state);
406     }
407 
408     PUT_UINT32_BE( ctx->state[0], output,  0 );
409     PUT_UINT32_BE( ctx->state[1], output,  4 );
410     PUT_UINT32_BE( ctx->state[2], output,  8 );
411     PUT_UINT32_BE( ctx->state[3], output, 12 );
412     PUT_UINT32_BE( ctx->state[4], output, 16 );
413 
414 out:
415     if (ctx->mode == ESP_MBEDTLS_SHA1_HARDWARE) {
416         esp_sha_unlock_engine(SHA1);
417         ctx->mode = ESP_MBEDTLS_SHA1_SOFTWARE;
418     }
419 
420     return ret;
421 }
422 
423 #endif /* MBEDTLS_SHA1_C && MBEDTLS_SHA1_ALT */
424