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