changeset 4151:6710a4fd6898 draft

Detect hmac(3) in libc or the library containing MD5. If not found, a compat function is provided, taken from NetBSD.
author Roy Marples <roy@marples.name>
date Thu, 05 Oct 2017 14:13:02 +0100
parents 4d9679283c1e
children 45cfa30f7b2b
files compat/crypt/hmac.c compat/crypt/hmac.h configure src/auth.c src/crypt/crypt.h src/crypt/hmac_md5.c tests/crypt/Makefile tests/crypt/test_hmac_md5.c
diffstat 8 files changed, 316 insertions(+), 167 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/compat/crypt/hmac.c	Thu Oct 05 14:13:02 2017 +0100
@@ -0,0 +1,182 @@
+/*	$NetBSD: hmac.c,v 1.5 2017/10/05 09:59:04 roy Exp $	*/
+
+/*-
+ * Copyright (c) 2016 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Christos Zoulas.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <string.h>
+#include <stdlib.h>
+
+#include "config.h"
+
+#ifdef HAVE_MD5_H
+#  ifndef DEPGEN
+#    include <md5.h>
+#  endif
+#endif
+
+#ifdef SHA2_H
+#  include SHA2_H
+#endif
+
+#if 0
+#include <md2.h>
+#include <md4.h>
+#include <md5.h>
+#include <rmd160.h>
+#include <sha1.h>
+#include <sha2.h>
+#endif
+
+#define HMAC_SIZE	128
+#define HMAC_IPAD	0x36
+#define HMAC_OPAD	0x5C
+
+static const struct hmac {
+	const char *name;
+	size_t ctxsize;
+	size_t digsize;
+	size_t blocksize;
+	void (*init)(void *);
+	void (*update)(void *, const uint8_t *, unsigned int);
+	void (*final)(uint8_t *, void *);
+} hmacs[] = {
+#if 0
+	{
+		"md2", sizeof(MD2_CTX), MD2_DIGEST_LENGTH, MD2_BLOCK_LENGTH,
+		(void *)MD2Init, (void *)MD2Update, (void *)MD2Final,
+	},
+	{
+		"md4", sizeof(MD4_CTX), MD4_DIGEST_LENGTH, MD4_BLOCK_LENGTH,
+		(void *)MD4Init, (void *)MD4Update, (void *)MD4Final,
+	},
+#endif
+	{
+		"md5", sizeof(MD5_CTX), MD5_DIGEST_LENGTH, MD5_BLOCK_LENGTH,
+		(void *)MD5Init, (void *)MD5Update, (void *)MD5Final,
+	},
+#if 0
+	{
+		"rmd160", sizeof(RMD160_CTX), RMD160_DIGEST_LENGTH,
+		RMD160_BLOCK_LENGTH,
+		(void *)RMD160Init, (void *)RMD160Update, (void *)RMD160Final,
+	},
+	{
+		"sha1", sizeof(SHA1_CTX), SHA1_DIGEST_LENGTH, SHA1_BLOCK_LENGTH,
+		(void *)SHA1Init, (void *)SHA1Update, (void *)SHA1Final,
+	},
+	{
+		"sha224", sizeof(SHA224_CTX), SHA224_DIGEST_LENGTH,
+		SHA224_BLOCK_LENGTH,
+		(void *)SHA224_Init, (void *)SHA224_Update,
+		(void *)SHA224_Final,
+	},
+#endif
+	{
+		"sha256", sizeof(SHA256_CTX), SHA256_DIGEST_LENGTH,
+		SHA256_BLOCK_LENGTH,
+		(void *)SHA256_Init, (void *)SHA256_Update,
+		(void *)SHA256_Final,
+	},
+#if 0
+	{
+		"sha384", sizeof(SHA384_CTX), SHA384_DIGEST_LENGTH,
+		SHA384_BLOCK_LENGTH,
+		(void *)SHA384_Init, (void *)SHA384_Update,
+		(void *)SHA384_Final,
+	},
+	{
+		"sha512", sizeof(SHA512_CTX), SHA512_DIGEST_LENGTH,
+		SHA512_BLOCK_LENGTH,
+		(void *)SHA512_Init, (void *)SHA512_Update,
+		(void *)SHA512_Final,
+	},
+#endif
+};
+
+static const struct hmac *
+hmac_find(const char *name)
+{
+	for (size_t i = 0; i < __arraycount(hmacs); i++) {
+		if (strcmp(hmacs[i].name, name) != 0)
+			continue;
+		return &hmacs[i];
+	}
+	return NULL;
+}
+
+ssize_t
+hmac(const char *name,
+    const void *key, size_t klen,
+    const void *text, size_t tlen,
+    void *digest, size_t dlen)
+{
+	uint8_t ipad[HMAC_SIZE], opad[HMAC_SIZE], d[HMAC_SIZE];
+	const uint8_t *k = key;
+	const struct hmac *h;
+	uint64_t c[32];
+	void *p;
+
+	if ((h = hmac_find(name)) == NULL)
+		return -1;
+
+
+	if (klen > h->blocksize) {
+		(*h->init)(c);
+		(*h->update)(c, k, (unsigned int)klen);
+		(*h->final)(d, c);
+		k = (void *)d;
+		klen = h->digsize;
+	}
+
+	/* Form input and output pads for the digests */
+	for (size_t i = 0; i < sizeof(ipad); i++) {
+		ipad[i] = (i < klen ? k[i] : 0) ^ HMAC_IPAD;
+		opad[i] = (i < klen ? k[i] : 0) ^ HMAC_OPAD;
+	}
+
+	p = dlen >= h->digsize ? digest : d;
+	if (p != digest) {
+		memcpy(p, digest, dlen);
+		memset((char *)p + dlen, 0, h->digsize - dlen);
+	}
+	(*h->init)(c);
+	(*h->update)(c, ipad, (unsigned int)h->blocksize);
+	(*h->update)(c, text, (unsigned int)tlen);
+	(*h->final)(p, c);
+
+	(*h->init)(c);
+	(*h->update)(c, opad, (unsigned int)h->blocksize);
+	(*h->update)(c, digest, (unsigned int)h->digsize);
+	(*h->final)(p, c);
+
+	if (p != digest)
+		memcpy(digest, p, dlen);
+
+	return (ssize_t)h->digsize;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/compat/crypt/hmac.h	Thu Oct 05 14:13:02 2017 +0100
@@ -0,0 +1,40 @@
+/*	$NetBSD: hmac.c,v 1.5 2017/10/05 09:59:04 roy Exp $	*/
+
+/*-
+ * Copyright (c) 2016 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Christos Zoulas.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef HMAC_H
+#define HMAC_H
+
+#include <sys/types.h>
+
+ssize_t	 hmac(const char *, const void *, size_t, const void *, size_t, void *,
+   size_t);
+
+#endif
--- a/configure	Thu Oct 05 08:05:08 2017 +0100
+++ b/configure	Thu Oct 05 14:13:02 2017 +0100
@@ -87,6 +87,7 @@
 	--without-md5) MD5=no;;
 	--without-sha2) SHA2=no;;
 	--without-sha256) SHA2=no;;
+	--without-hmac) HMAC=no;;
 	--without-dev) DEV=no;;
 	--without-udev) UDEV=no;;
 	--with-poll) POLL="$var";;
@@ -487,7 +488,9 @@
 	echo "Enabling Authentication"
 	echo "CPPFLAGS+=	-DAUTH" >>$CONFIG_MK
 	echo "SRCS+=		auth.c" >>$CONFIG_MK
-	echo "CRYPT_SRCS+=	crypt/hmac_md5.c" >>$CONFIG_MK
+	echo "CRYPT_SRCS+=	\${HMAC_SRC}" >>$CONFIG_MK
+fi
+if [ -z "$INET6" -o "$INET6" = yes -o -z "$AUTH" -o "$AUTH" = yes -o ]; then
 	echo "CRYPT_SRCS+=	\${MD5_SRC} \${SHA256_SRC}" >>$CONFIG_MK
 fi
 
@@ -1221,6 +1224,47 @@
 	[ -n "$SHA2_LIB" ] && echo "LDADD+=		$SHA2_LIB" >>$CONFIG_MK
 fi
 
+if [ -z "$HMAC" ]; then
+	HMAC_LIB=
+	printf "Testing for hmac ... "
+	cat <<EOF >_hmac.c
+#include <stdlib.h>
+#include <hmac.h>
+int main(void) {
+	hmac(NULL, NULL, 0, NULL, 0, NULL, 0);
+	return 0;
+}
+EOF
+	if $XCC _hmac.c $MD5_LIB -o _hmac 2>&3; then
+		HMAC=yes
+		echo "#define HAVE_HMAC_H" >>$CONFIG_H
+	else
+		# Remove this test if NetBSD-8 ships with
+		# hmac in it's own header and not stdlib.h
+		cat <<EOF >_hmac.c
+#include <stdlib.h>
+int main(void) {
+	hmac(NULL, NULL, 0, NULL, 0, NULL, 0);
+	return 0;
+}
+EOF
+		if $XCC _hmac.c $MD5_LIB -o _hmac 2>&3; then
+			HMAC=yes
+		else
+			HMAC=no
+		fi
+	fi
+	echo "$HMAC"
+	rm -f _hmac.c _hmac
+fi
+if [ "$HMAC" = no ]; then
+	echo "#include		\"compat/crypt/hmac.h\"" >>$CONFIG_H
+	echo "HMAC_SRC=		compat/crypt/hmac.c" >>$CONFIG_MK
+else
+	# echo "#define HAVE_HMAC_H" >>$CONFIG_H
+	echo "HMAC_SRC=" >>$CONFIG_MK
+fi
+
 if [ "$DEV" != no -a "$UDEV" != no ]; then
 	printf "Checking for libudev ... "
 	if type "$PKG_CONFIG" >/dev/null 2>&1; then
--- a/src/auth.c	Thu Oct 05 08:05:08 2017 +0100
+++ b/src/auth.c	Thu Oct 05 14:13:02 2017 +0100
@@ -37,11 +37,14 @@
 
 #include "config.h"
 #include "auth.h"
-#include "crypt/crypt.h"
 #include "dhcp.h"
 #include "dhcp6.h"
 #include "dhcpcd.h"
 
+#ifdef HAVE_HMAC_H
+#include <hmac.h>
+#endif
+
 #ifdef __sun
 #define htonll
 #define ntohll
@@ -105,7 +108,7 @@
 	size_t realm_len;
 	const struct token *t;
 	time_t now;
-	uint8_t hmac[HMAC_LENGTH];
+	uint8_t hmac_code[HMAC_LENGTH];
 
 	if (dlen < 3 + sizeof(replay)) {
 		errno = EINVAL;
@@ -174,7 +177,7 @@
 		secretid = 0;
 		break;
 	case AUTH_PROTO_DELAYED:
-		if (dlen < sizeof(secretid) + sizeof(hmac)) {
+		if (dlen < sizeof(secretid) + sizeof(hmac_code)) {
 			errno = EINVAL;
 			return NULL;
 		}
@@ -183,11 +186,11 @@
 		dlen -= sizeof(secretid);
 		break;
 	case AUTH_PROTO_DELAYEDREALM:
-		if (dlen < sizeof(secretid) + sizeof(hmac)) {
+		if (dlen < sizeof(secretid) + sizeof(hmac_code)) {
 			errno = EINVAL;
 			return NULL;
 		}
-		realm_len = dlen - (sizeof(secretid) + sizeof(hmac));
+		realm_len = dlen - (sizeof(secretid) + sizeof(hmac_code));
 		if (realm_len) {
 			realm = d;
 			d += realm_len;
@@ -320,10 +323,11 @@
 		memset(mm + offsetof(struct bootp, giaddr), 0, 4);
 	}
 
-	memset(hmac, 0, sizeof(hmac));
+	memset(hmac_code, 0, sizeof(hmac_code));
 	switch (algorithm) {
 	case AUTH_ALG_HMAC_MD5:
-		hmac_md5(mm, mlen, t->key, t->key_len, hmac);
+		hmac("md5", t->key, t->key_len, mm, mlen,
+		     hmac_code, sizeof(hmac_code));
 		break;
 	default:
 		errno = ENOSYS;
@@ -332,7 +336,7 @@
 	}
 
 	free(mm);
-	if (memcmp(d, &hmac, dlen)) {
+	if (memcmp(d, &hmac_code, dlen)) {
 		errno = EPERM;
 		return NULL;
 	}
@@ -472,7 +476,7 @@
     void *vdata, size_t dlen)
 {
 	uint64_t rdm;
-	uint8_t hmac[HMAC_LENGTH];
+	uint8_t hmac_code[HMAC_LENGTH];
 	time_t now;
 	uint8_t hops, *p, info, *m, *data;
 	uint32_t giaddr, secretid;
@@ -546,7 +550,7 @@
 			/* FALLTHROUGH */
 		case AUTH_PROTO_DELAYED:
 			if (info && t)
