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