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