-				dlen += sizeof(t->secretid) + sizeof(hmac);
+				dlen += sizeof(t->secretid) + sizeof(hmac_code);
 			break;
 		}
 		return (ssize_t)dlen;
@@ -651,8 +655,9 @@
 	/* Create our hash and write it out */
 	switch(auth->algorithm) {
 	case AUTH_ALG_HMAC_MD5:
-		hmac_md5(m, mlen, t->key, t->key_len, hmac);
-		memcpy(data, hmac, sizeof(hmac));
+		hmac("md5", t->key, t->key_len, m, mlen,
+		     hmac_code, sizeof(hmac_code));
+		memcpy(data, hmac_code, sizeof(hmac_code));
 		break;
 	}
 
@@ -665,5 +670,5 @@
 	}
 
 	/* Done! */
-	return (int)(dlen - sizeof(hmac)); /* should be zero */
+	return (int)(dlen - sizeof(hmac_code)); /* should be zero */
 }
--- a/src/crypt/crypt.h	Thu Oct 05 08:05:08 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,33 +0,0 @@
-/*
- * dhcpcd - DHCP client daemon
- * Copyright (c) 2006-2015 Roy Marples <roy@marples.name>
- * All rights reserved
-
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#ifndef CRYPT_H
-#define CRYPT_H
-
-void hmac_md5(const uint8_t *, size_t, const uint8_t *, size_t, uint8_t *);
-
-#endif
--- a/src/crypt/hmac_md5.c	Thu Oct 05 08:05:08 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,89 +0,0 @@
-/*
- * dhcpcd - DHCP client daemon
- * Copyright (c) 2006-2015 Roy Marples <roy@marples.name>
- * All rights reserved
-
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <inttypes.h>
-#include <string.h>
-
-#include "config.h"
-#include "crypt.h"
-
-#ifdef HAVE_MD5_H
-#  ifndef DEPGEN
-#    include <md5.h>
-#  endif
-#endif
-
-#define HMAC_PAD_LEN	64
-#define IPAD		0x36
-#define OPAD		0x5C
-
-/* hmac_md5 as per RFC3118 */
-void
-hmac_md5(const uint8_t *text, size_t text_len,
-    const uint8_t *key, size_t key_len,
-    uint8_t *digest)
-{
-	uint8_t k_ipad[HMAC_PAD_LEN], k_opad[HMAC_PAD_LEN];
-	uint8_t tk[MD5_DIGEST_LENGTH];
-	int i;
-	MD5_CTX context;
-
-	/* Ensure key is no bigger than HMAC_PAD_LEN */
-	if (key_len > HMAC_PAD_LEN) {
-		MD5Init(&context);
-		MD5Update(&context, key, (unsigned int)key_len);
-		MD5Final(tk, &context);
-		key = tk;
-		key_len = MD5_DIGEST_LENGTH;
-	}
-
-	/* store key in pads */
-	memcpy(k_ipad, key, key_len);
-	memcpy(k_opad, key, key_len);
-	if (key_len != HMAC_PAD_LEN) {
-		memset(k_ipad + key_len, 0, sizeof(k_ipad) - key_len);
-		memset(k_opad + key_len, 0, sizeof(k_opad) - key_len);
-	}
-
-	/* XOR key with ipad and opad values */
-	for (i = 0; i < HMAC_PAD_LEN; i++) {
-		k_ipad[i] ^= IPAD;
-		k_opad[i] ^= OPAD;
-	}
-
-	/* inner MD5 */
-	MD5Init(&context);
-	MD5Update(&context, k_ipad, HMAC_PAD_LEN);
-	MD5Update(&context, text, (unsigned int)text_len);
-	MD5Final(digest, &context);
-
-	/* outer MD5 */
-	MD5Init(&context);
-	MD5Update(&context, k_opad, HMAC_PAD_LEN);
-	MD5Update(&context, digest, MD5_DIGEST_LENGTH);
-	MD5Final(digest, &context);
-}
--- a/tests/crypt/Makefile	Thu Oct 05 08:05:08 2017 +0100
+++ b/tests/crypt/Makefile	Thu Oct 05 14:13:02 2017 +0100
@@ -3,7 +3,7 @@
 
 PROG=		run-test
 SRCS=		run-test.c
