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