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 
24 #if defined(MBEDTLS_SELF_TEST)
25 #if defined(MBEDTLS_PLATFORM_C)
26 #include "mbedtls/platform.h"
27 #else
28 #include <stdio.h>
29 #define mbedtls_printf printf
30 #endif /* MBEDTLS_PLATFORM_C */
31 #endif /* MBEDTLS_SELF_TEST */
32 
33 #include "sha/sha_dma.h"
34 
35 /* Implementation that should never be optimized out by the compiler */
mbedtls_zeroize(void * v,size_t n)36 static void mbedtls_zeroize( void *v, size_t n )
37 {
38     volatile unsigned char *p = (unsigned char *)v;
39     while ( n-- ) {
40         *p++ = 0;
41     }
42 }
43 
44 /*
45  * 32-bit integer manipulation macros (big endian)
46  */
47 
48 #ifndef PUT_UINT32_BE
49 #define PUT_UINT32_BE(n,b,i)                            \
50 {                                                       \
51     (b)[(i)    ] = (unsigned char) ( (n) >> 24 );       \
52     (b)[(i) + 1] = (unsigned char) ( (n) >> 16 );       \
53     (b)[(i) + 2] = (unsigned char) ( (n) >>  8 );       \
54     (b)[(i) + 3] = (unsigned char) ( (n)       );       \
55 }
56 #endif
57 
mbedtls_sha1_init(mbedtls_sha1_context * ctx)58 void mbedtls_sha1_init( mbedtls_sha1_context *ctx )
59 {
60     memset( ctx, 0, sizeof( mbedtls_sha1_context ) );
61 }
62 
mbedtls_sha1_free(mbedtls_sha1_context * ctx)63 void mbedtls_sha1_free( mbedtls_sha1_context *ctx )
64 {
65     if ( ctx == NULL ) {
66         return;
67     }
68     mbedtls_zeroize( ctx, sizeof( mbedtls_sha1_context ) );
69 }
70 
mbedtls_sha1_clone(mbedtls_sha1_context * dst,const mbedtls_sha1_context * src)71 void mbedtls_sha1_clone( mbedtls_sha1_context *dst,
72                          const mbedtls_sha1_context *src )
73 {
74     memcpy(dst, src, sizeof(mbedtls_sha1_context));
75 }
76 
77 /*
78  * SHA-1 context setup
79  */
mbedtls_sha1_starts(mbedtls_sha1_context * ctx)80 int mbedtls_sha1_starts( mbedtls_sha1_context *ctx )
81 {
82     ctx->total[0] = 0;
83     ctx->total[1] = 0;
84 
85     memset( ctx, 0, sizeof( mbedtls_sha1_context ) );
86     ctx->mode = SHA1;
87 
88     return 0;
89 }
90 
esp_internal_sha_update_state(mbedtls_sha1_context * ctx)91 static void esp_internal_sha_update_state(mbedtls_sha1_context *ctx)
92 {
93     if (ctx->sha_state == ESP_SHA1_STATE_INIT) {
94         ctx->first_block = true;
95         ctx->sha_state = ESP_SHA1_STATE_IN_PROCESS;
96     } else if (ctx->sha_state == ESP_SHA1_STATE_IN_PROCESS) {
97         ctx->first_block = false;
98         esp_sha_write_digest_state(ctx->mode, ctx->state);
99     }
100 }
101 
esp_internal_sha1_dma_process(mbedtls_sha1_context * ctx,const uint8_t * data,size_t len,uint8_t * buf,size_t buf_len)102 static int esp_internal_sha1_dma_process(mbedtls_sha1_context *ctx,
103         const uint8_t *data, size_t len,
104         uint8_t *buf, size_t buf_len)
105 {
106     return esp_sha_dma(SHA1, data, len, buf, buf_len, ctx->first_block);
107 }
108 
mbedtls_internal_sha1_process(mbedtls_sha1_context * ctx,const unsigned char data[64])109 int mbedtls_internal_sha1_process( mbedtls_sha1_context *ctx, const unsigned char data[64] )
110 {
111     int ret = -1;
112     esp_sha_acquire_hardware();
113     esp_internal_sha_update_state(ctx);
114 
115     ret = esp_sha_dma(ctx->mode, data, 64, 0, 0, ctx->first_block);
116     if (ret != 0) {
117         esp_sha_release_hardware();
118         return ret;
119     }
120 
121     esp_sha_read_digest_state(ctx->mode, ctx->state);
122     esp_sha_release_hardware();
123     return ret;
124 }
125 
mbedtls_sha1_update(mbedtls_sha1_context * ctx,const unsigned char * input,size_t ilen)126 int mbedtls_sha1_update( mbedtls_sha1_context *ctx, const unsigned char *input, size_t ilen )
127 {
128     size_t fill;
129     uint32_t left, len, local_len = 0;
130 
131     if ( !ilen || (input == NULL)) {
132         return 0;
133     }
134 
135     left = ctx->total[0] & 0x3F;
136     fill = 64 - left;
137 
138     ctx->total[0] += (uint32_t) ilen;
139     ctx->total[0] &= 0xFFFFFFFF;
140 
141     if ( ctx->total[0] < (uint32_t) ilen ) {
142         ctx->total[1]++;
143     }
144 
145     if ( left && ilen >= fill ) {
146         memcpy( (void *) (ctx->buffer + left), input, fill );
147 
148         input += fill;
149         ilen  -= fill;
150         left = 0;
151         local_len = 64;
152     }
153 
154     len = (ilen / 64) * 64;
155     if ( len || local_len) {
156 
157         esp_sha_acquire_hardware();
158 
159         esp_internal_sha_update_state(ctx);
160 
161         int ret = esp_internal_sha1_dma_process(ctx, input, len, ctx->buffer, local_len);
162         if (ret != 0) {
163             esp_sha_release_hardware();
164             return ret;
165         }
166 
167         esp_sha_read_digest_state(SHA1, ctx->state);
168 
169         esp_sha_release_hardware();
170 
171     }
172 
173     if ( ilen > 0 ) {
174         memcpy( (void *) (ctx->buffer + left), input + len, ilen - len );
175     }
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