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