xref: /reactos/dll/3rdparty/mbedtls/sha512.c (revision 02e84521)
1 /*
2  *  FIPS-180-2 compliant SHA-384/512 implementation
3  *
4  *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
5  *  SPDX-License-Identifier: GPL-2.0
6  *
7  *  This program is free software; you can redistribute it and/or modify
8  *  it under the terms of the GNU General Public License as published by
9  *  the Free Software Foundation; either version 2 of the License, or
10  *  (at your option) any later version.
11  *
12  *  This program is distributed in the hope that it will be useful,
13  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  *  GNU General Public License for more details.
16  *
17  *  You should have received a copy of the GNU General Public License along
18  *  with this program; if not, write to the Free Software Foundation, Inc.,
19  *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20  *
21  *  This file is part of mbed TLS (https://tls.mbed.org)
22  */
23 /*
24  *  The SHA-512 Secure Hash Standard was published by NIST in 2002.
25  *
26  *  http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf
27  */
28 
29 #if !defined(MBEDTLS_CONFIG_FILE)
30 #include "mbedtls/config.h"
31 #else
32 #include MBEDTLS_CONFIG_FILE
33 #endif
34 
35 #if defined(MBEDTLS_SHA512_C)
36 
37 #include "mbedtls/sha512.h"
38 
39 #if defined(_MSC_VER) || defined(__WATCOMC__)
40   #define UL64(x) x##ui64
41 #else
42   #define UL64(x) x##ULL
43 #endif
44 
45 #include <string.h>
46 
47 #if defined(MBEDTLS_SELF_TEST)
48 #if defined(MBEDTLS_PLATFORM_C)
49 #include "mbedtls/platform.h"
50 #else
51 #include <stdio.h>
52 #include <stdlib.h>
53 #define mbedtls_printf printf
54 #define mbedtls_calloc    calloc
55 #define mbedtls_free       free
56 #endif /* MBEDTLS_PLATFORM_C */
57 #endif /* MBEDTLS_SELF_TEST */
58 
59 #if !defined(MBEDTLS_SHA512_ALT)
60 
61 /* Implementation that should never be optimized out by the compiler */
62 static void mbedtls_zeroize( void *v, size_t n ) {
63     volatile unsigned char *p = v; while( n-- ) *p++ = 0;
64 }
65 
66 /*
67  * 64-bit integer manipulation macros (big endian)
68  */
69 #ifndef GET_UINT64_BE
70 #define GET_UINT64_BE(n,b,i)                            \
71 {                                                       \
72     (n) = ( (uint64_t) (b)[(i)    ] << 56 )       \
73         | ( (uint64_t) (b)[(i) + 1] << 48 )       \
74         | ( (uint64_t) (b)[(i) + 2] << 40 )       \
75         | ( (uint64_t) (b)[(i) + 3] << 32 )       \
76         | ( (uint64_t) (b)[(i) + 4] << 24 )       \
77         | ( (uint64_t) (b)[(i) + 5] << 16 )       \
78         | ( (uint64_t) (b)[(i) + 6] <<  8 )       \
79         | ( (uint64_t) (b)[(i) + 7]       );      \
80 }
81 #endif /* GET_UINT64_BE */
82 
83 #ifndef PUT_UINT64_BE
84 #define PUT_UINT64_BE(n,b,i)                            \
85 {                                                       \
86     (b)[(i)    ] = (unsigned char) ( (n) >> 56 );       \
87     (b)[(i) + 1] = (unsigned char) ( (n) >> 48 );       \
88     (b)[(i) + 2] = (unsigned char) ( (n) >> 40 );       \
89     (b)[(i) + 3] = (unsigned char) ( (n) >> 32 );       \
90     (b)[(i) + 4] = (unsigned char) ( (n) >> 24 );       \
91     (b)[(i) + 5] = (unsigned char) ( (n) >> 16 );       \
92     (b)[(i) + 6] = (unsigned char) ( (n) >>  8 );       \
93     (b)[(i) + 7] = (unsigned char) ( (n)       );       \
94 }
95 #endif /* PUT_UINT64_BE */
96 
97 void mbedtls_sha512_init( mbedtls_sha512_context *ctx )
98 {
99     memset( ctx, 0, sizeof( mbedtls_sha512_context ) );
100 }
101 
102 void mbedtls_sha512_free( mbedtls_sha512_context *ctx )
103 {
104     if( ctx == NULL )
105         return;
106 
107     mbedtls_zeroize( ctx, sizeof( mbedtls_sha512_context ) );
108 }
109 
110 void mbedtls_sha512_clone( mbedtls_sha512_context *dst,
111                            const mbedtls_sha512_context *src )
112 {
113     *dst = *src;
114 }
115 
116 /*
117  * SHA-512 context setup
118  */
119 int mbedtls_sha512_starts_ret( mbedtls_sha512_context *ctx, int is384 )
120 {
121     ctx->total[0] = 0;
122     ctx->total[1] = 0;
123 
124     if( is384 == 0 )
125     {
126         /* SHA-512 */
127         ctx->state[0] = UL64(0x6A09E667F3BCC908);
128         ctx->state[1] = UL64(0xBB67AE8584CAA73B);
129         ctx->state[2] = UL64(0x3C6EF372FE94F82B);
130         ctx->state[3] = UL64(0xA54FF53A5F1D36F1);
131         ctx->state[4] = UL64(0x510E527FADE682D1);
132         ctx->state[5] = UL64(0x9B05688C2B3E6C1F);
133         ctx->state[6] = UL64(0x1F83D9ABFB41BD6B);
134         ctx->state[7] = UL64(0x5BE0CD19137E2179);
135     }
136     else
137     {
138         /* SHA-384 */
139         ctx->state[0] = UL64(0xCBBB9D5DC1059ED8);
140         ctx->state[1] = UL64(0x629A292A367CD507);
141         ctx->state[2] = UL64(0x9159015A3070DD17);
142         ctx->state[3] = UL64(0x152FECD8F70E5939);
143         ctx->state[4] = UL64(0x67332667FFC00B31);
144         ctx->state[5] = UL64(0x8EB44A8768581511);
145         ctx->state[6] = UL64(0xDB0C2E0D64F98FA7);
146         ctx->state[7] = UL64(0x47B5481DBEFA4FA4);
147     }
148 
149     ctx->is384 = is384;
150 
151     return( 0 );
152 }
153 
154 #if !defined(MBEDTLS_DEPRECATED_REMOVED)
155 void mbedtls_sha512_starts( mbedtls_sha512_context *ctx,
156                             int is384 )
157 {
158     mbedtls_sha512_starts_ret( ctx, is384 );
159 }
160 #endif
161 
162 #if !defined(MBEDTLS_SHA512_PROCESS_ALT)
163 
164 /*
165  * Round constants
166  */
167 static const uint64_t K[80] =
168 {
169     UL64(0x428A2F98D728AE22),  UL64(0x7137449123EF65CD),
170     UL64(0xB5C0FBCFEC4D3B2F),  UL64(0xE9B5DBA58189DBBC),
171     UL64(0x3956C25BF348B538),  UL64(0x59F111F1B605D019),
172     UL64(0x923F82A4AF194F9B),  UL64(0xAB1C5ED5DA6D8118),
173     UL64(0xD807AA98A3030242),  UL64(0x12835B0145706FBE),
174     UL64(0x243185BE4EE4B28C),  UL64(0x550C7DC3D5FFB4E2),
175     UL64(0x72BE5D74F27B896F),  UL64(0x80DEB1FE3B1696B1),
176     UL64(0x9BDC06A725C71235),  UL64(0xC19BF174CF692694),
177     UL64(0xE49B69C19EF14AD2),  UL64(0xEFBE4786384F25E3),
178     UL64(0x0FC19DC68B8CD5B5),  UL64(0x240CA1CC77AC9C65),
179     UL64(0x2DE92C6F592B0275),  UL64(0x4A7484AA6EA6E483),
180     UL64(0x5CB0A9DCBD41FBD4),  UL64(0x76F988DA831153B5),
181     UL64(0x983E5152EE66DFAB),  UL64(0xA831C66D2DB43210),
182     UL64(0xB00327C898FB213F),  UL64(0xBF597FC7BEEF0EE4),
183     UL64(0xC6E00BF33DA88FC2),  UL64(0xD5A79147930AA725),
184     UL64(0x06CA6351E003826F),  UL64(0x142929670A0E6E70),
185     UL64(0x27B70A8546D22FFC),  UL64(0x2E1B21385C26C926),
186     UL64(0x4D2C6DFC5AC42AED),  UL64(0x53380D139D95B3DF),
187     UL64(0x650A73548BAF63DE),  UL64(0x766A0ABB3C77B2A8),
188     UL64(0x81C2C92E47EDAEE6),  UL64(0x92722C851482353B),
189     UL64(0xA2BFE8A14CF10364),  UL64(0xA81A664BBC423001),
190     UL64(0xC24B8B70D0F89791),  UL64(0xC76C51A30654BE30),
191     UL64(0xD192E819D6EF5218),  UL64(0xD69906245565A910),
192     UL64(0xF40E35855771202A),  UL64(0x106AA07032BBD1B8),
193     UL64(0x19A4C116B8D2D0C8),  UL64(0x1E376C085141AB53),
194     UL64(0x2748774CDF8EEB99),  UL64(0x34B0BCB5E19B48A8),
195     UL64(0x391C0CB3C5C95A63),  UL64(0x4ED8AA4AE3418ACB),
196     UL64(0x5B9CCA4F7763E373),  UL64(0x682E6FF3D6B2B8A3),
197     UL64(0x748F82EE5DEFB2FC),  UL64(0x78A5636F43172F60),
198     UL64(0x84C87814A1F0AB72),  UL64(0x8CC702081A6439EC),
199     UL64(0x90BEFFFA23631E28),  UL64(0xA4506CEBDE82BDE9),
200     UL64(0xBEF9A3F7B2C67915),  UL64(0xC67178F2E372532B),
201     UL64(0xCA273ECEEA26619C),  UL64(0xD186B8C721C0C207),
202     UL64(0xEADA7DD6CDE0EB1E),  UL64(0xF57D4F7FEE6ED178),
203     UL64(0x06F067AA72176FBA),  UL64(0x0A637DC5A2C898A6),
204     UL64(0x113F9804BEF90DAE),  UL64(0x1B710B35131C471B),
205     UL64(0x28DB77F523047D84),  UL64(0x32CAAB7B40C72493),
206     UL64(0x3C9EBE0A15C9BEBC),  UL64(0x431D67C49C100D4C),
207     UL64(0x4CC5D4BECB3E42B6),  UL64(0x597F299CFC657E2A),
208     UL64(0x5FCB6FAB3AD6FAEC),  UL64(0x6C44198C4A475817)
209 };
210 
211 int mbedtls_internal_sha512_process( mbedtls_sha512_context *ctx,
212                                      const unsigned char data[128] )
213 {
214     int i;
215     uint64_t temp1, temp2, W[80];
216     uint64_t A, B, C, D, E, F, G, H;
217 
218 #define  SHR(x,n) (x >> n)
219 #define ROTR(x,n) (SHR(x,n) | (x << (64 - n)))
220 
221 #define S0(x) (ROTR(x, 1) ^ ROTR(x, 8) ^  SHR(x, 7))
222 #define S1(x) (ROTR(x,19) ^ ROTR(x,61) ^  SHR(x, 6))
223 
224 #define S2(x) (ROTR(x,28) ^ ROTR(x,34) ^ ROTR(x,39))
225 #define S3(x) (ROTR(x,14) ^ ROTR(x,18) ^ ROTR(x,41))
226 
227 #define F0(x,y,z) ((x & y) | (z & (x | y)))
228 #define F1(x,y,z) (z ^ (x & (y ^ z)))
229 
230 #define P(a,b,c,d,e,f,g,h,x,K)                  \
231 {                                               \
232     temp1 = h + S3(e) + F1(e,f,g) + K + x;      \
233     temp2 = S2(a) + F0(a,b,c);                  \
234     d += temp1; h = temp1 + temp2;              \
235 }
236 
237     for( i = 0; i < 16; i++ )
238     {
239         GET_UINT64_BE( W[i], data, i << 3 );
240     }
241 
242     for( ; i < 80; i++ )
243     {
244         W[i] = S1(W[i -  2]) + W[i -  7] +
245                S0(W[i - 15]) + W[i - 16];
246     }
247 
248     A = ctx->state[0];
249     B = ctx->state[1];
250     C = ctx->state[2];
251     D = ctx->state[3];
252     E = ctx->state[4];
253     F = ctx->state[5];
254     G = ctx->state[6];
255     H = ctx->state[7];
256     i = 0;
257 
258     do
259     {
260         P( A, B, C, D, E, F, G, H, W[i], K[i] ); i++;
261         P( H, A, B, C, D, E, F, G, W[i], K[i] ); i++;
262         P( G, H, A, B, C, D, E, F, W[i], K[i] ); i++;
263         P( F, G, H, A, B, C, D, E, W[i], K[i] ); i++;
264         P( E, F, G, H, A, B, C, D, W[i], K[i] ); i++;
265         P( D, E, F, G, H, A, B, C, W[i], K[i] ); i++;
266         P( C, D, E, F, G, H, A, B, W[i], K[i] ); i++;
267         P( B, C, D, E, F, G, H, A, W[i], K[i] ); i++;
268     }
269     while( i < 80 );
270 
271     ctx->state[0] += A;
272     ctx->state[1] += B;
273     ctx->state[2] += C;
274     ctx->state[3] += D;
275     ctx->state[4] += E;
276     ctx->state[5] += F;
277     ctx->state[6] += G;
278     ctx->state[7] += H;
279 
280     return( 0 );
281 }
282 
283 #if !defined(MBEDTLS_DEPRECATED_REMOVED)
284 void mbedtls_sha512_process( mbedtls_sha512_context *ctx,
285                              const unsigned char data[128] )
286 {
287     mbedtls_internal_sha512_process( ctx, data );
288 }
289 #endif
290 #endif /* !MBEDTLS_SHA512_PROCESS_ALT */
291 
292 /*
293  * SHA-512 process buffer
294  */
295 int mbedtls_sha512_update_ret( mbedtls_sha512_context *ctx,
296                                const unsigned char *input,
297                                size_t ilen )
298 {
299     int ret;
300     size_t fill;
301     unsigned int left;
302 
303     if( ilen == 0 )
304         return( 0 );
305 
306     left = (unsigned int) (ctx->total[0] & 0x7F);
307     fill = 128 - left;
308 
309     ctx->total[0] += (uint64_t) ilen;
310 
311     if( ctx->total[0] < (uint64_t) ilen )
312         ctx->total[1]++;
313 
314     if( left && ilen >= fill )
315     {
316         memcpy( (void *) (ctx->buffer + left), input, fill );
317 
318         if( ( ret = mbedtls_internal_sha512_process( ctx, ctx->buffer ) ) != 0 )
319             return( ret );
320 
321         input += fill;
322         ilen  -= fill;
323         left = 0;
324     }
325 
326     while( ilen >= 128 )
327     {
328         if( ( ret = mbedtls_internal_sha512_process( ctx, input ) ) != 0 )
329             return( ret );
330 
331         input += 128;
332         ilen  -= 128;
333     }
334 
335     if( ilen > 0 )
336         memcpy( (void *) (ctx->buffer + left), input, ilen );
337 
338     return( 0 );
339 }
340 
341 #if !defined(MBEDTLS_DEPRECATED_REMOVED)
342 void mbedtls_sha512_update( mbedtls_sha512_context *ctx,
343                             const unsigned char *input,
344                             size_t ilen )
345 {
346     mbedtls_sha512_update_ret( ctx, input, ilen );
347 }
348 #endif
349 
350 /*
351  * SHA-512 final digest
352  */
353 int mbedtls_sha512_finish_ret( mbedtls_sha512_context *ctx,
354                                unsigned char output[64] )
355 {
356     int ret;
357     unsigned used;
358     uint64_t high, low;
359 
360     /*
361      * Add padding: 0x80 then 0x00 until 16 bytes remain for the length
362      */
363     used = ctx->total[0] & 0x7F;
364 
365     ctx->buffer[used++] = 0x80;
366 
367     if( used <= 112 )
368     {
369         /* Enough room for padding + length in current block */
370         memset( ctx->buffer + used, 0, 112 - used );
371     }
372     else
373     {
374         /* We'll need an extra block */
375         memset( ctx->buffer + used, 0, 128 - used );
376 
377         if( ( ret = mbedtls_internal_sha512_process( ctx, ctx->buffer ) ) != 0 )
378             return( ret );
379 
380         memset( ctx->buffer, 0, 112 );
381     }
382 
383     /*
384      * Add message length
385      */
386     high = ( ctx->total[0] >> 61 )
387          | ( ctx->total[1] <<  3 );
388     low  = ( ctx->total[0] <<  3 );
389 
390     PUT_UINT64_BE( high, ctx->buffer, 112 );
391     PUT_UINT64_BE( low,  ctx->buffer, 120 );
392 
393     if( ( ret = mbedtls_internal_sha512_process( ctx, ctx->buffer ) ) != 0 )
394         return( ret );
395 
396     /*
397      * Output final state
398      */
399     PUT_UINT64_BE( ctx->state[0], output,  0 );
400     PUT_UINT64_BE( ctx->state[1], output,  8 );
401     PUT_UINT64_BE( ctx->state[2], output, 16 );
402     PUT_UINT64_BE( ctx->state[3], output, 24 );
403     PUT_UINT64_BE( ctx->state[4], output, 32 );
404     PUT_UINT64_BE( ctx->state[5], output, 40 );
405 
406     if( ctx->is384 == 0 )
407     {
408         PUT_UINT64_BE( ctx->state[6], output, 48 );
409         PUT_UINT64_BE( ctx->state[7], output, 56 );
410     }
411 
412     return( 0 );
413 }
414 
415 #if !defined(MBEDTLS_DEPRECATED_REMOVED)
416 void mbedtls_sha512_finish( mbedtls_sha512_context *ctx,
417                             unsigned char output[64] )
418 {
419     mbedtls_sha512_finish_ret( ctx, output );
420 }
421 #endif
422 
423 #endif /* !MBEDTLS_SHA512_ALT */
424 
425 /*
426  * output = SHA-512( input buffer )
427  */
428 int mbedtls_sha512_ret( const unsigned char *input,
429                     size_t ilen,
430                     unsigned char output[64],
431                     int is384 )
432 {
433     int ret;
434     mbedtls_sha512_context ctx;
435 
436     mbedtls_sha512_init( &ctx );
437 
438     if( ( ret = mbedtls_sha512_starts_ret( &ctx, is384 ) ) != 0 )
439         goto exit;
440 
441     if( ( ret = mbedtls_sha512_update_ret( &ctx, input, ilen ) ) != 0 )
442         goto exit;
443 
444     if( ( ret = mbedtls_sha512_finish_ret( &ctx, output ) ) != 0 )
445         goto exit;
446 
447 exit:
448     mbedtls_sha512_free( &ctx );
449 
450     return( ret );
451 }
452 
453 #if !defined(MBEDTLS_DEPRECATED_REMOVED)
454 void mbedtls_sha512( const unsigned char *input,
455                      size_t ilen,
456                      unsigned char output[64],
457                      int is384 )
458 {
459     mbedtls_sha512_ret( input, ilen, output, is384 );
460 }
461 #endif
462 
463 #if defined(MBEDTLS_SELF_TEST)
464 
465 /*
466  * FIPS-180-2 test vectors
467  */
468 static const unsigned char sha512_test_buf[3][113] =
469 {
470     { "abc" },
471     { "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"
472       "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu" },
473     { "" }
474 };
475 
476 static const size_t sha512_test_buflen[3] =
477 {
478     3, 112, 1000
479 };
480 
481 static const unsigned char sha512_test_sum[6][64] =
482 {
483     /*
484      * SHA-384 test vectors
485      */
486     { 0xCB, 0x00, 0x75, 0x3F, 0x45, 0xA3, 0x5E, 0x8B,
487       0xB5, 0xA0, 0x3D, 0x69, 0x9A, 0xC6, 0x50, 0x07,
488       0x27, 0x2C, 0x32, 0xAB, 0x0E, 0xDE, 0xD1, 0x63,
489       0x1A, 0x8B, 0x60, 0x5A, 0x43, 0xFF, 0x5B, 0xED,
490       0x80, 0x86, 0x07, 0x2B, 0xA1, 0xE7, 0xCC, 0x23,
491       0x58, 0xBA, 0xEC, 0xA1, 0x34, 0xC8, 0x25, 0xA7 },
492     { 0x09, 0x33, 0x0C, 0x33, 0xF7, 0x11, 0x47, 0xE8,
493       0x3D, 0x19, 0x2F, 0xC7, 0x82, 0xCD, 0x1B, 0x47,
494       0x53, 0x11, 0x1B, 0x17, 0x3B, 0x3B, 0x05, 0xD2,
495       0x2F, 0xA0, 0x80, 0x86, 0xE3, 0xB0, 0xF7, 0x12,
496       0xFC, 0xC7, 0xC7, 0x1A, 0x55, 0x7E, 0x2D, 0xB9,
497       0x66, 0xC3, 0xE9, 0xFA, 0x91, 0x74, 0x60, 0x39 },
498     { 0x9D, 0x0E, 0x18, 0x09, 0x71, 0x64, 0x74, 0xCB,
499       0x08, 0x6E, 0x83, 0x4E, 0x31, 0x0A, 0x4A, 0x1C,
500       0xED, 0x14, 0x9E, 0x9C, 0x00, 0xF2, 0x48, 0x52,
501       0x79, 0x72, 0xCE, 0xC5, 0x70, 0x4C, 0x2A, 0x5B,
502       0x07, 0xB8, 0xB3, 0xDC, 0x38, 0xEC, 0xC4, 0xEB,
503       0xAE, 0x97, 0xDD, 0xD8, 0x7F, 0x3D, 0x89, 0x85 },
504 
505     /*
506      * SHA-512 test vectors
507      */
508     { 0xDD, 0xAF, 0x35, 0xA1, 0x93, 0x61, 0x7A, 0xBA,
509       0xCC, 0x41, 0x73, 0x49, 0xAE, 0x20, 0x41, 0x31,
510       0x12, 0xE6, 0xFA, 0x4E, 0x89, 0xA9, 0x7E, 0xA2,
511       0x0A, 0x9E, 0xEE, 0xE6, 0x4B, 0x55, 0xD3, 0x9A,
512       0x21, 0x92, 0x99, 0x2A, 0x27, 0x4F, 0xC1, 0xA8,
513       0x36, 0xBA, 0x3C, 0x23, 0xA3, 0xFE, 0xEB, 0xBD,
514       0x45, 0x4D, 0x44, 0x23, 0x64, 0x3C, 0xE8, 0x0E,
515       0x2A, 0x9A, 0xC9, 0x4F, 0xA5, 0x4C, 0xA4, 0x9F },
516     { 0x8E, 0x95, 0x9B, 0x75, 0xDA, 0xE3, 0x13, 0xDA,
517       0x8C, 0xF4, 0xF7, 0x28, 0x14, 0xFC, 0x14, 0x3F,
518       0x8F, 0x77, 0x79, 0xC6, 0xEB, 0x9F, 0x7F, 0xA1,
519       0x72, 0x99, 0xAE, 0xAD, 0xB6, 0x88, 0x90, 0x18,
520       0x50, 0x1D, 0x28, 0x9E, 0x49, 0x00, 0xF7, 0xE4,
521       0x33, 0x1B, 0x99, 0xDE, 0xC4, 0xB5, 0x43, 0x3A,
522       0xC7, 0xD3, 0x29, 0xEE, 0xB6, 0xDD, 0x26, 0x54,
523       0x5E, 0x96, 0xE5, 0x5B, 0x87, 0x4B, 0xE9, 0x09 },
524     { 0xE7, 0x18, 0x48, 0x3D, 0x0C, 0xE7, 0x69, 0x64,
525       0x4E, 0x2E, 0x42, 0xC7, 0xBC, 0x15, 0xB4, 0x63,
526       0x8E, 0x1F, 0x98, 0xB1, 0x3B, 0x20, 0x44, 0x28,
527       0x56, 0x32, 0xA8, 0x03, 0xAF, 0xA9, 0x73, 0xEB,
528       0xDE, 0x0F, 0xF2, 0x44, 0x87, 0x7E, 0xA6, 0x0A,
529       0x4C, 0xB0, 0x43, 0x2C, 0xE5, 0x77, 0xC3, 0x1B,
530       0xEB, 0x00, 0x9C, 0x5C, 0x2C, 0x49, 0xAA, 0x2E,
531       0x4E, 0xAD, 0xB2, 0x17, 0xAD, 0x8C, 0xC0, 0x9B }
532 };
533 
534 /*
535  * Checkup routine
536  */
537 int mbedtls_sha512_self_test( int verbose )
538 {
539     int i, j, k, buflen, ret = 0;
540     unsigned char *buf;
541     unsigned char sha512sum[64];
542     mbedtls_sha512_context ctx;
543 
544     buf = mbedtls_calloc( 1024, sizeof(unsigned char) );
545     if( NULL == buf )
546     {
547         if( verbose != 0 )
548             mbedtls_printf( "Buffer allocation failed\n" );
549 
550         return( 1 );
551     }
552 
553     mbedtls_sha512_init( &ctx );
554 
555     for( i = 0; i < 6; i++ )
556     {
557         j = i % 3;
558         k = i < 3;
559 
560         if( verbose != 0 )
561             mbedtls_printf( "  SHA-%d test #%d: ", 512 - k * 128, j + 1 );
562 
563         if( ( ret = mbedtls_sha512_starts_ret( &ctx, k ) ) != 0 )
564             goto fail;
565 
566         if( j == 2 )
567         {
568             memset( buf, 'a', buflen = 1000 );
569 
570             for( j = 0; j < 1000; j++ )
571             {
572                 ret = mbedtls_sha512_update_ret( &ctx, buf, buflen );
573                 if( ret != 0 )
574                     goto fail;
575             }
576         }
577         else
578         {
579             ret = mbedtls_sha512_update_ret( &ctx, sha512_test_buf[j],
580                                              sha512_test_buflen[j] );
581             if( ret != 0 )
582                 goto fail;
583         }
584 
585         if( ( ret = mbedtls_sha512_finish_ret( &ctx, sha512sum ) ) != 0 )
586             goto fail;
587 
588         if( memcmp( sha512sum, sha512_test_sum[i], 64 - k * 16 ) != 0 )
589         {
590             ret = 1;
591             goto fail;
592         }
593 
594         if( verbose != 0 )
595             mbedtls_printf( "passed\n" );
596     }
597 
598     if( verbose != 0 )
599         mbedtls_printf( "\n" );
600 
601     goto exit;
602 
603 fail:
604     if( verbose != 0 )
605         mbedtls_printf( "failed\n" );
606 
607 exit:
608     mbedtls_sha512_free( &ctx );
609     mbedtls_free( buf );
610 
611     return( ret );
612 }
613 
614 #endif /* MBEDTLS_SELF_TEST */
615 
616 #endif /* MBEDTLS_SHA512_C */
617