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