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