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