git: e7a629c851d7 - main - libmd, kern, stand: consolidate md5 implementations (NFC)

From: Kyle Evans <kevans_at_FreeBSD.org>
Date: Mon, 30 Sep 2024 03:36:04 UTC
The branch main has been updated by kevans:

URL: https://cgit.FreeBSD.org/src/commit/?id=e7a629c851d747772cc138efcb0418809ecdea55

commit e7a629c851d747772cc138efcb0418809ecdea55
Author:     Kyle Evans <kevans@FreeBSD.org>
AuthorDate: 2022-03-08 15:39:52 +0000
Commit:     Kyle Evans <kevans@FreeBSD.org>
CommitDate: 2024-09-30 03:34:18 +0000

    libmd, kern, stand: consolidate md5 implementations (NFC)
    
    Reduce the number of md5c.c between the three of these from two to one
    by just reaching into the kernel build for both userland builds.  The
    precedent for this already exists for sha2 in both cases.
    
    _libmd_ symbol privatization bits have been moved to sys/md5.h and
    md5.h remains to #include <sys/md5.h> for compatibility.
    
    This stops exporting MD5Pad() in the process because the kernel stopped
    exporting it in 502a35d60f4c.  soversion is bumped accordingly.
    
    This also renames the libc version of stack_protector.c; it previously
    only worked by coincidence because .PATH ordering worked out such that
    we got the right one, but this is not the case anymore.  Remove the
    landmine.
    
    PR:             280784 (exp-run)
    Reviewed by:    allanjude, delphij
    Differential Revision:  https://reviews.freebsd.org/D34497
---
 ObsoleteFiles.inc                                  |   3 +
 lib/libc/Makefile                                  |   2 +-
 lib/libc/md/Makefile.inc                           |   2 +-
 lib/libc/secure/Makefile.inc                       |   2 +-
 .../{stack_protector.c => libc_stack_protector.c}  |   0
 lib/libcrypt/Makefile                              |   2 +-
 lib/libmd/Makefile                                 |   3 +-
 lib/libmd/md5.h                                    |  40 ---
 lib/libmd/md5c.c                                   | 344 ---------------------
 lib/libssp/Makefile                                |   2 +-
 stand/libsa/Makefile                               |   4 +-
 sys/kern/md5c.c                                    |  23 +-
 sys/sys/md5.h                                      |  42 +++
 13 files changed, 72 insertions(+), 397 deletions(-)

diff --git a/ObsoleteFiles.inc b/ObsoleteFiles.inc
index 2686086970ce..9ecf5a8c3ecf 100644
--- a/ObsoleteFiles.inc
+++ b/ObsoleteFiles.inc
@@ -3230,6 +3230,9 @@ OLD_FILES+=usr/tests/usr.bin/uudecode/regress.153276.in
 OLD_DIRS+=usr/tests/usr.bin/uuencode
 OLD_DIRS+=usr/tests/usr.bin/uudecode
 
+# 20220308: libmd bumped to version 7
+OLD_LIBS+=lib/libmd.so.6
+
 # 20220318: snd_ds1 and snd_maestro drivers removed
 OLD_FILES+=usr/share/man/man4/snd_ds1.4.gz
 OLD_FILES+=usr/share/man/man4/snd_maestro.4.gz
diff --git a/lib/libc/Makefile b/lib/libc/Makefile
index ae059e53144c..d0c254e33396 100644
--- a/lib/libc/Makefile
+++ b/lib/libc/Makefile
@@ -220,6 +220,6 @@ GENDIRDEPS_FILTER+= N${RELDIR:H}/msun
 # Disable warnings in contributed sources.
 CWARNFLAGS:=	${.IMPSRC:Ngdtoa_*.c:C/^.+$/${CWARNFLAGS}/:C/^$/-w/}
 # Disable stack protection for SSP symbols.
