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
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 
mbedtls_sha512_init(mbedtls_sha512_context * ctx)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 
mbedtls_sha512_free(mbedtls_sha512_context * ctx)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 
mbedtls_sha512_clone(mbedtls_sha512_context * dst,const mbedtls_sha512_context * src)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  */
mbedtls_sha512_starts_ret(mbedtls_sha512_context * ctx,int is384)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)
mbedtls_sha512_starts(mbedtls_sha512_context * ctx,int is384)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 
mbedtls_internal_sha512_process(mbedtls_sha512_context * ctx,const unsigned char data[128])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 {                                               \
241     temp1 = h + S3(e) + F1(e,f,g) + K + x;      \
242     temp2 = S2(a) + F0(a,b,c);                  \
243     d += temp1; h = temp1 + temp2;              \
244 }
245 
246     for( i = 0; i < 16; i++ )
247     {
248         GET_UINT64_BE( W[i], data, i << 3 );
249     }
250 
251     for( ; i < 80; i++ )
252     {
253         W[i] = S1(W[i -  2]) + W[i -  7] +
254                S0(W[i - 15]) + W[i - 16];
255     }
256 
257     A = ctx->state[0];
258     B = ctx->state[1];
259     C = ctx->state[2];
260     D = ctx->state[3];
261     E = ctx->state[4];
262     F = ctx->state[5];
263     G = ctx->state[6];
264     H = ctx->state[7];
265     i = 0;
266 
267     do
268     {
269         P( A, B, C, D, E, F, G, H, W[i], K[i] ); i++;
270         P( H, A, B, C, D, E, F, G, W[i], K[i] ); i++;
271         P( G, H, A, B, C, D, E, F, W[i], K[i] ); i++;
272         P( F, G, H, A, B, C, D, E, W[i], K[i] ); i++;
273         P( E, F, G, H, A, B, C, D, W[i], K[i] ); i++;
274         P( D, E, F, G, H, A, B, C, W[i], K[i] ); i++;
275         P( C, D, E, F, G, H, A, B, W[i], K[i] ); i++;
276         P( B, C, D, E, F, G, H, A, W[i], K[i] ); i++;
277     }
278     while( i < 80 );
279 
280     ctx->state[0] += A;
281     ctx->state[1] += B;
282     ctx->state[2] += C;
283     ctx->state[3] += D;
284     ctx->state[4] += E;
285     ctx->state[5] += F;
286     ctx->state[6] += G;
287     ctx->state[7] += H;
288 
289     return( 0 );
290 }
291 
292 #if !defined(MBEDTLS_DEPRECATED_REMOVED)
mbedtls_sha512_process(mbedtls_sha512_context * ctx,const unsigned char data[128])293 void mbedtls_sha512_process( mbedtls_sha512_context *ctx,
294                              const unsigned char data[128] )
295 {
296     mbedtls_internal_sha512_process( ctx, data );
297 }
298 #endif
299 #endif /* !MBEDTLS_SHA512_PROCESS_ALT */
300 
301 /*
302  * SHA-512 process buffer
303  */
mbedtls_sha512_update_ret(mbedtls_sha512_context * ctx,const unsigned char * input,size_t ilen)304 int mbedtls_sha512_update_ret( mbedtls_sha512_context *ctx,
305                                const unsigned char *input,
306                                size_t ilen )
307 {
308     int ret;
309     size_t fill;
310     unsigned int left;
311 
312     SHA512_VALIDATE_RET( ctx != NULL );
313     SHA512_VALIDATE_RET( ilen == 0 || input != NULL );
314 
315     if( ilen == 0 )
316         return( 0 );
317 
318     left = (unsigned int) (ctx->total[0] & 0x7F);
319     fill = 128 - left;
320 
321     ctx->total[0] += (uint64_t) ilen;
322 
323     if( ctx->total[0] < (uint64_t) ilen )
324         ctx->total[1]++;
325 
326     if( left && ilen >= fill )
327     {
328         memcpy( (void *) (ctx->buffer + left), input, fill );
329 
330         if( ( ret = mbedtls_internal_sha512_process( ctx, ctx->buffer ) ) != 0 )
331             return( ret );
332 
333         input += fill;
334         ilen  -= fill;
335         left = 0;
336     }
337 
338     while( ilen >= 128 )
339     {
340         if( ( ret = mbedtls_internal_sha512_process( ctx, input ) ) != 0 )
341             return( ret );
342 
343         input += 128;
344         ilen  -= 128;
345     }
346 
347     if( ilen > 0 )
348         memcpy( (void *) (ctx->buffer + left), input, ilen );
349 
350     return( 0 );
351 }
352 
353 #if !defined(MBEDTLS_DEPRECATED_REMOVED)
mbedtls_sha512_update(mbedtls_sha512_context * ctx,const unsigned char * input,size_t ilen)354 void mbedtls_sha512_update( mbedtls_sha512_context *ctx,
355                             const unsigned char *input,
356                             size_t ilen )
357 {
358     mbedtls_sha512_update_ret( ctx, input, ilen );
359 }
360 #endif
361 
362 /*
363  * SHA-512 final digest
364  */
mbedtls_sha512_finish_ret(mbedtls_sha512_context * ctx,unsigned char output[64])365 int mbedtls_sha512_finish_ret( mbedtls_sha512_context *ctx,
366                                unsigned char output[64] )
367 {
368     int ret;
369     unsigned used;
370     uint64_t high, low;
371 
372     SHA512_VALIDATE_RET( ctx != NULL );
373     SHA512_VALIDATE_RET( (unsigned char *)output != NULL );
374 
375     /*
376      * Add padding: 0x80 then 0x00 until 16 bytes remain for the length
377      */
378     used = ctx->total[0] & 0x7F;
379 
380     ctx->buffer[used++] = 0x80;
381 
382     if( used <= 112 )
383     {
384         /* Enough room for padding + length in current block */
385         memset( ctx->buffer + used, 0, 112 - used );
386     }
387     else
388     {
389         /* We'll need an extra block */
390         memset( ctx->buffer + used, 0, 128 - used );
391 
392         if( ( ret = mbedtls_internal_sha512_process( ctx, ctx->buffer ) ) != 0 )
393             return( ret );
394 
395         memset( ctx->buffer, 0, 112 );
396     }
397 
398     /*
399      * Add message length
400      */
401     high = ( ctx->total[0] >> 61 )
402          | ( ctx->total[1] <<  3 );
403     low  = ( ctx->total[0] <<  3 );
404 
405     PUT_UINT64_BE( high, ctx->buffer, 112 );
406     PUT_UINT64_BE( low,  ctx->buffer, 120 );
407 
408     if( ( ret = mbedtls_internal_sha512_process( ctx, ctx->buffer ) ) != 0 )
409         return( ret );
410 
411     /*
412      * Output final state
413      */
414     PUT_UINT64_BE( ctx->state[0], output,  0 );
415     PUT_UINT64_BE( ctx->state[1], output,  8 );
416     PUT_UINT64_BE( ctx->state[2], output, 16 );
417     PUT_UINT64_BE( ctx->state[3], output, 24 );
418     PUT_UINT64_BE( ctx->state[4], output, 32 );
419     PUT_UINT64_BE( ctx->state[5], output, 40 );
420 
421     if( ctx->is384 == 0 )
422     {
423         PUT_UINT64_BE( ctx->state[6], output, 48 );
424         PUT_UINT64_BE( ctx->state[7], output, 56 );
425     }
426 
427     return( 0 );
428 }
429 
430 #if !defined(MBEDTLS_DEPRECATED_REMOVED)
mbedtls_sha512_finish(mbedtls_sha512_context * ctx,unsigned char output[64])431 void mbedtls_sha512_finish( mbedtls_sha512_context *ctx,
432                             unsigned char output[64] )
433 {
434     mbedtls_sha512_finish_ret( ctx, output );
435 }
436 #endif
437 
438 #endif /* !MBEDTLS_SHA512_ALT */
439 
440 /*
441  * output = SHA-512( input buffer )
442  */
mbedtls_sha512_ret(const unsigned char * input,size_t ilen,unsigned char output[64],int is384)443 int mbedtls_sha512_ret( const unsigned char *input,
444                     size_t ilen,
445                     unsigned char output[64],
446                     int is384 )
447 {
448     int ret;
449     mbedtls_sha512_context ctx;
450 
451     SHA512_VALIDATE_RET( is384 == 0 || is384 == 1 );
452     SHA512_VALIDATE_RET( ilen == 0 || input != NULL );
453     SHA512_VALIDATE_RET( (unsigned char *)output != NULL );
454 
455     mbedtls_sha512_init( &ctx );
456 
457     if( ( ret = mbedtls_sha512_starts_ret( &ctx, is384 ) ) != 0 )
458         goto exit;
459 
460     if( ( ret = mbedtls_sha512_update_ret( &ctx, input, ilen ) ) != 0 )
461         goto exit;
462 
463     if( ( ret = mbedtls_sha512_finish_ret( &ctx, output ) ) != 0 )
464         goto exit;
465 
466 exit:
467     mbedtls_sha512_free( &ctx );
468 
469     return( ret );
470 }
471 
472 #if !defined(MBEDTLS_DEPRECATED_REMOVED)
mbedtls_sha512(const unsigned char * input,size_t ilen,unsigned char output[64],int is384)473 void mbedtls_sha512( const unsigned char *input,
474                      size_t ilen,
475                      unsigned char output[64],
476                      int is384 )
477 {
478     mbedtls_sha512_ret( input, ilen, output, is384 );
479 }
480 #endif
481 
482 #if defined(MBEDTLS_SELF_TEST)
483 
484 /*
485  * FIPS-180-2 test vectors
486  */
487 static const unsigned char sha512_test_buf[3][113] =
488 {
489     { "abc" },
490     { "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"
491       "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu" },
492     { "" }
493 };
494 
495 static const size_t sha512_test_buflen[3] =
496 {
497     3, 112, 1000
498 };
499 
500 static const unsigned char sha512_test_sum[6][64] =
501 {
502     /*
503      * SHA-384 test vectors
504      */
505     { 0xCB, 0x00, 0x75, 0x3F, 0x45, 0xA3, 0x5E, 0x8B,
506       0xB5, 0xA0, 0x3D, 0x69, 0x9A, 0xC6, 0x50, 0x07,
507       0x27, 0x2C, 0x32, 0xAB, 0x0E, 0xDE, 0xD1, 0x63,
508       0x1A, 0x8B, 0x60, 0x5A, 0x43, 0xFF, 0x5B, 0xED,
509       0x80, 0x86, 0x07, 0x2B, 0xA1, 0xE7, 0xCC, 0x23,
510       0x58, 0xBA, 0xEC, 0xA1, 0x34, 0xC8, 0x25, 0xA7 },
511     { 0x09, 0x33, 0x0C, 0x33, 0xF7, 0x11, 0x47, 0xE8,
512       0x3D, 0x19, 0x2F, 0xC7, 0x82, 0xCD, 0x1B, 0x47,
513       0x53, 0x11, 0x1B, 0x17, 0x3B, 0x3B, 0x05, 0xD2,
514       0x2F, 0xA0, 0x80, 0x86, 0xE3, 0xB0, 0xF7, 0x12,
515       0xFC, 0xC7, 0xC7, 0x1A, 0x55, 0x7E, 0x2D, 0xB9,
516       0x66, 0xC3, 0xE9, 0xFA, 0x91, 0x74, 0x60, 0x39 },
517     { 0x9D, 0x0E, 0x18, 0x09, 0x71, 0x64, 0x74, 0xCB,
518       0x08, 0x6E, 0x83, 0x4E, 0x31, 0x0A, 0x4A, 0x1C,
519       0xED, 0x14, 0x9E, 0x9C, 0x00, 0xF2, 0x48, 0x52,
520       0x79, 0x72, 0xCE, 0xC5, 0x70, 0x4C, 0x2A, 0x5B,
521       0x07, 0xB8, 0xB3, 0xDC, 0x38, 0xEC, 0xC4, 0xEB,
522       0xAE, 0x97, 0xDD, 0xD8, 0x7F, 0x3D, 0x89, 0x85 },
523 
524     /*
525      * SHA-512 test vectors
526      */
527     { 0xDD, 0xAF, 0x35, 0xA1, 0x93, 0x61, 0x7A, 0xBA,
528       0xCC, 0x41, 0x73, 0x49, 0xAE, 0x20, 0x41, 0x31,
529       0x12, 0xE6, 0xFA, 0x4E, 0x89, 0xA9, 0x7E, 0xA2,
530       0x0A, 0x9E, 0xEE, 0xE6, 0x4B, 0x55, 0xD3, 0x9A,
531       0x21, 0x92, 0x99, 0x2A, 0x27, 0x4F, 0xC1, 0xA8,
532       0x36, 0xBA, 0x3C, 0x23, 0xA3, 0xFE, 0xEB, 0xBD,
533       0x45, 0x4D, 0x44, 0x23, 0x64, 0x3C, 0xE8, 0x0E,
534       0x2A, 0x9A, 0xC9, 0x4F, 0xA5, 0x4C, 0xA4, 0x9F },
535     { 0x8E, 0x95, 0x9B, 0x75, 0xDA, 0xE3, 0x13, 0xDA,
536       0x8C, 0xF4, 0xF7, 0x28, 0x14, 0xFC, 0x14, 0x3F,
537       0x8F, 0x77, 0x79, 0xC6, 0xEB, 0x9F, 0x7F, 0xA1,
538       0x72, 0x99, 0xAE, 0xAD, 0xB6, 0x88, 0x90, 0x18,
539       0x50, 0x1D, 0x28, 0x9E, 0x49, 0x00, 0xF7, 0xE4,
540       0x33, 0x1B, 0x99, 0xDE, 0xC4, 0xB5, 0x43, 0x3A,
541       0xC7, 0xD3, 0x29, 0xEE, 0xB6, 0xDD, 0x26, 0x54,
542       0x5E, 0x96, 0xE5, 0x5B, 0x87, 0x4B, 0xE9, 0x09 },
543     { 0xE7, 0x18, 0x48, 0x3D, 0x0C, 0xE7, 0x69, 0x64,
544       0x4E, 0x2E, 0x42, 0xC7, 0xBC, 0x15, 0xB4, 0x63,
545       0x8E, 0x1F, 0x98, 0xB1, 0x3B, 0x20, 0x44, 0x28,
546       0x56, 0x32, 0xA8, 0x03, 0xAF, 0xA9, 0x73, 0xEB,
547       0xDE, 0x0F, 0xF2, 0x44, 0x87, 0x7E, 0xA6, 0x0A,
548       0x4C, 0xB0, 0x43, 0x2C, 0xE5, 0x77, 0xC3, 0x1B,
549       0xEB, 0x00, 0x9C, 0x5C, 0x2C, 0x49, 0xAA, 0x2E,
550       0x4E, 0xAD, 0xB2, 0x17, 0xAD, 0x8C, 0xC0, 0x9B }
551 };
552 
553 /*
554  * Checkup routine
555  */
mbedtls_sha512_self_test(int verbose)556 int mbedtls_sha512_self_test( int verbose )
557 {
558     int i, j, k, buflen, ret = 0;
559     unsigned char *buf;
560     unsigned char sha512sum[64];
561     mbedtls_sha512_context ctx;
562 
563     buf = mbedtls_calloc( 1024, sizeof(unsigned char) );
564     if( NULL == buf )
565     {
566         if( verbose != 0 )
567             mbedtls_printf( "Buffer allocation failed\n" );
568 
569         return( 1 );
570     }
571 
572     mbedtls_sha512_init( &ctx );
573 
574     for( i = 0; i < 6; i++ )
575     {
576         j = i % 3;
577         k = i < 3;
578 
579         if( verbose != 0 )
580             mbedtls_printf( "  SHA-%d test #%d: ", 512 - k * 128, j + 1 );
581 
582         if( ( ret = mbedtls_sha512_starts_ret( &ctx, k ) ) != 0 )
583             goto fail;
584 
585         if( j == 2 )
586         {
587             memset( buf, 'a', buflen = 1000 );
588 
589             for( j = 0; j < 1000; j++ )
590             {
591                 ret = mbedtls_sha512_update_ret( &ctx, buf, buflen );
592                 if( ret != 0 )
593                     goto fail;
594             }
595         }
596         else
597         {
598             ret = mbedtls_sha512_update_ret( &ctx, sha512_test_buf[j],
599                                              sha512_test_buflen[j] );
600             if( ret != 0 )
601                 goto fail;
602         }
603 
604         if( ( ret = mbedtls_sha512_finish_ret( &ctx, sha512sum ) ) != 0 )
605             goto fail;
606 
607         if( memcmp( sha512sum, sha512_test_sum[i], 64 - k * 16 ) != 0 )
608         {
609             ret = 1;
610             goto fail;
611         }
612 
613         if( verbose != 0 )
614             mbedtls_printf( "passed\n" );
615     }
616 
617     if( verbose != 0 )
618         mbedtls_printf( "\n" );
619 
620     goto exit;
621 
622 fail:
623     if( verbose != 0 )
624         mbedtls_printf( "failed\n" );
625 
626 exit:
627     mbedtls_sha512_free( &ctx );
628     mbedtls_free( buf );
629 
630     return( ret );
631 }
632 
633 #endif /* MBEDTLS_SELF_TEST */
634 
635 #endif /* MBEDTLS_SHA512_C */
636