xref: /optee_os/lib/libmbedtls/mbedtls/library/sha512.c (revision 77bdbf67c42209142ef43129e01113d29d9c62f6)
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     { ("abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"
526       "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu") },
527     { "" }
528 };
529 
530 static const size_t sha512_test_buflen[3] =
531 {
532     3, 112, 1000
533 };
534 
535 static const unsigned char sha512_test_sum[][64] =
536 {
537 #if !defined(MBEDTLS_SHA512_NO_SHA384)
538     /*
539      * SHA-384 test vectors
540      */
541     { 0xCB, 0x00, 0x75, 0x3F, 0x45, 0xA3, 0x5E, 0x8B,
542       0xB5, 0xA0, 0x3D, 0x69, 0x9A, 0xC6, 0x50, 0x07,
543       0x27, 0x2C, 0x32, 0xAB, 0x0E, 0xDE, 0xD1, 0x63,
544       0x1A, 0x8B, 0x60, 0x5A, 0x43, 0xFF, 0x5B, 0xED,
545       0x80, 0x86, 0x07, 0x2B, 0xA1, 0xE7, 0xCC, 0x23,
546       0x58, 0xBA, 0xEC, 0xA1, 0x34, 0xC8, 0x25, 0xA7 },
547     { 0x09, 0x33, 0x0C, 0x33, 0xF7, 0x11, 0x47, 0xE8,
548       0x3D, 0x19, 0x2F, 0xC7, 0x82, 0xCD, 0x1B, 0x47,
549       0x53, 0x11, 0x1B, 0x17, 0x3B, 0x3B, 0x05, 0xD2,
550       0x2F, 0xA0, 0x80, 0x86, 0xE3, 0xB0, 0xF7, 0x12,
551       0xFC, 0xC7, 0xC7, 0x1A, 0x55, 0x7E, 0x2D, 0xB9,
552       0x66, 0xC3, 0xE9, 0xFA, 0x91, 0x74, 0x60, 0x39 },
553     { 0x9D, 0x0E, 0x18, 0x09, 0x71, 0x64, 0x74, 0xCB,
554       0x08, 0x6E, 0x83, 0x4E, 0x31, 0x0A, 0x4A, 0x1C,
555       0xED, 0x14, 0x9E, 0x9C, 0x00, 0xF2, 0x48, 0x52,
556       0x79, 0x72, 0xCE, 0xC5, 0x70, 0x4C, 0x2A, 0x5B,
557       0x07, 0xB8, 0xB3, 0xDC, 0x38, 0xEC, 0xC4, 0xEB,
558       0xAE, 0x97, 0xDD, 0xD8, 0x7F, 0x3D, 0x89, 0x85 },
559 #endif /* !MBEDTLS_SHA512_NO_SHA384 */
560 
561     /*
562      * SHA-512 test vectors
563      */
564     { 0xDD, 0xAF, 0x35, 0xA1, 0x93, 0x61, 0x7A, 0xBA,
565       0xCC, 0x41, 0x73, 0x49, 0xAE, 0x20, 0x41, 0x31,
566       0x12, 0xE6, 0xFA, 0x4E, 0x89, 0xA9, 0x7E, 0xA2,
567       0x0A, 0x9E, 0xEE, 0xE6, 0x4B, 0x55, 0xD3, 0x9A,
568       0x21, 0x92, 0x99, 0x2A, 0x27, 0x4F, 0xC1, 0xA8,
569       0x36, 0xBA, 0x3C, 0x23, 0xA3, 0xFE, 0xEB, 0xBD,
570       0x45, 0x4D, 0x44, 0x23, 0x64, 0x3C, 0xE8, 0x0E,
571       0x2A, 0x9A, 0xC9, 0x4F, 0xA5, 0x4C, 0xA4, 0x9F },
572     { 0x8E, 0x95, 0x9B, 0x75, 0xDA, 0xE3, 0x13, 0xDA,
573       0x8C, 0xF4, 0xF7, 0x28, 0x14, 0xFC, 0x14, 0x3F,
574       0x8F, 0x77, 0x79, 0xC6, 0xEB, 0x9F, 0x7F, 0xA1,
575       0x72, 0x99, 0xAE, 0xAD, 0xB6, 0x88, 0x90, 0x18,
576       0x50, 0x1D, 0x28, 0x9E, 0x49, 0x00, 0xF7, 0xE4,
577       0x33, 0x1B, 0x99, 0xDE, 0xC4, 0xB5, 0x43, 0x3A,
578       0xC7, 0xD3, 0x29, 0xEE, 0xB6, 0xDD, 0x26, 0x54,
579       0x5E, 0x96, 0xE5, 0x5B, 0x87, 0x4B, 0xE9, 0x09 },
580     { 0xE7, 0x18, 0x48, 0x3D, 0x0C, 0xE7, 0x69, 0x64,
581       0x4E, 0x2E, 0x42, 0xC7, 0xBC, 0x15, 0xB4, 0x63,
582       0x8E, 0x1F, 0x98, 0xB1, 0x3B, 0x20, 0x44, 0x28,
583       0x56, 0x32, 0xA8, 0x03, 0xAF, 0xA9, 0x73, 0xEB,
584       0xDE, 0x0F, 0xF2, 0x44, 0x87, 0x7E, 0xA6, 0x0A,
585       0x4C, 0xB0, 0x43, 0x2C, 0xE5, 0x77, 0xC3, 0x1B,
586       0xEB, 0x00, 0x9C, 0x5C, 0x2C, 0x49, 0xAA, 0x2E,
587       0x4E, 0xAD, 0xB2, 0x17, 0xAD, 0x8C, 0xC0, 0x9B }
588 };
589 
590 #define ARRAY_LENGTH( a )   ( sizeof( a ) / sizeof( ( a )[0] ) )
591 
592 /*
593  * Checkup routine
594  */
595 int mbedtls_sha512_self_test( int verbose )
596 {
597     int i, j, k, buflen, ret = 0;
598     unsigned char *buf;
599     unsigned char sha512sum[64];
600     mbedtls_sha512_context ctx;
601 
602     buf = mbedtls_calloc( 1024, sizeof(unsigned char) );
603     if( NULL == buf )
604     {
605         if( verbose != 0 )
606             mbedtls_printf( "Buffer allocation failed\n" );
607 
608         return( 1 );
609     }
610 
611     mbedtls_sha512_init( &ctx );
612 
613     for( i = 0; i < (int) ARRAY_LENGTH(sha512_test_sum); i++ )
614     {
615         j = i % 3;
616 #if !defined(MBEDTLS_SHA512_NO_SHA384)
617         k = i < 3;
618 #else
619         k = 0;
620 #endif
621 
622         if( verbose != 0 )
623             mbedtls_printf( "  SHA-%d test #%d: ", 512 - k * 128, j + 1 );
624 
625         if( ( ret = mbedtls_sha512_starts_ret( &ctx, k ) ) != 0 )
626             goto fail;
627 
628         if( j == 2 )
629         {
630             memset( buf, 'a', buflen = 1000 );
631 
632             for( j = 0; j < 1000; j++ )
633             {
634                 ret = mbedtls_sha512_update_ret( &ctx, buf, buflen );
635                 if( ret != 0 )
636                     goto fail;
637             }
638         }
639         else
640         {
641             ret = mbedtls_sha512_update_ret( &ctx, sha512_test_buf[j],
642                                              sha512_test_buflen[j] );
643             if( ret != 0 )
644                 goto fail;
645         }
646 
647         if( ( ret = mbedtls_sha512_finish_ret( &ctx, sha512sum ) ) != 0 )
648             goto fail;
649 
650         if( memcmp( sha512sum, sha512_test_sum[i], 64 - k * 16 ) != 0 )
651         {
652             ret = 1;
653             goto fail;
654         }
655 
656         if( verbose != 0 )
657             mbedtls_printf( "passed\n" );
658     }
659 
660     if( verbose != 0 )
661         mbedtls_printf( "\n" );
662 
663     goto exit;
664 
665 fail:
666     if( verbose != 0 )
667         mbedtls_printf( "failed\n" );
668 
669 exit:
670     mbedtls_sha512_free( &ctx );
671     mbedtls_free( buf );
672 
673     return( ret );
674 }
675 
676 #undef ARRAY_LENGTH
677 
678 #endif /* MBEDTLS_SELF_TEST */
679 
680 #endif /* MBEDTLS_SHA512_C */
681