1 /*
2  *  SHA-512 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 /*
23  *  The SHA-512 Secure Hash Standard was published by NIST in 2002.
24  *
25  *  http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf
26  */
27 
28 #if !defined(MBEDTLS_CONFIG_FILE)
29 #include "mbedtls/config.h"
30 #else
31 #include MBEDTLS_CONFIG_FILE
32 #endif
33 
34 #if defined(MBEDTLS_SHA512_C) && defined(MBEDTLS_SHA512_ALT)
35 
36 #include "mbedtls/sha512.h"
37 
38 #if defined(_MSC_VER) || defined(__WATCOMC__)
39 #define UL64(x) x##ui64
40 #else
41 #define UL64(x) x##ULL
42 #endif
43 
44 #include <string.h>
45 
46 #if defined(MBEDTLS_SELF_TEST)
47 #if defined(MBEDTLS_PLATFORM_C)
48 #include "mbedtls/platform.h"
49 #else
50 #include <stdio.h>
51 #define mbedtls_printf printf
52 #endif /* MBEDTLS_PLATFORM_C */
53 #endif /* MBEDTLS_SELF_TEST */
54 
55 #include "sha/sha_dma.h"
56 
57 /* Implementation that should never be optimized out by the compiler */
mbedtls_zeroize(void * v,size_t n)58 static void mbedtls_zeroize( void *v, size_t n )
59 {
60     volatile unsigned char *p = v;
61     while ( n-- ) {
62         *p++ = 0;
63     }
64 }
65 
66 /*
67  * 64-bit integer manipulation macros (big endian)
68  */
69 #ifndef PUT_UINT64_BE
70 #define PUT_UINT64_BE(n,b,i)                            \
71 {                                                       \
72     (b)[(i)    ] = (unsigned char) ( (n) >> 56 );       \
73     (b)[(i) + 1] = (unsigned char) ( (n) >> 48 );       \
74     (b)[(i) + 2] = (unsigned char) ( (n) >> 40 );       \
75     (b)[(i) + 3] = (unsigned char) ( (n) >> 32 );       \
76     (b)[(i) + 4] = (unsigned char) ( (n) >> 24 );       \
77     (b)[(i) + 5] = (unsigned char) ( (n) >> 16 );       \
78     (b)[(i) + 6] = (unsigned char) ( (n) >>  8 );       \
79     (b)[(i) + 7] = (unsigned char) ( (n)       );       \
80 }
81 #endif /* PUT_UINT64_BE */
82 
esp_sha512_set_mode(mbedtls_sha512_context * ctx,esp_sha_type type)83 void esp_sha512_set_mode(mbedtls_sha512_context *ctx, esp_sha_type type)
84 {
85     switch (type) {
86     case SHA2_384:
87     case SHA2_512224:
88     case SHA2_512256:
89     case SHA2_512T:
90         ctx->mode = type;
91         break;
92     default:
93         ctx->mode = SHA2_512;
94         break;
95     }
96 }
97 
98 
99 /* For SHA512/t mode the intial hash value will depend on t */
esp_sha512_set_t(mbedtls_sha512_context * ctx,uint16_t t_val)100 void esp_sha512_set_t( mbedtls_sha512_context *ctx, uint16_t t_val)
101 {
102     ctx->t_val = t_val;
103 }
104 
mbedtls_sha512_init(mbedtls_sha512_context * ctx)105 void mbedtls_sha512_init( mbedtls_sha512_context *ctx )
106 {
107     memset( ctx, 0, sizeof( mbedtls_sha512_context ) );
108 }
109 
mbedtls_sha512_free(mbedtls_sha512_context * ctx)110 void mbedtls_sha512_free( mbedtls_sha512_context *ctx )
111 {
112     if ( ctx == NULL ) {
113         return;
114     }
115 
116     mbedtls_zeroize( ctx, sizeof( mbedtls_sha512_context ) );
117 }
118 
mbedtls_sha512_clone(mbedtls_sha512_context * dst,const mbedtls_sha512_context * src)119 void mbedtls_sha512_clone( mbedtls_sha512_context *dst,
120                            const mbedtls_sha512_context *src )
121 {
122     memcpy(dst, src, sizeof(mbedtls_sha512_context));
123 }
124 
125 /*
126  * SHA-512 context setup
127  */
mbedtls_sha512_starts_ret(mbedtls_sha512_context * ctx,int is384)128 int mbedtls_sha512_starts_ret( mbedtls_sha512_context *ctx, int is384 )
129 {
130     mbedtls_zeroize( ctx, sizeof( mbedtls_sha512_context ) );
131 
132     if ( is384 ) {
133         ctx->mode = SHA2_384;
134     } else {
135         ctx->mode = SHA2_512;
136     }
137 
138     return 0;
139 }
140 
141 #if !defined(MBEDTLS_DEPRECATED_REMOVED)
mbedtls_sha512_starts(mbedtls_sha512_context * ctx,int is384)142 void mbedtls_sha512_starts( mbedtls_sha512_context *ctx,
143                             int is384 )
144 {
145     mbedtls_sha512_starts_ret( ctx, is384 );
146 }
147 #endif
148 
esp_internal_sha512_dma_process(mbedtls_sha512_context * ctx,const uint8_t * data,size_t len,uint8_t * buf,size_t buf_len)149 static int esp_internal_sha512_dma_process(mbedtls_sha512_context *ctx,
150         const uint8_t *data, size_t len,
151         uint8_t *buf, size_t buf_len)
152 {
153 
154 
155     return esp_sha_dma(ctx->mode, data, len, buf, buf_len, ctx->first_block);
156 
157 
158 }
159 
mbedtls_internal_sha512_process(mbedtls_sha512_context * ctx,const unsigned char data[128])160 int mbedtls_internal_sha512_process( mbedtls_sha512_context *ctx, const unsigned char data[128] )
161 {
162     int ret;
163     esp_sha_acquire_hardware();
164     ret = esp_internal_sha512_dma_process(ctx, data, 128, 0, 0);
165     esp_sha_release_hardware();
166 
167     return ret;
168 
169 }
170 
171 #if !defined(MBEDTLS_DEPRECATED_REMOVED)
mbedtls_sha512_process(mbedtls_sha512_context * ctx,const unsigned char data[128])172 void mbedtls_sha512_process( mbedtls_sha512_context *ctx,
173                              const unsigned char data[128] )
174 {
175     mbedtls_internal_sha512_process( ctx, data );
176 }
177 #endif
178 
179 /*
180  * SHA-512 process buffer
181  */
mbedtls_sha512_update_ret(mbedtls_sha512_context * ctx,const unsigned char * input,size_t ilen)182 int mbedtls_sha512_update_ret( mbedtls_sha512_context *ctx, const unsigned char *input,
183                                size_t ilen )
184 {
185     int ret;
186     size_t fill;
187     unsigned int left, len, local_len = 0;
188 
189     if ( ilen == 0 ) {
190         return 0;
191     }
192 
193     left = (unsigned int) (ctx->total[0] & 0x7F);
194     fill = 128 - left;
195 
196     ctx->total[0] += (uint64_t) ilen;
197 
198     if ( ctx->total[0] < (uint64_t) ilen ) {
199         ctx->total[1]++;
200     }
201 
202     if ( left && ilen >= fill ) {
203         memcpy( (void *) (ctx->buffer + left), input, fill );
204 
205         input += fill;
206         ilen  -= fill;
207         left = 0;
208         local_len = 128;
209     }
210 
211     len = (ilen / 128) * 128;
212 
213     if ( len || local_len) {
214 
215         esp_sha_acquire_hardware();
216 
217         if (ctx->sha_state == ESP_SHA512_STATE_INIT) {
218 
219             if (ctx->mode == SHA2_512T) {
220                 esp_sha_512_t_init_hash(ctx->t_val);
221                 ctx->first_block = false;
222             } else {
223                 ctx->first_block = true;
224             }
225             ctx->sha_state = ESP_SHA512_STATE_IN_PROCESS;
226 
227         } else if (ctx->sha_state == ESP_SHA512_STATE_IN_PROCESS) {
228             ctx->first_block = false;
229             esp_sha_write_digest_state(ctx->mode, ctx->state);
230         }
231 
232         ret = esp_internal_sha512_dma_process(ctx, input, len, ctx->buffer, local_len);
233 
234         esp_sha_read_digest_state(ctx->mode, ctx->state);
235 
236         esp_sha_release_hardware();
237 
238         if (ret != 0) {
239             return ret;
240         }
241 
242     }
243 
244 
245     if ( ilen > 0 ) {
246         memcpy( (void *) (ctx->buffer + left), input + len, ilen - len );
247     }
248 
249     return 0;
250 }
251 
252 #if !defined(MBEDTLS_DEPRECATED_REMOVED)
mbedtls_sha512_update(mbedtls_sha512_context * ctx,const unsigned char * input,size_t ilen)253 void mbedtls_sha512_update( mbedtls_sha512_context *ctx,
254                             const unsigned char *input,
255                             size_t ilen )
256 {
257     mbedtls_sha512_update_ret( ctx, input, ilen );
258 }
259 #endif
260 
261 
262 static const unsigned char sha512_padding[128] = {
263     0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
264     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
265     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
266     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
267     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
268     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
269     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
270     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
271 };
272 
273 /*
274  * SHA-512 final digest
275  */
mbedtls_sha512_finish_ret(mbedtls_sha512_context * ctx,unsigned char output[64])276 int mbedtls_sha512_finish_ret( mbedtls_sha512_context *ctx, unsigned char output[64] )
277 {
278     int ret;
279     size_t last, padn;
280     uint64_t high, low;
281     unsigned char msglen[16];
282 
283     high = ( ctx->total[0] >> 61 )
284            | ( ctx->total[1] <<  3 );
285     low  = ( ctx->total[0] <<  3 );
286 
287     PUT_UINT64_BE( high, msglen, 0 );
288     PUT_UINT64_BE( low,  msglen, 8 );
289 
290     last = (size_t)( ctx->total[0] & 0x7F );
291     padn = ( last < 112 ) ? ( 112 - last ) : ( 240 - last );
292 
293     if ( ( ret = mbedtls_sha512_update_ret( ctx, sha512_padding, padn ) ) != 0 ) {
294         return ret;
295     }
296 
297     if ( ( ret = mbedtls_sha512_update_ret( ctx, msglen, 16 ) ) != 0 ) {
298         return ret;
299     }
300 
301     if (ctx->mode == SHA2_384) {
302         memcpy(output, ctx->state, 48);
303     } else {
304         memcpy(output, ctx->state, 64);
305     }
306 
307     return ret;
308 }
309 
310 #if !defined(MBEDTLS_DEPRECATED_REMOVED)
mbedtls_sha512_finish(mbedtls_sha512_context * ctx,unsigned char output[64])311 void mbedtls_sha512_finish( mbedtls_sha512_context *ctx,
312                             unsigned char output[64] )
313 {
314     mbedtls_sha512_finish_ret( ctx, output );
315 }
316 #endif
317 
318 #endif /* MBEDTLS_SHA512_C && MBEDTLS_SHA512_ALT */
319