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