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