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