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 502a35d60f.  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
This commit is contained in:
Kyle Evans 2022-03-08 09:39:52 -06:00
parent 9ba8670a8b
commit e7a629c851
13 changed files with 72 additions and 397 deletions

View file

@ -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

View file

@ -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/^$//}

View file

@ -1,3 +1,3 @@
.PATH: ${SRCTOP}/lib/libmd
.PATH: ${SRCTOP}/sys/kern
SRCS+= md5c.c

View file

@ -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

View file

@ -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 \

View file

@ -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

View file

@ -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_ */

View file

@ -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

View file

@ -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.

View file

@ -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

View file

@ -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

View file

@ -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