1 /*
2  * SHA-1 implementation with hardware ESP support added.
3  *
4  * SPDX-FileCopyrightText: The Mbed TLS Contributors
5  *
6  * SPDX-License-Identifier: Apache-2.0
7  *
8  * SPDX-FileContributor: 2016-2023 Espressif Systems (Shanghai) CO LTD
9  */
10 /*
11  *  The SHA-1 standard was published by NIST in 1993.
12  *
13  *  http://www.itl.nist.gov/fipspubs/fip180-1.htm
14  */
15 
16 #include <mbedtls/build_info.h>
17 
18 #if defined(MBEDTLS_SHA1_C) && defined(MBEDTLS_SHA1_ALT)
19 
20 #include "mbedtls/sha1.h"
21 
22 #include <string.h>
23 #include <assert.h>
24 
25 #if defined(MBEDTLS_SELF_TEST)
26 #if defined(MBEDTLS_PLATFORM_C)
27 #include "mbedtls/platform.h"
28 #else
29 #include <stdio.h>
30 #define mbedtls_printf printf
31 #endif /* MBEDTLS_PLATFORM_C */
32 #endif /* MBEDTLS_SELF_TEST */
33 
34 #include "sha/sha_block.h"
35 
36 /* Implementation that should never be optimized out by the compiler */
mbedtls_zeroize(void * v,size_t n)37 static void mbedtls_zeroize( void *v, size_t n )
38 {
39     volatile unsigned char *p = (unsigned char *)v;
40     while ( n-- ) {
41         *p++ = 0;
42     }
43 }
44 
45 /*
46  * 32-bit integer manipulation macros (big endian)
47  */
48 
49 #ifndef PUT_UINT32_BE
50 #define PUT_UINT32_BE(n,b,i)                            \
51 {                                                       \
52     (b)[(i)    ] = (unsigned char) ( (n) >> 24 );       \
53     (b)[(i) + 1] = (unsigned char) ( (n) >> 16 );       \
54     (b)[(i) + 2] = (unsigned char) ( (n) >>  8 );       \
55     (b)[(i) + 3] = (unsigned char) ( (n)       );       \
56 }
57 #endif
58 
mbedtls_sha1_init(mbedtls_sha1_context * ctx)59 void mbedtls_sha1_init( mbedtls_sha1_context *ctx )
60 {
61     assert(ctx != NULL);
62 
63     memset( ctx, 0, sizeof( mbedtls_sha1_context ) );
64 }
65 
mbedtls_sha1_free(mbedtls_sha1_context * ctx)66 void mbedtls_sha1_free( mbedtls_sha1_context *ctx )
67 {
68     if ( ctx == NULL ) {
69         return;
70     }
71     mbedtls_zeroize( ctx, sizeof( mbedtls_sha1_context ) );
72 }
73 
mbedtls_sha1_clone(mbedtls_sha1_context * dst,const mbedtls_sha1_context * src)74 void mbedtls_sha1_clone( mbedtls_sha1_context *dst,
75                          const mbedtls_sha1_context *src )
76 {
77     memcpy(dst, src, sizeof(mbedtls_sha1_context));
78 }
79 
80 /*
81  * SHA-1 context setup
82  */
mbedtls_sha1_starts(mbedtls_sha1_context * ctx)83 int mbedtls_sha1_starts( mbedtls_sha1_context *ctx )
84 {
85     ctx->total[0] = 0;
86     ctx->total[1] = 0;
87     memset( ctx, 0, sizeof( mbedtls_sha1_context ) );
88     ctx->mode = SHA1;
89 
90     return 0;
91 }
92 
esp_internal_sha_update_state(mbedtls_sha1_context * ctx)93 static void esp_internal_sha_update_state(mbedtls_sha1_context *ctx)
94 {
95     if (ctx->sha_state == ESP_SHA1_STATE_INIT) {
96         ctx->first_block = true;
97         ctx->sha_state = ESP_SHA1_STATE_IN_PROCESS;
98     } else if (ctx->sha_state == ESP_SHA1_STATE_IN_PROCESS) {
99         ctx->first_block = false;
100         esp_sha_write_digest_state(ctx->mode, ctx->state);
101     }
102 }
103 
esp_internal_sha1_block_process(mbedtls_sha1_context * ctx,const uint8_t * data)104 static void esp_internal_sha1_block_process(mbedtls_sha1_context *ctx, const uint8_t *data)
105 {
106     esp_sha_block(SHA1, data, ctx->first_block);
107 
108     if (ctx->first_block) {
109         ctx->first_block = false;
110     }
111 }
112 
mbedtls_internal_sha1_process(mbedtls_sha1_context * ctx,const unsigned char data[64])113 int mbedtls_internal_sha1_process( mbedtls_sha1_context *ctx, const unsigned char data[64] )
114 {
115     esp_sha_acquire_hardware();
116     esp_internal_sha_update_state(ctx);
117     esp_sha_block(ctx->mode, data, ctx->first_block);
118     esp_sha_read_digest_state(ctx->mode, ctx->state);
119     esp_sha_release_hardware();
120     return 0;
121 }
122 
mbedtls_sha1_update(mbedtls_sha1_context * ctx,const unsigned char * input,size_t ilen)123 int mbedtls_sha1_update( mbedtls_sha1_context *ctx, const unsigned char *input, size_t ilen )
124 {
125     size_t fill;
126     uint32_t left, local_len = 0;
127 
128     if ( !ilen || (input == NULL)) {
129         return 0;
130     }
131 
132     left = ctx->total[0] & 0x3F;
133     fill = 64 - left;
134 
135     ctx->total[0] += (uint32_t) ilen;
136     ctx->total[0] &= 0xFFFFFFFF;
137 
138     if ( ctx->total[0] < (uint32_t) ilen ) {
139         ctx->total[1]++;
140     }
141 
142     if ( left && ilen >= fill ) {
143         memcpy( (void *) (ctx->buffer + left), input, fill );
144         input += fill;
145         ilen  -= fill;
146         left = 0;
147         local_len = 64;
148     }
149 
150     if ( (ilen >= 64) || local_len) {
151 
152         esp_sha_acquire_hardware();
153 
154         esp_internal_sha_update_state(ctx);
155 
156         /* First process buffered block, if any */
157         if ( local_len ) {
158             esp_internal_sha1_block_process(ctx, ctx->buffer);
159         }
160 
161         while ( ilen >= 64 ) {
162             esp_internal_sha1_block_process(ctx, input);
163 
164             input += 64;
165             ilen  -= 64;
166         }
167 
168         esp_sha_read_digest_state(SHA1, ctx->state);
169 
170         esp_sha_release_hardware();
171 
172     }
173 
174     if ( ilen > 0 ) {
175         memcpy( (void *) (ctx->buffer + left), input, ilen);
176     }
177     return 0;
178 }
179 
180 static const unsigned char sha1_padding[64] = {
181     0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
182     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
183     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
184     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
185 };
186 
187 /*
188 * SHA-1 final digest
189  */
mbedtls_sha1_finish(mbedtls_sha1_context * ctx,unsigned char output[20])190 int mbedtls_sha1_finish( mbedtls_sha1_context *ctx, unsigned char output[20] )
191 {
192     int ret = -1;
193     uint32_t last, padn;
194     uint32_t high, low;
195     unsigned char msglen[8];
196 
197     high = ( ctx->total[0] >> 29 )
198            | ( ctx->total[1] <<  3 );
199     low  = ( ctx->total[0] <<  3 );
200 
201     PUT_UINT32_BE( high, msglen, 0 );
202     PUT_UINT32_BE( low,  msglen, 4 );
203 
204     last = ctx->total[0] & 0x3F;
205     padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
206 
207 
208     if ( ( ret = mbedtls_sha1_update( ctx, sha1_padding, padn ) ) != 0 ) {
209         return ret;
210     }
211     if ( ( ret = mbedtls_sha1_update( ctx, msglen, 8 ) ) != 0 ) {
212         return ret;
213     }
214 
215     memcpy(output, ctx->state, 20);
216 
217     return ret;
218 }
219 
220 #endif /* MBEDTLS_SHA1_C && MBEDTLS_SHA1_ALT */
221