-SRCS+=		test_hmac_md5.c ${TOP}/src/crypt/hmac_md5.c
+SRCS+=		test_hmac_md5.c
 
 CFLAGS?=	-O2
 CSTD?=		c99
@@ -11,9 +11,9 @@
 
 CPPFLAGS+=	-I${TOP} -I${TOP}/src
 
-T_COMPAT_SRCS=	${COMPAT_SRCS:compat/%=${TOP}/compat/%}
-T_MD5_SRC=	${MD5_SRC:compat/%=${TOP}/compat/%}
-OBJS+=		${SRCS:.c=.o} ${T_COMPAT_SRCS:.c=.o} ${T_MD5_SRC:.c=.o}
+CRYPT_SRCS=	${HMAC_SRC} ${MD5_SRC}
+PCRYPT_SRCS=	${CRYPT_SRCS:compat/%=${TOP}/compat/%}
+OBJS+=		${SRCS:.c=.o} ${PCRYPT_SRCS:.c=.o}
 
 .c.o:
 	${CC} ${CFLAGS} ${CPPFLAGS} -c $< -o $@
@@ -26,10 +26,8 @@
 distclean: clean
 	rm -f .depend
 
-.depend: ${SRCS} ${T_COMPAT_SRCS} ${T_MD5_SRC}
-	${CC} ${CPPFLAGS} -MM ${SRCS} ${T_COMPAT_SRCS} ${T_MD5_SRC} > .depend
-
-depend: .depend
+.depend: ${SRCS} ${PCRYPT_SRCS}
+	${CC} ${CPPFLAGS} -MM ${SRCS} ${PCRYPT_SRCS}
 
 ${PROG}: ${DEPEND} ${OBJS}
 	${CC} ${LDFLAGS} -o $@ ${OBJS} ${LDADD}
