• 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 /*
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