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