1 /*
2 * FIPS-180-2 compliant SHA-384/512 implementation
3 *
4 * Copyright The Mbed TLS Contributors
5 * SPDX-License-Identifier: Apache-2.0
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License"); you may
8 * not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 */
19 /*
20 * The SHA-512 Secure Hash Standard was published by NIST in 2002.
21 *
22 * http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf
23 */
24
25 #include "common.h"
26
27 #if defined(MBEDTLS_SHA512_C)
28
29 #include "mbedtls/sha512.h"
30 #include "mbedtls/platform_util.h"
31 #include "mbedtls/error.h"
32
33 #if defined(_MSC_VER) || defined(__WATCOMC__)
34 #define UL64(x) x##ui64
35 #else
36 #define UL64(x) x##ULL
37 #endif
38
39 #include <string.h>
40
41 #include "mbedtls/platform.h"
42
43 #if defined(__aarch64__)
44 # if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT) || \
45 defined(MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY)
46 # include <arm_neon.h>
47 # endif
48 # if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT)
49 # if defined(__unix__)
50 # if defined(__linux__)
51 /* Our preferred method of detection is getauxval() */
52 # include <sys/auxv.h>
53 # endif
54 /* Use SIGILL on Unix, and fall back to it on Linux */
55 # include <signal.h>
56 # endif
57 # endif
58 #elif defined(_M_ARM64)
59 # if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT) || \
60 defined(MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY)
61 # include <arm64_neon.h>
62 # endif
63 #else
64 # undef MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY
65 # undef MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT
66 #endif
67
68 #if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT)
69 /*
70 * Capability detection code comes early, so we can disable
71 * MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT if no detection mechanism found
72 */
73 #if defined(HWCAP_SHA512)
mbedtls_a64_crypto_sha512_determine_support(void)74 static int mbedtls_a64_crypto_sha512_determine_support( void )
75 {
76 return( ( getauxval( AT_HWCAP ) & HWCAP_SHA512 ) ? 1 : 0 );
77 }
78 #elif defined(__APPLE__)
79 #include <sys/types.h>
80 #include <sys/sysctl.h>
81
mbedtls_a64_crypto_sha512_determine_support(void)82 static int mbedtls_a64_crypto_sha512_determine_support( void )
83 {
84 int value = 0;
85 size_t value_len = sizeof(value);
86
87 int ret = sysctlbyname( "hw.optional.armv8_2_sha512", &value, &value_len,
88 NULL, 0 );
89 return( ret == 0 && value != 0 );
90 }
91 #elif defined(_M_ARM64)
92 /*
93 * As of March 2022, there don't appear to be any PF_ARM_V8_* flags
94 * available to pass to IsProcessorFeaturePresent() to check for
95 * SHA-512 support. So we fall back to the C code only.
96 */
97 #if defined(_MSC_VER)
98 #pragma message "No mechanism to detect A64_CRYPTO found, using C code only"
99 #else
100 #warning "No mechanism to detect A64_CRYPTO found, using C code only"
101 #endif
102 #elif defined(__unix__) && defined(SIG_SETMASK)
103 /* Detection with SIGILL, setjmp() and longjmp() */
104 #include <signal.h>
105 #include <setjmp.h>
106
107 #ifndef asm
108 #define asm __asm__
109 #endif
110
111 static jmp_buf return_from_sigill;
112
113 /*
114 * A64 SHA512 support detection via SIGILL
115 */
sigill_handler(int signal)116 static void sigill_handler( int signal )
117 {
118 (void) signal;
119 longjmp( return_from_sigill, 1 );
120 }
121
mbedtls_a64_crypto_sha512_determine_support(void)122 static int mbedtls_a64_crypto_sha512_determine_support( void )
123 {
124 struct sigaction old_action, new_action;
125
126 sigset_t old_mask;
127 if( sigprocmask( 0, NULL, &old_mask ) )
128 return( 0 );
129
130 sigemptyset( &new_action.sa_mask );
131 new_action.sa_flags = 0;
132 new_action.sa_handler = sigill_handler;
133
134 sigaction( SIGILL, &new_action, &old_action );
135
136 static int ret = 0;
137
138 if( setjmp( return_from_sigill ) == 0 ) /* First return only */
139 {
140 /* If this traps, we will return a second time from setjmp() with 1 */
141 asm( "sha512h q0, q0, v0.2d" : : : "v0" );
142 ret = 1;
143 }
144
145 sigaction( SIGILL, &old_action, NULL );
146 sigprocmask( SIG_SETMASK, &old_mask, NULL );
147
148 return( ret );
149 }
150 #else
151 #warning "No mechanism to detect A64_CRYPTO found, using C code only"
152 #undef MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT
153 #endif /* HWCAP_SHA512, __APPLE__, __unix__ && SIG_SETMASK */
154
155 #endif /* MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT */
156
157 #if !defined(MBEDTLS_SHA512_ALT)
158
159 #define SHA512_BLOCK_SIZE 128
160
161 #if defined(MBEDTLS_SHA512_SMALLER)
sha512_put_uint64_be(uint64_t n,unsigned char * b,uint8_t i)162 static void sha512_put_uint64_be( uint64_t n, unsigned char *b, uint8_t i )
163 {
164 MBEDTLS_PUT_UINT64_BE(n, b, i);
165 }
166 #else
167 #define sha512_put_uint64_be MBEDTLS_PUT_UINT64_BE
168 #endif /* MBEDTLS_SHA512_SMALLER */
169
mbedtls_sha512_init(mbedtls_sha512_context * ctx)170 void mbedtls_sha512_init( mbedtls_sha512_context *ctx )
171 {
172 memset( ctx, 0, sizeof( mbedtls_sha512_context ) );
173 }
174
mbedtls_sha512_free(mbedtls_sha512_context * ctx)175 void mbedtls_sha512_free( mbedtls_sha512_context *ctx )
176 {
177 if( ctx == NULL )
178 return;
179
180 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_sha512_context ) );
181 }
182
mbedtls_sha512_clone(mbedtls_sha512_context * dst,const mbedtls_sha512_context * src)183 void mbedtls_sha512_clone( mbedtls_sha512_context *dst,
184 const mbedtls_sha512_context *src )
185 {
186 *dst = *src;
187 }
188
189 /*
190 * SHA-512 context setup
191 */
mbedtls_sha512_starts(mbedtls_sha512_context * ctx,int is384)192 int mbedtls_sha512_starts( mbedtls_sha512_context *ctx, int is384 )
193 {
194 #if defined(MBEDTLS_SHA384_C)
195 if( is384 != 0 && is384 != 1 )
196 return MBEDTLS_ERR_SHA512_BAD_INPUT_DATA;
197 #else
198 if( is384 != 0 )
199 return MBEDTLS_ERR_SHA512_BAD_INPUT_DATA;
200 #endif
201
202 ctx->total[0] = 0;
203 ctx->total[1] = 0;
204
205 if( is384 == 0 )
206 {
207 /* SHA-512 */
208 ctx->state[0] = UL64(0x6A09E667F3BCC908);
209 ctx->state[1] = UL64(0xBB67AE8584CAA73B);
210 ctx->state[2] = UL64(0x3C6EF372FE94F82B);
211 ctx->state[3] = UL64(0xA54FF53A5F1D36F1);
212 ctx->state[4] = UL64(0x510E527FADE682D1);
213 ctx->state[5] = UL64(0x9B05688C2B3E6C1F);
214 ctx->state[6] = UL64(0x1F83D9ABFB41BD6B);
215 ctx->state[7] = UL64(0x5BE0CD19137E2179);
216 }
217 else
218 {
219 #if !defined(MBEDTLS_SHA384_C)
220 return( MBEDTLS_ERR_SHA512_BAD_INPUT_DATA );
221 #else
222 /* SHA-384 */
223 ctx->state[0] = UL64(0xCBBB9D5DC1059ED8);
224 ctx->state[1] = UL64(0x629A292A367CD507);
225 ctx->state[2] = UL64(0x9159015A3070DD17);
226 ctx->state[3] = UL64(0x152FECD8F70E5939);
227 ctx->state[4] = UL64(0x67332667FFC00B31);
228 ctx->state[5] = UL64(0x8EB44A8768581511);
229 ctx->state[6] = UL64(0xDB0C2E0D64F98FA7);
230 ctx->state[7] = UL64(0x47B5481DBEFA4FA4);
231 #endif /* MBEDTLS_SHA384_C */
232 }
233
234 #if defined(MBEDTLS_SHA384_C)
235 ctx->is384 = is384;
236 #endif
237
238 return( 0 );
239 }
240
241 #if !defined(MBEDTLS_SHA512_PROCESS_ALT)
242
243 /*
244 * Round constants
245 */
246 static const uint64_t K[80] =
247 {
248 UL64(0x428A2F98D728AE22), UL64(0x7137449123EF65CD),
249 UL64(0xB5C0FBCFEC4D3B2F), UL64(0xE9B5DBA58189DBBC),
250 UL64(0x3956C25BF348B538), UL64(0x59F111F1B605D019),
251 UL64(0x923F82A4AF194F9B), UL64(0xAB1C5ED5DA6D8118),
252 UL64(0xD807AA98A3030242), UL64(0x12835B0145706FBE),
253 UL64(0x243185BE4EE4B28C), UL64(0x550C7DC3D5FFB4E2),
254 UL64(0x72BE5D74F27B896F), UL64(0x80DEB1FE3B1696B1),
255 UL64(0x9BDC06A725C71235), UL64(0xC19BF174CF692694),
256 UL64(0xE49B69C19EF14AD2), UL64(0xEFBE4786384F25E3),
257 UL64(0x0FC19DC68B8CD5B5), UL64(0x240CA1CC77AC9C65),
258 UL64(0x2DE92C6F592B0275), UL64(0x4A7484AA6EA6E483),
259 UL64(0x5CB0A9DCBD41FBD4), UL64(0x76F988DA831153B5),
260 UL64(0x983E5152EE66DFAB), UL64(0xA831C66D2DB43210),
261 UL64(0xB00327C898FB213F), UL64(0xBF597FC7BEEF0EE4),
262 UL64(0xC6E00BF33DA88FC2), UL64(0xD5A79147930AA725),
263 UL64(0x06CA6351E003826F), UL64(0x142929670A0E6E70),
264 UL64(0x27B70A8546D22FFC), UL64(0x2E1B21385C26C926),
265 UL64(0x4D2C6DFC5AC42AED), UL64(0x53380D139D95B3DF),
266 UL64(0x650A73548BAF63DE), UL64(0x766A0ABB3C77B2A8),
267 UL64(0x81C2C92E47EDAEE6), UL64(0x92722C851482353B),
268 UL64(0xA2BFE8A14CF10364), UL64(0xA81A664BBC423001),
269 UL64(0xC24B8B70D0F89791), UL64(0xC76C51A30654BE30),
270 UL64(0xD192E819D6EF5218), UL64(0xD69906245565A910),
271 UL64(0xF40E35855771202A), UL64(0x106AA07032BBD1B8),
272 UL64(0x19A4C116B8D2D0C8), UL64(0x1E376C085141AB53),
273 UL64(0x2748774CDF8EEB99), UL64(0x34B0BCB5E19B48A8),
274 UL64(0x391C0CB3C5C95A63), UL64(0x4ED8AA4AE3418ACB),
275 UL64(0x5B9CCA4F7763E373), UL64(0x682E6FF3D6B2B8A3),
276 UL64(0x748F82EE5DEFB2FC), UL64(0x78A5636F43172F60),
277 UL64(0x84C87814A1F0AB72), UL64(0x8CC702081A6439EC),
278 UL64(0x90BEFFFA23631E28), UL64(0xA4506CEBDE82BDE9),
279 UL64(0xBEF9A3F7B2C67915), UL64(0xC67178F2E372532B),
280 UL64(0xCA273ECEEA26619C), UL64(0xD186B8C721C0C207),
281 UL64(0xEADA7DD6CDE0EB1E), UL64(0xF57D4F7FEE6ED178),
282 UL64(0x06F067AA72176FBA), UL64(0x0A637DC5A2C898A6),
283 UL64(0x113F9804BEF90DAE), UL64(0x1B710B35131C471B),
284 UL64(0x28DB77F523047D84), UL64(0x32CAAB7B40C72493),
285 UL64(0x3C9EBE0A15C9BEBC), UL64(0x431D67C49C100D4C),
286 UL64(0x4CC5D4BECB3E42B6), UL64(0x597F299CFC657E2A),
287 UL64(0x5FCB6FAB3AD6FAEC), UL64(0x6C44198C4A475817)
288 };
289 #endif
290
291 #if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT) || \
292 defined(MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY)
293
294 #if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY)
295 # define mbedtls_internal_sha512_process_many_a64_crypto mbedtls_internal_sha512_process_many
296 # define mbedtls_internal_sha512_process_a64_crypto mbedtls_internal_sha512_process
297 #endif
298
299 #ifndef asm
300 #define asm __asm__
301 #endif
302
303 /* Accelerated SHA-512 implementation originally written by Simon Tatham for PuTTY,
304 * under the MIT licence; dual-licensed as Apache 2 with his kind permission.
305 */
306
307 #if defined(__clang__) && \
308 (__clang_major__ < 13 || \
309 (__clang_major__ == 13 && __clang_minor__ == 0 && __clang_patchlevel__ == 0))
vsha512su0q_u64(uint64x2_t x,uint64x2_t y)310 static inline uint64x2_t vsha512su0q_u64(uint64x2_t x, uint64x2_t y)
311 {
312 asm( "sha512su0 %0.2D,%1.2D" : "+w" (x) : "w" (y) );
313 return( x );
314 }
vsha512su1q_u64(uint64x2_t x,uint64x2_t y,uint64x2_t z)315 static inline uint64x2_t vsha512su1q_u64(uint64x2_t x, uint64x2_t y, uint64x2_t z)
316 {
317 asm( "sha512su1 %0.2D,%1.2D,%2.2D" : "+w" (x) : "w" (y), "w" (z) );
318 return( x );
319 }
vsha512hq_u64(uint64x2_t x,uint64x2_t y,uint64x2_t z)320 static inline uint64x2_t vsha512hq_u64(uint64x2_t x, uint64x2_t y, uint64x2_t z)
321 {
322 asm( "sha512h %0,%1,%2.2D" : "+w" (x) : "w" (y), "w" (z) );
323 return( x );
324 }
vsha512h2q_u64(uint64x2_t x,uint64x2_t y,uint64x2_t z)325 static inline uint64x2_t vsha512h2q_u64(uint64x2_t x, uint64x2_t y, uint64x2_t z)
326 {
327 asm( "sha512h2 %0,%1,%2.2D" : "+w" (x) : "w" (y), "w" (z) );
328 return( x );
329 }
330 #endif /* __clang__ etc */
331
mbedtls_internal_sha512_process_many_a64_crypto(mbedtls_sha512_context * ctx,const uint8_t * msg,size_t len)332 static size_t mbedtls_internal_sha512_process_many_a64_crypto(
333 mbedtls_sha512_context *ctx, const uint8_t *msg, size_t len )
334 {
335 uint64x2_t ab = vld1q_u64( &ctx->state[0] );
336 uint64x2_t cd = vld1q_u64( &ctx->state[2] );
337 uint64x2_t ef = vld1q_u64( &ctx->state[4] );
338 uint64x2_t gh = vld1q_u64( &ctx->state[6] );
339
340 size_t processed = 0;
341
342 for ( ;
343 len >= SHA512_BLOCK_SIZE;
344 processed += SHA512_BLOCK_SIZE,
345 msg += SHA512_BLOCK_SIZE,
346 len -= SHA512_BLOCK_SIZE )
347 {
348 uint64x2_t initial_sum, sum, intermed;
349
350 uint64x2_t ab_orig = ab;
351 uint64x2_t cd_orig = cd;
352 uint64x2_t ef_orig = ef;
353 uint64x2_t gh_orig = gh;
354
355 uint64x2_t s0 = (uint64x2_t) vld1q_u8( msg + 16 * 0 );
356 uint64x2_t s1 = (uint64x2_t) vld1q_u8( msg + 16 * 1 );
357 uint64x2_t s2 = (uint64x2_t) vld1q_u8( msg + 16 * 2 );
358 uint64x2_t s3 = (uint64x2_t) vld1q_u8( msg + 16 * 3 );
359 uint64x2_t s4 = (uint64x2_t) vld1q_u8( msg + 16 * 4 );
360 uint64x2_t s5 = (uint64x2_t) vld1q_u8( msg + 16 * 5 );
361 uint64x2_t s6 = (uint64x2_t) vld1q_u8( msg + 16 * 6 );
362 uint64x2_t s7 = (uint64x2_t) vld1q_u8( msg + 16 * 7 );
363
364 #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ /* assume LE if these not defined; untested on BE */
365 s0 = vreinterpretq_u64_u8( vrev64q_u8( vreinterpretq_u8_u64( s0 ) ) );
366 s1 = vreinterpretq_u64_u8( vrev64q_u8( vreinterpretq_u8_u64( s1 ) ) );
367 s2 = vreinterpretq_u64_u8( vrev64q_u8( vreinterpretq_u8_u64( s2 ) ) );
368 s3 = vreinterpretq_u64_u8( vrev64q_u8( vreinterpretq_u8_u64( s3 ) ) );
369 s4 = vreinterpretq_u64_u8( vrev64q_u8( vreinterpretq_u8_u64( s4 ) ) );
370 s5 = vreinterpretq_u64_u8( vrev64q_u8( vreinterpretq_u8_u64( s5 ) ) );
371 s6 = vreinterpretq_u64_u8( vrev64q_u8( vreinterpretq_u8_u64( s6 ) ) );
372 s7 = vreinterpretq_u64_u8( vrev64q_u8( vreinterpretq_u8_u64( s7 ) ) );
373 #endif
374
375 /* Rounds 0 and 1 */
376 initial_sum = vaddq_u64( s0, vld1q_u64( &K[0] ) );
377 sum = vaddq_u64( vextq_u64( initial_sum, initial_sum, 1 ), gh );
378 intermed = vsha512hq_u64( sum, vextq_u64( ef, gh, 1 ), vextq_u64( cd, ef, 1 ) );
379 gh = vsha512h2q_u64( intermed, cd, ab );
380 cd = vaddq_u64( cd, intermed );
381
382 /* Rounds 2 and 3 */
383 initial_sum = vaddq_u64( s1, vld1q_u64( &K[2] ) );
384 sum = vaddq_u64( vextq_u64( initial_sum, initial_sum, 1 ), ef );
385 intermed = vsha512hq_u64( sum, vextq_u64( cd, ef, 1 ), vextq_u64( ab, cd, 1 ) );
386 ef = vsha512h2q_u64( intermed, ab, gh );
387 ab = vaddq_u64( ab, intermed );
388
389 /* Rounds 4 and 5 */
390 initial_sum = vaddq_u64( s2, vld1q_u64( &K[4] ) );
391 sum = vaddq_u64( vextq_u64( initial_sum, initial_sum, 1 ), cd );
392 intermed = vsha512hq_u64( sum, vextq_u64( ab, cd, 1 ), vextq_u64( gh, ab, 1 ) );
393 cd = vsha512h2q_u64( intermed, gh, ef );
394 gh = vaddq_u64( gh, intermed );
395
396 /* Rounds 6 and 7 */
397 initial_sum = vaddq_u64( s3, vld1q_u64( &K[6] ) );
398 sum = vaddq_u64( vextq_u64( initial_sum, initial_sum, 1 ), ab );
399 intermed = vsha512hq_u64( sum, vextq_u64( gh, ab, 1 ), vextq_u64( ef, gh, 1 ) );
400 ab = vsha512h2q_u64( intermed, ef, cd );
401 ef = vaddq_u64( ef, intermed );
402
403 /* Rounds 8 and 9 */
404 initial_sum = vaddq_u64( s4, vld1q_u64( &K[8] ) );
405 sum = vaddq_u64( vextq_u64( initial_sum, initial_sum, 1 ), gh );
406 intermed = vsha512hq_u64( sum, vextq_u64( ef, gh, 1 ), vextq_u64( cd, ef, 1 ) );
407 gh = vsha512h2q_u64( intermed, cd, ab );
408 cd = vaddq_u64( cd, intermed );
409
410 /* Rounds 10 and 11 */
411 initial_sum = vaddq_u64( s5, vld1q_u64( &K[10] ) );
412 sum = vaddq_u64( vextq_u64( initial_sum, initial_sum, 1 ), ef );
413 intermed = vsha512hq_u64( sum, vextq_u64( cd, ef, 1 ), vextq_u64( ab, cd, 1 ) );
414 ef = vsha512h2q_u64( intermed, ab, gh );
415 ab = vaddq_u64( ab, intermed );
416
417 /* Rounds 12 and 13 */
418 initial_sum = vaddq_u64( s6, vld1q_u64( &K[12] ) );
419 sum = vaddq_u64( vextq_u64( initial_sum, initial_sum, 1 ), cd );
420 intermed = vsha512hq_u64( sum, vextq_u64( ab, cd, 1 ), vextq_u64( gh, ab, 1 ) );
421 cd = vsha512h2q_u64( intermed, gh, ef );
422 gh = vaddq_u64( gh, intermed );
423
424 /* Rounds 14 and 15 */
425 initial_sum = vaddq_u64( s7, vld1q_u64( &K[14] ) );
426 sum = vaddq_u64( vextq_u64( initial_sum, initial_sum, 1 ), ab );
427 intermed = vsha512hq_u64( sum, vextq_u64( gh, ab, 1 ), vextq_u64( ef, gh, 1 ) );
428 ab = vsha512h2q_u64( intermed, ef, cd );
429 ef = vaddq_u64( ef, intermed );
430
431 for ( unsigned int t = 16; t < 80; t += 16 )
432 {
433 /* Rounds t and t + 1 */
434 s0 = vsha512su1q_u64( vsha512su0q_u64( s0, s1 ), s7, vextq_u64( s4, s5, 1 ) );
435 initial_sum = vaddq_u64( s0, vld1q_u64( &K[t] ) );
436 sum = vaddq_u64( vextq_u64( initial_sum, initial_sum, 1 ), gh );
437 intermed = vsha512hq_u64( sum, vextq_u64( ef, gh, 1 ), vextq_u64( cd, ef, 1 ) );
438 gh = vsha512h2q_u64( intermed, cd, ab );
439 cd = vaddq_u64( cd, intermed );
440
441 /* Rounds t + 2 and t + 3 */
442 s1 = vsha512su1q_u64( vsha512su0q_u64( s1, s2 ), s0, vextq_u64( s5, s6, 1 ) );
443 initial_sum = vaddq_u64( s1, vld1q_u64( &K[t + 2] ) );
444 sum = vaddq_u64( vextq_u64( initial_sum, initial_sum, 1 ), ef );
445 intermed = vsha512hq_u64( sum, vextq_u64( cd, ef, 1 ), vextq_u64( ab, cd, 1 ) );
446 ef = vsha512h2q_u64( intermed, ab, gh );
447 ab = vaddq_u64( ab, intermed );
448
449 /* Rounds t + 4 and t + 5 */
450 s2 = vsha512su1q_u64( vsha512su0q_u64( s2, s3 ), s1, vextq_u64( s6, s7, 1 ) );
451 initial_sum = vaddq_u64( s2, vld1q_u64( &K[t + 4] ) );
452 sum = vaddq_u64( vextq_u64( initial_sum, initial_sum, 1 ), cd );
453 intermed = vsha512hq_u64( sum, vextq_u64( ab, cd, 1 ), vextq_u64( gh, ab, 1 ) );
454 cd = vsha512h2q_u64( intermed, gh, ef );
455 gh = vaddq_u64( gh, intermed );
456
457 /* Rounds t + 6 and t + 7 */
458 s3 = vsha512su1q_u64( vsha512su0q_u64( s3, s4 ), s2, vextq_u64( s7, s0, 1 ) );
459 initial_sum = vaddq_u64( s3, vld1q_u64( &K[t + 6] ) );
460 sum = vaddq_u64( vextq_u64( initial_sum, initial_sum, 1 ), ab );
461 intermed = vsha512hq_u64( sum, vextq_u64( gh, ab, 1 ), vextq_u64( ef, gh, 1 ) );
462 ab = vsha512h2q_u64( intermed, ef, cd );
463 ef = vaddq_u64( ef, intermed );
464
465 /* Rounds t + 8 and t + 9 */
466 s4 = vsha512su1q_u64( vsha512su0q_u64( s4, s5 ), s3, vextq_u64( s0, s1, 1 ) );
467 initial_sum = vaddq_u64( s4, vld1q_u64( &K[t + 8] ) );
468 sum = vaddq_u64( vextq_u64( initial_sum, initial_sum, 1 ), gh );
469 intermed = vsha512hq_u64( sum, vextq_u64( ef, gh, 1 ), vextq_u64( cd, ef, 1 ) );
470 gh = vsha512h2q_u64( intermed, cd, ab );
471 cd = vaddq_u64( cd, intermed );
472
473 /* Rounds t + 10 and t + 11 */
474 s5 = vsha512su1q_u64( vsha512su0q_u64( s5, s6 ), s4, vextq_u64( s1, s2, 1 ) );
475 initial_sum = vaddq_u64( s5, vld1q_u64( &K[t + 10] ) );
476 sum = vaddq_u64( vextq_u64( initial_sum, initial_sum, 1 ), ef );
477 intermed = vsha512hq_u64( sum, vextq_u64( cd, ef, 1 ), vextq_u64( ab, cd, 1 ) );
478 ef = vsha512h2q_u64( intermed, ab, gh );
479 ab = vaddq_u64( ab, intermed );
480
481 /* Rounds t + 12 and t + 13 */
482 s6 = vsha512su1q_u64( vsha512su0q_u64( s6, s7 ), s5, vextq_u64( s2, s3, 1 ) );
483 initial_sum = vaddq_u64( s6, vld1q_u64( &K[t + 12] ) );
484 sum = vaddq_u64( vextq_u64( initial_sum, initial_sum, 1 ), cd );
485 intermed = vsha512hq_u64( sum, vextq_u64( ab, cd, 1 ), vextq_u64( gh, ab, 1 ) );
486 cd = vsha512h2q_u64( intermed, gh, ef );
487 gh = vaddq_u64( gh, intermed );
488
489 /* Rounds t + 14 and t + 15 */
490 s7 = vsha512su1q_u64( vsha512su0q_u64( s7, s0 ), s6, vextq_u64( s3, s4, 1 ) );
491 initial_sum = vaddq_u64( s7, vld1q_u64( &K[t + 14] ) );
492 sum = vaddq_u64( vextq_u64( initial_sum, initial_sum, 1 ), ab );
493 intermed = vsha512hq_u64( sum, vextq_u64( gh, ab, 1 ), vextq_u64( ef, gh, 1 ) );
494 ab = vsha512h2q_u64( intermed, ef, cd );
495 ef = vaddq_u64( ef, intermed );
496 }
497
498 ab = vaddq_u64( ab, ab_orig );
499 cd = vaddq_u64( cd, cd_orig );
500 ef = vaddq_u64( ef, ef_orig );
501 gh = vaddq_u64( gh, gh_orig );
502 }
503
504 vst1q_u64( &ctx->state[0], ab );
505 vst1q_u64( &ctx->state[2], cd );
506 vst1q_u64( &ctx->state[4], ef );
507 vst1q_u64( &ctx->state[6], gh );
508
509 return( processed );
510 }
511
512 #if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT)
513 /*
514 * This function is for internal use only if we are building both C and A64
515 * versions, otherwise it is renamed to be the public mbedtls_internal_sha512_process()
516 */
517 static
518 #endif
mbedtls_internal_sha512_process_a64_crypto(mbedtls_sha512_context * ctx,const unsigned char data[SHA512_BLOCK_SIZE])519 int mbedtls_internal_sha512_process_a64_crypto( mbedtls_sha512_context *ctx,
520 const unsigned char data[SHA512_BLOCK_SIZE] )
521 {
522 return( mbedtls_internal_sha512_process_many_a64_crypto( ctx, data,
523 SHA512_BLOCK_SIZE ) == SHA512_BLOCK_SIZE ) ? 0 : -1;
524 }
525
526 #endif /* MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT || MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY */
527
528
529 #if !defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT)
530 #define mbedtls_internal_sha512_process_many_c mbedtls_internal_sha512_process_many
531 #define mbedtls_internal_sha512_process_c mbedtls_internal_sha512_process
532 #endif
533
534
535 #if !defined(MBEDTLS_SHA512_PROCESS_ALT) && !defined(MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY)
536
537 #if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT)
538 /*
539 * This function is for internal use only if we are building both C and A64
540 * versions, otherwise it is renamed to be the public mbedtls_internal_sha512_process()
541 */
542 static
543 #endif
mbedtls_internal_sha512_process_c(mbedtls_sha512_context * ctx,const unsigned char data[SHA512_BLOCK_SIZE])544 int mbedtls_internal_sha512_process_c( mbedtls_sha512_context *ctx,
545 const unsigned char data[SHA512_BLOCK_SIZE] )
546 {
547 int i;
548 struct
549 {
550 uint64_t temp1, temp2, W[80];
551 uint64_t A[8];
552 } local;
553
554 #define SHR(x,n) ((x) >> (n))
555 #define ROTR(x,n) (SHR((x),(n)) | ((x) << (64 - (n))))
556
557 #define S0(x) (ROTR(x, 1) ^ ROTR(x, 8) ^ SHR(x, 7))
558 #define S1(x) (ROTR(x,19) ^ ROTR(x,61) ^ SHR(x, 6))
559
560 #define S2(x) (ROTR(x,28) ^ ROTR(x,34) ^ ROTR(x,39))
561 #define S3(x) (ROTR(x,14) ^ ROTR(x,18) ^ ROTR(x,41))
562
563 #define F0(x,y,z) (((x) & (y)) | ((z) & ((x) | (y))))
564 #define F1(x,y,z) ((z) ^ ((x) & ((y) ^ (z))))
565
566 #define P(a,b,c,d,e,f,g,h,x,K) \
567 do \
568 { \
569 local.temp1 = (h) + S3(e) + F1((e),(f),(g)) + (K) + (x); \
570 local.temp2 = S2(a) + F0((a),(b),(c)); \
571 (d) += local.temp1; (h) = local.temp1 + local.temp2; \
572 } while( 0 )
573
574 for( i = 0; i < 8; i++ )
575 local.A[i] = ctx->state[i];
576
577 #if defined(MBEDTLS_SHA512_SMALLER)
578 for( i = 0; i < 80; i++ )
579 {
580 if( i < 16 )
581 {
582 local.W[i] = MBEDTLS_GET_UINT64_BE( data, i << 3 );
583 }
584 else
585 {
586 local.W[i] = S1(local.W[i - 2]) + local.W[i - 7] +
587 S0(local.W[i - 15]) + local.W[i - 16];
588 }
589
590 P( local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
591 local.A[5], local.A[6], local.A[7], local.W[i], K[i] );
592
593 local.temp1 = local.A[7]; local.A[7] = local.A[6];
594 local.A[6] = local.A[5]; local.A[5] = local.A[4];
595 local.A[4] = local.A[3]; local.A[3] = local.A[2];
596 local.A[2] = local.A[1]; local.A[1] = local.A[0];
597 local.A[0] = local.temp1;
598 }
599 #else /* MBEDTLS_SHA512_SMALLER */
600 for( i = 0; i < 16; i++ )
601 {
602 local.W[i] = MBEDTLS_GET_UINT64_BE( data, i << 3 );
603 }
604
605 for( ; i < 80; i++ )
606 {
607 local.W[i] = S1(local.W[i - 2]) + local.W[i - 7] +
608 S0(local.W[i - 15]) + local.W[i - 16];
609 }
610
611 i = 0;
612 do
613 {
614 P( local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
615 local.A[5], local.A[6], local.A[7], local.W[i], K[i] ); i++;
616 P( local.A[7], local.A[0], local.A[1], local.A[2], local.A[3],
617 local.A[4], local.A[5], local.A[6], local.W[i], K[i] ); i++;
618 P( local.A[6], local.A[7], local.A[0], local.A[1], local.A[2],
619 local.A[3], local.A[4], local.A[5], local.W[i], K[i] ); i++;
620 P( local.A[5], local.A[6], local.A[7], local.A[0], local.A[1],
621 local.A[2], local.A[3], local.A[4], local.W[i], K[i] ); i++;
622 P( local.A[4], local.A[5], local.A[6], local.A[7], local.A[0],
623 local.A[1], local.A[2], local.A[3], local.W[i], K[i] ); i++;
624 P( local.A[3], local.A[4], local.A[5], local.A[6], local.A[7],
625 local.A[0], local.A[1], local.A[2], local.W[i], K[i] ); i++;
626 P( local.A[2], local.A[3], local.A[4], local.A[5], local.A[6],
627 local.A[7], local.A[0], local.A[1], local.W[i], K[i] ); i++;
628 P( local.A[1], local.A[2], local.A[3], local.A[4], local.A[5],
629 local.A[6], local.A[7], local.A[0], local.W[i], K[i] ); i++;
630 }
631 while( i < 80 );
632 #endif /* MBEDTLS_SHA512_SMALLER */
633
634 for( i = 0; i < 8; i++ )
635 ctx->state[i] += local.A[i];
636
637 /* Zeroise buffers and variables to clear sensitive data from memory. */
638 mbedtls_platform_zeroize( &local, sizeof( local ) );
639
640 return( 0 );
641 }
642
643 #endif /* !MBEDTLS_SHA512_PROCESS_ALT && !MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY */
644
645
646 #if !defined(MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY)
647
mbedtls_internal_sha512_process_many_c(mbedtls_sha512_context * ctx,const uint8_t * data,size_t len)648 static size_t mbedtls_internal_sha512_process_many_c(
649 mbedtls_sha512_context *ctx, const uint8_t *data, size_t len)
650 {
651 size_t processed = 0;
652
653 while( len >= SHA512_BLOCK_SIZE )
654 {
655 if( mbedtls_internal_sha512_process_c( ctx, data ) != 0)
656 return( 0 );
657
658 data += SHA512_BLOCK_SIZE;
659 len -= SHA512_BLOCK_SIZE;
660
661 processed += SHA512_BLOCK_SIZE;
662 }
663
664 return( processed );
665 }
666
667 #endif /* !MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY */
668
669
670 #if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT)
671
mbedtls_a64_crypto_sha512_has_support(void)672 static int mbedtls_a64_crypto_sha512_has_support( void )
673 {
674 static int done = 0;
675 static int supported = 0;
676
677 if( !done )
678 {
679 supported = mbedtls_a64_crypto_sha512_determine_support();
680 done = 1;
681 }
682
683 return( supported );
684 }
685
mbedtls_internal_sha512_process_many(mbedtls_sha512_context * ctx,const uint8_t * msg,size_t len)686 static size_t mbedtls_internal_sha512_process_many( mbedtls_sha512_context *ctx,
687 const uint8_t *msg, size_t len )
688 {
689 if( mbedtls_a64_crypto_sha512_has_support() )
690 return( mbedtls_internal_sha512_process_many_a64_crypto( ctx, msg, len ) );
691 else
692 return( mbedtls_internal_sha512_process_many_c( ctx, msg, len ) );
693 }
694
mbedtls_internal_sha512_process(mbedtls_sha512_context * ctx,const unsigned char data[SHA512_BLOCK_SIZE])695 int mbedtls_internal_sha512_process( mbedtls_sha512_context *ctx,
696 const unsigned char data[SHA512_BLOCK_SIZE] )
697 {
698 if( mbedtls_a64_crypto_sha512_has_support() )
699 return( mbedtls_internal_sha512_process_a64_crypto( ctx, data ) );
700 else
701 return( mbedtls_internal_sha512_process_c( ctx, data ) );
702 }
703
704 #endif /* MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT */
705
706 /*
707 * SHA-512 process buffer
708 */
mbedtls_sha512_update(mbedtls_sha512_context * ctx,const unsigned char * input,size_t ilen)709 int mbedtls_sha512_update( mbedtls_sha512_context *ctx,
710 const unsigned char *input,
711 size_t ilen )
712 {
713 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
714 size_t fill;
715 unsigned int left;
716
717 if( ilen == 0 )
718 return( 0 );
719
720 left = (unsigned int) (ctx->total[0] & 0x7F);
721 fill = SHA512_BLOCK_SIZE - left;
722
723 ctx->total[0] += (uint64_t) ilen;
724
725 if( ctx->total[0] < (uint64_t) ilen )
726 ctx->total[1]++;
727
728 if( left && ilen >= fill )
729 {
730 memcpy( (void *) (ctx->buffer + left), input, fill );
731
732 if( ( ret = mbedtls_internal_sha512_process( ctx, ctx->buffer ) ) != 0 )
733 return( ret );
734
735 input += fill;
736 ilen -= fill;
737 left = 0;
738 }
739
740 while( ilen >= SHA512_BLOCK_SIZE )
741 {
742 size_t processed =
743 mbedtls_internal_sha512_process_many( ctx, input, ilen );
744 if( processed < SHA512_BLOCK_SIZE )
745 return( MBEDTLS_ERR_ERROR_GENERIC_ERROR );
746
747 input += processed;
748 ilen -= processed;
749 }
750
751 if( ilen > 0 )
752 memcpy( (void *) (ctx->buffer + left), input, ilen );
753
754 return( 0 );
755 }
756
757 /*
758 * SHA-512 final digest
759 */
mbedtls_sha512_finish(mbedtls_sha512_context * ctx,unsigned char * output)760 int mbedtls_sha512_finish( mbedtls_sha512_context *ctx,
761 unsigned char *output )
762 {
763 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
764 unsigned used;
765 uint64_t high, low;
766
767 /*
768 * Add padding: 0x80 then 0x00 until 16 bytes remain for the length
769 */
770 used = ctx->total[0] & 0x7F;
771
772 ctx->buffer[used++] = 0x80;
773
774 if( used <= 112 )
775 {
776 /* Enough room for padding + length in current block */
777 memset( ctx->buffer + used, 0, 112 - used );
778 }
779 else
780 {
781 /* We'll need an extra block */
782 memset( ctx->buffer + used, 0, SHA512_BLOCK_SIZE - used );
783
784 if( ( ret = mbedtls_internal_sha512_process( ctx, ctx->buffer ) ) != 0 )
785 return( ret );
786
787 memset( ctx->buffer, 0, 112 );
788 }
789
790 /*
791 * Add message length
792 */
793 high = ( ctx->total[0] >> 61 )
794 | ( ctx->total[1] << 3 );
795 low = ( ctx->total[0] << 3 );
796
797 sha512_put_uint64_be( high, ctx->buffer, 112 );
798 sha512_put_uint64_be( low, ctx->buffer, 120 );
799
800 if( ( ret = mbedtls_internal_sha512_process( ctx, ctx->buffer ) ) != 0 )
801 return( ret );
802
803 /*
804 * Output final state
805 */
806 sha512_put_uint64_be( ctx->state[0], output, 0 );
807 sha512_put_uint64_be( ctx->state[1], output, 8 );
808 sha512_put_uint64_be( ctx->state[2], output, 16 );
809 sha512_put_uint64_be( ctx->state[3], output, 24 );
810 sha512_put_uint64_be( ctx->state[4], output, 32 );
811 sha512_put_uint64_be( ctx->state[5], output, 40 );
812
813 int truncated = 0;
814 #if defined(MBEDTLS_SHA384_C)
815 truncated = ctx->is384;
816 #endif
817 if( !truncated )
818 {
819 sha512_put_uint64_be( ctx->state[6], output, 48 );
820 sha512_put_uint64_be( ctx->state[7], output, 56 );
821 }
822
823 return( 0 );
824 }
825
826 #endif /* !MBEDTLS_SHA512_ALT */
827
828 /*
829 * output = SHA-512( input buffer )
830 */
mbedtls_sha512(const unsigned char * input,size_t ilen,unsigned char * output,int is384)831 int mbedtls_sha512( const unsigned char *input,
832 size_t ilen,
833 unsigned char *output,
834 int is384 )
835 {
836 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
837 mbedtls_sha512_context ctx;
838
839 #if defined(MBEDTLS_SHA384_C)
840 if( is384 != 0 && is384 != 1 )
841 return MBEDTLS_ERR_SHA512_BAD_INPUT_DATA;
842 #else
843 if( is384 != 0 )
844 return MBEDTLS_ERR_SHA512_BAD_INPUT_DATA;
845 #endif
846
847 mbedtls_sha512_init( &ctx );
848
849 if( ( ret = mbedtls_sha512_starts( &ctx, is384 ) ) != 0 )
850 goto exit;
851
852 if( ( ret = mbedtls_sha512_update( &ctx, input, ilen ) ) != 0 )
853 goto exit;
854
855 if( ( ret = mbedtls_sha512_finish( &ctx, output ) ) != 0 )
856 goto exit;
857
858 exit:
859 mbedtls_sha512_free( &ctx );
860
861 return( ret );
862 }
863
864 #if defined(MBEDTLS_SELF_TEST)
865
866 /*
867 * FIPS-180-2 test vectors
868 */
869 static const unsigned char sha512_test_buf[3][113] =
870 {
871 { "abc" },
872 { "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu" },
873 { "" }
874 };
875
876 static const size_t sha512_test_buflen[3] =
877 {
878 3, 112, 1000
879 };
880
881 static const unsigned char sha512_test_sum[][64] =
882 {
883 #if defined(MBEDTLS_SHA384_C)
884 /*
885 * SHA-384 test vectors
886 */
887 { 0xCB, 0x00, 0x75, 0x3F, 0x45, 0xA3, 0x5E, 0x8B,
888 0xB5, 0xA0, 0x3D, 0x69, 0x9A, 0xC6, 0x50, 0x07,
889 0x27, 0x2C, 0x32, 0xAB, 0x0E, 0xDE, 0xD1, 0x63,
890 0x1A, 0x8B, 0x60, 0x5A, 0x43, 0xFF, 0x5B, 0xED,
891 0x80, 0x86, 0x07, 0x2B, 0xA1, 0xE7, 0xCC, 0x23,
892 0x58, 0xBA, 0xEC, 0xA1, 0x34, 0xC8, 0x25, 0xA7 },
893 { 0x09, 0x33, 0x0C, 0x33, 0xF7, 0x11, 0x47, 0xE8,
894 0x3D, 0x19, 0x2F, 0xC7, 0x82, 0xCD, 0x1B, 0x47,
895 0x53, 0x11, 0x1B, 0x17, 0x3B, 0x3B, 0x05, 0xD2,
896 0x2F, 0xA0, 0x80, 0x86, 0xE3, 0xB0, 0xF7, 0x12,
897 0xFC, 0xC7, 0xC7, 0x1A, 0x55, 0x7E, 0x2D, 0xB9,
898 0x66, 0xC3, 0xE9, 0xFA, 0x91, 0x74, 0x60, 0x39 },
899 { 0x9D, 0x0E, 0x18, 0x09, 0x71, 0x64, 0x74, 0xCB,
900 0x08, 0x6E, 0x83, 0x4E, 0x31, 0x0A, 0x4A, 0x1C,
901 0xED, 0x14, 0x9E, 0x9C, 0x00, 0xF2, 0x48, 0x52,
902 0x79, 0x72, 0xCE, 0xC5, 0x70, 0x4C, 0x2A, 0x5B,
903 0x07, 0xB8, 0xB3, 0xDC, 0x38, 0xEC, 0xC4, 0xEB,
904 0xAE, 0x97, 0xDD, 0xD8, 0x7F, 0x3D, 0x89, 0x85 },
905 #endif /* MBEDTLS_SHA384_C */
906
907 /*
908 * SHA-512 test vectors
909 */
910 { 0xDD, 0xAF, 0x35, 0xA1, 0x93, 0x61, 0x7A, 0xBA,
911 0xCC, 0x41, 0x73, 0x49, 0xAE, 0x20, 0x41, 0x31,
912 0x12, 0xE6, 0xFA, 0x4E, 0x89, 0xA9, 0x7E, 0xA2,
913 0x0A, 0x9E, 0xEE, 0xE6, 0x4B, 0x55, 0xD3, 0x9A,
914 0x21, 0x92, 0x99, 0x2A, 0x27, 0x4F, 0xC1, 0xA8,
915 0x36, 0xBA, 0x3C, 0x23, 0xA3, 0xFE, 0xEB, 0xBD,
916 0x45, 0x4D, 0x44, 0x23, 0x64, 0x3C, 0xE8, 0x0E,
917 0x2A, 0x9A, 0xC9, 0x4F, 0xA5, 0x4C, 0xA4, 0x9F },
918 { 0x8E, 0x95, 0x9B, 0x75, 0xDA, 0xE3, 0x13, 0xDA,
919 0x8C, 0xF4, 0xF7, 0x28, 0x14, 0xFC, 0x14, 0x3F,
920 0x8F, 0x77, 0x79, 0xC6, 0xEB, 0x9F, 0x7F, 0xA1,
921 0x72, 0x99, 0xAE, 0xAD, 0xB6, 0x88, 0x90, 0x18,
922 0x50, 0x1D, 0x28, 0x9E, 0x49, 0x00, 0xF7, 0xE4,
923 0x33, 0x1B, 0x99, 0xDE, 0xC4, 0xB5, 0x43, 0x3A,
924 0xC7, 0xD3, 0x29, 0xEE, 0xB6, 0xDD, 0x26, 0x54,
925 0x5E, 0x96, 0xE5, 0x5B, 0x87, 0x4B, 0xE9, 0x09 },
926 { 0xE7, 0x18, 0x48, 0x3D, 0x0C, 0xE7, 0x69, 0x64,
927 0x4E, 0x2E, 0x42, 0xC7, 0xBC, 0x15, 0xB4, 0x63,
928 0x8E, 0x1F, 0x98, 0xB1, 0x3B, 0x20, 0x44, 0x28,
929 0x56, 0x32, 0xA8, 0x03, 0xAF, 0xA9, 0x73, 0xEB,
930 0xDE, 0x0F, 0xF2, 0x44, 0x87, 0x7E, 0xA6, 0x0A,
931 0x4C, 0xB0, 0x43, 0x2C, 0xE5, 0x77, 0xC3, 0x1B,
932 0xEB, 0x00, 0x9C, 0x5C, 0x2C, 0x49, 0xAA, 0x2E,
933 0x4E, 0xAD, 0xB2, 0x17, 0xAD, 0x8C, 0xC0, 0x9B }
934 };
935
936 #define ARRAY_LENGTH( a ) ( sizeof( a ) / sizeof( ( a )[0] ) )
937
938 /*
939 * Checkup routine
940 */
mbedtls_sha512_self_test(int verbose)941 int mbedtls_sha512_self_test( int verbose )
942 {
943 int i, j, k, buflen, ret = 0;
944 unsigned char *buf;
945 unsigned char sha512sum[64];
946 mbedtls_sha512_context ctx;
947
948 buf = mbedtls_calloc( 1024, sizeof(unsigned char) );
949 if( NULL == buf )
950 {
951 if( verbose != 0 )
952 mbedtls_printf( "Buffer allocation failed\n" );
953
954 return( 1 );
955 }
956
957 mbedtls_sha512_init( &ctx );
958
959 for( i = 0; i < (int) ARRAY_LENGTH(sha512_test_sum); i++ )
960 {
961 j = i % 3;
962 #if defined(MBEDTLS_SHA384_C)
963 k = i < 3;
964 #else
965 k = 0;
966 #endif
967
968 if( verbose != 0 )
969 mbedtls_printf( " SHA-%d test #%d: ", 512 - k * 128, j + 1 );
970
971 if( ( ret = mbedtls_sha512_starts( &ctx, k ) ) != 0 )
972 goto fail;
973
974 if( j == 2 )
975 {
976 memset( buf, 'a', buflen = 1000 );
977
978 for( j = 0; j < 1000; j++ )
979 {
980 ret = mbedtls_sha512_update( &ctx, buf, buflen );
981 if( ret != 0 )
982 goto fail;
983 }
984 }
985 else
986 {
987 ret = mbedtls_sha512_update( &ctx, sha512_test_buf[j],
988 sha512_test_buflen[j] );
989 if( ret != 0 )
990 goto fail;
991 }
992
993 if( ( ret = mbedtls_sha512_finish( &ctx, sha512sum ) ) != 0 )
994 goto fail;
995
996 if( memcmp( sha512sum, sha512_test_sum[i], 64 - k * 16 ) != 0 )
997 {
998 ret = 1;
999 goto fail;
1000 }
1001
1002 if( verbose != 0 )
1003 mbedtls_printf( "passed\n" );
1004 }
1005
1006 if( verbose != 0 )
1007 mbedtls_printf( "\n" );
1008
1009 goto exit;
1010
1011 fail:
1012 if( verbose != 0 )
1013 mbedtls_printf( "failed\n" );
1014
1015 exit:
1016 mbedtls_sha512_free( &ctx );
1017 mbedtls_free( buf );
1018
1019 return( ret );
1020 }
1021
1022 #undef ARRAY_LENGTH
1023
1024 #endif /* MBEDTLS_SELF_TEST */
1025
1026 #endif /* MBEDTLS_SHA512_C */
1027