--- a/tests/crypt/test_hmac_md5.c	Thu Oct 05 08:05:08 2017 +0100
+++ b/tests/crypt/test_hmac_md5.c	Thu Oct 05 14:13:02 2017 +0100
@@ -30,10 +30,12 @@
 #include <stdlib.h>
 #include <string.h>
 
-#include "crypt/crypt.h"
+#include "config.h"
 #include "test.h"
 
-/* RFC2202 MD5 implementation */
+#ifdef HAVE_HMAC_H
+#include <hmac.h>
+#endif
 
 static void
 print_hmac(FILE *stream, const uint8_t *hmac)
@@ -66,14 +68,14 @@
 	    0x92, 0x94, 0x72, 0x7a, 0x36, 0x38, 0xbb, 0x1c,
 	    0x13, 0xf4, 0x8e, 0xf8, 0x15, 0x8b, 0xfc, 0x9d,
 	};
-	uint8_t hmac[16];
+	uint8_t digest[16];
 	int i;
 
 	printf ("HMAC MD5 Test 1:\t\t");
 	for (i = 0; i < 16; i++)
 		key[i] = 0x0b;
-	hmac_md5(text, 8, key, 16, hmac);
-	test_hmac(hmac, expect);
+	hmac("md5", key, 16, text, 8, digest, sizeof(digest));
+	test_hmac(digest, expect);
 }
 
 static void
