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