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