• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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