-SSP_CFLAGS:=	${.IMPSRC:N*/stack_protector.c:C/^.+$/${SSP_CFLAGS}/}
+SSP_CFLAGS:=	${.IMPSRC:N*/libc_stack_protector.c:C/^.+$/${SSP_CFLAGS}/}
 # Generate stack unwinding tables for cancellation points
 CANCELPOINTS_CFLAGS:=	${.IMPSRC:Mcancelpoints_*:C/^.+$/${CANCELPOINTS_CFLAGS}/:C/^$//}
diff --git a/lib/libc/md/Makefile.inc b/lib/libc/md/Makefile.inc
index 346fb93017a6..82c5f0670485 100644
--- a/lib/libc/md/Makefile.inc
+++ b/lib/libc/md/Makefile.inc
@@ -1,3 +1,3 @@
-.PATH: ${SRCTOP}/lib/libmd
+.PATH: ${SRCTOP}/sys/kern
 
 SRCS+=	md5c.c
diff --git a/lib/libc/secure/Makefile.inc b/lib/libc/secure/Makefile.inc
index e5286a5a380f..5ee6f38d8b98 100644
--- a/lib/libc/secure/Makefile.inc
+++ b/lib/libc/secure/Makefile.inc
@@ -15,7 +15,7 @@ CFLAGS.vsnprintf_chk.c+=	-Wno-unused-parameter
 CFLAGS.vsprintf_chk.c+=	-Wno-unused-parameter
 
 # Sources common to both syscall interfaces:
-SRCS+=	stack_protector.c \
+SRCS+=	libc_stack_protector.c \
 	stack_protector_compat.c
 
 SYM_MAPS+=    ${LIBC_SRCTOP}/secure/Symbol.map
diff --git a/lib/libc/secure/stack_protector.c b/lib/libc/secure/libc_stack_protector.c
similarity index 100%
rename from lib/libc/secure/stack_protector.c
rename to lib/libc/secure/libc_stack_protector.c
diff --git a/lib/libcrypt/Makefile b/lib/libcrypt/Makefile
index 9511bba81e26..d9bd85f7e699 100644
--- a/lib/libcrypt/Makefile
+++ b/lib/libcrypt/Makefile
@@ -10,7 +10,7 @@ PACKAGE=	runtime
 SHLIB_MAJOR=	5
 LIB=		crypt
 
-.PATH:		${SRCTOP}/lib/libmd ${SRCTOP}/sys/crypto/sha2
+.PATH:		${SRCTOP}/sys/kern ${SRCTOP}/sys/crypto/sha2
 SRCS=		crypt.c misc.c \
 		crypt-md5.c md5c.c \
 		crypt-nthash.c md4c.c \
diff --git a/lib/libmd/Makefile b/lib/libmd/Makefile
index 4c2ed2f7f9c7..0a0890e06550 100644
--- a/lib/libmd/Makefile
+++ b/lib/libmd/Makefile
@@ -5,7 +5,7 @@ SHLIBDIR?= /lib
 
 PACKAGE=	runtime
 LIB=	md
-SHLIB_MAJOR= 6
+SHLIB_MAJOR= 7
 SRCS=	md4c.c md5c.c md4hl.c md5hl.c \
 	rmd160c.c rmd160hl.c \
 	sha0c.c sha0hl.c sha1c.c sha1hl.c \
@@ -105,6 +105,7 @@ CFLAGS+= -DWEAK_REFS
 CFLAGS.skein_block.c+= -DSKEIN_LOOP=995
 .PATH: ${.CURDIR}/${MACHINE_ARCH} ${SRCTOP}/sys/crypto/sha2
 .PATH: ${SRCTOP}/sys/crypto/skein ${SRCTOP}/sys/crypto/skein/${MACHINE_ARCH}
+.PATH: ${SRCTOP}/sys/kern
 
 USE_ASM_SOURCES?=1
 .if defined(BOOTSTRAPPING) || ${MK_MACHDEP_OPTIMIZATIONS} == no
diff --git a/lib/libmd/md5.h b/lib/libmd/md5.h
index a4a9f47d4d90..fca9d5f6ee6e 100644
--- a/lib/libmd/md5.h
+++ b/lib/libmd/md5.h
@@ -2,45 +2,5 @@
 #ifndef _MD5_H_
 #define _MD5_H_
 
-#ifndef _KERNEL
-
-/* Ensure libmd symbols do not clash with libcrypto */
-
-#ifndef MD5Init
-#define MD5Init		_libmd_MD5Init
-#endif
-#ifndef MD5Update
-#define MD5Update	_libmd_MD5Update
-#endif
-#ifndef MD5Pad
-#define MD5Pad		_libmd_MD5Pad
-#endif
-#ifndef MD5Final
-#define MD5Final	_libmd_MD5Final
-#endif
-#ifndef MD5Transform
-#define MD5Transform	_libmd_MD5Transform
-#endif
-#ifndef MD5End
-#define MD5End		_libmd_MD5End
-#endif
-#ifndef MD5Fd
-#define MD5Fd		_libmd_MD5Fd
-#endif
-#ifndef MD5FdChunk
-#define MD5FdChunk	_libmd_MD5FdChunk
-#endif
-#ifndef MD5File
-#define MD5File		_libmd_MD5File
-#endif
-#ifndef MD5FileChunk
-#define MD5FileChunk	_libmd_MD5FileChunk
-#endif
-#ifndef MD5Data
-#define MD5Data		_libmd_MD5Data
-#endif
-
-#endif
-
 #include <sys/md5.h>
 #endif /* _MD5_H_ */
diff --git a/lib/libmd/md5c.c b/lib/libmd/md5c.c
deleted file mode 100644
index 56f21f441e2c..000000000000
--- a/lib/libmd/md5c.c
+++ /dev/null
@@ -1,344 +0,0 @@
-/*-
- * SPDX-License-Identifier: RSA-MD
- *
- * MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm
- *
- * Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
- * rights reserved.
- *
- * License to copy and use this software is granted provided that it
- * is identified as the "RSA Data Security, Inc. MD5 Message-Digest
- * Algorithm" in all material mentioning or referencing this software
- * or this function.
- *
- * License is also granted to make and use derivative works provided
- * that such works are identified as "derived from the RSA Data
- * Security, Inc. MD5 Message-Digest Algorithm" in all material
- * mentioning or referencing the derived work.
- *
- * RSA Data Security, Inc. makes no representations concerning either
- * the merchantability of this software or the suitability of this
- * software for any particular purpose. It is provided "as is"
- * without express or implied warranty of any kind.
- *
- * These notices must be retained in any copies of any part of this
- * documentation and/or software.
- *
- * This code is the same as the code published by RSA Inc.  It has been
- * edited for clarity and style only.
- */
-
-#include <sys/types.h>
-
-#ifdef _KERNEL
-#include <sys/systm.h>
-#else
-#include <string.h>
-#endif
-
-#include <machine/endian.h>
-#include <sys/endian.h>
-#include "md5.h"
-
-static void MD5Transform(u_int32_t [4], const unsigned char [64]);
-
-#ifdef _KERNEL
-#define memset(x,y,z)	bzero(x,z);
-#define memcpy(x,y,z)	bcopy(y, x, z)
-#endif
-
-#if (BYTE_ORDER == LITTLE_ENDIAN)
-#define Encode memcpy
-#define Decode memcpy
-#else 
-
-/*
- * Encodes input (u_int32_t) into output (unsigned char). Assumes len is
- * a multiple of 4.
- */
-
-static void
-Encode (unsigned char *output, u_int32_t *input, unsigned int len)
-{
-	unsigned int i;
-	u_int32_t *op = (u_int32_t *)output;
-
-	for (i = 0; i < len / 4; i++)
-		op[i] = htole32(input[i]);
-}
-
-/*
- * Decodes input (unsigned char) into output (u_int32_t). Assumes len is
- * a multiple of 4.
- */
-
-static void
-Decode (u_int32_t *output, const unsigned char *input, unsigned int len)
-{
-	unsigned int i;
-	const u_int32_t *ip = (const u_int32_t *)input;
-
-	for (i = 0; i < len / 4; i++)
-		output[i] = le32toh(ip[i]);
-}
-#endif
-
-static unsigned char PADDING[64] = {
-  0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-};
-
-/* F, G, H and I are basic MD5 functions. */
-#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
-#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
-#define H(x, y, z) ((x) ^ (y) ^ (z))
-#define I(x, y, z) ((y) ^ ((x) | (~z)))
-
-/* ROTATE_LEFT rotates x left n bits. */
-#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
-
-/*
- * FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
- * Rotation is separate from addition to prevent recomputation.
- */
-#define FF(a, b, c, d, x, s, ac) { \
-	(a) += F ((b), (c), (d)) + (x) + (u_int32_t)(ac); \
-	(a) = ROTATE_LEFT ((a), (s)); \
-	(a) += (b); \
-	}
-#define GG(a, b, c, d, x, s, ac) { \
-	(a) += G ((b), (c), (d)) + (x) + (u_int32_t)(ac); \
-	(a) = ROTATE_LEFT ((a), (s)); \
-	(a) += (b); \
-	}
-#define HH(a, b, c, d, x, s, ac) { \
-	(a) += H ((b), (c), (d)) + (x) + (u_int32_t)(ac); \
-	(a) = ROTATE_LEFT ((a), (s)); \
-	(a) += (b); \
-	}
-#define II(a, b, c, d, x, s, ac) { \
-	(a) += I ((b), (c), (d)) + (x) + (u_int32_t)(ac); \
-	(a) = ROTATE_LEFT ((a), (s)); \
-	(a) += (b); \
-	}
-
-/* MD5 initialization. Begins an MD5 operation, writing a new context. */
-
-void
-MD5Init (MD5_CTX *context)
-{
-
-	context->count[0] = context->count[1] = 0;
-
-	/* Load magic initialization constants.  */
-	context->state[0] = 0x67452301;
-	context->state[1] = 0xefcdab89;
-	context->state[2] = 0x98badcfe;
-	context->state[3] = 0x10325476;
-}
-
-/* 
- * MD5 block update operation. Continues an MD5 message-digest
- * operation, processing another message block, and updating the
- * context.
- */
-
-void
-MD5Update (MD5_CTX *context, const void *in, unsigned int inputLen)
-{
-	unsigned int i, idx, partLen;
-	const unsigned char *input = in;
-
-	/* Compute number of bytes mod 64 */
-	idx = (unsigned int)((context->count[0] >> 3) & 0x3F);
-
-	/* Update number of bits */
-	if ((context->count[0] += ((u_int32_t)inputLen << 3))
-	    < ((u_int32_t)inputLen << 3))
-		context->count[1]++;
-	context->count[1] += ((u_int32_t)inputLen >> 29);
-
-	partLen = 64 - idx;
-
-	/* Transform as many times as possible. */
-	if (inputLen >= partLen) {
-		memcpy((void *)&context->buffer[idx], (const void *)input,
-		    partLen);
-		MD5Transform (context->state, context->buffer);
-
-		for (i = partLen; i + 63 < inputLen; i += 64)
-			MD5Transform (context->state, &input[i]);
-
-		idx = 0;
-	}
-	else
-		i = 0;
-
-	/* Buffer remaining input */
-	memcpy ((void *)&context->buffer[idx], (const void *)&input[i],
-	    inputLen-i);
-}
-
-/*
- * MD5 padding. Adds padding followed by original length.
- */
-
-void
-MD5Pad (MD5_CTX *context)
-{
-	unsigned char bits[8];
-	unsigned int idx, padLen;
-
-	/* Save number of bits */
-	Encode (bits, context->count, 8);
-
-	/* Pad out to 56 mod 64. */
-	idx = (unsigned int)((context->count[0] >> 3) & 0x3f);
-	padLen = (idx < 56) ? (56 - idx) : (120 - idx);
-	MD5Update (context, PADDING, padLen);
-
-	/* Append length (before padding) */
-	MD5Update (context, bits, 8);
-}
-
-/*
- * MD5 finalization. Ends an MD5 message-digest operation, writing the
- * the message digest and zeroizing the context.
- */
-
-void
-MD5Final (unsigned char digest[16], MD5_CTX *context)
-{
-	/* Do padding. */
-	MD5Pad (context);
-
-	/* Store state in digest */
-	Encode (digest, context->state, 16);
-
-	/* Zeroize sensitive information. */
-	explicit_bzero(context, sizeof(*context));
-}
-
-/* MD5 basic transformation. Transforms state based on block. */
-
-static void
-MD5Transform (u_int32_t state[4], const unsigned char block[64])
-{
-	u_int32_t a = state[0], b = state[1], c = state[2], d = state[3], x[16];
-
-	Decode (x, block, 64);
-
-	/* Round 1 */
-#define S11 7
-#define S12 12
-#define S13 17
-#define S14 22
-	FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
-	FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
-	FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
-	FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
-	FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
-	FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
-	FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
-	FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
-	FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
-	FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
-	FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
-	FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
-	FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
-	FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
-	FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
-	FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
-
-	/* Round 2 */
-#define S21 5
-#define S22 9
-#define S23 14
-#define S24 20
-	GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
-	GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
-	GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
-	GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
-	GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
-	GG (d, a, b, c, x[10], S22,  0x2441453); /* 22 */
-	GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
-	GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
-	GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
-	GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
-	GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
-	GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
-	GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
-	GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
-	GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
-	GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
-
-	/* Round 3 */
-#define S31 4
-#define S32 11
-#define S33 16
-#define S34 23
-	HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
-	HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
-	HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
-	HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
-	HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
-	HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
-	HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
-	HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
-	HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
-	HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
-	HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
-	HH (b, c, d, a, x[ 6], S34,  0x4881d05); /* 44 */
-	HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
-	HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
-	HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
-	HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
-
-	/* Round 4 */
-#define S41 6
-#define S42 10
-#define S43 15
-#define S44 21
-	II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
-	II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
-	II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
-	II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
-	II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
-	II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
-	II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
-	II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
-	II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
-	II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
-	II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
-	II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
-	II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
-	II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
-	II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
-	II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
-
-	state[0] += a;
-	state[1] += b;
-	state[2] += c;
-	state[3] += d;
-
-	/* Zeroize sensitive information. */
-	memset ((void *)x, 0, sizeof (x));
-}
-
-#ifdef WEAK_REFS
-/* When building libmd, provide weak references. Note: this is not
-   activated in the context of compiling these sources for internal
-   use in libcrypt.
- */
-#undef MD5Init
-__weak_reference(_libmd_MD5Init, MD5Init);
-#undef MD5Update
-__weak_reference(_libmd_MD5Update, MD5Update);
-#undef MD5Pad
-__weak_reference(_libmd_MD5Pad, MD5Pad);
-#undef MD5Final
-__weak_reference(_libmd_MD5Final, MD5Final);
-#undef MD5Transform
-__weak_reference(_libmd_MD5Transform, MD5Transform);
-#endif
diff --git a/lib/libssp/Makefile b/lib/libssp/Makefile
index c481839ee324..d4038b705acb 100644
--- a/lib/libssp/Makefile
+++ b/lib/libssp/Makefile
@@ -27,7 +27,7 @@ CFLAGS+=	-I${SRCTOP}/lib/libc/include
 # _elf_aux_info is exported from libc as elf_aux_info(3), so just that for the
 # libssp build instead.
 CFLAGS+=	-D_elf_aux_info=elf_aux_info
