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