xref: /reactos/dll/3rdparty/mbedtls/sha512.c (revision 84ccccab)
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: GPL-2.0
6  *
7  *  This program is free software; you can redistribute it and/or modify
8  *  it under the terms of the GNU General Public License as published by
9  *  the Free Software Foundation; either version 2 of the License, or
10  *  (at your option) any later version.
11  *
12  *  This program is distributed in the hope that it will be useful,
13  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  *  GNU General Public License for more details.
16  *
17  *  You should have received a copy of the GNU General Public License along
18  *  with this program; if not, write to the Free Software Foundation, Inc.,
19  *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20  *
21  *  This file is part of mbed TLS (https://tls.mbed.org)
22  */
23 /*
24  *  The SHA-512 Secure Hash Standard was published by NIST in 2002.
25  *
26  *  http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf
27  */
28 
29 #if !defined(MBEDTLS_CONFIG_FILE)
30 #include "mbedtls/config.h"
31 #else
32 #include MBEDTLS_CONFIG_FILE
33 #endif
34 
35 #if defined(MBEDTLS_SHA512_C)
36 
37 #include "mbedtls/sha512.h"
38 
39 #if defined(_MSC_VER) || defined(__WATCOMC__)
40   #define UL64(x) x##ui64
41 #else
42   #define UL64(x) x##ULL
43 #endif
44 
45 #include <string.h>
46 
47 #if defined(MBEDTLS_SELF_TEST)
48 #if defined(MBEDTLS_PLATFORM_C)
49 #include "mbedtls/platform.h"
50 #else
51 #include <stdio.h>
52 #include <stdlib.h>
53 #define mbedtls_printf printf
54 #define mbedtls_calloc    calloc
55 #define mbedtls_free       free
56 #endif /* MBEDTLS_PLATFORM_C */
57 #endif /* MBEDTLS_SELF_TEST */
58 
59 #if !defined(MBEDTLS_SHA512_ALT)
60 
61 /* Implementation that should never be optimized out by the compiler */
62 static void mbedtls_zeroize( void *v, size_t n ) {
63     volatile unsigned char *p = v; while( n-- ) *p++ = 0;
64 }
65 
66 /*
67  * 64-bit integer manipulation macros (big endian)
68  */
69 #ifndef GET_UINT64_BE
70 #define GET_UINT64_BE(n,b,i)                            \
71 {                                                       \
72     (n) = ( (uint64_t) (b)[(i)    ] << 56 )       \
73         | ( (uint64_t) (b)[(i) + 1] << 48 )       \
74         | ( (uint64_t) (b)[(i) + 2] << 40 )       \
75         | ( (uint64_t) (b)[(i) + 3] << 32 )       \
76         | ( (uint64_t) (b)[(i) + 4] << 24 )       \
77         | ( (uint64_t) (b)[(i) + 5] << 16 )       \
78         | ( (uint64_t) (b)[(i) + 6] <<  8 )       \
79         | ( (uint64_t) (b)[(i) + 7]       );      \
80 }
81 #endif /* GET_UINT64_BE */
82 
83 #ifndef PUT_UINT64_BE
84 #define PUT_UINT64_BE(n,b,i)                            \
85 {                                                       \
86     (b)[(i)    ] = (unsigned char) ( (n) >> 56 );       \
87     (b)[(i) + 1] = (unsigned char) ( (n) >> 48 );       \
88     (b)[(i) + 2] = (unsigned char) ( (n) >> 40 );       \
89     (b)[(i) + 3] = (unsigned char) ( (n) >> 32 );       \
90     (b)[(i) + 4] = (unsigned char) ( (n) >> 24 );       \
91     (b)[(i) + 5] = (unsigned char) ( (n) >> 16 );       \
92     (b)[(i) + 6] = (unsigned char) ( (n) >>  8 );       \
93     (b)[(i) + 7] = (unsigned char) ( (n)       );       \
94 }
95 #endif /* PUT_UINT64_BE */
96 
97 void mbedtls_sha512_init( mbedtls_sha512_context *ctx )
98 {
99     memset( ctx, 0, sizeof( mbedtls_sha512_context ) );
100 }
101 
102 void mbedtls_sha512_free( mbedtls_sha512_context *ctx )
103 {
104     if( ctx == NULL )
105         return;
106 
107     mbedtls_zeroize( ctx, sizeof( mbedtls_sha512_context ) );
108 }
109 
110 void mbedtls_sha512_clone( mbedtls_sha512_context *dst,
111                            const mbedtls_sha512_context *src )
112 {
113     *dst = *src;
114 }
115 
116 /*
117  * SHA-512 context setup
118  */
119 void mbedtls_sha512_starts( mbedtls_sha512_context *ctx, int is384 )
120 {
121     ctx->total[0] = 0;
122     ctx->total[1] = 0;
123 
124     if( is384 == 0 )
125     {
126         /* SHA-512 */
127         ctx->state[0] = UL64(0x6A09E667F3BCC908);
128         ctx->state[1] = UL64(0xBB67AE8584CAA73B);
129         ctx->state[2] = UL64(0x3C6EF372FE94F82B);
130         ctx->state[3] = UL64(0xA54FF53A5F1D36F1);
131         ctx->state[4] = UL64(0x510E527FADE682D1);
132         ctx->state[5] = UL64(0x9B05688C2B3E6C1F);
133         ctx->state[6] = UL64(0x1F83D9ABFB41BD6B);
134         ctx->state[7] = UL64(0x5BE0CD19137E2179);
135     }
136     else
137     {
138         /* SHA-384 */
139         ctx->state[0] = UL64(0xCBBB9D5DC1059ED8);
140         ctx->state[1] = UL64(0x629A292A367CD507);
141         ctx->state[2] = UL64(0x9159015A3070DD17);
142         ctx->state[3] = UL64(0x152FECD8F70E5939);
143         ctx->state[4] = UL64(0x67332667FFC00B31);
144         ctx->state[5] = UL64(0x8EB44A8768581511);
145         ctx->state[6] = UL64(0xDB0C2E0D64F98FA7);
146         ctx->state[7] = UL64(0x47B5481DBEFA4FA4);
147     }
148 
149     ctx->is384 = is384;
150 }
151 
152 #if !defined(MBEDTLS_SHA512_PROCESS_ALT)
153 
154 /*
155  * Round constants
156  */
157 static const uint64_t K[80] =
158 {
159     UL64(0x428A2F98D728AE22),  UL64(0x7137449123EF65CD),
160     UL64(0xB5C0FBCFEC4D3B2F),  UL64(0xE9B5DBA58189DBBC),
161     UL64(0x3956C25BF348B538),  UL64(0x59F111F1B605D019),
162     UL64(0x923F82A4AF194F9B),  UL64(0xAB1C5ED5DA6D8118),
163     UL64(0xD807AA98A3030242),  UL64(0x12835B0145706FBE),
164     UL64(0x243185BE4EE4B28C),  UL64(0x550C7DC3D5FFB4E2),
165     UL64(0x72BE5D74F27B896F),  UL64(0x80DEB1FE3B1696B1),
166     UL64(0x9BDC06A725C71235),  UL64(0xC19BF174CF692694),
167     UL64(0xE49B69C19EF14AD2),  UL64(0xEFBE4786384F25E3),
168     UL64(0x0FC19DC68B8CD5B5),  UL64(0x240CA1CC77AC9C65),
169     UL64(0x2DE92C6F592B0275),  UL64(0x4A7484AA6EA6E483),
170     UL64(0x5CB0A9DCBD41FBD4),  UL64(0x76F988DA831153B5),
171     UL64(0x983E5152EE66DFAB),  UL64(0xA831C66D2DB43210),
172     UL64(0xB00327C898FB213F),  UL64(0xBF597FC7BEEF0EE4),
173     UL64(0xC6E00BF33DA88FC2),  UL64(0xD5A79147930AA725),
174     UL64(0x06CA6351E003826F),  UL64(0x142929670A0E6E70),
175     UL64(0x27B70A8546D22FFC),  UL64(0x2E1B21385C26C926),
176     UL64(0x4D2C6DFC5AC42AED),  UL64(0x53380D139D95B3DF),
177     UL64(0x650A73548BAF63DE),  UL64(0x766A0ABB3C77B2A8),
178     UL64(0x81C2C92E47EDAEE6),  UL64(0x92722C851482353B),
179     UL64(0xA2BFE8A14CF10364),  UL64(0xA81A664BBC423001),
180     UL64(0xC24B8B70D0F89791),  UL64(0xC76C51A30654BE30),
181     UL64(0xD192E819D6EF5218),  UL64(0xD69906245565A910),
182     UL64(0xF40E35855771202A),  UL64(0x106AA07032BBD1B8),
183     UL64(0x19A4C116B8D2D0C8),  UL64(0x1E376C085141AB53),
184     UL64(0x2748774CDF8EEB99),  UL64(0x34B0BCB5E19B48A8),
185     UL64(0x391C0CB3C5C95A63),  UL64(0x4ED8AA4AE3418ACB),
186     UL64(0x5B9CCA4F7763E373),  UL64(0x682E6FF3D6B2B8A3),
187     UL64(0x748F82EE5DEFB2FC),  UL64(0x78A5636F43172F60),
188     UL64(0x84C87814A1F0AB72),  UL64(0x8CC702081A6439EC),
189     UL64(0x90BEFFFA23631E28),  UL64(0xA4506CEBDE82BDE9),
190     UL64(0xBEF9A3F7B2C67915),  UL64(0xC67178F2E372532B),
191     UL64(0xCA273ECEEA26619C),  UL64(0xD186B8C721C0C207),
192     UL64(0xEADA7DD6CDE0EB1E),  UL64(0xF57D4F7FEE6ED178),
193     UL64(0x06F067AA72176FBA),  UL64(0x0A637DC5A2C898A6),
194     UL64(0x113F9804BEF90DAE),  UL64(0x1B710B35131C471B),
195     UL64(0x28DB77F523047D84),  UL64(0x32CAAB7B40C72493),
196     UL64(0x3C9EBE0A15C9BEBC),  UL64(0x431D67C49C100D4C),
197     UL64(0x4CC5D4BECB3E42B6),  UL64(0x597F299CFC657E2A),
198     UL64(0x5FCB6FAB3AD6FAEC),  UL64(0x6C44198C4A475817)
199 };
200 
201 void mbedtls_sha512_process( mbedtls_sha512_context *ctx, const unsigned char data[128] )
202 {
203     int i;
204     uint64_t temp1, temp2, W[80];
205     uint64_t A, B, C, D, E, F, G, H;
206 
207 #define  SHR(x,n) (x >> n)
208 #define ROTR(x,n) (SHR(x,n) | (x << (64 - n)))
209 
210 #define S0(x) (ROTR(x, 1) ^ ROTR(x, 8) ^  SHR(x, 7))
211 #define S1(x) (ROTR(x,19) ^ ROTR(x,61) ^  SHR(x, 6))
212 
213 #define S2(x) (ROTR(x,28) ^ ROTR(x,34) ^ ROTR(x,39))
214 #define S3(x) (ROTR(x,14) ^ ROTR(x,18) ^ ROTR(x,41))
215 
216 #define F0(x,y,z) ((x & y) | (z & (x | y)))
217 #define F1(x,y,z) (z ^ (x & (y ^ z)))
218 
219 #define P(a,b,c,d,e,f,g,h,x,K)                  \
220 {                                               \
221     temp1 = h + S3(e) + F1(e,f,g) + K + x;      \
222     temp2 = S2(a) + F0(a,b,c);                  \
223     d += temp1; h = temp1 + temp2;              \
224 }
225 
226     for( i = 0; i < 16; i++ )
227     {
228         GET_UINT64_BE( W[i], data, i << 3 );
229     }
230 
231     for( ; i < 80; i++ )
232     {
233         W[i] = S1(W[i -  2]) + W[i -  7] +
234                S0(W[i - 15]) + W[i - 16];
235     }
236 
237     A = ctx->state[0];
238     B = ctx->state[1];
239     C = ctx->state[2];
240     D = ctx->state[3];
241     E = ctx->state[4];
242     F = ctx->state[5];
243     G = ctx->state[6];
244     H = ctx->state[7];
245     i = 0;
246 
247     do
248     {
249         P( A, B, C, D, E, F, G, H, W[i], K[i] ); i++;
250         P( H, A, B, C, D, E, F, G, W[i], K[i] ); i++;
251         P( G, H, A, B, C, D, E, F, W[i], K[i] ); i++;
252         P( F, G, H, A, B, C, D, E, W[i], K[i] ); i++;
253         P( E, F, G, H, A, B, C, D, W[i], K[i] ); i++;
254         P( D, E, F, G, H, A, B, C, W[i], K[i] ); i++;
255         P( C, D, E, F, G, H, A, B, W[i], K[i] ); i++;
256         P( B, C, D, E, F, G, H, A, W[i], K[i] ); i++;
257     }
258     while( i < 80 );
259 
260     ctx->state[0] += A;
261     ctx->state[1] += B;
262     ctx->state[2] += C;
263     ctx->state[3] += D;
264     ctx->state[4] += E;
265     ctx->state[5] += F;
266     ctx->state[6] += G;
267     ctx->state[7] += H;
268 }
269 #endif /* !MBEDTLS_SHA512_PROCESS_ALT */
270 
271 /*
272  * SHA-512 process buffer
273  */
274 void mbedtls_sha512_update( mbedtls_sha512_context *ctx, const unsigned char *input,
275                     size_t ilen )
276 {
277     size_t fill;
278     unsigned int left;
279 
280     if( ilen == 0 )
281         return;
282 
283     left = (unsigned int) (ctx->total[0] & 0x7F);
284     fill = 128 - left;
285 
286     ctx->total[0] += (uint64_t) ilen;
287 
288     if( ctx->total[0] < (uint64_t) ilen )
289         ctx->total[1]++;
290 
291     if( left && ilen >= fill )
292     {
293         memcpy( (void *) (ctx->buffer + left), input, fill );
294         mbedtls_sha512_process( ctx, ctx->buffer );
295         input += fill;
296         ilen  -= fill;
297         left = 0;
298     }
299 
300     while( ilen >= 128 )
301     {
302         mbedtls_sha512_process( ctx, input );
303         input += 128;
304         ilen  -= 128;
305     }
306 
307     if( ilen > 0 )
308         memcpy( (void *) (ctx->buffer + left), input, ilen );
309 }
310 
311 static const unsigned char sha512_padding[128] =
312 {
313  0x80, 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     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
320     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
321 };
322 
323 /*
324  * SHA-512 final digest
325  */
326 void mbedtls_sha512_finish( mbedtls_sha512_context *ctx, unsigned char output[64] )
327 {
328     size_t last, padn;
329     uint64_t high, low;
330     unsigned char msglen[16];
331 
332     high = ( ctx->total[0] >> 61 )
333          | ( ctx->total[1] <<  3 );
334     low  = ( ctx->total[0] <<  3 );
335 
336     PUT_UINT64_BE( high, msglen, 0 );
337     PUT_UINT64_BE( low,  msglen, 8 );
338 
339     last = (size_t)( ctx->total[0] & 0x7F );
340     padn = ( last < 112 ) ? ( 112 - last ) : ( 240 - last );
341 
342     mbedtls_sha512_update( ctx, sha512_padding, padn );
343     mbedtls_sha512_update( ctx, msglen, 16 );
344 
345     PUT_UINT64_BE( ctx->state[0], output,  0 );
346     PUT_UINT64_BE( ctx->state[1], output,  8 );
347     PUT_UINT64_BE( ctx->state[2], output, 16 );
348     PUT_UINT64_BE( ctx->state[3], output, 24 );
349     PUT_UINT64_BE( ctx->state[4], output, 32 );
350     PUT_UINT64_BE( ctx->state[5], output, 40 );
351 
352     if( ctx->is384 == 0 )
353     {
354         PUT_UINT64_BE( ctx->state[6], output, 48 );
355         PUT_UINT64_BE( ctx->state[7], output, 56 );
356     }
357 }
358 
359 #endif /* !MBEDTLS_SHA512_ALT */
360 
361 /*
362  * output = SHA-512( input buffer )
363  */
364 void mbedtls_sha512( const unsigned char *input, size_t ilen,
365              unsigned char output[64], int is384 )
366 {
367     mbedtls_sha512_context ctx;
368 
369     mbedtls_sha512_init( &ctx );
370     mbedtls_sha512_starts( &ctx, is384 );
371     mbedtls_sha512_update( &ctx, input, ilen );
372     mbedtls_sha512_finish( &ctx, output );
373     mbedtls_sha512_free( &ctx );
374 }
375 
376 #if defined(MBEDTLS_SELF_TEST)
377 
378 /*
379  * FIPS-180-2 test vectors
380  */
381 static const unsigned char sha512_test_buf[3][113] =
382 {
383     { "abc" },
384     { "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"
385       "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu" },
386     { "" }
387 };
388 
389 static const int sha512_test_buflen[3] =
390 {
391     3, 112, 1000
392 };
393 
394 static const unsigned char sha512_test_sum[6][64] =
395 {
396     /*
397      * SHA-384 test vectors
398      */
399     { 0xCB, 0x00, 0x75, 0x3F, 0x45, 0xA3, 0x5E, 0x8B,
400       0xB5, 0xA0, 0x3D, 0x69, 0x9A, 0xC6, 0x50, 0x07,
401       0x27, 0x2C, 0x32, 0xAB, 0x0E, 0xDE, 0xD1, 0x63,
402       0x1A, 0x8B, 0x60, 0x5A, 0x43, 0xFF, 0x5B, 0xED,
403       0x80, 0x86, 0x07, 0x2B, 0xA1, 0xE7, 0xCC, 0x23,
404       0x58, 0xBA, 0xEC, 0xA1, 0x34, 0xC8, 0x25, 0xA7 },
405     { 0x09, 0x33, 0x0C, 0x33, 0xF7, 0x11, 0x47, 0xE8,
406       0x3D, 0x19, 0x2F, 0xC7, 0x82, 0xCD, 0x1B, 0x47,
407       0x53, 0x11, 0x1B, 0x17, 0x3B, 0x3B, 0x05, 0xD2,
408       0x2F, 0xA0, 0x80, 0x86, 0xE3, 0xB0, 0xF7, 0x12,
409       0xFC, 0xC7, 0xC7, 0x1A, 0x55, 0x7E, 0x2D, 0xB9,
410       0x66, 0xC3, 0xE9, 0xFA, 0x91, 0x74, 0x60, 0x39 },
411     { 0x9D, 0x0E, 0x18, 0x09, 0x71, 0x64, 0x74, 0xCB,
412       0x08, 0x6E, 0x83, 0x4E, 0x31, 0x0A, 0x4A, 0x1C,
413       0xED, 0x14, 0x9E, 0x9C, 0x00, 0xF2, 0x48, 0x52,
414       0x79, 0x72, 0xCE, 0xC5, 0x70, 0x4C, 0x2A, 0x5B,
415       0x07, 0xB8, 0xB3, 0xDC, 0x38, 0xEC, 0xC4, 0xEB,
416       0xAE, 0x97, 0xDD, 0xD8, 0x7F, 0x3D, 0x89, 0x85 },
417 
418     /*
419      * SHA-512 test vectors
420      */
421     { 0xDD, 0xAF, 0x35, 0xA1, 0x93, 0x61, 0x7A, 0xBA,
422       0xCC, 0x41, 0x73, 0x49, 0xAE, 0x20, 0x41, 0x31,
423       0x12, 0xE6, 0xFA, 0x4E, 0x89, 0xA9, 0x7E, 0xA2,
424       0x0A, 0x9E, 0xEE, 0xE6, 0x4B, 0x55, 0xD3, 0x9A,
425       0x21, 0x92, 0x99, 0x2A, 0x27, 0x4F, 0xC1, 0xA8,
426       0x36, 0xBA, 0x3C, 0x23, 0xA3, 0xFE, 0xEB, 0xBD,
427       0x45, 0x4D, 0x44, 0x23, 0x64, 0x3C, 0xE8, 0x0E,
428       0x2A, 0x9A, 0xC9, 0x4F, 0xA5, 0x4C, 0xA4, 0x9F },
429     { 0x8E, 0x95, 0x9B, 0x75, 0xDA, 0xE3, 0x13, 0xDA,
430       0x8C, 0xF4, 0xF7, 0x28, 0x14, 0xFC, 0x14, 0x3F,
431       0x8F, 0x77, 0x79, 0xC6, 0xEB, 0x9F, 0x7F, 0xA1,
432       0x72, 0x99, 0xAE, 0xAD, 0xB6, 0x88, 0x90, 0x18,
433       0x50, 0x1D, 0x28, 0x9E, 0x49, 0x00, 0xF7, 0xE4,
434       0x33, 0x1B, 0x99, 0xDE, 0xC4, 0xB5, 0x43, 0x3A,
435       0xC7, 0xD3, 0x29, 0xEE, 0xB6, 0xDD, 0x26, 0x54,
436       0x5E, 0x96, 0xE5, 0x5B, 0x87, 0x4B, 0xE9, 0x09 },
437     { 0xE7, 0x18, 0x48, 0x3D, 0x0C, 0xE7, 0x69, 0x64,
438       0x4E, 0x2E, 0x42, 0xC7, 0xBC, 0x15, 0xB4, 0x63,
439       0x8E, 0x1F, 0x98, 0xB1, 0x3B, 0x20, 0x44, 0x28,
440       0x56, 0x32, 0xA8, 0x03, 0xAF, 0xA9, 0x73, 0xEB,
441       0xDE, 0x0F, 0xF2, 0x44, 0x87, 0x7E, 0xA6, 0x0A,
442       0x4C, 0xB0, 0x43, 0x2C, 0xE5, 0x77, 0xC3, 0x1B,
443       0xEB, 0x00, 0x9C, 0x5C, 0x2C, 0x49, 0xAA, 0x2E,
444       0x4E, 0xAD, 0xB2, 0x17, 0xAD, 0x8C, 0xC0, 0x9B }
445 };
446 
447 /*
448  * Checkup routine
449  */
450 int mbedtls_sha512_self_test( int verbose )
451 {
452     int i, j, k, buflen, ret = 0;
453     unsigned char *buf;
454     unsigned char sha512sum[64];
455     mbedtls_sha512_context ctx;
456 
457     buf = mbedtls_calloc( 1024, sizeof(unsigned char) );
458     if( NULL == buf )
459     {
460         if( verbose != 0 )
461             mbedtls_printf( "Buffer allocation failed\n" );
462 
463         return( 1 );
464     }
465 
466     mbedtls_sha512_init( &ctx );
467 
468     for( i = 0; i < 6; i++ )
469     {
470         j = i % 3;
471         k = i < 3;
472 
473         if( verbose != 0 )
474             mbedtls_printf( "  SHA-%d test #%d: ", 512 - k * 128, j + 1 );
475 
476         mbedtls_sha512_starts( &ctx, k );
477 
478         if( j == 2 )
479         {
480             memset( buf, 'a', buflen = 1000 );
481 
482             for( j = 0; j < 1000; j++ )
483                 mbedtls_sha512_update( &ctx, buf, buflen );
484         }
485         else
486             mbedtls_sha512_update( &ctx, sha512_test_buf[j],
487                                  sha512_test_buflen[j] );
488 
489         mbedtls_sha512_finish( &ctx, sha512sum );
490 
491         if( memcmp( sha512sum, sha512_test_sum[i], 64 - k * 16 ) != 0 )
492         {
493             if( verbose != 0 )
494                 mbedtls_printf( "failed\n" );
495 
496             ret = 1;
497             goto exit;
498         }
499 
500         if( verbose != 0 )
501             mbedtls_printf( "passed\n" );
502     }
503 
504     if( verbose != 0 )
505         mbedtls_printf( "\n" );
506 
507 exit:
508     mbedtls_sha512_free( &ctx );
509     mbedtls_free( buf );
510 
511     return( ret );
512 }
513 
514 #endif /* MBEDTLS_SELF_TEST */
515 
516 #endif /* MBEDTLS_SHA512_C */
517