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