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 */
mbedtls_zeroize(void * v,size_t n)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 
mbedtls_sha512_init(mbedtls_sha512_context * ctx)95 void mbedtls_sha512_init( mbedtls_sha512_context *ctx )
96 {
97     memset( ctx, 0, sizeof( mbedtls_sha512_context ) );
98 }
99 
mbedtls_sha512_free(mbedtls_sha512_context * ctx)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 
mbedtls_sha512_clone(mbedtls_sha512_context * dst,const mbedtls_sha512_context * src)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  */
mbedtls_sha512_starts(mbedtls_sha512_context * ctx,int is384)117 void mbedtls_sha512_starts( 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 
150 #if !defined(MBEDTLS_SHA512_PROCESS_ALT)
151 
152 /*
153  * Round constants
154  */
155 static const uint64_t K[80] =
156 {
157     UL64(0x428A2F98D728AE22),  UL64(0x7137449123EF65CD),
158     UL64(0xB5C0FBCFEC4D3B2F),  UL64(0xE9B5DBA58189DBBC),
159     UL64(0x3956C25BF348B538),  UL64(0x59F111F1B605D019),
160     UL64(0x923F82A4AF194F9B),  UL64(0xAB1C5ED5DA6D8118),
161     UL64(0xD807AA98A3030242),  UL64(0x12835B0145706FBE),
162     UL64(0x243185BE4EE4B28C),  UL64(0x550C7DC3D5FFB4E2),
163     UL64(0x72BE5D74F27B896F),  UL64(0x80DEB1FE3B1696B1),
164     UL64(0x9BDC06A725C71235),  UL64(0xC19BF174CF692694),
165     UL64(0xE49B69C19EF14AD2),  UL64(0xEFBE4786384F25E3),
166     UL64(0x0FC19DC68B8CD5B5),  UL64(0x240CA1CC77AC9C65),
167     UL64(0x2DE92C6F592B0275),  UL64(0x4A7484AA6EA6E483),
168     UL64(0x5CB0A9DCBD41FBD4),  UL64(0x76F988DA831153B5),
169     UL64(0x983E5152EE66DFAB),  UL64(0xA831C66D2DB43210),
170     UL64(0xB00327C898FB213F),  UL64(0xBF597FC7BEEF0EE4),
171     UL64(0xC6E00BF33DA88FC2),  UL64(0xD5A79147930AA725),
172     UL64(0x06CA6351E003826F),  UL64(0x142929670A0E6E70),
173     UL64(0x27B70A8546D22FFC),  UL64(0x2E1B21385C26C926),
174     UL64(0x4D2C6DFC5AC42AED),  UL64(0x53380D139D95B3DF),
175     UL64(0x650A73548BAF63DE),  UL64(0x766A0ABB3C77B2A8),
176     UL64(0x81C2C92E47EDAEE6),  UL64(0x92722C851482353B),
177     UL64(0xA2BFE8A14CF10364),  UL64(0xA81A664BBC423001),
178     UL64(0xC24B8B70D0F89791),  UL64(0xC76C51A30654BE30),
179     UL64(0xD192E819D6EF5218),  UL64(0xD69906245565A910),
180     UL64(0xF40E35855771202A),  UL64(0x106AA07032BBD1B8),
181     UL64(0x19A4C116B8D2D0C8),  UL64(0x1E376C085141AB53),
182     UL64(0x2748774CDF8EEB99),  UL64(0x34B0BCB5E19B48A8),
183     UL64(0x391C0CB3C5C95A63),  UL64(0x4ED8AA4AE3418ACB),
184     UL64(0x5B9CCA4F7763E373),  UL64(0x682E6FF3D6B2B8A3),
185     UL64(0x748F82EE5DEFB2FC),  UL64(0x78A5636F43172F60),
186     UL64(0x84C87814A1F0AB72),  UL64(0x8CC702081A6439EC),
187     UL64(0x90BEFFFA23631E28),  UL64(0xA4506CEBDE82BDE9),
188     UL64(0xBEF9A3F7B2C67915),  UL64(0xC67178F2E372532B),
189     UL64(0xCA273ECEEA26619C),  UL64(0xD186B8C721C0C207),
190     UL64(0xEADA7DD6CDE0EB1E),  UL64(0xF57D4F7FEE6ED178),
191     UL64(0x06F067AA72176FBA),  UL64(0x0A637DC5A2C898A6),
192     UL64(0x113F9804BEF90DAE),  UL64(0x1B710B35131C471B),
193     UL64(0x28DB77F523047D84),  UL64(0x32CAAB7B40C72493),
194     UL64(0x3C9EBE0A15C9BEBC),  UL64(0x431D67C49C100D4C),
195     UL64(0x4CC5D4BECB3E42B6),  UL64(0x597F299CFC657E2A),
196     UL64(0x5FCB6FAB3AD6FAEC),  UL64(0x6C44198C4A475817)
197 };
198 
mbedtls_sha512_process(mbedtls_sha512_context * ctx,const unsigned char data[128])199 void mbedtls_sha512_process( mbedtls_sha512_context *ctx, const unsigned char data[128] )
200 {
201     int i;
202     uint64_t temp1, temp2, W[80];
203     uint64_t A, B, C, D, E, F, G, H;
204 
205 #define  SHR(x,n) (x >> n)
206 #define ROTR(x,n) (SHR(x,n) | (x << (64 - n)))
207 
208 #define S0(x) (ROTR(x, 1) ^ ROTR(x, 8) ^  SHR(x, 7))
209 #define S1(x) (ROTR(x,19) ^ ROTR(x,61) ^  SHR(x, 6))
210 
211 #define S2(x) (ROTR(x,28) ^ ROTR(x,34) ^ ROTR(x,39))
212 #define S3(x) (ROTR(x,14) ^ ROTR(x,18) ^ ROTR(x,41))
213 
214 #define F0(x,y,z) ((x & y) | (z & (x | y)))
215 #define F1(x,y,z) (z ^ (x & (y ^ z)))
216 
217 #define P(a,b,c,d,e,f,g,h,x,K)                  \
218 {                                               \
219     temp1 = h + S3(e) + F1(e,f,g) + K + x;      \
220     temp2 = S2(a) + F0(a,b,c);                  \
221     d += temp1; h = temp1 + temp2;              \
222 }
223 
224     for( i = 0; i < 16; i++ )
225     {
226         GET_UINT64_BE( W[i], data, i << 3 );
227     }
228 
229     for( ; i < 80; i++ )
230     {
231         W[i] = S1(W[i -  2]) + W[i -  7] +
232                S0(W[i - 15]) + W[i - 16];
233     }
234 
235     A = ctx->state[0];
236     B = ctx->state[1];
237     C = ctx->state[2];
238     D = ctx->state[3];
239     E = ctx->state[4];
240     F = ctx->state[5];
241     G = ctx->state[6];
242     H = ctx->state[7];
243     i = 0;
244 
245     do
246     {
247         P( A, B, C, D, E, F, G, H, W[i], K[i] ); i++;
248         P( H, A, B, C, D, E, F, G, W[i], K[i] ); i++;
249         P( G, H, A, B, C, D, E, F, W[i], K[i] ); i++;
250         P( F, G, H, A, B, C, D, E, W[i], K[i] ); i++;
251         P( E, F, G, H, A, B, C, D, W[i], K[i] ); i++;
252         P( D, E, F, G, H, A, B, C, W[i], K[i] ); i++;
253         P( C, D, E, F, G, H, A, B, W[i], K[i] ); i++;
254         P( B, C, D, E, F, G, H, A, W[i], K[i] ); i++;
255     }
256     while( i < 80 );
257 
258     ctx->state[0] += A;
259     ctx->state[1] += B;
260     ctx->state[2] += C;
261     ctx->state[3] += D;
262     ctx->state[4] += E;
263     ctx->state[5] += F;
264     ctx->state[6] += G;
265     ctx->state[7] += H;
266 }
267 #endif /* !MBEDTLS_SHA512_PROCESS_ALT */
268 
269 /*
270  * SHA-512 process buffer
271  */
mbedtls_sha512_update(mbedtls_sha512_context * ctx,const unsigned char * input,size_t ilen)272 void mbedtls_sha512_update( mbedtls_sha512_context *ctx, const unsigned char *input,
273                     size_t ilen )
274 {
275     size_t fill;
276     unsigned int left;
277 
278     if( ilen == 0 )
279         return;
280 
281     left = (unsigned int) (ctx->total[0] & 0x7F);
282     fill = 128 - left;
283 
284     ctx->total[0] += (uint64_t) ilen;
285 
286     if( ctx->total[0] < (uint64_t) ilen )
287         ctx->total[1]++;
288 
289     if( left && ilen >= fill )
290     {
291         memcpy( (void *) (ctx->buffer + left), input, fill );
292         mbedtls_sha512_process( ctx, ctx->buffer );
293         input += fill;
294         ilen  -= fill;
295         left = 0;
296     }
297 
298     while( ilen >= 128 )
299     {
300         mbedtls_sha512_process( ctx, input );
301         input += 128;
302         ilen  -= 128;
303     }
304 
305     if( ilen > 0 )
306         memcpy( (void *) (ctx->buffer + left), input, ilen );
307 }
308 
309 static const unsigned char sha512_padding[128] =
310 {
311  0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
312     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
313     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
314     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
315     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
316     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
317     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
318     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
319 };
320 
321 /*
322  * SHA-512 final digest
323  */
mbedtls_sha512_finish(mbedtls_sha512_context * ctx,unsigned char output[64])324 void mbedtls_sha512_finish( mbedtls_sha512_context *ctx, unsigned char output[64] )
325 {
326     size_t last, padn;
327     uint64_t high, low;
328     unsigned char msglen[16];
329 
330     high = ( ctx->total[0] >> 61 )
331          | ( ctx->total[1] <<  3 );
332     low  = ( ctx->total[0] <<  3 );
333 
334     PUT_UINT64_BE( high, msglen, 0 );
335     PUT_UINT64_BE( low,  msglen, 8 );
336 
337     last = (size_t)( ctx->total[0] & 0x7F );
338     padn = ( last < 112 ) ? ( 112 - last ) : ( 240 - last );
339 
340     mbedtls_sha512_update( ctx, sha512_padding, padn );
341     mbedtls_sha512_update( ctx, msglen, 16 );
342 
343     PUT_UINT64_BE( ctx->state[0], output,  0 );
344     PUT_UINT64_BE( ctx->state[1], output,  8 );
345     PUT_UINT64_BE( ctx->state[2], output, 16 );
346     PUT_UINT64_BE( ctx->state[3], output, 24 );
347     PUT_UINT64_BE( ctx->state[4], output, 32 );
348     PUT_UINT64_BE( ctx->state[5], output, 40 );
349 
350     if( ctx->is384 == 0 )
351     {
352         PUT_UINT64_BE( ctx->state[6], output, 48 );
353         PUT_UINT64_BE( ctx->state[7], output, 56 );
354     }
355 }
356 
357 #endif /* !MBEDTLS_SHA512_ALT */
358 
359 /*
360  * output = SHA-512( input buffer )
361  */
mbedtls_sha512(const unsigned char * input,size_t ilen,unsigned char output[64],int is384)362 void mbedtls_sha512( const unsigned char *input, size_t ilen,
363              unsigned char output[64], int is384 )
364 {
365     mbedtls_sha512_context ctx;
366 
367     mbedtls_sha512_init( &ctx );
368     mbedtls_sha512_starts( &ctx, is384 );
369     mbedtls_sha512_update( &ctx, input, ilen );
370     mbedtls_sha512_finish( &ctx, output );
371     mbedtls_sha512_free( &ctx );
372 }
373 
374 #if defined(MBEDTLS_SELF_TEST)
375 
376 /*
377  * FIPS-180-2 test vectors
378  */
379 static const unsigned char sha512_test_buf[3][113] =
380 {
381     { "abc" },
382     { "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"
383       "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu" },
384     { "" }
385 };
386 
387 static const int sha512_test_buflen[3] =
388 {
389     3, 112, 1000
390 };
391 
392 static const unsigned char sha512_test_sum[6][64] =
393 {
394     /*
395      * SHA-384 test vectors
396      */
397     { 0xCB, 0x00, 0x75, 0x3F, 0x45, 0xA3, 0x5E, 0x8B,
398       0xB5, 0xA0, 0x3D, 0x69, 0x9A, 0xC6, 0x50, 0x07,
399       0x27, 0x2C, 0x32, 0xAB, 0x0E, 0xDE, 0xD1, 0x63,
400       0x1A, 0x8B, 0x60, 0x5A, 0x43, 0xFF, 0x5B, 0xED,
401       0x80, 0x86, 0x07, 0x2B, 0xA1, 0xE7, 0xCC, 0x23,
402       0x58, 0xBA, 0xEC, 0xA1, 0x34, 0xC8, 0x25, 0xA7 },
403     { 0x09, 0x33, 0x0C, 0x33, 0xF7, 0x11, 0x47, 0xE8,
404       0x3D, 0x19, 0x2F, 0xC7, 0x82, 0xCD, 0x1B, 0x47,
405       0x53, 0x11, 0x1B, 0x17, 0x3B, 0x3B, 0x05, 0xD2,
406       0x2F, 0xA0, 0x80, 0x86, 0xE3, 0xB0, 0xF7, 0x12,
407       0xFC, 0xC7, 0xC7, 0x1A, 0x55, 0x7E, 0x2D, 0xB9,
408       0x66, 0xC3, 0xE9, 0xFA, 0x91, 0x74, 0x60, 0x39 },
409     { 0x9D, 0x0E, 0x18, 0x09, 0x71, 0x64, 0x74, 0xCB,
410       0x08, 0x6E, 0x83, 0x4E, 0x31, 0x0A, 0x4A, 0x1C,
411       0xED, 0x14, 0x9E, 0x9C, 0x00, 0xF2, 0x48, 0x52,
412       0x79, 0x72, 0xCE, 0xC5, 0x70, 0x4C, 0x2A, 0x5B,
413       0x07, 0xB8, 0xB3, 0xDC, 0x38, 0xEC, 0xC4, 0xEB,
414       0xAE, 0x97, 0xDD, 0xD8, 0x7F, 0x3D, 0x89, 0x85 },
415 
416     /*
417      * SHA-512 test vectors
418      */
419     { 0xDD, 0xAF, 0x35, 0xA1, 0x93, 0x61, 0x7A, 0xBA,
420       0xCC, 0x41, 0x73, 0x49, 0xAE, 0x20, 0x41, 0x31,
421       0x12, 0xE6, 0xFA, 0x4E, 0x89, 0xA9, 0x7E, 0xA2,
422       0x0A, 0x9E, 0xEE, 0xE6, 0x4B, 0x55, 0xD3, 0x9A,
423       0x21, 0x92, 0x99, 0x2A, 0x27, 0x4F, 0xC1, 0xA8,
424       0x36, 0xBA, 0x3C, 0x23, 0xA3, 0xFE, 0xEB, 0xBD,
425       0x45, 0x4D, 0x44, 0x23, 0x64, 0x3C, 0xE8, 0x0E,
426       0x2A, 0x9A, 0xC9, 0x4F, 0xA5, 0x4C, 0xA4, 0x9F },
427     { 0x8E, 0x95, 0x9B, 0x75, 0xDA, 0xE3, 0x13, 0xDA,
428       0x8C, 0xF4, 0xF7, 0x28, 0x14, 0xFC, 0x14, 0x3F,
429       0x8F, 0x77, 0x79, 0xC6, 0xEB, 0x9F, 0x7F, 0xA1,
430       0x72, 0x99, 0xAE, 0xAD, 0xB6, 0x88, 0x90, 0x18,
431       0x50, 0x1D, 0x28, 0x9E, 0x49, 0x00, 0xF7, 0xE4,
432       0x33, 0x1B, 0x99, 0xDE, 0xC4, 0xB5, 0x43, 0x3A,
433       0xC7, 0xD3, 0x29, 0xEE, 0xB6, 0xDD, 0x26, 0x54,
434       0x5E, 0x96, 0xE5, 0x5B, 0x87, 0x4B, 0xE9, 0x09 },
435     { 0xE7, 0x18, 0x48, 0x3D, 0x0C, 0xE7, 0x69, 0x64,
436       0x4E, 0x2E, 0x42, 0xC7, 0xBC, 0x15, 0xB4, 0x63,
437       0x8E, 0x1F, 0x98, 0xB1, 0x3B, 0x20, 0x44, 0x28,
438       0x56, 0x32, 0xA8, 0x03, 0xAF, 0xA9, 0x73, 0xEB,
439       0xDE, 0x0F, 0xF2, 0x44, 0x87, 0x7E, 0xA6, 0x0A,
440       0x4C, 0xB0, 0x43, 0x2C, 0xE5, 0x77, 0xC3, 0x1B,
441       0xEB, 0x00, 0x9C, 0x5C, 0x2C, 0x49, 0xAA, 0x2E,
442       0x4E, 0xAD, 0xB2, 0x17, 0xAD, 0x8C, 0xC0, 0x9B }
443 };
444 
445 /*
446  * Checkup routine
447  */
mbedtls_sha512_self_test(int verbose)448 int mbedtls_sha512_self_test( int verbose )
449 {
450     int i, j, k, buflen, ret = 0;
451     unsigned char *buf;
452     unsigned char sha512sum[64];
453     mbedtls_sha512_context ctx;
454 
455     buf = mbedtls_calloc( 1024, sizeof(unsigned char) );
456     if( NULL == buf )
457     {
458         if( verbose != 0 )
459             mbedtls_printf( "Buffer allocation failed\n" );
460 
461         return( 1 );
462     }
463 
464     mbedtls_sha512_init( &ctx );
465 
466     for( i = 0; i < 6; i++ )
467     {
468         j = i % 3;
469         k = i < 3;
470 
471         if( verbose != 0 )
472             mbedtls_printf( "  SHA-%d test #%d: ", 512 - k * 128, j + 1 );
473 
474         mbedtls_sha512_starts( &ctx, k );
475 
476         if( j == 2 )
477         {
478             memset( buf, 'a', buflen = 1000 );
479 
480             for( j = 0; j < 1000; j++ )
481                 mbedtls_sha512_update( &ctx, buf, buflen );
482         }
483         else
484             mbedtls_sha512_update( &ctx, sha512_test_buf[j],
485                                  sha512_test_buflen[j] );
486 
487         mbedtls_sha512_finish( &ctx, sha512sum );
488 
489         if( memcmp( sha512sum, sha512_test_sum[i], 64 - k * 16 ) != 0 )
490         {
491             if( verbose != 0 )
492                 mbedtls_printf( "failed\n" );
493 
494             ret = 1;
495             goto exit;
496         }
497 
498         if( verbose != 0 )
499             mbedtls_printf( "passed\n" );
500     }
501 
502     if( verbose != 0 )
503         mbedtls_printf( "\n" );
504 
505 exit:
506     mbedtls_sha512_free( &ctx );
507     mbedtls_free( buf );
508 
509     return( ret );
510 }
511 
512 #endif /* MBEDTLS_SELF_TEST */
513 
514 #endif /* MBEDTLS_SHA512_C */
515