-SRCS+=		stack_protector.c
+SRCS+=		libc_stack_protector.c
 
 # Stack protection on libssp symbols should be considered harmful, as we may
 # be talking about, for example, the guard setup constructor.
diff --git a/stand/libsa/Makefile b/stand/libsa/Makefile
index 6064a6780921..3d46b9c7ffa1 100644
--- a/stand/libsa/Makefile
+++ b/stand/libsa/Makefile
@@ -189,8 +189,8 @@ SRCS+=	g_eli_hmac.c pkcs5v2.c
 .PATH: ${SYSDIR}/crypto/sha2
 SRCS+=		sha256c.c sha512c.c
 
-# md5 from libmd
-.PATH: ${SRCTOP}/lib/libmd
+# md5 from the kernel
+.PATH: ${SYSDIR}/kern
 SRCS+=		md5c.c
 
 .if ${DO32:U0} == 0
diff --git a/sys/kern/md5c.c b/sys/kern/md5c.c
index cc28ba484e95..b1ceac656cdd 100644
--- a/sys/kern/md5c.c
+++ b/sys/kern/md5c.c
@@ -1,4 +1,6 @@
 /*-
+ * SPDX-License-Identifier: RSA-MD
+ *
  * MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm
  *
  * Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
@@ -26,10 +28,6 @@
  * edited for clarity and style only.
  */
 
