Branch data Line data Source code
1 : : /*
2 : : * FIPS-180-2 compliant SHA-256 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-256 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(__clang__) && (__clang_major__ >= 4)
14 : :
15 : : /* Ideally, we would simply use MBEDTLS_ARCH_IS_ARMV8_A in the following #if,
16 : : * but that is defined by build_info.h, and we need this block to happen first. */
17 : : #if defined(__ARM_ARCH) && (__ARM_ARCH_PROFILE == 'A')
18 : : #if __ARM_ARCH >= 8
19 : : #define MBEDTLS_SHA256_ARCH_IS_ARMV8_A
20 : : #endif
21 : : #endif
22 : :
23 : : #if defined(MBEDTLS_SHA256_ARCH_IS_ARMV8_A) && !defined(__ARM_FEATURE_CRYPTO)
24 : : /* TODO: Re-consider above after https://reviews.llvm.org/D131064 merged.
25 : : *
26 : : * The intrinsic declaration are guarded by predefined ACLE macros in clang:
27 : : * these are normally only enabled by the -march option on the command line.
28 : : * By defining the macros ourselves we gain access to those declarations without
29 : : * requiring -march on the command line.
30 : : *
31 : : * `arm_neon.h` is included by common.h, so we put these defines
32 : : * at the top of this file, before any includes.
33 : : */
34 : : #define __ARM_FEATURE_CRYPTO 1
35 : : /* See: https://arm-software.github.io/acle/main/acle.html#cryptographic-extensions
36 : : *
37 : : * `__ARM_FEATURE_CRYPTO` is deprecated, but we need to continue to specify it
38 : : * for older compilers.
39 : : */
40 : : #define __ARM_FEATURE_SHA2 1
41 : : #define MBEDTLS_ENABLE_ARM_CRYPTO_EXTENSIONS_COMPILER_FLAG
42 : : #endif
43 : :
44 : : #endif /* defined(__clang__) && (__clang_major__ >= 4) */
45 : :
46 : : /* Ensure that SIG_SETMASK is defined when -std=c99 is used. */
47 : : #if !defined(_GNU_SOURCE)
48 : : #define _GNU_SOURCE
49 : : #endif
50 : :
51 : : #include "common.h"
52 : :
53 : : #if defined(MBEDTLS_SHA256_C) || defined(MBEDTLS_SHA224_C)
54 : :
55 : : #include "mbedtls/sha256.h"
56 : : #include "mbedtls/platform_util.h"
57 : : #include "mbedtls/error.h"
58 : :
59 : : #include <string.h>
60 : :
61 : : #include "mbedtls/platform.h"
62 : :
63 : : #if defined(MBEDTLS_ARCH_IS_ARMV8_A)
64 : :
65 : : # if defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT) || \
66 : : defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_ONLY)
67 : : # if !defined(MBEDTLS_HAVE_NEON_INTRINSICS)
68 : : # if defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT)
69 : : # warning "Target does not support NEON instructions"
70 : : # undef MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT
71 : : # else
72 : : # error "Target does not support NEON instructions"
73 : : # endif
74 : : # endif
75 : : # endif
76 : :
77 : : # if defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT) || \
78 : : defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_ONLY)
79 : : /* *INDENT-OFF* */
80 : :
81 : : # if !defined(__ARM_FEATURE_CRYPTO) || defined(MBEDTLS_ENABLE_ARM_CRYPTO_EXTENSIONS_COMPILER_FLAG)
82 : : # if defined(__ARMCOMPILER_VERSION)
83 : : # if __ARMCOMPILER_VERSION <= 6090000
84 : : # error "Must use minimum -march=armv8-a+crypto for MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_*"
85 : : # endif
86 : : # pragma clang attribute push (__attribute__((target("sha2"))), apply_to=function)
87 : : # define MBEDTLS_POP_TARGET_PRAGMA
88 : : # elif defined(__clang__)
89 : : # if __clang_major__ < 4
90 : : # error "A more recent Clang is required for MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_*"
91 : : # endif
92 : : # pragma clang attribute push (__attribute__((target("crypto"))), apply_to=function)
93 : : # define MBEDTLS_POP_TARGET_PRAGMA
94 : : # elif defined(__GNUC__)
95 : : /* FIXME: GCC 5 claims to support Armv8 Crypto Extensions, but some
96 : : * intrinsics are missing. Missing intrinsics could be worked around.
97 : : */
98 : : # if __GNUC__ < 6
99 : : # error "A more recent GCC is required for MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_*"
100 : : # else
101 : : # pragma GCC push_options
102 : : # pragma GCC target ("arch=armv8-a+crypto")
103 : : # define MBEDTLS_POP_TARGET_PRAGMA
104 : : # endif
105 : : # else
106 : : # error "Only GCC and Clang supported for MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_*"
107 : : # endif
108 : : # endif
109 : : /* *INDENT-ON* */
110 : :
111 : : # endif
112 : : # if defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT)
113 : : # if defined(__unix__)
114 : : # if defined(__linux__)
115 : : /* Our preferred method of detection is getauxval() */
116 : : # include <sys/auxv.h>
117 : : /* These are not always defined via sys/auxv.h */
118 : : # if !defined(HWCAP_SHA2)
119 : : # define HWCAP_SHA2 (1 << 6)
120 : : # endif
121 : : # if !defined(HWCAP2_SHA2)
122 : : # define HWCAP2_SHA2 (1 << 3)
123 : : # endif
124 : : # endif
125 : : /* Use SIGILL on Unix, and fall back to it on Linux */
126 : : # include <signal.h>
127 : : # endif
128 : : # endif
129 : : #elif !defined(MBEDTLS_PLATFORM_IS_WINDOWS_ON_ARM64)
130 : : # undef MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_ONLY
131 : : # undef MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT
132 : : #endif
133 : :
134 : : #if defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT)
135 : : /*
136 : : * Capability detection code comes early, so we can disable
137 : : * MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT if no detection mechanism found
138 : : */
139 : : #if defined(MBEDTLS_ARCH_IS_ARM64) && defined(HWCAP_SHA2)
140 : : static int mbedtls_a64_crypto_sha256_determine_support(void)
141 : : {
142 : : return (getauxval(AT_HWCAP) & HWCAP_SHA2) ? 1 : 0;
143 : : }
144 : : #elif defined(MBEDTLS_ARCH_IS_ARM32) && defined(HWCAP2_SHA2)
145 : : static int mbedtls_a64_crypto_sha256_determine_support(void)
146 : : {
147 : : return (getauxval(AT_HWCAP2) & HWCAP2_SHA2) ? 1 : 0;
148 : : }
149 : : #elif defined(__APPLE__)
150 : : static int mbedtls_a64_crypto_sha256_determine_support(void)
151 : : {
152 : : return 1;
153 : : }
154 : : #elif defined(MBEDTLS_PLATFORM_IS_WINDOWS_ON_ARM64)
155 : : #ifndef WIN32_LEAN_AND_MEAN
156 : : #define WIN32_LEAN_AND_MEAN
157 : : #endif
158 : : #include <Windows.h>
159 : : #include <processthreadsapi.h>
160 : :
161 : : static int mbedtls_a64_crypto_sha256_determine_support(void)
162 : : {
163 : : return IsProcessorFeaturePresent(PF_ARM_V8_CRYPTO_INSTRUCTIONS_AVAILABLE) ?
164 : : 1 : 0;
165 : : }
166 : : #elif defined(__unix__) && defined(SIG_SETMASK)
167 : : /* Detection with SIGILL, setjmp() and longjmp() */
168 : : #include <signal.h>
169 : : #include <setjmp.h>
170 : :
171 : : static jmp_buf return_from_sigill;
172 : :
173 : : /*
174 : : * Armv8-A SHA256 support detection via SIGILL
175 : : */
176 : : static void sigill_handler(int signal)
177 : : {
178 : : (void) signal;
179 : : longjmp(return_from_sigill, 1);
180 : : }
181 : :
182 : : static int mbedtls_a64_crypto_sha256_determine_support(void)
183 : : {
184 : : struct sigaction old_action, new_action;
185 : :
186 : : sigset_t old_mask;
187 : : if (sigprocmask(0, NULL, &old_mask)) {
188 : : return 0;
189 : : }
190 : :
191 : : sigemptyset(&new_action.sa_mask);
192 : : new_action.sa_flags = 0;
193 : : new_action.sa_handler = sigill_handler;
194 : :
195 : : sigaction(SIGILL, &new_action, &old_action);
196 : :
197 : : static int ret = 0;
198 : :
199 : : if (setjmp(return_from_sigill) == 0) { /* First return only */
200 : : /* If this traps, we will return a second time from setjmp() with 1 */
201 : : #if defined(MBEDTLS_ARCH_IS_ARM64)
202 : : asm volatile ("sha256h q0, q0, v0.4s" : : : "v0");
203 : : #else
204 : : asm volatile ("sha256h.32 q0, q0, q0" : : : "q0");
205 : : #endif
206 : : ret = 1;
207 : : }
208 : :
209 : : sigaction(SIGILL, &old_action, NULL);
210 : : sigprocmask(SIG_SETMASK, &old_mask, NULL);
211 : :
212 : : return ret;
213 : : }
214 : : #else
215 : : #warning "No mechanism to detect ARMV8_CRYPTO found, using C code only"
216 : : #undef MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT
217 : : #endif /* HWCAP_SHA2, __APPLE__, __unix__ && SIG_SETMASK */
218 : :
219 : : #endif /* MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT */
220 : :
221 : : #if !defined(MBEDTLS_SHA256_ALT)
222 : :
223 : : #define SHA256_BLOCK_SIZE 64
224 : :
225 : 350 : void mbedtls_sha256_init(mbedtls_sha256_context *ctx)
226 : : {
227 : 350 : memset(ctx, 0, sizeof(mbedtls_sha256_context));
228 : 350 : }
229 : :
230 : 776 : void mbedtls_sha256_free(mbedtls_sha256_context *ctx)
231 : : {
232 [ + - ]: 776 : if (ctx == NULL) {
233 : : return;
234 : : }
235 : :
236 : 776 : mbedtls_platform_zeroize(ctx, sizeof(mbedtls_sha256_context));
237 : : }
238 : :
239 : 0 : void mbedtls_sha256_clone(mbedtls_sha256_context *dst,
240 : : const mbedtls_sha256_context *src)
241 : : {
242 : 0 : *dst = *src;
243 : 0 : }
244 : :
245 : : /*
246 : : * SHA-256 context setup
247 : : */
248 : 430 : int mbedtls_sha256_starts(mbedtls_sha256_context *ctx, int is224)
249 : : {
250 : : #if defined(MBEDTLS_SHA224_C) && defined(MBEDTLS_SHA256_C)
251 [ + - ]: 430 : if (is224 != 0 && is224 != 1) {
252 : : return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
253 : : }
254 : : #elif defined(MBEDTLS_SHA256_C)
255 : : if (is224 != 0) {
256 : : return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
257 : : }
258 : : #else /* defined MBEDTLS_SHA224_C only */
259 : : if (is224 == 0) {
260 : : return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
261 : : }
262 : : #endif
263 : :
264 : 430 : ctx->total[0] = 0;
265 : 430 : ctx->total[1] = 0;
266 : :
267 [ + - ]: 430 : if (is224 == 0) {
268 : : #if defined(MBEDTLS_SHA256_C)
269 : 430 : ctx->state[0] = 0x6A09E667;
270 : 430 : ctx->state[1] = 0xBB67AE85;
271 : 430 : ctx->state[2] = 0x3C6EF372;
272 : 430 : ctx->state[3] = 0xA54FF53A;
273 : 430 : ctx->state[4] = 0x510E527F;
274 : 430 : ctx->state[5] = 0x9B05688C;
275 : 430 : ctx->state[6] = 0x1F83D9AB;
276 : 430 : ctx->state[7] = 0x5BE0CD19;
277 : : #endif
278 : : } else {
279 : : #if defined(MBEDTLS_SHA224_C)
280 : 0 : ctx->state[0] = 0xC1059ED8;
281 : 0 : ctx->state[1] = 0x367CD507;
282 : 0 : ctx->state[2] = 0x3070DD17;
283 : 0 : ctx->state[3] = 0xF70E5939;
284 : 0 : ctx->state[4] = 0xFFC00B31;
285 : 0 : ctx->state[5] = 0x68581511;
286 : 0 : ctx->state[6] = 0x64F98FA7;
287 : 0 : ctx->state[7] = 0xBEFA4FA4;
288 : : #endif
289 : : }
290 : :
291 : : #if defined(MBEDTLS_SHA224_C)
292 : 430 : ctx->is224 = is224;
293 : : #endif
294 : :
295 : 430 : return 0;
296 : : }
297 : :
298 : : #if !defined(MBEDTLS_SHA256_PROCESS_ALT)
299 : : static const uint32_t K[] =
300 : : {
301 : : 0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5,
302 : : 0x3956C25B, 0x59F111F1, 0x923F82A4, 0xAB1C5ED5,
303 : : 0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3,
304 : : 0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174,
305 : : 0xE49B69C1, 0xEFBE4786, 0x0FC19DC6, 0x240CA1CC,
306 : : 0x2DE92C6F, 0x4A7484AA, 0x5CB0A9DC, 0x76F988DA,
307 : : 0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7,
308 : : 0xC6E00BF3, 0xD5A79147, 0x06CA6351, 0x14292967,
309 : : 0x27B70A85, 0x2E1B2138, 0x4D2C6DFC, 0x53380D13,
310 : : 0x650A7354, 0x766A0ABB, 0x81C2C92E, 0x92722C85,
311 : : 0xA2BFE8A1, 0xA81A664B, 0xC24B8B70, 0xC76C51A3,
312 : : 0xD192E819, 0xD6990624, 0xF40E3585, 0x106AA070,
313 : : 0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5,
314 : : 0x391C0CB3, 0x4ED8AA4A, 0x5B9CCA4F, 0x682E6FF3,
315 : : 0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208,
316 : : 0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2,
317 : : };
318 : :
319 : : #endif
320 : :
321 : : #if defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT) || \
322 : : defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_ONLY)
323 : :
324 : : #if defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_ONLY)
325 : : # define mbedtls_internal_sha256_process_many_a64_crypto mbedtls_internal_sha256_process_many
326 : : # define mbedtls_internal_sha256_process_a64_crypto mbedtls_internal_sha256_process
327 : : #endif
328 : :
329 : : static size_t mbedtls_internal_sha256_process_many_a64_crypto(
330 : : mbedtls_sha256_context *ctx, const uint8_t *msg, size_t len)
331 : : {
332 : : uint32x4_t abcd = vld1q_u32(&ctx->state[0]);
333 : : uint32x4_t efgh = vld1q_u32(&ctx->state[4]);
334 : :
335 : : size_t processed = 0;
336 : :
337 : : for (;
338 : : len >= SHA256_BLOCK_SIZE;
339 : : processed += SHA256_BLOCK_SIZE,
340 : : msg += SHA256_BLOCK_SIZE,
341 : : len -= SHA256_BLOCK_SIZE) {
342 : : uint32x4_t tmp, abcd_prev;
343 : :
344 : : uint32x4_t abcd_orig = abcd;
345 : : uint32x4_t efgh_orig = efgh;
346 : :
347 : : uint32x4_t sched0 = vreinterpretq_u32_u8(vld1q_u8(msg + 16 * 0));
348 : : uint32x4_t sched1 = vreinterpretq_u32_u8(vld1q_u8(msg + 16 * 1));
349 : : uint32x4_t sched2 = vreinterpretq_u32_u8(vld1q_u8(msg + 16 * 2));
350 : : uint32x4_t sched3 = vreinterpretq_u32_u8(vld1q_u8(msg + 16 * 3));
351 : :
352 : : #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ /* Will be true if not defined */
353 : : /* Untested on BE */
354 : : sched0 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(sched0)));
355 : : sched1 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(sched1)));
356 : : sched2 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(sched2)));
357 : : sched3 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(sched3)));
358 : : #endif
359 : :
360 : : /* Rounds 0 to 3 */
361 : : tmp = vaddq_u32(sched0, vld1q_u32(&K[0]));
362 : : abcd_prev = abcd;
363 : : abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
364 : : efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
365 : :
366 : : /* Rounds 4 to 7 */
367 : : tmp = vaddq_u32(sched1, vld1q_u32(&K[4]));
368 : : abcd_prev = abcd;
369 : : abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
370 : : efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
371 : :
372 : : /* Rounds 8 to 11 */
373 : : tmp = vaddq_u32(sched2, vld1q_u32(&K[8]));
374 : : abcd_prev = abcd;
375 : : abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
376 : : efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
377 : :
378 : : /* Rounds 12 to 15 */
379 : : tmp = vaddq_u32(sched3, vld1q_u32(&K[12]));
380 : : abcd_prev = abcd;
381 : : abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
382 : : efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
383 : :
384 : : for (int t = 16; t < 64; t += 16) {
385 : : /* Rounds t to t + 3 */
386 : : sched0 = vsha256su1q_u32(vsha256su0q_u32(sched0, sched1), sched2, sched3);
387 : : tmp = vaddq_u32(sched0, vld1q_u32(&K[t]));
388 : : abcd_prev = abcd;
389 : : abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
390 : : efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
391 : :
392 : : /* Rounds t + 4 to t + 7 */
393 : : sched1 = vsha256su1q_u32(vsha256su0q_u32(sched1, sched2), sched3, sched0);
394 : : tmp = vaddq_u32(sched1, vld1q_u32(&K[t + 4]));
395 : : abcd_prev = abcd;
396 : : abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
397 : : efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
398 : :
399 : : /* Rounds t + 8 to t + 11 */
400 : : sched2 = vsha256su1q_u32(vsha256su0q_u32(sched2, sched3), sched0, sched1);
401 : : tmp = vaddq_u32(sched2, vld1q_u32(&K[t + 8]));
402 : : abcd_prev = abcd;
403 : : abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
404 : : efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
405 : :
406 : : /* Rounds t + 12 to t + 15 */
407 : : sched3 = vsha256su1q_u32(vsha256su0q_u32(sched3, sched0), sched1, sched2);
408 : : tmp = vaddq_u32(sched3, vld1q_u32(&K[t + 12]));
409 : : abcd_prev = abcd;
410 : : abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
411 : : efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
412 : : }
413 : :
414 : : abcd = vaddq_u32(abcd, abcd_orig);
415 : : efgh = vaddq_u32(efgh, efgh_orig);
416 : : }
417 : :
418 : : vst1q_u32(&ctx->state[0], abcd);
419 : : vst1q_u32(&ctx->state[4], efgh);
420 : :
421 : : return processed;
422 : : }
423 : :
424 : : #if defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT)
425 : : /*
426 : : * This function is for internal use only if we are building both C and Armv8-A
427 : : * versions, otherwise it is renamed to be the public mbedtls_internal_sha256_process()
428 : : */
429 : : static
430 : : #endif
431 : : int mbedtls_internal_sha256_process_a64_crypto(mbedtls_sha256_context *ctx,
432 : : const unsigned char data[SHA256_BLOCK_SIZE])
433 : : {
434 : : return (mbedtls_internal_sha256_process_many_a64_crypto(ctx, data,
435 : : SHA256_BLOCK_SIZE) ==
436 : : SHA256_BLOCK_SIZE) ? 0 : -1;
437 : : }
438 : :
439 : : #endif /* MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT || MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_ONLY */
440 : :
441 : : #if defined(MBEDTLS_POP_TARGET_PRAGMA)
442 : : #if defined(__clang__)
443 : : #pragma clang attribute pop
444 : : #elif defined(__GNUC__)
445 : : #pragma GCC pop_options
446 : : #endif
447 : : #undef MBEDTLS_POP_TARGET_PRAGMA
448 : : #endif
449 : :
450 : : #if !defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT)
451 : : #define mbedtls_internal_sha256_process_many_c mbedtls_internal_sha256_process_many
452 : : #define mbedtls_internal_sha256_process_c mbedtls_internal_sha256_process
453 : : #endif
454 : :
455 : :
456 : : #if !defined(MBEDTLS_SHA256_PROCESS_ALT) && \
457 : : !defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_ONLY)
458 : :
459 : : #define SHR(x, n) (((x) & 0xFFFFFFFF) >> (n))
460 : : #define ROTR(x, n) (SHR(x, n) | ((x) << (32 - (n))))
461 : :
462 : : #define S0(x) (ROTR(x, 7) ^ ROTR(x, 18) ^ SHR(x, 3))
463 : : #define S1(x) (ROTR(x, 17) ^ ROTR(x, 19) ^ SHR(x, 10))
464 : :
465 : : #define S2(x) (ROTR(x, 2) ^ ROTR(x, 13) ^ ROTR(x, 22))
466 : : #define S3(x) (ROTR(x, 6) ^ ROTR(x, 11) ^ ROTR(x, 25))
467 : :
468 : : #define F0(x, y, z) (((x) & (y)) | ((z) & ((x) | (y))))
469 : : #define F1(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
470 : :
471 : : #define R(t) \
472 : : ( \
473 : : local.W[t] = S1(local.W[(t) - 2]) + local.W[(t) - 7] + \
474 : : S0(local.W[(t) - 15]) + local.W[(t) - 16] \
475 : : )
476 : :
477 : : #define P(a, b, c, d, e, f, g, h, x, K) \
478 : : do \
479 : : { \
480 : : local.temp1 = (h) + S3(e) + F1((e), (f), (g)) + (K) + (x); \
481 : : local.temp2 = S2(a) + F0((a), (b), (c)); \
482 : : (d) += local.temp1; (h) = local.temp1 + local.temp2; \
483 : : } while (0)
484 : :
485 : : #if defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT)
486 : : /*
487 : : * This function is for internal use only if we are building both C and Armv8
488 : : * versions, otherwise it is renamed to be the public mbedtls_internal_sha256_process()
489 : : */
490 : : static
491 : : #endif
492 : 1088 : int mbedtls_internal_sha256_process_c(mbedtls_sha256_context *ctx,
493 : : const unsigned char data[SHA256_BLOCK_SIZE])
494 : : {
495 : 1088 : struct {
496 : : uint32_t temp1, temp2, W[64];
497 : : uint32_t A[8];
498 : : } local;
499 : :
500 : 1088 : unsigned int i;
501 : :
502 [ + + ]: 9792 : for (i = 0; i < 8; i++) {
503 : 8704 : local.A[i] = ctx->state[i];
504 : : }
505 : :
506 : : #if defined(MBEDTLS_SHA256_SMALLER)
507 : : for (i = 0; i < 64; i++) {
508 : : if (i < 16) {
509 : : local.W[i] = MBEDTLS_GET_UINT32_BE(data, 4 * i);
510 : : } else {
511 : : R(i);
512 : : }
513 : :
514 : : P(local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
515 : : local.A[5], local.A[6], local.A[7], local.W[i], K[i]);
516 : :
517 : : local.temp1 = local.A[7]; local.A[7] = local.A[6];
518 : : local.A[6] = local.A[5]; local.A[5] = local.A[4];
519 : : local.A[4] = local.A[3]; local.A[3] = local.A[2];
520 : : local.A[2] = local.A[1]; local.A[1] = local.A[0];
521 : : local.A[0] = local.temp1;
522 : : }
523 : : #else /* MBEDTLS_SHA256_SMALLER */
524 [ + + ]: 18496 : for (i = 0; i < 16; i++) {
525 : 17408 : local.W[i] = MBEDTLS_GET_UINT32_BE(data, 4 * i);
526 : : }
527 : :
528 [ + + ]: 3264 : for (i = 0; i < 16; i += 8) {
529 : 2176 : P(local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
530 : : local.A[5], local.A[6], local.A[7], local.W[i+0], K[i+0]);
531 : 2176 : P(local.A[7], local.A[0], local.A[1], local.A[2], local.A[3],
532 : : local.A[4], local.A[5], local.A[6], local.W[i+1], K[i+1]);
533 : 2176 : P(local.A[6], local.A[7], local.A[0], local.A[1], local.A[2],
534 : : local.A[3], local.A[4], local.A[5], local.W[i+2], K[i+2]);
535 : 2176 : P(local.A[5], local.A[6], local.A[7], local.A[0], local.A[1],
536 : : local.A[2], local.A[3], local.A[4], local.W[i+3], K[i+3]);
537 : 2176 : P(local.A[4], local.A[5], local.A[6], local.A[7], local.A[0],
538 : : local.A[1], local.A[2], local.A[3], local.W[i+4], K[i+4]);
539 : 2176 : P(local.A[3], local.A[4], local.A[5], local.A[6], local.A[7],
540 : : local.A[0], local.A[1], local.A[2], local.W[i+5], K[i+5]);
541 : 2176 : P(local.A[2], local.A[3], local.A[4], local.A[5], local.A[6],
542 : : local.A[7], local.A[0], local.A[1], local.W[i+6], K[i+6]);
543 : 2176 : P(local.A[1], local.A[2], local.A[3], local.A[4], local.A[5],
544 : : local.A[6], local.A[7], local.A[0], local.W[i+7], K[i+7]);
545 : : }
546 : :
547 [ + + ]: 7616 : for (i = 16; i < 64; i += 8) {
548 : 6528 : P(local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
549 : : local.A[5], local.A[6], local.A[7], R(i+0), K[i+0]);
550 : 6528 : P(local.A[7], local.A[0], local.A[1], local.A[2], local.A[3],
551 : : local.A[4], local.A[5], local.A[6], R(i+1), K[i+1]);
552 : 6528 : P(local.A[6], local.A[7], local.A[0], local.A[1], local.A[2],
553 : : local.A[3], local.A[4], local.A[5], R(i+2), K[i+2]);
554 : 6528 : P(local.A[5], local.A[6], local.A[7], local.A[0], local.A[1],
555 : : local.A[2], local.A[3], local.A[4], R(i+3), K[i+3]);
556 : 6528 : P(local.A[4], local.A[5], local.A[6], local.A[7], local.A[0],
557 : : local.A[1], local.A[2], local.A[3], R(i+4), K[i+4]);
558 : 6528 : P(local.A[3], local.A[4], local.A[5], local.A[6], local.A[7],
559 : : local.A[0], local.A[1], local.A[2], R(i+5), K[i+5]);
560 : 6528 : P(local.A[2], local.A[3], local.A[4], local.A[5], local.A[6],
561 : : local.A[7], local.A[0], local.A[1], R(i+6), K[i+6]);
562 : 6528 : P(local.A[1], local.A[2], local.A[3], local.A[4], local.A[5],
563 : : local.A[6], local.A[7], local.A[0], R(i+7), K[i+7]);
564 : : }
565 : : #endif /* MBEDTLS_SHA256_SMALLER */
566 : :
567 [ + + ]: 9792 : for (i = 0; i < 8; i++) {
568 : 8704 : ctx->state[i] += local.A[i];
569 : : }
570 : :
571 : : /* Zeroise buffers and variables to clear sensitive data from memory. */
572 : 1088 : mbedtls_platform_zeroize(&local, sizeof(local));
573 : :
574 : 1088 : return 0;
575 : : }
576 : :
577 : : #endif /* !MBEDTLS_SHA256_PROCESS_ALT && !MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_ONLY */
578 : :
579 : :
580 : : #if !defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_ONLY)
581 : :
582 : 461 : static size_t mbedtls_internal_sha256_process_many_c(
583 : : mbedtls_sha256_context *ctx, const uint8_t *data, size_t len)
584 : : {
585 : 461 : size_t processed = 0;
586 : :
587 [ + + ]: 1116 : while (len >= SHA256_BLOCK_SIZE) {
588 [ + - ]: 655 : if (mbedtls_internal_sha256_process_c(ctx, data) != 0) {
589 : : return 0;
590 : : }
591 : :
592 : 655 : data += SHA256_BLOCK_SIZE;
593 : 655 : len -= SHA256_BLOCK_SIZE;
594 : :
595 : 655 : processed += SHA256_BLOCK_SIZE;
596 : : }
597 : :
598 : : return processed;
599 : : }
600 : :
601 : : #endif /* !MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_ONLY */
602 : :
603 : :
604 : : #if defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT)
605 : :
606 : : static int mbedtls_a64_crypto_sha256_has_support(void)
607 : : {
608 : : static int done = 0;
609 : : static int supported = 0;
610 : :
611 : : if (!done) {
612 : : supported = mbedtls_a64_crypto_sha256_determine_support();
613 : : done = 1;
614 : : }
615 : :
616 : : return supported;
617 : : }
618 : :
619 : : static size_t mbedtls_internal_sha256_process_many(mbedtls_sha256_context *ctx,
620 : : const uint8_t *msg, size_t len)
621 : : {
622 : : if (mbedtls_a64_crypto_sha256_has_support()) {
623 : : return mbedtls_internal_sha256_process_many_a64_crypto(ctx, msg, len);
624 : : } else {
625 : : return mbedtls_internal_sha256_process_many_c(ctx, msg, len);
626 : : }
627 : : }
628 : :
629 : : int mbedtls_internal_sha256_process(mbedtls_sha256_context *ctx,
630 : : const unsigned char data[SHA256_BLOCK_SIZE])
631 : : {
632 : : if (mbedtls_a64_crypto_sha256_has_support()) {
633 : : return mbedtls_internal_sha256_process_a64_crypto(ctx, data);
634 : : } else {
635 : : return mbedtls_internal_sha256_process_c(ctx, data);
636 : : }
637 : : }
638 : :
639 : : #endif /* MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT */
640 : :
641 : :
642 : : /*
643 : : * SHA-256 process buffer
644 : : */
645 : 837 : int mbedtls_sha256_update(mbedtls_sha256_context *ctx,
646 : : const unsigned char *input,
647 : : size_t ilen)
648 : : {
649 : 837 : int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
650 : 837 : size_t fill;
651 : 837 : uint32_t left;
652 : :
653 [ - + ]: 837 : if (ilen == 0) {
654 : : return 0;
655 : : }
656 : :
657 : 837 : left = ctx->total[0] & 0x3F;
658 : 837 : fill = SHA256_BLOCK_SIZE - left;
659 : :
660 : 837 : ctx->total[0] += (uint32_t) ilen;
661 : 837 : ctx->total[0] &= 0xFFFFFFFF;
662 : :
663 [ - + ]: 837 : if (ctx->total[0] < (uint32_t) ilen) {
664 : 0 : ctx->total[1]++;
665 : : }
666 : :
667 [ + + ]: 837 : if (left && ilen >= fill) {
668 : 3 : memcpy((void *) (ctx->buffer + left), input, fill);
669 : :
670 [ + - ]: 3 : if ((ret = mbedtls_internal_sha256_process(ctx, ctx->buffer)) != 0) {
671 : : return ret;
672 : : }
673 : :
674 : 3 : input += fill;
675 : 3 : ilen -= fill;
676 : 3 : left = 0;
677 : : }
678 : :
679 [ + + ]: 1298 : while (ilen >= SHA256_BLOCK_SIZE) {
680 : 461 : size_t processed =
681 : 461 : mbedtls_internal_sha256_process_many(ctx, input, ilen);
682 [ + - ]: 461 : if (processed < SHA256_BLOCK_SIZE) {
683 : : return MBEDTLS_ERR_ERROR_GENERIC_ERROR;
684 : : }
685 : :
686 : 461 : input += processed;
687 : 461 : ilen -= processed;
688 : : }
689 : :
690 [ + + ]: 837 : if (ilen > 0) {
691 : 446 : memcpy((void *) (ctx->buffer + left), input, ilen);
692 : : }
693 : :
694 : : return 0;
695 : : }
696 : :
697 : : /*
698 : : * SHA-256 final digest
699 : : */
700 : 428 : int mbedtls_sha256_finish(mbedtls_sha256_context *ctx,
701 : : unsigned char *output)
702 : : {
703 : 428 : int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
704 : 428 : uint32_t used;
705 : 428 : uint32_t high, low;
706 : 428 : int truncated = 0;
707 : :
708 : : /*
709 : : * Add padding: 0x80 then 0x00 until 8 bytes remain for the length
710 : : */
711 : 428 : used = ctx->total[0] & 0x3F;
712 : :
713 : 428 : ctx->buffer[used++] = 0x80;
714 : :
715 [ + + ]: 428 : if (used <= 56) {
716 : : /* Enough room for padding + length in current block */
717 : 426 : memset(ctx->buffer + used, 0, 56 - used);
718 : : } else {
719 : : /* We'll need an extra block */
720 : 2 : memset(ctx->buffer + used, 0, SHA256_BLOCK_SIZE - used);
721 : :
722 [ - + ]: 2 : if ((ret = mbedtls_internal_sha256_process(ctx, ctx->buffer)) != 0) {
723 : 0 : goto exit;
724 : : }
725 : :
726 : 2 : memset(ctx->buffer, 0, 56);
727 : : }
728 : :
729 : : /*
730 : : * Add message length
731 : : */
732 : 428 : high = (ctx->total[0] >> 29)
733 : 428 : | (ctx->total[1] << 3);
734 : 428 : low = (ctx->total[0] << 3);
735 : :
736 : 428 : MBEDTLS_PUT_UINT32_BE(high, ctx->buffer, 56);
737 : 428 : MBEDTLS_PUT_UINT32_BE(low, ctx->buffer, 60);
738 : :
739 [ - + ]: 428 : if ((ret = mbedtls_internal_sha256_process(ctx, ctx->buffer)) != 0) {
740 : 0 : goto exit;
741 : : }
742 : :
743 : : /*
744 : : * Output final state
745 : : */
746 [ + - ]: 428 : MBEDTLS_PUT_UINT32_BE(ctx->state[0], output, 0);
747 : 428 : MBEDTLS_PUT_UINT32_BE(ctx->state[1], output, 4);
748 : 428 : MBEDTLS_PUT_UINT32_BE(ctx->state[2], output, 8);
749 : 428 : MBEDTLS_PUT_UINT32_BE(ctx->state[3], output, 12);
750 : 428 : MBEDTLS_PUT_UINT32_BE(ctx->state[4], output, 16);
751 : 428 : MBEDTLS_PUT_UINT32_BE(ctx->state[5], output, 20);
752 : 428 : MBEDTLS_PUT_UINT32_BE(ctx->state[6], output, 24);
753 : :
754 : : #if defined(MBEDTLS_SHA224_C)
755 : 428 : truncated = ctx->is224;
756 : : #endif
757 [ + - ]: 428 : if (!truncated) {
758 : 428 : MBEDTLS_PUT_UINT32_BE(ctx->state[7], output, 28);
759 : : }
760 : :
761 : : ret = 0;
762 : :
763 : 428 : exit:
764 : 428 : mbedtls_sha256_free(ctx);
765 : 428 : return ret;
766 : : }
767 : :
768 : : #endif /* !MBEDTLS_SHA256_ALT */
769 : :
770 : : /*
771 : : * output = SHA-256( input buffer )
772 : : */
773 : 4 : int mbedtls_sha256(const unsigned char *input,
774 : : size_t ilen,
775 : : unsigned char *output,
776 : : int is224)
777 : : {
778 : 4 : int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
779 : 4 : mbedtls_sha256_context ctx;
780 : :
781 : : #if defined(MBEDTLS_SHA224_C) && defined(MBEDTLS_SHA256_C)
782 [ + - ]: 4 : if (is224 != 0 && is224 != 1) {
783 : : return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
784 : : }
785 : : #elif defined(MBEDTLS_SHA256_C)
786 : : if (is224 != 0) {
787 : : return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
788 : : }
789 : : #else /* defined MBEDTLS_SHA224_C only */
790 : : if (is224 == 0) {
791 : : return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
792 : : }
793 : : #endif
794 : :
795 : 4 : mbedtls_sha256_init(&ctx);
796 : :
797 [ - + ]: 4 : if ((ret = mbedtls_sha256_starts(&ctx, is224)) != 0) {
798 : 0 : goto exit;
799 : : }
800 : :
801 [ - + ]: 4 : if ((ret = mbedtls_sha256_update(&ctx, input, ilen)) != 0) {
802 : 0 : goto exit;
803 : : }
804 : :
805 : 4 : if ((ret = mbedtls_sha256_finish(&ctx, output)) != 0) {
806 : : goto exit;
807 : : }
808 : :
809 : 4 : exit:
810 : 4 : mbedtls_sha256_free(&ctx);
811 : :
812 : 4 : return ret;
813 : : }
814 : :
815 : : #if defined(MBEDTLS_SELF_TEST)
816 : : /*
817 : : * FIPS-180-2 test vectors
818 : : */
819 : : static const unsigned char sha_test_buf[3][57] =
820 : : {
821 : : { "abc" },
822 : : { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" },
823 : : { "" }
824 : : };
825 : :
826 : : static const size_t sha_test_buflen[3] =
827 : : {
828 : : 3, 56, 1000
829 : : };
830 : :
831 : : typedef const unsigned char (sha_test_sum_t)[32];
832 : :
833 : : /*
834 : : * SHA-224 test vectors
835 : : */
836 : : #if defined(MBEDTLS_SHA224_C)
837 : : static sha_test_sum_t sha224_test_sum[] =
838 : : {
839 : : { 0x23, 0x09, 0x7D, 0x22, 0x34, 0x05, 0xD8, 0x22,
840 : : 0x86, 0x42, 0xA4, 0x77, 0xBD, 0xA2, 0x55, 0xB3,
841 : : 0x2A, 0xAD, 0xBC, 0xE4, 0xBD, 0xA0, 0xB3, 0xF7,
842 : : 0xE3, 0x6C, 0x9D, 0xA7 },
843 : : { 0x75, 0x38, 0x8B, 0x16, 0x51, 0x27, 0x76, 0xCC,
844 : : 0x5D, 0xBA, 0x5D, 0xA1, 0xFD, 0x89, 0x01, 0x50,
845 : : 0xB0, 0xC6, 0x45, 0x5C, 0xB4, 0xF5, 0x8B, 0x19,
846 : : 0x52, 0x52, 0x25, 0x25 },
847 : : { 0x20, 0x79, 0x46, 0x55, 0x98, 0x0C, 0x91, 0xD8,
848 : : 0xBB, 0xB4, 0xC1, 0xEA, 0x97, 0x61, 0x8A, 0x4B,
849 : : 0xF0, 0x3F, 0x42, 0x58, 0x19, 0x48, 0xB2, 0xEE,
850 : : 0x4E, 0xE7, 0xAD, 0x67 }
851 : : };
852 : : #endif
853 : :
854 : : /*
855 : : * SHA-256 test vectors
856 : : */
857 : : #if defined(MBEDTLS_SHA256_C)
858 : : static sha_test_sum_t sha256_test_sum[] =
859 : : {
860 : : { 0xBA, 0x78, 0x16, 0xBF, 0x8F, 0x01, 0xCF, 0xEA,
861 : : 0x41, 0x41, 0x40, 0xDE, 0x5D, 0xAE, 0x22, 0x23,
862 : : 0xB0, 0x03, 0x61, 0xA3, 0x96, 0x17, 0x7A, 0x9C,
863 : : 0xB4, 0x10, 0xFF, 0x61, 0xF2, 0x00, 0x15, 0xAD },
864 : : { 0x24, 0x8D, 0x6A, 0x61, 0xD2, 0x06, 0x38, 0xB8,
865 : : 0xE5, 0xC0, 0x26, 0x93, 0x0C, 0x3E, 0x60, 0x39,
866 : : 0xA3, 0x3C, 0xE4, 0x59, 0x64, 0xFF, 0x21, 0x67,
867 : : 0xF6, 0xEC, 0xED, 0xD4, 0x19, 0xDB, 0x06, 0xC1 },
868 : : { 0xCD, 0xC7, 0x6E, 0x5C, 0x99, 0x14, 0xFB, 0x92,
869 : : 0x81, 0xA1, 0xC7, 0xE2, 0x84, 0xD7, 0x3E, 0x67,
870 : : 0xF1, 0x80, 0x9A, 0x48, 0xA4, 0x97, 0x20, 0x0E,
871 : : 0x04, 0x6D, 0x39, 0xCC, 0xC7, 0x11, 0x2C, 0xD0 }
872 : : };
873 : : #endif
874 : :
875 : : /*
876 : : * Checkup routine
877 : : */
878 : : static int mbedtls_sha256_common_self_test(int verbose, int is224)
879 : : {
880 : : int i, buflen, ret = 0;
881 : : unsigned char *buf;
882 : : unsigned char sha256sum[32];
883 : : mbedtls_sha256_context ctx;
884 : :
885 : : #if defined(MBEDTLS_SHA224_C) && defined(MBEDTLS_SHA256_C)
886 : : sha_test_sum_t *sha_test_sum = (is224) ? sha224_test_sum : sha256_test_sum;
887 : : #elif defined(MBEDTLS_SHA256_C)
888 : : sha_test_sum_t *sha_test_sum = sha256_test_sum;
889 : : #else
890 : : sha_test_sum_t *sha_test_sum = sha224_test_sum;
891 : : #endif
892 : :
893 : : buf = mbedtls_calloc(1024, sizeof(unsigned char));
894 : : if (NULL == buf) {
895 : : if (verbose != 0) {
896 : : mbedtls_printf("Buffer allocation failed\n");
897 : : }
898 : :
899 : : return 1;
900 : : }
901 : :
902 : : mbedtls_sha256_init(&ctx);
903 : :
904 : : for (i = 0; i < 3; i++) {
905 : : if (verbose != 0) {
906 : : mbedtls_printf(" SHA-%d test #%d: ", 256 - is224 * 32, i + 1);
907 : : }
908 : :
909 : : if ((ret = mbedtls_sha256_starts(&ctx, is224)) != 0) {
910 : : goto fail;
911 : : }
912 : :
913 : : if (i == 2) {
914 : : memset(buf, 'a', buflen = 1000);
915 : :
916 : : for (int j = 0; j < 1000; j++) {
917 : : ret = mbedtls_sha256_update(&ctx, buf, buflen);
918 : : if (ret != 0) {
919 : : goto fail;
920 : : }
921 : : }
922 : :
923 : : } else {
924 : : ret = mbedtls_sha256_update(&ctx, sha_test_buf[i],
925 : : sha_test_buflen[i]);
926 : : if (ret != 0) {
927 : : goto fail;
928 : : }
929 : : }
930 : :
931 : : if ((ret = mbedtls_sha256_finish(&ctx, sha256sum)) != 0) {
932 : : goto fail;
933 : : }
934 : :
935 : :
936 : : if (memcmp(sha256sum, sha_test_sum[i], 32 - is224 * 4) != 0) {
937 : : ret = 1;
938 : : goto fail;
939 : : }
940 : :
941 : : if (verbose != 0) {
942 : : mbedtls_printf("passed\n");
943 : : }
944 : : }
945 : :
946 : : if (verbose != 0) {
947 : : mbedtls_printf("\n");
948 : : }
949 : :
950 : : goto exit;
951 : :
952 : : fail:
953 : : if (verbose != 0) {
954 : : mbedtls_printf("failed\n");
955 : : }
956 : :
957 : : exit:
958 : : mbedtls_sha256_free(&ctx);
959 : : mbedtls_free(buf);
960 : :
961 : : return ret;
962 : : }
963 : :
964 : : #if defined(MBEDTLS_SHA256_C)
965 : : int mbedtls_sha256_self_test(int verbose)
966 : : {
967 : : return mbedtls_sha256_common_self_test(verbose, 0);
968 : : }
969 : : #endif /* MBEDTLS_SHA256_C */
970 : :
971 : : #if defined(MBEDTLS_SHA224_C)
972 : : int mbedtls_sha224_self_test(int verbose)
973 : : {
974 : : return mbedtls_sha256_common_self_test(verbose, 1);
975 : : }
976 : : #endif /* MBEDTLS_SHA224_C */
977 : :
978 : : #endif /* MBEDTLS_SELF_TEST */
979 : :
980 : : #endif /* MBEDTLS_SHA256_C || MBEDTLS_SHA224_C */
|