xref: /freebsd/sys/crypto/sha2/sha512c.c (revision c7a063741720ef81d4caa4613242579d12f1d605)
1 /*-
2  * Copyright 2005 Colin Percival
3  * Copyright (c) 2015 Allan Jude <allanjude@FreeBSD.org>
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25  * SUCH DAMAGE.
26  */
27 
28 #include <sys/cdefs.h>
29 __FBSDID("$FreeBSD$");
30 
31 #include <sys/endian.h>
32 #include <sys/types.h>
33 
34 #ifdef _KERNEL
35 #include <sys/systm.h>
36 #else
37 #include <string.h>
38 #endif
39 
40 #include "sha512.h"
41 #include "sha512t.h"
42 #include "sha384.h"
43 #include "sha512c_impl.h"
44 
45 #if defined(ARM64_SHA512)
46 #include <sys/auxv.h>
47 #include <machine/ifunc.h>
48 #endif
49 
50 #if BYTE_ORDER == BIG_ENDIAN
51 
52 /* Copy a vector of big-endian uint64_t into a vector of bytes */
53 #define be64enc_vect(dst, src, len)	\
54 	memcpy((void *)dst, (const void *)src, (size_t)len)
55 
56 /* Copy a vector of bytes into a vector of big-endian uint64_t */
57 #define be64dec_vect(dst, src, len)	\
58 	memcpy((void *)dst, (const void *)src, (size_t)len)
59 
60 #else /* BYTE_ORDER != BIG_ENDIAN */
61 
62 /*
63  * Encode a length len/4 vector of (uint64_t) into a length len vector of
64  * (unsigned char) in big-endian form.  Assumes len is a multiple of 8.
65  */
66 static void
67 be64enc_vect(unsigned char *dst, const uint64_t *src, size_t len)
68 {
69 	size_t i;
70 
71 	for (i = 0; i < len / 8; i++)
72 		be64enc(dst + i * 8, src[i]);
73 }
74 
75 /*
76  * Decode a big-endian length len vector of (unsigned char) into a length
77  * len/4 vector of (uint64_t).  Assumes len is a multiple of 8.
78  */
79 static void
80 be64dec_vect(uint64_t *dst, const unsigned char *src, size_t len)
81 {
82 	size_t i;
83 
84 	for (i = 0; i < len / 8; i++)
85 		dst[i] = be64dec(src + i * 8);
86 }
87 
88 #endif /* BYTE_ORDER != BIG_ENDIAN */
89 
90 /* SHA512 round constants. */
91 static const uint64_t K[80] = {
92 	0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL,
93 	0xb5c0fbcfec4d3b2fULL, 0xe9b5dba58189dbbcULL,
94 	0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL,
95 	0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL,
96 	0xd807aa98a3030242ULL, 0x12835b0145706fbeULL,
97 	0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL,
98 	0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL,
99 	0x9bdc06a725c71235ULL, 0xc19bf174cf692694ULL,
100 	0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL,
101 	0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL,
102 	0x2de92c6f592b0275ULL, 0x4a7484aa6ea6e483ULL,
103 	0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL,
104 	0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL,
105 	0xb00327c898fb213fULL, 0xbf597fc7beef0ee4ULL,
106 	0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL,
107 	0x06ca6351e003826fULL, 0x142929670a0e6e70ULL,
108 	0x27b70a8546d22ffcULL, 0x2e1b21385c26c926ULL,
109 	0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL,
110 	0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL,
111 	0x81c2c92e47edaee6ULL, 0x92722c851482353bULL,
112 	0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL,
113 	0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL,
114 	0xd192e819d6ef5218ULL, 0xd69906245565a910ULL,
115 	0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL,
116 	0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL,
117 	0x2748774cdf8eeb99ULL, 0x34b0bcb5e19b48a8ULL,
118 	0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL,
119 	0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL,
120 	0x748f82ee5defb2fcULL, 0x78a5636f43172f60ULL,
121 	0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL,
122 	0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL,
123 	0xbef9a3f7b2c67915ULL, 0xc67178f2e372532bULL,
124 	0xca273eceea26619cULL, 0xd186b8c721c0c207ULL,
125 	0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL,
126 	0x06f067aa72176fbaULL, 0x0a637dc5a2c898a6ULL,
127 	0x113f9804bef90daeULL, 0x1b710b35131c471bULL,
128 	0x28db77f523047d84ULL, 0x32caab7b40c72493ULL,
129 	0x3c9ebe0a15c9bebcULL, 0x431d67c49c100d4cULL,
130 	0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL,
131 	0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL
132 };
133 
134 /* Elementary functions used by SHA512 */
135 #define Ch(x, y, z)	((x & (y ^ z)) ^ z)
136 #define Maj(x, y, z)	((x & (y | z)) | (y & z))
137 #define SHR(x, n)	(x >> n)
138 #define ROTR(x, n)	((x >> n) | (x << (64 - n)))
139 #define S0(x)		(ROTR(x, 28) ^ ROTR(x, 34) ^ ROTR(x, 39))
140 #define S1(x)		(ROTR(x, 14) ^ ROTR(x, 18) ^ ROTR(x, 41))
141 #define s0(x)		(ROTR(x, 1) ^ ROTR(x, 8) ^ SHR(x, 7))
142 #define s1(x)		(ROTR(x, 19) ^ ROTR(x, 61) ^ SHR(x, 6))
143 
144 /* SHA512 round function */
145 #define RND(a, b, c, d, e, f, g, h, k)			\
146 	h += S1(e) + Ch(e, f, g) + k;			\
147 	d += h;						\
148 	h += S0(a) + Maj(a, b, c);
149 
150 /* Adjusted round function for rotating state */
151 #define RNDr(S, W, i, ii)			\
152 	RND(S[(80 - i) % 8], S[(81 - i) % 8],	\
153 	    S[(82 - i) % 8], S[(83 - i) % 8],	\
154 	    S[(84 - i) % 8], S[(85 - i) % 8],	\
155 	    S[(86 - i) % 8], S[(87 - i) % 8],	\
156 	    W[i + ii] + K[i + ii])
157 
158 /* Message schedule computation */
159 #define MSCH(W, ii, i)				\
160 	W[i + ii + 16] = s1(W[i + ii + 14]) + W[i + ii + 9] + s0(W[i + ii + 1]) + W[i + ii]
161 
162 /*
163  * SHA512 block compression function.  The 512-bit state is transformed via
164  * the 512-bit input block to produce a new state.
165  */
166 static void
167 #if defined(ARM64_SHA512)
168 SHA512_Transform_c(uint64_t * state, const unsigned char block[SHA512_BLOCK_LENGTH])
169 #else
170 SHA512_Transform(uint64_t * state, const unsigned char block[SHA512_BLOCK_LENGTH])
171 #endif
172 {
173 	uint64_t W[80];
174 	uint64_t S[8];
175 	int i;
176 
177 	/* 1. Prepare the first part of the message schedule W. */
178 	be64dec_vect(W, block, SHA512_BLOCK_LENGTH);
179 
180 	/* 2. Initialize working variables. */
181 	memcpy(S, state, SHA512_DIGEST_LENGTH);
182 
183 	/* 3. Mix. */
184 	for (i = 0; i < 80; i += 16) {
185 		RNDr(S, W, 0, i);
186 		RNDr(S, W, 1, i);
187 		RNDr(S, W, 2, i);
188 		RNDr(S, W, 3, i);
189 		RNDr(S, W, 4, i);
190 		RNDr(S, W, 5, i);
191 		RNDr(S, W, 6, i);
192 		RNDr(S, W, 7, i);
193 		RNDr(S, W, 8, i);
194 		RNDr(S, W, 9, i);
195 		RNDr(S, W, 10, i);
196 		RNDr(S, W, 11, i);
197 		RNDr(S, W, 12, i);
198 		RNDr(S, W, 13, i);
199 		RNDr(S, W, 14, i);
200 		RNDr(S, W, 15, i);
201 
202 		if (i == 64)
203 			break;
204 		MSCH(W, 0, i);
205 		MSCH(W, 1, i);
206 		MSCH(W, 2, i);
207 		MSCH(W, 3, i);
208 		MSCH(W, 4, i);
209 		MSCH(W, 5, i);
210 		MSCH(W, 6, i);
211 		MSCH(W, 7, i);
212 		MSCH(W, 8, i);
213 		MSCH(W, 9, i);
214 		MSCH(W, 10, i);
215 		MSCH(W, 11, i);
216 		MSCH(W, 12, i);
217 		MSCH(W, 13, i);
218 		MSCH(W, 14, i);
219 		MSCH(W, 15, i);
220 	}
221 
222 	/* 4. Mix local working variables into global state */
223 	for (i = 0; i < 8; i++)
224 		state[i] += S[i];
225 }
226 
227 #if defined(ARM64_SHA512)
228 static void
229 SHA512_Transform_arm64(uint64_t * state,
230     const unsigned char block[SHA512_BLOCK_LENGTH])
231 {
232 	SHA512_Transform_arm64_impl(state, block, K);
233 }
234 
235 DEFINE_UIFUNC(static, void, SHA512_Transform,
236     (uint64_t * state, const unsigned char block[SHA512_BLOCK_LENGTH]))
237 {
238 	u_long hwcap;
239 
240 	if (elf_aux_info(AT_HWCAP, &hwcap, sizeof(hwcap)) == 0) {
241 		if ((hwcap & HWCAP_SHA512) != 0) {
242 			return (SHA512_Transform_arm64);
243 		}
244 	}
245 
246 	return (SHA512_Transform_c);
247 }
248 #endif
249 
250 static unsigned char PAD[SHA512_BLOCK_LENGTH] = {
251 	0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
252 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
253 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
254 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
255 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
256 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
257 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
258 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
259 };
260 
261 /* Add padding and terminating bit-count. */
262 static void
263 SHA512_Pad(SHA512_CTX * ctx)
264 {
265 	size_t r;
266 
267 	/* Figure out how many bytes we have buffered. */
268 	r = (ctx->count[1] >> 3) & 0x7f;
269 
270 	/* Pad to 112 mod 128, transforming if we finish a block en route. */
271 	if (r < 112) {
272 		/* Pad to 112 mod 128. */
273 		memcpy(&ctx->buf[r], PAD, 112 - r);
274 	} else {
275 		/* Finish the current block and mix. */
276 		memcpy(&ctx->buf[r], PAD, 128 - r);
277 		SHA512_Transform(ctx->state, ctx->buf);
278 
279 		/* The start of the final block is all zeroes. */
280 		memset(&ctx->buf[0], 0, 112);
281 	}
282 
283 	/* Add the terminating bit-count. */
284 	be64enc_vect(&ctx->buf[112], ctx->count, 16);
285 
286 	/* Mix in the final block. */
287 	SHA512_Transform(ctx->state, ctx->buf);
288 }
289 
290 /* SHA-512 initialization.  Begins a SHA-512 operation. */
291 void
292 SHA512_Init(SHA512_CTX * ctx)
293 {
294 
295 	/* Zero bits processed so far */
296 	ctx->count[0] = ctx->count[1] = 0;
297 
298 	/* Magic initialization constants */
299 	ctx->state[0] = 0x6a09e667f3bcc908ULL;
300 	ctx->state[1] = 0xbb67ae8584caa73bULL;
301 	ctx->state[2] = 0x3c6ef372fe94f82bULL;
302 	ctx->state[3] = 0xa54ff53a5f1d36f1ULL;
303 	ctx->state[4] = 0x510e527fade682d1ULL;
304 	ctx->state[5] = 0x9b05688c2b3e6c1fULL;
305 	ctx->state[6] = 0x1f83d9abfb41bd6bULL;
306 	ctx->state[7] = 0x5be0cd19137e2179ULL;
307 }
308 
309 /* Add bytes into the hash */
310 void
311 SHA512_Update(SHA512_CTX * ctx, const void *in, size_t len)
312 {
313 	uint64_t bitlen[2];
314 	uint64_t r;
315 	const unsigned char *src = in;
316 
317 	/* Number of bytes left in the buffer from previous updates */
318 	r = (ctx->count[1] >> 3) & 0x7f;
319 
320 	/* Convert the length into a number of bits */
321 	bitlen[1] = ((uint64_t)len) << 3;
322 	bitlen[0] = ((uint64_t)len) >> 61;
323 
324 	/* Update number of bits */
325 	if ((ctx->count[1] += bitlen[1]) < bitlen[1])
326 		ctx->count[0]++;
327 	ctx->count[0] += bitlen[0];
328 
329 	/* Handle the case where we don't need to perform any transforms */
330 	if (len < SHA512_BLOCK_LENGTH - r) {
331 		memcpy(&ctx->buf[r], src, len);
332 		return;
333 	}
334 
335 	/* Finish the current block */
336 	memcpy(&ctx->buf[r], src, SHA512_BLOCK_LENGTH - r);
337 	SHA512_Transform(ctx->state, ctx->buf);
338 	src += SHA512_BLOCK_LENGTH - r;
339 	len -= SHA512_BLOCK_LENGTH - r;
340 
341 	/* Perform complete blocks */
342 	while (len >= SHA512_BLOCK_LENGTH) {
343 		SHA512_Transform(ctx->state, src);
344 		src += SHA512_BLOCK_LENGTH;
345 		len -= SHA512_BLOCK_LENGTH;
346 	}
347 
348 	/* Copy left over data into buffer */
349 	memcpy(ctx->buf, src, len);
350 }
351 
352 /*
353  * SHA-512 finalization.  Pads the input data, exports the hash value,
354  * and clears the context state.
355  */
356 void
357 SHA512_Final(unsigned char digest[static SHA512_DIGEST_LENGTH], SHA512_CTX *ctx)
358 {
359 
360 	/* Add padding */
361 	SHA512_Pad(ctx);
362 
363 	/* Write the hash */
364 	be64enc_vect(digest, ctx->state, SHA512_DIGEST_LENGTH);
365 
366 	/* Clear the context state */
367 	explicit_bzero(ctx, sizeof(*ctx));
368 }
369 
370 /*** SHA-512t: *********************************************************/
371 /*
372  * the SHA512t transforms are identical to SHA512 so reuse the existing function
373  */
374 void
375 SHA512_224_Init(SHA512_CTX * ctx)
376 {
377 
378 	/* Zero bits processed so far */
379 	ctx->count[0] = ctx->count[1] = 0;
380 
381 	/* Magic initialization constants */
382 	ctx->state[0] = 0x8c3d37c819544da2ULL;
383 	ctx->state[1] = 0x73e1996689dcd4d6ULL;
384 	ctx->state[2] = 0x1dfab7ae32ff9c82ULL;
385 	ctx->state[3] = 0x679dd514582f9fcfULL;
386 	ctx->state[4] = 0x0f6d2b697bd44da8ULL;
387 	ctx->state[5] = 0x77e36f7304c48942ULL;
388 	ctx->state[6] = 0x3f9d85a86a1d36c8ULL;
389 	ctx->state[7] = 0x1112e6ad91d692a1ULL;
390 }
391 
392 void
393 SHA512_224_Update(SHA512_CTX * ctx, const void *in, size_t len)
394 {
395 
396 	SHA512_Update(ctx, in, len);
397 }
398 
399 void
400 SHA512_224_Final(unsigned char digest[static SHA512_224_DIGEST_LENGTH], SHA512_CTX * ctx)
401 {
402 
403 	/* Add padding */
404 	SHA512_Pad(ctx);
405 
406 	/* Write the hash */
407 	be64enc_vect(digest, ctx->state, SHA512_224_DIGEST_LENGTH);
408 
409 	/* Clear the context state */
410 	explicit_bzero(ctx, sizeof(*ctx));
411 }
412 
413 void
414 SHA512_256_Init(SHA512_CTX * ctx)
415 {
416 
417 	/* Zero bits processed so far */
418 	ctx->count[0] = ctx->count[1] = 0;
419 
420 	/* Magic initialization constants */
421 	ctx->state[0] = 0x22312194fc2bf72cULL;
422 	ctx->state[1] = 0x9f555fa3c84c64c2ULL;
423 	ctx->state[2] = 0x2393b86b6f53b151ULL;
424 	ctx->state[3] = 0x963877195940eabdULL;
425 	ctx->state[4] = 0x96283ee2a88effe3ULL;
426 	ctx->state[5] = 0xbe5e1e2553863992ULL;
427 	ctx->state[6] = 0x2b0199fc2c85b8aaULL;
428 	ctx->state[7] = 0x0eb72ddc81c52ca2ULL;
429 }
430 
431 void
432 SHA512_256_Update(SHA512_CTX * ctx, const void *in, size_t len)
433 {
434 
435 	SHA512_Update(ctx, in, len);
436 }
437 
438 void
439 SHA512_256_Final(unsigned char digest[static SHA512_256_DIGEST_LENGTH], SHA512_CTX * ctx)
440 {
441 
442 	/* Add padding */
443 	SHA512_Pad(ctx);
444 
445 	/* Write the hash */
446 	be64enc_vect(digest, ctx->state, SHA512_256_DIGEST_LENGTH);
447 
448 	/* Clear the context state */
449 	explicit_bzero(ctx, sizeof(*ctx));
450 }
451 
452 /*** SHA-384: *********************************************************/
453 /*
454  * the SHA384 and SHA512 transforms are identical, so SHA384 is skipped
455  */
456 
457 /* SHA-384 initialization.  Begins a SHA-384 operation. */
458 void
459 SHA384_Init(SHA384_CTX * ctx)
460 {
461 
462 	/* Zero bits processed so far */
463 	ctx->count[0] = ctx->count[1] = 0;
464 
465 	/* Magic initialization constants */
466 	ctx->state[0] = 0xcbbb9d5dc1059ed8ULL;
467 	ctx->state[1] = 0x629a292a367cd507ULL;
468 	ctx->state[2] = 0x9159015a3070dd17ULL;
469 	ctx->state[3] = 0x152fecd8f70e5939ULL;
470 	ctx->state[4] = 0x67332667ffc00b31ULL;
471 	ctx->state[5] = 0x8eb44a8768581511ULL;
472 	ctx->state[6] = 0xdb0c2e0d64f98fa7ULL;
473 	ctx->state[7] = 0x47b5481dbefa4fa4ULL;
474 }
475 
476 /* Add bytes into the SHA-384 hash */
477 void
478 SHA384_Update(SHA384_CTX * ctx, const void *in, size_t len)
479 {
480 
481 	SHA512_Update((SHA512_CTX *)ctx, in, len);
482 }
483 
484 /*
485  * SHA-384 finalization.  Pads the input data, exports the hash value,
486  * and clears the context state.
487  */
488 void
489 SHA384_Final(unsigned char digest[static SHA384_DIGEST_LENGTH], SHA384_CTX *ctx)
490 {
491 
492 	/* Add padding */
493 	SHA512_Pad((SHA512_CTX *)ctx);
494 
495 	/* Write the hash */
496 	be64enc_vect(digest, ctx->state, SHA384_DIGEST_LENGTH);
497 
498 	/* Clear the context state */
499 	explicit_bzero(ctx, sizeof(*ctx));
500 }
501 
502 #ifdef WEAK_REFS
503 /* When building libmd, provide weak references. Note: this is not
504    activated in the context of compiling these sources for internal
505    use in libcrypt.
506  */
507 #undef SHA512_Init
508 __weak_reference(_libmd_SHA512_Init, SHA512_Init);
509 #undef SHA512_Update
510 __weak_reference(_libmd_SHA512_Update, SHA512_Update);
511 #undef SHA512_Final
512 __weak_reference(_libmd_SHA512_Final, SHA512_Final);
513 #undef SHA512_Transform
514 __weak_reference(_libmd_SHA512_Transform, SHA512_Transform);
515 
516 #undef SHA512_224_Init
517 __weak_reference(_libmd_SHA512_224_Init, SHA512_224_Init);
518 #undef SHA512_224_Update
519 __weak_reference(_libmd_SHA512_224_Update, SHA512_224_Update);
520 #undef SHA512_224_Final
521 __weak_reference(_libmd_SHA512_224_Final, SHA512_224_Final);
522 
523 #undef SHA512_256_Init
524 __weak_reference(_libmd_SHA512_256_Init, SHA512_256_Init);
525 #undef SHA512_256_Update
526 __weak_reference(_libmd_SHA512_256_Update, SHA512_256_Update);
527 #undef SHA512_256_Final
528 __weak_reference(_libmd_SHA512_256_Final, SHA512_256_Final);
529 
530 #undef SHA384_Init
531 __weak_reference(_libmd_SHA384_Init, SHA384_Init);
532 #undef SHA384_Update
533 __weak_reference(_libmd_SHA384_Update, SHA384_Update);
534 #undef SHA384_Final
535 __weak_reference(_libmd_SHA384_Final, SHA384_Final);
536 #endif
537