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