@@ -85,11 +87,11 @@
 	    0x75, 0x0c, 0x78, 0x3e, 0x6a, 0xb0, 0xb5, 0x03,
 	    0xea, 0xa8, 0x6e, 0x31, 0x0a, 0x5d, 0xb7, 0x38,
 	};
-	uint8_t hmac[16];
+	uint8_t digest[16];
 
 	printf("HMAC MD5 Test 2:\t\t");
-	hmac_md5(text, 28, key, 4, hmac);
-	test_hmac(hmac, expect);
+	hmac("md5", key, 4, text, 28, digest, sizeof(digest));
+	test_hmac(digest, expect);
 }
 
 static void
@@ -99,7 +101,7 @@
 	    0x56, 0xbe, 0x34, 0x52, 0x1d, 0x14, 0x4c, 0x88,
 	    0xdb, 0xb8, 0xc7, 0x33, 0xf0, 0xe8, 0xb3, 0xf6,
 	};
-	uint8_t hmac[16];
+	uint8_t digest[16];
 	uint8_t text[50];
 	uint8_t key[16];
 	int i;
@@ -109,8 +111,8 @@
 		text[i] = 0xdd;
 	for (i = 0; i < 16; i++)
 		key[i] = 0xaa;
-	hmac_md5(text, 50, key, 16, hmac);
-	test_hmac(hmac, expect);
+	hmac("md5", key, 16, text, 50, digest, sizeof(digest));
+	test_hmac(digest, expect);
 }
 
 static void
