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