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