-/*
- * This file should be kept in sync with src/lib/libmd/md5c.c
- */
-
 #include <sys/types.h>
 
 #ifdef _KERNEL
@@ -220,7 +218,7 @@ MD5Final(unsigned char digest[static MD5_DIGEST_LENGTH], MD5_CTX *context)
 	Encode (digest, context->state, MD5_DIGEST_LENGTH);
 
 	/* Zeroize sensitive information. */
-	memset (context, 0, sizeof (*context));
+	explicit_bzero (context, sizeof (*context));
 }
 
 /* MD5 basic transformation. Transforms state based on block. */
@@ -328,3 +326,18 @@ MD5Transform(uint32_t state[4], const unsigned char block[64])
 	/* Zeroize sensitive information. */
 	memset ((void *)x, 0, sizeof (x));
 }
+
+#ifdef WEAK_REFS
+/* When building libmd, provide weak references. Note: this is not
+   activated in the context of compiling these sources for internal
+   use in libcrypt.
+ */
+#undef MD5Init
+__weak_reference(_libmd_MD5Init, MD5Init);
+#undef MD5Update
+__weak_reference(_libmd_MD5Update, MD5Update);
+#undef MD5Final
+__weak_reference(_libmd_MD5Final, MD5Final);
+#undef MD5Transform
+__weak_reference(_libmd_MD5Transform, MD5Transform);
+#endif
diff --git a/sys/sys/md5.h b/sys/sys/md5.h
index ac9a1dbfe4ae..2320a1a860bb 100644
--- a/sys/sys/md5.h
+++ b/sys/sys/md5.h
@@ -29,6 +29,8 @@ documentation and/or software.
 #ifndef _SYS_MD5_H_
 #define _SYS_MD5_H_
 
