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