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