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