@@ -120,7 +122,7 @@
 	    0x69, 0x7e, 0xaf, 0x0a, 0xca, 0x3a, 0x3a, 0xea,
 	    0x3a, 0x75, 0x16, 0x47, 0x46, 0xff, 0xaa, 0x79,
 	};
-	uint8_t hmac[16];
+	uint8_t digest[16];
 	uint8_t text[50];
 	uint8_t key[25];
 	uint8_t i;
@@ -130,8 +132,8 @@
 		text[i] = 0xcd;
 	for (i = 0; i < 25; i++)
 		key[i] = (uint8_t)(i + 1);
-	hmac_md5(text, 50, key, 25, hmac);
-	test_hmac(hmac, expect);
+	hmac("md5", key, 25, text, 50, digest, sizeof(digest));
+	test_hmac(digest, expect);
 }
 
 static void
@@ -142,15 +144,15 @@
 	    0x56, 0x46, 0x1e, 0xf2, 0x34, 0x2e, 0xdc, 0x00,
 	    0xf9, 0xba, 0xb9, 0x95, 0x69, 0x0e, 0xfd, 0x4c,
 	};
-	uint8_t hmac[16];
+	uint8_t digest[16];
 	uint8_t key[16];
 	int i;
 
 	printf ("HMAC MD5 Test 5:\t\t");
 	for (i = 0; i < 16; i++)
 		key[i] = 0x0c;
-	hmac_md5(text, 20, key, 16, hmac);
-	test_hmac(hmac, expect);
+	hmac("md5", key, 16, text, 20, digest, sizeof(digest));
+	test_hmac(digest, expect);
 }
 
 static void
@@ -161,15 +163,15 @@
 	    0x6b, 0x1a, 0xb7, 0xfe, 0x4b, 0xd7, 0xbf, 0x8f,
 	    0x0b, 0x62, 0xe6, 0xce, 0x61, 0xb9, 0xd0, 0xcd,
 	};
-	uint8_t hmac[16];
+	uint8_t digest[16];
 	uint8_t key[80];
 	int i;
 
 	printf ("HMAC MD5 Test 6:\t\t");
 	for (i = 0; i < 80; i++)
 		key[i] = 0xaa;
-	hmac_md5(text, 54, key, 80, hmac);
-	test_hmac(hmac, expect);
+	hmac("md5", key, 80, text, 54, digest, sizeof(digest));
+	test_hmac(digest, expect);
 }
 
 static void
@@ -180,15 +182,15 @@
 	    0x6f, 0x63, 0x0f, 0xad, 0x67, 0xcd, 0xa0, 0xee,
 	    0x1f, 0xb1, 0xf5, 0x62, 0xdb, 0x3a, 0xa5, 0x3e,
 	};
-	uint8_t hmac[16];
+	uint8_t digest[16];
 	uint8_t key[80];
 	int i;
 
 	printf ("HMAC MD5 Test 7:\t\t");
 	for (i = 0; i < 80; i++)
 		key[i] = 0xaa;
-	hmac_md5(text, 73, key, 80, hmac);
-	test_hmac(hmac, expect);
+	hmac("md5", key, 80, text, 73, digest, sizeof(digest));
+	test_hmac(digest, expect);
 }
 
 int test_hmac_md5(void)