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
be64enc_vect(unsigned char * dst,const uint64_t * src,size_t len)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
be64dec_vect(uint64_t * dst,const unsigned char * src,size_t len)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)
SHA512_Transform_c(uint64_t * state,const unsigned char block[SHA512_BLOCK_LENGTH])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
SHA512_Transform_arm64(uint64_t * state,const unsigned char block[SHA512_BLOCK_LENGTH])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
SHA512_Pad(SHA512_CTX * ctx)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
SHA512_Init(SHA512_CTX * ctx)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
SHA512_Update(SHA512_CTX * ctx,const void * in,size_t len)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
SHA512_Final(unsigned char digest[static SHA512_DIGEST_LENGTH],SHA512_CTX * ctx)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
SHA512_224_Init(SHA512_CTX * ctx)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
SHA512_224_Update(SHA512_CTX * ctx,const void * in,size_t len)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
SHA512_224_Final(unsigned char digest[static SHA512_224_DIGEST_LENGTH],SHA512_CTX * ctx)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
SHA512_256_Init(SHA512_CTX * ctx)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
SHA512_256_Update(SHA512_CTX * ctx,const void * in,size_t len)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
SHA512_256_Final(unsigned char digest[static SHA512_256_DIGEST_LENGTH],SHA512_CTX * ctx)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
SHA384_Init(SHA384_CTX * ctx)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
SHA384_Update(SHA384_CTX * ctx,const void * in,size_t len)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
SHA384_Final(unsigned char digest[static SHA384_DIGEST_LENGTH],SHA384_CTX * ctx)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