1 /*
2 * SHA-1 implementation with hardware ESP support added.
3 *
4 * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
5 * Additions Copyright (C) 2016-2020, Espressif Systems (Shanghai) PTE LTD
6 * SPDX-License-Identifier: Apache-2.0
7 *
8 * Licensed under the Apache License, Version 2.0 (the "License"); you may
9 * not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
11 *
12 * http://www.apache.org/licenses/LICENSE-2.0
13 *
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
16 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 *
20 */
21 /*
22 * The SHA-1 standard was published by NIST in 1993.
23 *
24 * http://www.itl.nist.gov/fipspubs/fip180-1.htm
25 */
26
27 #if !defined(MBEDTLS_CONFIG_FILE)
28 #include "mbedtls/config.h"
29 #else
30 #include MBEDTLS_CONFIG_FILE
31 #endif
32
33 #if defined(MBEDTLS_SHA1_C) && defined(MBEDTLS_SHA1_ALT)
34
35 #include "mbedtls/sha1.h"
36
37 #include <string.h>
38
39 #if defined(MBEDTLS_SELF_TEST)
40 #if defined(MBEDTLS_PLATFORM_C)
41 #include "mbedtls/platform.h"
42 #else
43 #include <stdio.h>
44 #define mbedtls_printf printf
45 #endif /* MBEDTLS_PLATFORM_C */
46 #endif /* MBEDTLS_SELF_TEST */
47
48 #include "sha/sha_dma.h"
49
50 /* Implementation that should never be optimized out by the compiler */
mbedtls_zeroize(void * v,size_t n)51 static void mbedtls_zeroize( void *v, size_t n )
52 {
53 volatile unsigned char *p = (unsigned char *)v;
54 while ( n-- ) {
55 *p++ = 0;
56 }
57 }
58
59 /*
60 * 32-bit integer manipulation macros (big endian)
61 */
62
63 #ifndef PUT_UINT32_BE
64 #define PUT_UINT32_BE(n,b,i) \
65 { \
66 (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \
67 (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \
68 (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \
69 (b)[(i) + 3] = (unsigned char) ( (n) ); \
70 }
71 #endif
72
mbedtls_sha1_init(mbedtls_sha1_context * ctx)73 void mbedtls_sha1_init( mbedtls_sha1_context *ctx )
74 {
75 memset( ctx, 0, sizeof( mbedtls_sha1_context ) );
76 }
77
mbedtls_sha1_free(mbedtls_sha1_context * ctx)78 void mbedtls_sha1_free( mbedtls_sha1_context *ctx )
79 {
80 if ( ctx == NULL ) {
81 return;
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 memcpy(dst, src, sizeof(mbedtls_sha1_context));
90 }
91
92 /*
93 * SHA-1 context setup
94 */
mbedtls_sha1_starts_ret(mbedtls_sha1_context * ctx)95 int mbedtls_sha1_starts_ret( mbedtls_sha1_context *ctx )
96 {
97 ctx->total[0] = 0;
98 ctx->total[1] = 0;
99
100 memset( ctx, 0, sizeof( mbedtls_sha1_context ) );
101 ctx->mode = SHA1;
102
103 return 0;
104 }
105
106 #if !defined(MBEDTLS_DEPRECATED_REMOVED)
mbedtls_sha1_starts(mbedtls_sha1_context * ctx)107 void mbedtls_sha1_starts( mbedtls_sha1_context *ctx )
108 {
109 mbedtls_sha1_starts_ret( ctx );
110 }
111 #endif
112
esp_internal_sha1_dma_process(mbedtls_sha1_context * ctx,const uint8_t * data,size_t len,uint8_t * buf,size_t buf_len)113 static int esp_internal_sha1_dma_process(mbedtls_sha1_context *ctx,
114 const uint8_t *data, size_t len,
115 uint8_t *buf, size_t buf_len)
116 {
117 return esp_sha_dma(SHA1, data, len, buf, buf_len, ctx->first_block);
118 }
119
mbedtls_internal_sha1_process(mbedtls_sha1_context * ctx,const unsigned char data[64])120 int mbedtls_internal_sha1_process( mbedtls_sha1_context *ctx, const unsigned char data[64] )
121 {
122 int ret;
123 esp_sha_acquire_hardware();
124 ret = esp_sha_dma(ctx->mode, data, 64, 0, 0, ctx->first_block);
125 esp_sha_release_hardware();
126 return ret;
127 }
128
129 #if !defined(MBEDTLS_DEPRECATED_REMOVED)
mbedtls_sha1_process(mbedtls_sha1_context * ctx,const unsigned char data[64])130 void mbedtls_sha1_process( mbedtls_sha1_context *ctx,
131 const unsigned char data[64] )
132 {
133 mbedtls_internal_sha1_process( ctx, data );
134 }
135 #endif
136
mbedtls_sha1_update_ret(mbedtls_sha1_context * ctx,const unsigned char * input,size_t ilen)137 int mbedtls_sha1_update_ret( mbedtls_sha1_context *ctx, const unsigned char *input, size_t ilen )
138 {
139 int ret;
140 size_t fill;
141 uint32_t left, len, local_len = 0;
142
143 if ( !ilen || (input == NULL)) {
144 return 0;
145 }
146
147 left = ctx->total[0] & 0x3F;
148 fill = 64 - left;
149
150 ctx->total[0] += (uint32_t) ilen;
151 ctx->total[0] &= 0xFFFFFFFF;
152
153 if ( ctx->total[0] < (uint32_t) ilen ) {
154 ctx->total[1]++;
155 }
156
157 if ( left && ilen >= fill ) {
158 memcpy( (void *) (ctx->buffer + left), input, fill );
159
160 input += fill;
161 ilen -= fill;
162 left = 0;
163 local_len = 64;
164 }
165
166 len = (ilen / 64) * 64;
167 if ( len || local_len) {
168
169 esp_sha_acquire_hardware();
170 if (ctx->sha_state == ESP_SHA1_STATE_INIT) {
171 ctx->first_block = true;
172
173 ctx->sha_state = ESP_SHA1_STATE_IN_PROCESS;
174 } else if (ctx->sha_state == ESP_SHA1_STATE_IN_PROCESS) {
175 ctx->first_block = false;
176 esp_sha_write_digest_state(SHA1, ctx->state);
177 }
178
179 ret = esp_internal_sha1_dma_process(ctx, input, len, ctx->buffer, local_len);
180
181 esp_sha_read_digest_state(SHA1, ctx->state);
182
183 esp_sha_release_hardware();
184
185 if (ret != 0) {
186 return ret;
187 }
188
189 }
190
191 if ( ilen > 0 ) {
192 memcpy( (void *) (ctx->buffer + left), input + len, ilen - len );
193 }
194
195 return 0;
196 }
197
198 #if !defined(MBEDTLS_DEPRECATED_REMOVED)
mbedtls_sha1_update(mbedtls_sha1_context * ctx,const unsigned char * input,size_t ilen)199 void mbedtls_sha1_update( mbedtls_sha1_context *ctx,
200 const unsigned char *input,
201 size_t ilen )
202 {
203 mbedtls_sha1_update_ret( ctx, input, ilen );
204 }
205 #endif
206
207 static const unsigned char sha1_padding[64] = {
208 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
209 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
210 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
211 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
212 };
213
214 /*
215 * SHA-1 final digest
216 */
mbedtls_sha1_finish_ret(mbedtls_sha1_context * ctx,unsigned char output[20])217 int mbedtls_sha1_finish_ret( mbedtls_sha1_context *ctx, unsigned char output[20] )
218 {
219 int ret;
220 uint32_t last, padn;
221 uint32_t high, low;
222 unsigned char msglen[8];
223
224 high = ( ctx->total[0] >> 29 )
225 | ( ctx->total[1] << 3 );
226 low = ( ctx->total[0] << 3 );
227
228 PUT_UINT32_BE( high, msglen, 0 );
229 PUT_UINT32_BE( low, msglen, 4 );
230
231 last = ctx->total[0] & 0x3F;
232 padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
233
234
235 if ( ( ret = mbedtls_sha1_update_ret( ctx, sha1_padding, padn ) ) != 0 ) {
236 return ret;
237 }
238 if ( ( ret = mbedtls_sha1_update_ret( ctx, msglen, 8 ) ) != 0 ) {
239 return ret;
240 }
241
242 memcpy(output, ctx->state, 20);
243
244 return ret;
245 }
246
247 #if !defined(MBEDTLS_DEPRECATED_REMOVED)
mbedtls_sha1_finish(mbedtls_sha1_context * ctx,unsigned char output[20])248 void mbedtls_sha1_finish( mbedtls_sha1_context *ctx,
249 unsigned char output[20] )
250 {
251 mbedtls_sha1_finish_ret( ctx, output );
252 }
253 #endif
254
255 #endif /* MBEDTLS_SHA1_C && MBEDTLS_SHA1_ALT */
256