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