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 #if defined(__aarch64__) && !defined(__ARM_FEATURE_SHA512) && \
14     defined(__clang__) && __clang_major__ >= 7
15 /* TODO: Re-consider above after https://reviews.llvm.org/D131064 merged.
16  *
17  * The intrinsic declaration are guarded by predefined ACLE macros in clang:
18  * these are normally only enabled by the -march option on the command line.
19  * By defining the macros ourselves we gain access to those declarations without
20  * requiring -march on the command line.
21  *
22  * `arm_neon.h` could be included by any header file, so we put these defines
23  * at the top of this file, before any includes.
24  */
25 #define __ARM_FEATURE_SHA512 1
26 #define MBEDTLS_ENABLE_ARM_SHA3_EXTENSIONS_COMPILER_FLAG
27 #endif
28 
29 #include "common.h"
30 
31 #if defined(MBEDTLS_SHA512_C) || defined(MBEDTLS_SHA384_C)
32 
33 #include "mbedtls/sha512.h"
34 #include "mbedtls/platform_util.h"
35 #include "mbedtls/error.h"
36 
37 #if defined(_MSC_VER) || defined(__WATCOMC__)
38   #define UL64(x) x##ui64
39 #else
40   #define UL64(x) x##ULL
41 #endif
42 
43 #include <string.h>
44 
45 #include "mbedtls/platform.h"
46 
47 #if defined(__aarch64__)
48 #  if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT) || \
49     defined(MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY)
50 /* *INDENT-OFF* */
51 #   ifdef __ARM_NEON
52 #       include <arm_neon.h>
53 #   else
54 #       error "Target does not support NEON instructions"
55 #   endif
56 /*
57  * Best performance comes from most recent compilers, with intrinsics and -O3.
58  * Must compile with -march=armv8.2-a+sha3, but we can't detect armv8.2-a, and
59  * can't always detect __ARM_FEATURE_SHA512 (notably clang 7-12).
60  *
61  * GCC < 8 won't work at all (lacks the sha512 instructions)
62  * GCC >= 8 uses intrinsics, sets __ARM_FEATURE_SHA512
63  *
64  * Clang < 7 won't work at all (lacks the sha512 instructions)
65  * Clang 7-12 don't have intrinsics (but we work around that with inline
66  *            assembler) or __ARM_FEATURE_SHA512
67  * Clang == 13.0.0 same as clang 12 (only seen on macOS)
68  * Clang >= 13.0.1 has __ARM_FEATURE_SHA512 and intrinsics
69  */
70 #    if !defined(__ARM_FEATURE_SHA512) || defined(MBEDTLS_ENABLE_ARM_SHA3_EXTENSIONS_COMPILER_FLAG)
71        /* Test Clang first, as it defines __GNUC__ */
72 #      if defined(__ARMCOMPILER_VERSION)
73 #        if __ARMCOMPILER_VERSION < 6090000
74 #          error "A more recent armclang is required for MBEDTLS_SHA512_USE_A64_CRYPTO_*"
75 #        elif __ARMCOMPILER_VERSION == 6090000
76 #          error "Must use minimum -march=armv8.2-a+sha3 for MBEDTLS_SHA512_USE_A64_CRYPTO_*"
77 #        else
78 #          pragma clang attribute push (__attribute__((target("sha3"))), apply_to=function)
79 #          define MBEDTLS_POP_TARGET_PRAGMA
80 #        endif
81 #      elif defined(__clang__)
82 #        if __clang_major__ < 7
83 #          error "A more recent Clang is required for MBEDTLS_SHA512_USE_A64_CRYPTO_*"
84 #        else
85 #          pragma clang attribute push (__attribute__((target("sha3"))), apply_to=function)
86 #          define MBEDTLS_POP_TARGET_PRAGMA
87 #        endif
88 #      elif defined(__GNUC__)
89 #        if __GNUC__ < 8
90 #          error "A more recent GCC is required for MBEDTLS_SHA512_USE_A64_CRYPTO_*"
91 #        else
92 #          pragma GCC push_options
93 #          pragma GCC target ("arch=armv8.2-a+sha3")
94 #          define MBEDTLS_POP_TARGET_PRAGMA
95 #        endif
96 #      else
97 #        error "Only GCC and Clang supported for MBEDTLS_SHA512_USE_A64_CRYPTO_*"
98 #      endif
99 #    endif
100 /* *INDENT-ON* */
101 #  endif
102 #  if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT)
103 #    if defined(__unix__)
104 #      if defined(__linux__)
105 /* Our preferred method of detection is getauxval() */
106 #        include <sys/auxv.h>
107 #      endif
108 /* Use SIGILL on Unix, and fall back to it on Linux */
109 #      include <signal.h>
110 #    endif
111 #  endif
112 #elif defined(_M_ARM64)
113 #  if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT) || \
114     defined(MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY)
115 #    include <arm64_neon.h>
116 #  endif
117 #else
118 #  undef MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY
119 #  undef MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT
120 #endif
121 
122 #if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT)
123 /*
124  * Capability detection code comes early, so we can disable
125  * MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT if no detection mechanism found
126  */
127 #if defined(HWCAP_SHA512)
mbedtls_a64_crypto_sha512_determine_support(void)128 static int mbedtls_a64_crypto_sha512_determine_support(void)
129 {
130     return (getauxval(AT_HWCAP) & HWCAP_SHA512) ? 1 : 0;
131 }
132 #elif defined(__APPLE__)
133 #include <sys/types.h>
134 #include <sys/sysctl.h>
135 
mbedtls_a64_crypto_sha512_determine_support(void)136 static int mbedtls_a64_crypto_sha512_determine_support(void)
137 {
138     int value = 0;
139     size_t value_len = sizeof(value);
140 
141     int ret = sysctlbyname("hw.optional.armv8_2_sha512", &value, &value_len,
142                            NULL, 0);
143     return ret == 0 && value != 0;
144 }
145 #elif defined(_M_ARM64)
146 /*
147  * As of March 2022, there don't appear to be any PF_ARM_V8_* flags
148  * available to pass to IsProcessorFeaturePresent() to check for
149  * SHA-512 support. So we fall back to the C code only.
150  */
151 #if defined(_MSC_VER)
152 #pragma message "No mechanism to detect A64_CRYPTO found, using C code only"
153 #else
154 #warning "No mechanism to detect A64_CRYPTO found, using C code only"
155 #endif
156 #elif defined(__unix__) && defined(SIG_SETMASK)
157 /* Detection with SIGILL, setjmp() and longjmp() */
158 #include <signal.h>
159 #include <setjmp.h>
160 
161 static jmp_buf return_from_sigill;
162 
163 /*
164  * A64 SHA512 support detection via SIGILL
165  */
sigill_handler(int signal)166 static void sigill_handler(int signal)
167 {
168     (void) signal;
169     longjmp(return_from_sigill, 1);
170 }
171 
mbedtls_a64_crypto_sha512_determine_support(void)172 static int mbedtls_a64_crypto_sha512_determine_support(void)
173 {
174     struct sigaction old_action, new_action;
175 
176     sigset_t old_mask;
177     if (sigprocmask(0, NULL, &old_mask)) {
178         return 0;
179     }
180 
181     sigemptyset(&new_action.sa_mask);
182     new_action.sa_flags = 0;
183     new_action.sa_handler = sigill_handler;
184 
185     sigaction(SIGILL, &new_action, &old_action);
186 
187     static int ret = 0;
188 
189     if (setjmp(return_from_sigill) == 0) {         /* First return only */
190         /* If this traps, we will return a second time from setjmp() with 1 */
191         asm ("sha512h q0, q0, v0.2d" : : : "v0");
192         ret = 1;
193     }
194 
195     sigaction(SIGILL, &old_action, NULL);
196     sigprocmask(SIG_SETMASK, &old_mask, NULL);
197 
198     return ret;
199 }
200 #else
201 #warning "No mechanism to detect A64_CRYPTO found, using C code only"
202 #undef MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT
203 #endif  /* HWCAP_SHA512, __APPLE__, __unix__ && SIG_SETMASK */
204 
205 #endif  /* MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT */
206 
207 #if !defined(MBEDTLS_SHA512_ALT)
208 
209 #define SHA512_BLOCK_SIZE 128
210 
211 #if defined(MBEDTLS_SHA512_SMALLER)
sha512_put_uint64_be(uint64_t n,unsigned char * b,uint8_t i)212 static void sha512_put_uint64_be(uint64_t n, unsigned char *b, uint8_t i)
213 {
214     MBEDTLS_PUT_UINT64_BE(n, b, i);
215 }
216 #else
217 #define sha512_put_uint64_be    MBEDTLS_PUT_UINT64_BE
218 #endif /* MBEDTLS_SHA512_SMALLER */
219 
mbedtls_sha512_init(mbedtls_sha512_context * ctx)220 void mbedtls_sha512_init(mbedtls_sha512_context *ctx)
221 {
222     memset(ctx, 0, sizeof(mbedtls_sha512_context));
223 }
224 
mbedtls_sha512_free(mbedtls_sha512_context * ctx)225 void mbedtls_sha512_free(mbedtls_sha512_context *ctx)
226 {
227     if (ctx == NULL) {
228         return;
229     }
230 
231     mbedtls_platform_zeroize(ctx, sizeof(mbedtls_sha512_context));
232 }
233 
mbedtls_sha512_clone(mbedtls_sha512_context * dst,const mbedtls_sha512_context * src)234 void mbedtls_sha512_clone(mbedtls_sha512_context *dst,
235                           const mbedtls_sha512_context *src)
236 {
237     *dst = *src;
238 }
239 
240 /*
241  * SHA-512 context setup
242  */
mbedtls_sha512_starts(mbedtls_sha512_context * ctx,int is384)243 int mbedtls_sha512_starts(mbedtls_sha512_context *ctx, int is384)
244 {
245 #if defined(MBEDTLS_SHA384_C) && defined(MBEDTLS_SHA512_C)
246     if (is384 != 0 && is384 != 1) {
247         return MBEDTLS_ERR_SHA512_BAD_INPUT_DATA;
248     }
249 #elif defined(MBEDTLS_SHA512_C)
250     if (is384 != 0) {
251         return MBEDTLS_ERR_SHA512_BAD_INPUT_DATA;
252     }
253 #else /* defined MBEDTLS_SHA384_C only */
254     if (is384 == 0) {
255         return MBEDTLS_ERR_SHA512_BAD_INPUT_DATA;
256     }
257 #endif
258 
259     ctx->total[0] = 0;
260     ctx->total[1] = 0;
261 
262     if (is384 == 0) {
263 #if defined(MBEDTLS_SHA512_C)
264         ctx->state[0] = UL64(0x6A09E667F3BCC908);
265         ctx->state[1] = UL64(0xBB67AE8584CAA73B);
266         ctx->state[2] = UL64(0x3C6EF372FE94F82B);
267         ctx->state[3] = UL64(0xA54FF53A5F1D36F1);
268         ctx->state[4] = UL64(0x510E527FADE682D1);
269         ctx->state[5] = UL64(0x9B05688C2B3E6C1F);
270         ctx->state[6] = UL64(0x1F83D9ABFB41BD6B);
271         ctx->state[7] = UL64(0x5BE0CD19137E2179);
272 #endif /* MBEDTLS_SHA512_C */
273     } else {
274 #if defined(MBEDTLS_SHA384_C)
275         ctx->state[0] = UL64(0xCBBB9D5DC1059ED8);
276         ctx->state[1] = UL64(0x629A292A367CD507);
277         ctx->state[2] = UL64(0x9159015A3070DD17);
278         ctx->state[3] = UL64(0x152FECD8F70E5939);
279         ctx->state[4] = UL64(0x67332667FFC00B31);
280         ctx->state[5] = UL64(0x8EB44A8768581511);
281         ctx->state[6] = UL64(0xDB0C2E0D64F98FA7);
282         ctx->state[7] = UL64(0x47B5481DBEFA4FA4);
283 #endif /* MBEDTLS_SHA384_C */
284     }
285 
286 #if defined(MBEDTLS_SHA384_C)
287     ctx->is384 = is384;
288 #endif
289 
290     return 0;
291 }
292 
293 #if !defined(MBEDTLS_SHA512_PROCESS_ALT)
294 
295 /*
296  * Round constants
297  */
298 static const uint64_t K[80] =
299 {
300     UL64(0x428A2F98D728AE22),  UL64(0x7137449123EF65CD),
301     UL64(0xB5C0FBCFEC4D3B2F),  UL64(0xE9B5DBA58189DBBC),
302     UL64(0x3956C25BF348B538),  UL64(0x59F111F1B605D019),
303     UL64(0x923F82A4AF194F9B),  UL64(0xAB1C5ED5DA6D8118),
304     UL64(0xD807AA98A3030242),  UL64(0x12835B0145706FBE),
305     UL64(0x243185BE4EE4B28C),  UL64(0x550C7DC3D5FFB4E2),
306     UL64(0x72BE5D74F27B896F),  UL64(0x80DEB1FE3B1696B1),
307     UL64(0x9BDC06A725C71235),  UL64(0xC19BF174CF692694),
308     UL64(0xE49B69C19EF14AD2),  UL64(0xEFBE4786384F25E3),
309     UL64(0x0FC19DC68B8CD5B5),  UL64(0x240CA1CC77AC9C65),
310     UL64(0x2DE92C6F592B0275),  UL64(0x4A7484AA6EA6E483),
311     UL64(0x5CB0A9DCBD41FBD4),  UL64(0x76F988DA831153B5),
312     UL64(0x983E5152EE66DFAB),  UL64(0xA831C66D2DB43210),
313     UL64(0xB00327C898FB213F),  UL64(0xBF597FC7BEEF0EE4),
314     UL64(0xC6E00BF33DA88FC2),  UL64(0xD5A79147930AA725),
315     UL64(0x06CA6351E003826F),  UL64(0x142929670A0E6E70),
316     UL64(0x27B70A8546D22FFC),  UL64(0x2E1B21385C26C926),
317     UL64(0x4D2C6DFC5AC42AED),  UL64(0x53380D139D95B3DF),
318     UL64(0x650A73548BAF63DE),  UL64(0x766A0ABB3C77B2A8),
319     UL64(0x81C2C92E47EDAEE6),  UL64(0x92722C851482353B),
320     UL64(0xA2BFE8A14CF10364),  UL64(0xA81A664BBC423001),
321     UL64(0xC24B8B70D0F89791),  UL64(0xC76C51A30654BE30),
322     UL64(0xD192E819D6EF5218),  UL64(0xD69906245565A910),
323     UL64(0xF40E35855771202A),  UL64(0x106AA07032BBD1B8),
324     UL64(0x19A4C116B8D2D0C8),  UL64(0x1E376C085141AB53),
325     UL64(0x2748774CDF8EEB99),  UL64(0x34B0BCB5E19B48A8),
326     UL64(0x391C0CB3C5C95A63),  UL64(0x4ED8AA4AE3418ACB),
327     UL64(0x5B9CCA4F7763E373),  UL64(0x682E6FF3D6B2B8A3),
328     UL64(0x748F82EE5DEFB2FC),  UL64(0x78A5636F43172F60),
329     UL64(0x84C87814A1F0AB72),  UL64(0x8CC702081A6439EC),
330     UL64(0x90BEFFFA23631E28),  UL64(0xA4506CEBDE82BDE9),
331     UL64(0xBEF9A3F7B2C67915),  UL64(0xC67178F2E372532B),
332     UL64(0xCA273ECEEA26619C),  UL64(0xD186B8C721C0C207),
333     UL64(0xEADA7DD6CDE0EB1E),  UL64(0xF57D4F7FEE6ED178),
334     UL64(0x06F067AA72176FBA),  UL64(0x0A637DC5A2C898A6),
335     UL64(0x113F9804BEF90DAE),  UL64(0x1B710B35131C471B),
336     UL64(0x28DB77F523047D84),  UL64(0x32CAAB7B40C72493),
337     UL64(0x3C9EBE0A15C9BEBC),  UL64(0x431D67C49C100D4C),
338     UL64(0x4CC5D4BECB3E42B6),  UL64(0x597F299CFC657E2A),
339     UL64(0x5FCB6FAB3AD6FAEC),  UL64(0x6C44198C4A475817)
340 };
341 #endif
342 
343 #if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT) || \
344     defined(MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY)
345 
346 #if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY)
347 #  define mbedtls_internal_sha512_process_many_a64_crypto mbedtls_internal_sha512_process_many
348 #  define mbedtls_internal_sha512_process_a64_crypto      mbedtls_internal_sha512_process
349 #endif
350 
351 /* Accelerated SHA-512 implementation originally written by Simon Tatham for PuTTY,
352  * under the MIT licence; dual-licensed as Apache 2 with his kind permission.
353  */
354 
355 #if defined(__clang__) && \
356     (__clang_major__ < 13 || \
357      (__clang_major__ == 13 && __clang_minor__ == 0 && __clang_patchlevel__ == 0))
vsha512su0q_u64(uint64x2_t x,uint64x2_t y)358 static inline uint64x2_t vsha512su0q_u64(uint64x2_t x, uint64x2_t y)
359 {
360     asm ("sha512su0 %0.2D,%1.2D" : "+w" (x) : "w" (y));
361     return x;
362 }
vsha512su1q_u64(uint64x2_t x,uint64x2_t y,uint64x2_t z)363 static inline uint64x2_t vsha512su1q_u64(uint64x2_t x, uint64x2_t y, uint64x2_t z)
364 {
365     asm ("sha512su1 %0.2D,%1.2D,%2.2D" : "+w" (x) : "w" (y), "w" (z));
366     return x;
367 }
vsha512hq_u64(uint64x2_t x,uint64x2_t y,uint64x2_t z)368 static inline uint64x2_t vsha512hq_u64(uint64x2_t x, uint64x2_t y, uint64x2_t z)
369 {
370     asm ("sha512h %0,%1,%2.2D" : "+w" (x) : "w" (y), "w" (z));
371     return x;
372 }
vsha512h2q_u64(uint64x2_t x,uint64x2_t y,uint64x2_t z)373 static inline uint64x2_t vsha512h2q_u64(uint64x2_t x, uint64x2_t y, uint64x2_t z)
374 {
375     asm ("sha512h2 %0,%1,%2.2D" : "+w" (x) : "w" (y), "w" (z));
376     return x;
377 }
378 #endif  /* __clang__ etc */
379 
mbedtls_internal_sha512_process_many_a64_crypto(mbedtls_sha512_context * ctx,const uint8_t * msg,size_t len)380 static size_t mbedtls_internal_sha512_process_many_a64_crypto(
381     mbedtls_sha512_context *ctx, const uint8_t *msg, size_t len)
382 {
383     uint64x2_t ab = vld1q_u64(&ctx->state[0]);
384     uint64x2_t cd = vld1q_u64(&ctx->state[2]);
385     uint64x2_t ef = vld1q_u64(&ctx->state[4]);
386     uint64x2_t gh = vld1q_u64(&ctx->state[6]);
387 
388     size_t processed = 0;
389 
390     for (;
391          len >= SHA512_BLOCK_SIZE;
392          processed += SHA512_BLOCK_SIZE,
393          msg += SHA512_BLOCK_SIZE,
394          len -= SHA512_BLOCK_SIZE) {
395         uint64x2_t initial_sum, sum, intermed;
396 
397         uint64x2_t ab_orig = ab;
398         uint64x2_t cd_orig = cd;
399         uint64x2_t ef_orig = ef;
400         uint64x2_t gh_orig = gh;
401 
402         uint64x2_t s0 = (uint64x2_t) vld1q_u8(msg + 16 * 0);
403         uint64x2_t s1 = (uint64x2_t) vld1q_u8(msg + 16 * 1);
404         uint64x2_t s2 = (uint64x2_t) vld1q_u8(msg + 16 * 2);
405         uint64x2_t s3 = (uint64x2_t) vld1q_u8(msg + 16 * 3);
406         uint64x2_t s4 = (uint64x2_t) vld1q_u8(msg + 16 * 4);
407         uint64x2_t s5 = (uint64x2_t) vld1q_u8(msg + 16 * 5);
408         uint64x2_t s6 = (uint64x2_t) vld1q_u8(msg + 16 * 6);
409         uint64x2_t s7 = (uint64x2_t) vld1q_u8(msg + 16 * 7);
410 
411 #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__  /* assume LE if these not defined; untested on BE */
412         s0 = vreinterpretq_u64_u8(vrev64q_u8(vreinterpretq_u8_u64(s0)));
413         s1 = vreinterpretq_u64_u8(vrev64q_u8(vreinterpretq_u8_u64(s1)));
414         s2 = vreinterpretq_u64_u8(vrev64q_u8(vreinterpretq_u8_u64(s2)));
415         s3 = vreinterpretq_u64_u8(vrev64q_u8(vreinterpretq_u8_u64(s3)));
416         s4 = vreinterpretq_u64_u8(vrev64q_u8(vreinterpretq_u8_u64(s4)));
417         s5 = vreinterpretq_u64_u8(vrev64q_u8(vreinterpretq_u8_u64(s5)));
418         s6 = vreinterpretq_u64_u8(vrev64q_u8(vreinterpretq_u8_u64(s6)));
419         s7 = vreinterpretq_u64_u8(vrev64q_u8(vreinterpretq_u8_u64(s7)));
420 #endif
421 
422         /* Rounds 0 and 1 */
423         initial_sum = vaddq_u64(s0, vld1q_u64(&K[0]));
424         sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), gh);
425         intermed = vsha512hq_u64(sum, vextq_u64(ef, gh, 1), vextq_u64(cd, ef, 1));
426         gh = vsha512h2q_u64(intermed, cd, ab);
427         cd = vaddq_u64(cd, intermed);
428 
429         /* Rounds 2 and 3 */
430         initial_sum = vaddq_u64(s1, vld1q_u64(&K[2]));
431         sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), ef);
432         intermed = vsha512hq_u64(sum, vextq_u64(cd, ef, 1), vextq_u64(ab, cd, 1));
433         ef = vsha512h2q_u64(intermed, ab, gh);
434         ab = vaddq_u64(ab, intermed);
435 
436         /* Rounds 4 and 5 */
437         initial_sum = vaddq_u64(s2, vld1q_u64(&K[4]));
438         sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), cd);
439         intermed = vsha512hq_u64(sum, vextq_u64(ab, cd, 1), vextq_u64(gh, ab, 1));
440         cd = vsha512h2q_u64(intermed, gh, ef);
441         gh = vaddq_u64(gh, intermed);
442 
443         /* Rounds 6 and 7 */
444         initial_sum = vaddq_u64(s3, vld1q_u64(&K[6]));
445         sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), ab);
446         intermed = vsha512hq_u64(sum, vextq_u64(gh, ab, 1), vextq_u64(ef, gh, 1));
447         ab = vsha512h2q_u64(intermed, ef, cd);
448         ef = vaddq_u64(ef, intermed);
449 
450         /* Rounds 8 and 9 */
451         initial_sum = vaddq_u64(s4, vld1q_u64(&K[8]));
452         sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), gh);
453         intermed = vsha512hq_u64(sum, vextq_u64(ef, gh, 1), vextq_u64(cd, ef, 1));
454         gh = vsha512h2q_u64(intermed, cd, ab);
455         cd = vaddq_u64(cd, intermed);
456 
457         /* Rounds 10 and 11 */
458         initial_sum = vaddq_u64(s5, vld1q_u64(&K[10]));
459         sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), ef);
460         intermed = vsha512hq_u64(sum, vextq_u64(cd, ef, 1), vextq_u64(ab, cd, 1));
461         ef = vsha512h2q_u64(intermed, ab, gh);
462         ab = vaddq_u64(ab, intermed);
463 
464         /* Rounds 12 and 13 */
465         initial_sum = vaddq_u64(s6, vld1q_u64(&K[12]));
466         sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), cd);
467         intermed = vsha512hq_u64(sum, vextq_u64(ab, cd, 1), vextq_u64(gh, ab, 1));
468         cd = vsha512h2q_u64(intermed, gh, ef);
469         gh = vaddq_u64(gh, intermed);
470 
471         /* Rounds 14 and 15 */
472         initial_sum = vaddq_u64(s7, vld1q_u64(&K[14]));
473         sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), ab);
474         intermed = vsha512hq_u64(sum, vextq_u64(gh, ab, 1), vextq_u64(ef, gh, 1));
475         ab = vsha512h2q_u64(intermed, ef, cd);
476         ef = vaddq_u64(ef, intermed);
477 
478         for (unsigned int t = 16; t < 80; t += 16) {
479             /* Rounds t and t + 1 */
480             s0 = vsha512su1q_u64(vsha512su0q_u64(s0, s1), s7, vextq_u64(s4, s5, 1));
481             initial_sum = vaddq_u64(s0, vld1q_u64(&K[t]));
482             sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), gh);
483             intermed = vsha512hq_u64(sum, vextq_u64(ef, gh, 1), vextq_u64(cd, ef, 1));
484             gh = vsha512h2q_u64(intermed, cd, ab);
485             cd = vaddq_u64(cd, intermed);
486 
487             /* Rounds t + 2 and t + 3 */
488             s1 = vsha512su1q_u64(vsha512su0q_u64(s1, s2), s0, vextq_u64(s5, s6, 1));
489             initial_sum = vaddq_u64(s1, vld1q_u64(&K[t + 2]));
490             sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), ef);
491             intermed = vsha512hq_u64(sum, vextq_u64(cd, ef, 1), vextq_u64(ab, cd, 1));
492             ef = vsha512h2q_u64(intermed, ab, gh);
493             ab = vaddq_u64(ab, intermed);
494 
495             /* Rounds t + 4 and t + 5 */
496             s2 = vsha512su1q_u64(vsha512su0q_u64(s2, s3), s1, vextq_u64(s6, s7, 1));
497             initial_sum = vaddq_u64(s2, vld1q_u64(&K[t + 4]));
498             sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), cd);
499             intermed = vsha512hq_u64(sum, vextq_u64(ab, cd, 1), vextq_u64(gh, ab, 1));
500             cd = vsha512h2q_u64(intermed, gh, ef);
501             gh = vaddq_u64(gh, intermed);
502 
503             /* Rounds t + 6 and t + 7 */
504             s3 = vsha512su1q_u64(vsha512su0q_u64(s3, s4), s2, vextq_u64(s7, s0, 1));
505             initial_sum = vaddq_u64(s3, vld1q_u64(&K[t + 6]));
506             sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), ab);
507             intermed = vsha512hq_u64(sum, vextq_u64(gh, ab, 1), vextq_u64(ef, gh, 1));
508             ab = vsha512h2q_u64(intermed, ef, cd);
509             ef = vaddq_u64(ef, intermed);
510 
511             /* Rounds t + 8 and t + 9 */
512             s4 = vsha512su1q_u64(vsha512su0q_u64(s4, s5), s3, vextq_u64(s0, s1, 1));
513             initial_sum = vaddq_u64(s4, vld1q_u64(&K[t + 8]));
514             sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), gh);
515             intermed = vsha512hq_u64(sum, vextq_u64(ef, gh, 1), vextq_u64(cd, ef, 1));
516             gh = vsha512h2q_u64(intermed, cd, ab);
517             cd = vaddq_u64(cd, intermed);
518 
519             /* Rounds t + 10 and t + 11 */
520             s5 = vsha512su1q_u64(vsha512su0q_u64(s5, s6), s4, vextq_u64(s1, s2, 1));
521             initial_sum = vaddq_u64(s5, vld1q_u64(&K[t + 10]));
522             sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), ef);
523             intermed = vsha512hq_u64(sum, vextq_u64(cd, ef, 1), vextq_u64(ab, cd, 1));
524             ef = vsha512h2q_u64(intermed, ab, gh);
525             ab = vaddq_u64(ab, intermed);
526 
527             /* Rounds t + 12 and t + 13 */
528             s6 = vsha512su1q_u64(vsha512su0q_u64(s6, s7), s5, vextq_u64(s2, s3, 1));
529             initial_sum = vaddq_u64(s6, vld1q_u64(&K[t + 12]));
530             sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), cd);
531             intermed = vsha512hq_u64(sum, vextq_u64(ab, cd, 1), vextq_u64(gh, ab, 1));
532             cd = vsha512h2q_u64(intermed, gh, ef);
533             gh = vaddq_u64(gh, intermed);
534 
535             /* Rounds t + 14 and t + 15 */
536             s7 = vsha512su1q_u64(vsha512su0q_u64(s7, s0), s6, vextq_u64(s3, s4, 1));
537             initial_sum = vaddq_u64(s7, vld1q_u64(&K[t + 14]));
538             sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), ab);
539             intermed = vsha512hq_u64(sum, vextq_u64(gh, ab, 1), vextq_u64(ef, gh, 1));
540             ab = vsha512h2q_u64(intermed, ef, cd);
541             ef = vaddq_u64(ef, intermed);
542         }
543 
544         ab = vaddq_u64(ab, ab_orig);
545         cd = vaddq_u64(cd, cd_orig);
546         ef = vaddq_u64(ef, ef_orig);
547         gh = vaddq_u64(gh, gh_orig);
548     }
549 
550     vst1q_u64(&ctx->state[0], ab);
551     vst1q_u64(&ctx->state[2], cd);
552     vst1q_u64(&ctx->state[4], ef);
553     vst1q_u64(&ctx->state[6], gh);
554 
555     return processed;
556 }
557 
558 #if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT)
559 /*
560  * This function is for internal use only if we are building both C and A64
561  * versions, otherwise it is renamed to be the public mbedtls_internal_sha512_process()
562  */
563 static
564 #endif
mbedtls_internal_sha512_process_a64_crypto(mbedtls_sha512_context * ctx,const unsigned char data[SHA512_BLOCK_SIZE])565 int mbedtls_internal_sha512_process_a64_crypto(mbedtls_sha512_context *ctx,
566                                                const unsigned char data[SHA512_BLOCK_SIZE])
567 {
568     return (mbedtls_internal_sha512_process_many_a64_crypto(ctx, data,
569                                                             SHA512_BLOCK_SIZE) ==
570             SHA512_BLOCK_SIZE) ? 0 : -1;
571 }
572 
573 #endif /* MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT || MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY */
574 
575 #if defined(MBEDTLS_POP_TARGET_PRAGMA)
576 #if defined(__clang__)
577 #pragma clang attribute pop
578 #elif defined(__GNUC__)
579 #pragma GCC pop_options
580 #endif
581 #undef MBEDTLS_POP_TARGET_PRAGMA
582 #endif
583 
584 
585 #if !defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT)
586 #define mbedtls_internal_sha512_process_many_c mbedtls_internal_sha512_process_many
587 #define mbedtls_internal_sha512_process_c      mbedtls_internal_sha512_process
588 #endif
589 
590 
591 #if !defined(MBEDTLS_SHA512_PROCESS_ALT) && !defined(MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY)
592 
593 #if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT)
594 /*
595  * This function is for internal use only if we are building both C and A64
596  * versions, otherwise it is renamed to be the public mbedtls_internal_sha512_process()
597  */
598 static
599 #endif
mbedtls_internal_sha512_process_c(mbedtls_sha512_context * ctx,const unsigned char data[SHA512_BLOCK_SIZE])600 int mbedtls_internal_sha512_process_c(mbedtls_sha512_context *ctx,
601                                       const unsigned char data[SHA512_BLOCK_SIZE])
602 {
603     int i;
604     struct {
605         uint64_t temp1, temp2, W[80];
606         uint64_t A[8];
607     } local;
608 
609 #define  SHR(x, n) ((x) >> (n))
610 #define ROTR(x, n) (SHR((x), (n)) | ((x) << (64 - (n))))
611 
612 #define S0(x) (ROTR(x, 1) ^ ROTR(x, 8) ^  SHR(x, 7))
613 #define S1(x) (ROTR(x, 19) ^ ROTR(x, 61) ^  SHR(x, 6))
614 
615 #define S2(x) (ROTR(x, 28) ^ ROTR(x, 34) ^ ROTR(x, 39))
616 #define S3(x) (ROTR(x, 14) ^ ROTR(x, 18) ^ ROTR(x, 41))
617 
618 #define F0(x, y, z) (((x) & (y)) | ((z) & ((x) | (y))))
619 #define F1(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
620 
621 #define P(a, b, c, d, e, f, g, h, x, K)                                      \
622     do                                                              \
623     {                                                               \
624         local.temp1 = (h) + S3(e) + F1((e), (f), (g)) + (K) + (x);    \
625         local.temp2 = S2(a) + F0((a), (b), (c));                      \
626         (d) += local.temp1; (h) = local.temp1 + local.temp2;        \
627     } while (0)
628 
629     for (i = 0; i < 8; i++) {
630         local.A[i] = ctx->state[i];
631     }
632 
633 #if defined(MBEDTLS_SHA512_SMALLER)
634     for (i = 0; i < 80; i++) {
635         if (i < 16) {
636             local.W[i] = MBEDTLS_GET_UINT64_BE(data, i << 3);
637         } else {
638             local.W[i] = S1(local.W[i -  2]) + local.W[i -  7] +
639                          S0(local.W[i - 15]) + local.W[i - 16];
640         }
641 
642         P(local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
643           local.A[5], local.A[6], local.A[7], local.W[i], K[i]);
644 
645         local.temp1 = local.A[7]; local.A[7] = local.A[6];
646         local.A[6] = local.A[5]; local.A[5] = local.A[4];
647         local.A[4] = local.A[3]; local.A[3] = local.A[2];
648         local.A[2] = local.A[1]; local.A[1] = local.A[0];
649         local.A[0] = local.temp1;
650     }
651 #else /* MBEDTLS_SHA512_SMALLER */
652     for (i = 0; i < 16; i++) {
653         local.W[i] = MBEDTLS_GET_UINT64_BE(data, i << 3);
654     }
655 
656     for (; i < 80; i++) {
657         local.W[i] = S1(local.W[i -  2]) + local.W[i -  7] +
658                      S0(local.W[i - 15]) + local.W[i - 16];
659     }
660 
661     i = 0;
662     do {
663         P(local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
664           local.A[5], local.A[6], local.A[7], local.W[i], K[i]); i++;
665         P(local.A[7], local.A[0], local.A[1], local.A[2], local.A[3],
666           local.A[4], local.A[5], local.A[6], local.W[i], K[i]); i++;
667         P(local.A[6], local.A[7], local.A[0], local.A[1], local.A[2],
668           local.A[3], local.A[4], local.A[5], local.W[i], K[i]); i++;
669         P(local.A[5], local.A[6], local.A[7], local.A[0], local.A[1],
670           local.A[2], local.A[3], local.A[4], local.W[i], K[i]); i++;
671         P(local.A[4], local.A[5], local.A[6], local.A[7], local.A[0],
672           local.A[1], local.A[2], local.A[3], local.W[i], K[i]); i++;
673         P(local.A[3], local.A[4], local.A[5], local.A[6], local.A[7],
674           local.A[0], local.A[1], local.A[2], local.W[i], K[i]); i++;
675         P(local.A[2], local.A[3], local.A[4], local.A[5], local.A[6],
676           local.A[7], local.A[0], local.A[1], local.W[i], K[i]); i++;
677         P(local.A[1], local.A[2], local.A[3], local.A[4], local.A[5],
678           local.A[6], local.A[7], local.A[0], local.W[i], K[i]); i++;
679     } while (i < 80);
680 #endif /* MBEDTLS_SHA512_SMALLER */
681 
682     for (i = 0; i < 8; i++) {
683         ctx->state[i] += local.A[i];
684     }
685 
686     /* Zeroise buffers and variables to clear sensitive data from memory. */
687     mbedtls_platform_zeroize(&local, sizeof(local));
688 
689     return 0;
690 }
691 
692 #endif /* !MBEDTLS_SHA512_PROCESS_ALT && !MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY */
693 
694 
695 #if !defined(MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY)
696 
mbedtls_internal_sha512_process_many_c(mbedtls_sha512_context * ctx,const uint8_t * data,size_t len)697 static size_t mbedtls_internal_sha512_process_many_c(
698     mbedtls_sha512_context *ctx, const uint8_t *data, size_t len)
699 {
700     size_t processed = 0;
701 
702     while (len >= SHA512_BLOCK_SIZE) {
703         if (mbedtls_internal_sha512_process_c(ctx, data) != 0) {
704             return 0;
705         }
706 
707         data += SHA512_BLOCK_SIZE;
708         len  -= SHA512_BLOCK_SIZE;
709 
710         processed += SHA512_BLOCK_SIZE;
711     }
712 
713     return processed;
714 }
715 
716 #endif /* !MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY */
717 
718 
719 #if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT)
720 
mbedtls_a64_crypto_sha512_has_support(void)721 static int mbedtls_a64_crypto_sha512_has_support(void)
722 {
723     static int done = 0;
724     static int supported = 0;
725 
726     if (!done) {
727         supported = mbedtls_a64_crypto_sha512_determine_support();
728         done = 1;
729     }
730 
731     return supported;
732 }
733 
mbedtls_internal_sha512_process_many(mbedtls_sha512_context * ctx,const uint8_t * msg,size_t len)734 static size_t mbedtls_internal_sha512_process_many(mbedtls_sha512_context *ctx,
735                                                    const uint8_t *msg, size_t len)
736 {
737     if (mbedtls_a64_crypto_sha512_has_support()) {
738         return mbedtls_internal_sha512_process_many_a64_crypto(ctx, msg, len);
739     } else {
740         return mbedtls_internal_sha512_process_many_c(ctx, msg, len);
741     }
742 }
743 
mbedtls_internal_sha512_process(mbedtls_sha512_context * ctx,const unsigned char data[SHA512_BLOCK_SIZE])744 int mbedtls_internal_sha512_process(mbedtls_sha512_context *ctx,
745                                     const unsigned char data[SHA512_BLOCK_SIZE])
746 {
747     if (mbedtls_a64_crypto_sha512_has_support()) {
748         return mbedtls_internal_sha512_process_a64_crypto(ctx, data);
749     } else {
750         return mbedtls_internal_sha512_process_c(ctx, data);
751     }
752 }
753 
754 #endif /* MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT */
755 
756 /*
757  * SHA-512 process buffer
758  */
mbedtls_sha512_update(mbedtls_sha512_context * ctx,const unsigned char * input,size_t ilen)759 int mbedtls_sha512_update(mbedtls_sha512_context *ctx,
760                           const unsigned char *input,
761                           size_t ilen)
762 {
763     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
764     size_t fill;
765     unsigned int left;
766 
767     if (ilen == 0) {
768         return 0;
769     }
770 
771     left = (unsigned int) (ctx->total[0] & 0x7F);
772     fill = SHA512_BLOCK_SIZE - left;
773 
774     ctx->total[0] += (uint64_t) ilen;
775 
776     if (ctx->total[0] < (uint64_t) ilen) {
777         ctx->total[1]++;
778     }
779 
780     if (left && ilen >= fill) {
781         memcpy((void *) (ctx->buffer + left), input, fill);
782 
783         if ((ret = mbedtls_internal_sha512_process(ctx, ctx->buffer)) != 0) {
784             return ret;
785         }
786 
787         input += fill;
788         ilen  -= fill;
789         left = 0;
790     }
791 
792     while (ilen >= SHA512_BLOCK_SIZE) {
793         size_t processed =
794             mbedtls_internal_sha512_process_many(ctx, input, ilen);
795         if (processed < SHA512_BLOCK_SIZE) {
796             return MBEDTLS_ERR_ERROR_GENERIC_ERROR;
797         }
798 
799         input += processed;
800         ilen  -= processed;
801     }
802 
803     if (ilen > 0) {
804         memcpy((void *) (ctx->buffer + left), input, ilen);
805     }
806 
807     return 0;
808 }
809 
810 /*
811  * SHA-512 final digest
812  */
mbedtls_sha512_finish(mbedtls_sha512_context * ctx,unsigned char * output)813 int mbedtls_sha512_finish(mbedtls_sha512_context *ctx,
814                           unsigned char *output)
815 {
816     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
817     unsigned used;
818     uint64_t high, low;
819     int truncated = 0;
820 
821     /*
822      * Add padding: 0x80 then 0x00 until 16 bytes remain for the length
823      */
824     used = ctx->total[0] & 0x7F;
825 
826     ctx->buffer[used++] = 0x80;
827 
828     if (used <= 112) {
829         /* Enough room for padding + length in current block */
830         memset(ctx->buffer + used, 0, 112 - used);
831     } else {
832         /* We'll need an extra block */
833         memset(ctx->buffer + used, 0, SHA512_BLOCK_SIZE - used);
834 
835         if ((ret = mbedtls_internal_sha512_process(ctx, ctx->buffer)) != 0) {
836             goto exit;
837         }
838 
839         memset(ctx->buffer, 0, 112);
840     }
841 
842     /*
843      * Add message length
844      */
845     high = (ctx->total[0] >> 61)
846            | (ctx->total[1] <<  3);
847     low  = (ctx->total[0] <<  3);
848 
849     sha512_put_uint64_be(high, ctx->buffer, 112);
850     sha512_put_uint64_be(low,  ctx->buffer, 120);
851 
852     if ((ret = mbedtls_internal_sha512_process(ctx, ctx->buffer)) != 0) {
853         goto exit;
854     }
855 
856     /*
857      * Output final state
858      */
859     sha512_put_uint64_be(ctx->state[0], output,  0);
860     sha512_put_uint64_be(ctx->state[1], output,  8);
861     sha512_put_uint64_be(ctx->state[2], output, 16);
862     sha512_put_uint64_be(ctx->state[3], output, 24);
863     sha512_put_uint64_be(ctx->state[4], output, 32);
864     sha512_put_uint64_be(ctx->state[5], output, 40);
865 
866 #if defined(MBEDTLS_SHA384_C)
867     truncated = ctx->is384;
868 #endif
869     if (!truncated) {
870         sha512_put_uint64_be(ctx->state[6], output, 48);
871         sha512_put_uint64_be(ctx->state[7], output, 56);
872     }
873 
874     ret = 0;
875 
876 exit:
877     mbedtls_sha512_free(ctx);
878     return ret;
879 }
880 
881 #endif /* !MBEDTLS_SHA512_ALT */
882 
883 /*
884  * output = SHA-512( input buffer )
885  */
mbedtls_sha512(const unsigned char * input,size_t ilen,unsigned char * output,int is384)886 int mbedtls_sha512(const unsigned char *input,
887                    size_t ilen,
888                    unsigned char *output,
889                    int is384)
890 {
891     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
892     mbedtls_sha512_context ctx;
893 
894 #if defined(MBEDTLS_SHA384_C) && defined(MBEDTLS_SHA512_C)
895     if (is384 != 0 && is384 != 1) {
896         return MBEDTLS_ERR_SHA512_BAD_INPUT_DATA;
897     }
898 #elif defined(MBEDTLS_SHA512_C)
899     if (is384 != 0) {
900         return MBEDTLS_ERR_SHA512_BAD_INPUT_DATA;
901     }
902 #else /* defined MBEDTLS_SHA384_C only */
903     if (is384 == 0) {
904         return MBEDTLS_ERR_SHA512_BAD_INPUT_DATA;
905     }
906 #endif
907 
908     mbedtls_sha512_init(&ctx);
909 
910     if ((ret = mbedtls_sha512_starts(&ctx, is384)) != 0) {
911         goto exit;
912     }
913 
914     if ((ret = mbedtls_sha512_update(&ctx, input, ilen)) != 0) {
915         goto exit;
916     }
917 
918     if ((ret = mbedtls_sha512_finish(&ctx, output)) != 0) {
919         goto exit;
920     }
921 
922 exit:
923     mbedtls_sha512_free(&ctx);
924 
925     return ret;
926 }
927 
928 #if defined(MBEDTLS_SELF_TEST)
929 
930 /*
931  * FIPS-180-2 test vectors
932  */
933 static const unsigned char sha_test_buf[3][113] =
934 {
935     { "abc" },
936     {
937         "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu"
938     },
939     { "" }
940 };
941 
942 static const size_t sha_test_buflen[3] =
943 {
944     3, 112, 1000
945 };
946 
947 typedef const unsigned char (sha_test_sum_t)[64];
948 
949 /*
950  * SHA-384 test vectors
951  */
952 #if defined(MBEDTLS_SHA384_C)
953 static sha_test_sum_t sha384_test_sum[] =
954 {
955     { 0xCB, 0x00, 0x75, 0x3F, 0x45, 0xA3, 0x5E, 0x8B,
956       0xB5, 0xA0, 0x3D, 0x69, 0x9A, 0xC6, 0x50, 0x07,
957       0x27, 0x2C, 0x32, 0xAB, 0x0E, 0xDE, 0xD1, 0x63,
958       0x1A, 0x8B, 0x60, 0x5A, 0x43, 0xFF, 0x5B, 0xED,
959       0x80, 0x86, 0x07, 0x2B, 0xA1, 0xE7, 0xCC, 0x23,
960       0x58, 0xBA, 0xEC, 0xA1, 0x34, 0xC8, 0x25, 0xA7 },
961     { 0x09, 0x33, 0x0C, 0x33, 0xF7, 0x11, 0x47, 0xE8,
962       0x3D, 0x19, 0x2F, 0xC7, 0x82, 0xCD, 0x1B, 0x47,
963       0x53, 0x11, 0x1B, 0x17, 0x3B, 0x3B, 0x05, 0xD2,
964       0x2F, 0xA0, 0x80, 0x86, 0xE3, 0xB0, 0xF7, 0x12,
965       0xFC, 0xC7, 0xC7, 0x1A, 0x55, 0x7E, 0x2D, 0xB9,
966       0x66, 0xC3, 0xE9, 0xFA, 0x91, 0x74, 0x60, 0x39 },
967     { 0x9D, 0x0E, 0x18, 0x09, 0x71, 0x64, 0x74, 0xCB,
968       0x08, 0x6E, 0x83, 0x4E, 0x31, 0x0A, 0x4A, 0x1C,
969       0xED, 0x14, 0x9E, 0x9C, 0x00, 0xF2, 0x48, 0x52,
970       0x79, 0x72, 0xCE, 0xC5, 0x70, 0x4C, 0x2A, 0x5B,
971       0x07, 0xB8, 0xB3, 0xDC, 0x38, 0xEC, 0xC4, 0xEB,
972       0xAE, 0x97, 0xDD, 0xD8, 0x7F, 0x3D, 0x89, 0x85 }
973 };
974 #endif /* MBEDTLS_SHA384_C */
975 
976 /*
977  * SHA-512 test vectors
978  */
979 #if defined(MBEDTLS_SHA512_C)
980 static sha_test_sum_t sha512_test_sum[] =
981 {
982     { 0xDD, 0xAF, 0x35, 0xA1, 0x93, 0x61, 0x7A, 0xBA,
983       0xCC, 0x41, 0x73, 0x49, 0xAE, 0x20, 0x41, 0x31,
984       0x12, 0xE6, 0xFA, 0x4E, 0x89, 0xA9, 0x7E, 0xA2,
985       0x0A, 0x9E, 0xEE, 0xE6, 0x4B, 0x55, 0xD3, 0x9A,
986       0x21, 0x92, 0x99, 0x2A, 0x27, 0x4F, 0xC1, 0xA8,
987       0x36, 0xBA, 0x3C, 0x23, 0xA3, 0xFE, 0xEB, 0xBD,
988       0x45, 0x4D, 0x44, 0x23, 0x64, 0x3C, 0xE8, 0x0E,
989       0x2A, 0x9A, 0xC9, 0x4F, 0xA5, 0x4C, 0xA4, 0x9F },
990     { 0x8E, 0x95, 0x9B, 0x75, 0xDA, 0xE3, 0x13, 0xDA,
991       0x8C, 0xF4, 0xF7, 0x28, 0x14, 0xFC, 0x14, 0x3F,
992       0x8F, 0x77, 0x79, 0xC6, 0xEB, 0x9F, 0x7F, 0xA1,
993       0x72, 0x99, 0xAE, 0xAD, 0xB6, 0x88, 0x90, 0x18,
994       0x50, 0x1D, 0x28, 0x9E, 0x49, 0x00, 0xF7, 0xE4,
995       0x33, 0x1B, 0x99, 0xDE, 0xC4, 0xB5, 0x43, 0x3A,
996       0xC7, 0xD3, 0x29, 0xEE, 0xB6, 0xDD, 0x26, 0x54,
997       0x5E, 0x96, 0xE5, 0x5B, 0x87, 0x4B, 0xE9, 0x09 },
998     { 0xE7, 0x18, 0x48, 0x3D, 0x0C, 0xE7, 0x69, 0x64,
999       0x4E, 0x2E, 0x42, 0xC7, 0xBC, 0x15, 0xB4, 0x63,
1000       0x8E, 0x1F, 0x98, 0xB1, 0x3B, 0x20, 0x44, 0x28,
1001       0x56, 0x32, 0xA8, 0x03, 0xAF, 0xA9, 0x73, 0xEB,
1002       0xDE, 0x0F, 0xF2, 0x44, 0x87, 0x7E, 0xA6, 0x0A,
1003       0x4C, 0xB0, 0x43, 0x2C, 0xE5, 0x77, 0xC3, 0x1B,
1004       0xEB, 0x00, 0x9C, 0x5C, 0x2C, 0x49, 0xAA, 0x2E,
1005       0x4E, 0xAD, 0xB2, 0x17, 0xAD, 0x8C, 0xC0, 0x9B }
1006 };
1007 #endif /* MBEDTLS_SHA512_C */
1008 
mbedtls_sha512_common_self_test(int verbose,int is384)1009 static int mbedtls_sha512_common_self_test(int verbose, int is384)
1010 {
1011     int i, buflen, ret = 0;
1012     unsigned char *buf;
1013     unsigned char sha512sum[64];
1014     mbedtls_sha512_context ctx;
1015 
1016 #if defined(MBEDTLS_SHA384_C) && defined(MBEDTLS_SHA512_C)
1017     sha_test_sum_t *sha_test_sum = (is384) ? sha384_test_sum : sha512_test_sum;
1018 #elif defined(MBEDTLS_SHA512_C)
1019     sha_test_sum_t *sha_test_sum = sha512_test_sum;
1020 #else
1021     sha_test_sum_t *sha_test_sum = sha384_test_sum;
1022 #endif
1023 
1024     buf = mbedtls_calloc(1024, sizeof(unsigned char));
1025     if (NULL == buf) {
1026         if (verbose != 0) {
1027             mbedtls_printf("Buffer allocation failed\n");
1028         }
1029 
1030         return 1;
1031     }
1032 
1033     mbedtls_sha512_init(&ctx);
1034 
1035     for (i = 0; i < 3; i++) {
1036         if (verbose != 0) {
1037             mbedtls_printf("  SHA-%d test #%d: ", 512 - is384 * 128, i + 1);
1038         }
1039 
1040         if ((ret = mbedtls_sha512_starts(&ctx, is384)) != 0) {
1041             goto fail;
1042         }
1043 
1044         if (i == 2) {
1045             memset(buf, 'a', buflen = 1000);
1046 
1047             for (int j = 0; j < 1000; j++) {
1048                 ret = mbedtls_sha512_update(&ctx, buf, buflen);
1049                 if (ret != 0) {
1050                     goto fail;
1051                 }
1052             }
1053         } else {
1054             ret = mbedtls_sha512_update(&ctx, sha_test_buf[i],
1055                                         sha_test_buflen[i]);
1056             if (ret != 0) {
1057                 goto fail;
1058             }
1059         }
1060 
1061         if ((ret = mbedtls_sha512_finish(&ctx, sha512sum)) != 0) {
1062             goto fail;
1063         }
1064 
1065         if (memcmp(sha512sum, sha_test_sum[i], 64 - is384 * 16) != 0) {
1066             ret = 1;
1067             goto fail;
1068         }
1069 
1070         if (verbose != 0) {
1071             mbedtls_printf("passed\n");
1072         }
1073     }
1074 
1075     if (verbose != 0) {
1076         mbedtls_printf("\n");
1077     }
1078 
1079     goto exit;
1080 
1081 fail:
1082     if (verbose != 0) {
1083         mbedtls_printf("failed\n");
1084     }
1085 
1086 exit:
1087     mbedtls_sha512_free(&ctx);
1088     mbedtls_free(buf);
1089 
1090     return ret;
1091 }
1092 
1093 #if defined(MBEDTLS_SHA512_C)
mbedtls_sha512_self_test(int verbose)1094 int mbedtls_sha512_self_test(int verbose)
1095 {
1096     return mbedtls_sha512_common_self_test(verbose, 0);
1097 }
1098 #endif /* MBEDTLS_SHA512_C */
1099 
1100 #if defined(MBEDTLS_SHA384_C)
mbedtls_sha384_self_test(int verbose)1101 int mbedtls_sha384_self_test(int verbose)
1102 {
1103     return mbedtls_sha512_common_self_test(verbose, 1);
1104 }
1105 #endif /* MBEDTLS_SHA384_C */
1106 
1107 #undef ARRAY_LENGTH
1108 
1109 #endif /* MBEDTLS_SELF_TEST */
1110 
1111 #endif /* MBEDTLS_SHA512_C || MBEDTLS_SHA384_C */
1112