+#include <sys/types.h>
+
 #define MD5_BLOCK_LENGTH		64
 #define MD5_DIGEST_LENGTH		16
 #define MD5_DIGEST_STRING_LENGTH	(MD5_DIGEST_LENGTH * 2 + 1)
@@ -40,6 +42,46 @@ typedef struct MD5Context {
   unsigned char buffer[64];	/* input buffer */
 } MD5_CTX;
 
+#ifndef _KERNEL
+
+/* Ensure libmd symbols do not clash with libcrypto */
+
+#ifndef MD5Init
+#define MD5Init		_libmd_MD5Init
+#endif
+#ifndef MD5Update
+#define MD5Update	_libmd_MD5Update
+#endif
+#ifndef MD5Pad
+#define MD5Pad		_libmd_MD5Pad
+#endif
+#ifndef MD5Final
+#define MD5Final	_libmd_MD5Final
+#endif
+#ifndef MD5Transform
+#define MD5Transform	_libmd_MD5Transform
+#endif
+#ifndef MD5End
+#define MD5End		_libmd_MD5End
+#endif
+#ifndef MD5Fd
+#define MD5Fd		_libmd_MD5Fd
+#endif
+#ifndef MD5FdChunk
+#define MD5FdChunk	_libmd_MD5FdChunk
+#endif
+#ifndef MD5File
+#define MD5File		_libmd_MD5File
+#endif
+#ifndef MD5FileChunk
+#define MD5FileChunk	_libmd_MD5FileChunk
+#endif
+#ifndef MD5Data
+#define MD5Data		_libmd_MD5Data
+#endif
+
+#endif
+
 #include <sys/cdefs.h>
 
 __BEGIN_DECLS