summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNiels Provos <provos@cvs.openbsd.org>1997-11-24 19:14:17 +0000
committerNiels Provos <provos@cvs.openbsd.org>1997-11-24 19:14:17 +0000
commite6cda69f0bd9ff2bd19dfbd0144610703481846b (patch)
treead0fb8877b7f189ab98c895cc255b7d26a4c236d
parent33cee386e689e7acbbd46da941e7a7c55eeeef49 (diff)
add ripemd-160 as authentication function.
-rw-r--r--sys/netinet/ip_ah.h11
-rw-r--r--sys/netinet/ip_ah_new.c11
-rw-r--r--sys/netinet/ip_esp.h15
-rw-r--r--sys/netinet/ip_esp_new.c11
-rw-r--r--sys/netinet/ip_ipsp.h3
-rw-r--r--sys/netinet/ip_rmd160.c391
-rw-r--r--sys/netinet/ip_rmd160.h47
7 files changed, 477 insertions, 12 deletions
diff --git a/sys/netinet/ip_ah.h b/sys/netinet/ip_ah.h
index 6f5fd764ed5..b93e78847cd 100644
--- a/sys/netinet/ip_ah.h
+++ b/sys/netinet/ip_ah.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip_ah.h,v 1.10 1997/11/04 09:10:59 provos Exp $ */
+/* $OpenBSD: ip_ah.h,v 1.11 1997/11/24 19:14:11 provos Exp $ */
/*
* The author of this code is John Ioannidis, ji@tla.org,
@@ -34,6 +34,7 @@
#include <sys/md5k.h>
#include <netinet/ip_sha1.h>
+#include <netinet/ip_rmd160.h>
struct ah_hash {
int type;
@@ -59,6 +60,7 @@ struct ah_old
/* Authenticator lengths */
#define AH_MD5_ALEN 16
#define AH_SHA1_ALEN 20
+#define AH_RMD160_ALEN 20
#define AH_ALEN_MAX AH_SHA1_ALEN /* Keep this updated */
@@ -121,11 +123,13 @@ struct ah_new_xdata
{
MD5_CTX amx_MD5_ictx; /* Internal key+padding */
SHA1_CTX amx_SHA1_ictx;
+ RMD160_CTX amx_RMD160_ictx;
} amx_ictx;
union
{
MD5_CTX amx_MD5_octx; /* External key+padding */
SHA1_CTX amx_SHA1_octx;
+ RMD160_CTX amx_RMD160_octx;
} amx_octx;
};
@@ -133,9 +137,8 @@ struct ah_new_xdata
#define amx_md5_octx amx_octx.amx_MD5_octx
#define amx_sha1_ictx amx_ictx.amx_SHA1_ictx
#define amx_sha1_octx amx_octx.amx_SHA1_octx
-
-#define AHMD5_ALEN 16 /* Size of MD5 digest */
-#define AHSHA1_ALEN 20 /* Size of SHA-1 digest */
+#define amx_rmd160_ictx amx_ictx.amx_RMD160_ictx
+#define amx_rmd160_octx amx_octx.amx_RMD160_octx
struct ah_old_xdata
{
diff --git a/sys/netinet/ip_ah_new.c b/sys/netinet/ip_ah_new.c
index 5b6086caec3..08c51acc335 100644
--- a/sys/netinet/ip_ah_new.c
+++ b/sys/netinet/ip_ah_new.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip_ah_new.c,v 1.13 1997/11/18 09:09:43 deraadt Exp $ */
+/* $OpenBSD: ip_ah_new.c,v 1.14 1997/11/24 19:14:12 provos Exp $ */
/*
* The author of this code is John Ioannidis, ji@tla.org,
@@ -81,6 +81,13 @@ struct ah_hash ah_new_hash[] = {
(void (*)(void *)) SHA1Init,
(void (*)(void *, u_int8_t *, u_int16_t)) SHA1Update,
(void (*)(u_int8_t *, void *)) SHA1Final
+ },
+ { ALG_AUTH_RMD160, "HMAC-RIPEMD-160-96",
+ AH_RMD160_ALEN,
+ sizeof(RMD160_CTX),
+ (void (*)(void *)) RMD160Init,
+ (void (*)(void *, u_int8_t *, u_int16_t)) RMD160Update,
+ (void (*)(u_int8_t *, void *)) RMD160Final
}
};
@@ -271,6 +278,7 @@ ah_new_input(struct mbuf *m, struct tdb *tdb)
union {
MD5_CTX md5ctx;
SHA1_CTX sha1ctx;
+ RMD160_CTX rmd160ctx;
} ctx;
u_int8_t optval;
u_char buffer[40];
@@ -557,6 +565,7 @@ ah_new_output(struct mbuf *m, struct sockaddr_encap *gw, struct tdb *tdb,
union {
MD5_CTX md5ctx;
SHA1_CTX sha1ctx;
+ RMD160_CTX rmd160ctx;
} ctx;
int ilen, ohlen;
u_int8_t optval;
diff --git a/sys/netinet/ip_esp.h b/sys/netinet/ip_esp.h
index c28421c1d60..fb6c8aa7a13 100644
--- a/sys/netinet/ip_esp.h
+++ b/sys/netinet/ip_esp.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip_esp.h,v 1.15 1997/11/18 00:12:14 provos Exp $ */
+/* $OpenBSD: ip_esp.h,v 1.16 1997/11/24 19:14:13 provos Exp $ */
/*
* The author of this code is John Ioannidis, ji@tla.org,
@@ -37,6 +37,7 @@
#endif
#include <netinet/ip_sha1.h>
+#include <netinet/ip_rmd160.h>
#include <netinet/ip_blf.h>
#include <netinet/ip_cast.h>
@@ -189,13 +190,15 @@ struct esp_new_xdata
}Xu;
union
{
- MD5_CTX edx_MD5_ictx;
- SHA1_CTX edx_SHA1_ictx;
+ MD5_CTX edx_MD5_ictx;
+ SHA1_CTX edx_SHA1_ictx;
+ RMD160_CTX edx_RMD160_ictx;
} edx_ictx;
union
{
- MD5_CTX edx_MD5_octx;
- SHA1_CTX edx_SHA1_octx;
+ MD5_CTX edx_MD5_octx;
+ SHA1_CTX edx_SHA1_octx;
+ RMD160_CTX edx_RMD160_octx;
} edx_octx;
};
@@ -205,6 +208,8 @@ struct esp_new_xdata
#define edx_md5_octx edx_octx.edx_MD5_octx
#define edx_sha1_ictx edx_ictx.edx_SHA1_ictx
#define edx_sha1_octx edx_octx.edx_SHA1_octx
+#define edx_rmd160_ictx edx_ictx.edx_RMD160_ictx
+#define edx_rmd160_octx edx_octx.edx_RMD160_octx
#define ESP_OLD_FLENGTH 12
#define ESP_NEW_FLENGTH 16
diff --git a/sys/netinet/ip_esp_new.c b/sys/netinet/ip_esp_new.c
index ccb65185216..1263df399c7 100644
--- a/sys/netinet/ip_esp_new.c
+++ b/sys/netinet/ip_esp_new.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip_esp_new.c,v 1.13 1997/11/18 09:09:45 deraadt Exp $ */
+/* $OpenBSD: ip_esp_new.c,v 1.14 1997/11/24 19:14:14 provos Exp $ */
/*
* The author of this code is John Ioannidis, ji@tla.org,
@@ -93,6 +93,13 @@ struct esp_hash esp_new_hash[] = {
(void (*) (void *)) SHA1Init,
(void (*) (void *, u_int8_t *, u_int16_t)) SHA1Update,
(void (*) (u_int8_t *, void *)) SHA1Final
+ },
+ { ALG_AUTH_RMD160, "HMAC-RIPEMD-160-96",
+ AH_RMD160_ALEN,
+ sizeof(RMD160_CTX),
+ (void (*)(void *)) RMD160Init,
+ (void (*)(void *, u_int8_t *, u_int16_t)) RMD160Update,
+ (void (*)(u_int8_t *, void *)) RMD160Final
}
};
@@ -467,6 +474,7 @@ esp_new_input(struct mbuf *m, struct tdb *tdb)
union {
MD5_CTX md5ctx;
SHA1_CTX sha1ctx;
+ RMD160_CTX rmd160ctx;
} ctx;
u_char buf[AH_ALEN_MAX], buf2[AH_ALEN_MAX];
@@ -855,6 +863,7 @@ esp_new_output(struct mbuf *m, struct sockaddr_encap *gw, struct tdb *tdb,
union {
MD5_CTX md5ctx;
SHA1_CTX sha1ctx;
+ RMD160_CTX rmd160ctx;
} ctx;
int iphlen, blks, alen;
diff --git a/sys/netinet/ip_ipsp.h b/sys/netinet/ip_ipsp.h
index c1c2be2256d..a38abcc4b7d 100644
--- a/sys/netinet/ip_ipsp.h
+++ b/sys/netinet/ip_ipsp.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip_ipsp.h,v 1.15 1997/11/04 09:11:17 provos Exp $ */
+/* $OpenBSD: ip_ipsp.h,v 1.16 1997/11/24 19:14:15 provos Exp $ */
/*
* The author of this code is John Ioannidis, ji@tla.org,
@@ -130,6 +130,7 @@ struct xformsw
/* Supported key hash algorithms */
#define ALG_AUTH_MD5 1
#define ALG_AUTH_SHA1 2
+#define ALG_AUTH_RMD160 3
/* Supported encryption algorithms */
#define ALG_ENC_DES 1
diff --git a/sys/netinet/ip_rmd160.c b/sys/netinet/ip_rmd160.c
new file mode 100644
index 00000000000..dca3589e69c
--- /dev/null
+++ b/sys/netinet/ip_rmd160.c
@@ -0,0 +1,391 @@
+/********************************************************************\
+ *
+ * FILE: rmd160.c
+ *
+ * CONTENTS: A sample C-implementation of the RIPEMD-160
+ * hash-function.
+ * TARGET: any computer with an ANSI C compiler
+ *
+ * AUTHOR: Antoon Bosselaers, ESAT-COSIC
+ * (Arranged for libc by Todd C. Miller)
+ * DATE: 1 March 1996
+ * VERSION: 1.0
+ *
+ * Copyright (c) Katholieke Universiteit Leuven
+ * 1996, All Rights Reserved
+ *
+\********************************************************************/
+
+/* header files */
+#include <sys/param.h>
+#include <sys/systm.h>
+
+#include <netinet/ip_rmd160.h>
+
+/********************************************************************/
+
+/* macro definitions */
+
+/* collect four bytes into one word: */
+#define BYTES_TO_DWORD(strptr) \
+ (((u_int32_t) *((strptr)+3) << 24) | \
+ ((u_int32_t) *((strptr)+2) << 16) | \
+ ((u_int32_t) *((strptr)+1) << 8) | \
+ ((u_int32_t) *(strptr)))
+
+/* ROL(x, n) cyclically rotates x over n bits to the left */
+/* x must be of an unsigned 32 bits type and 0 <= n < 32. */
+#define ROL(x, n) (((x) << (n)) | ((x) >> (32-(n))))
+
+/* the three basic functions F(), G() and H() */
+#define F(x, y, z) ((x) ^ (y) ^ (z))
+#define G(x, y, z) (((x) & (y)) | (~(x) & (z)))
+#define H(x, y, z) (((x) | ~(y)) ^ (z))
+#define I(x, y, z) (((x) & (z)) | ((y) & ~(z)))
+#define J(x, y, z) ((x) ^ ((y) | ~(z)))
+
+/* the eight basic operations FF() through III() */
+#define FF(a, b, c, d, e, x, s) { \
+ (a) += F((b), (c), (d)) + (x); \
+ (a) = ROL((a), (s)) + (e); \
+ (c) = ROL((c), 10); \
+}
+#define GG(a, b, c, d, e, x, s) { \
+ (a) += G((b), (c), (d)) + (x) + 0x5a827999U; \
+ (a) = ROL((a), (s)) + (e); \
+ (c) = ROL((c), 10); \
+}
+#define HH(a, b, c, d, e, x, s) { \
+ (a) += H((b), (c), (d)) + (x) + 0x6ed9eba1U; \
+ (a) = ROL((a), (s)) + (e); \
+ (c) = ROL((c), 10); \
+}
+#define II(a, b, c, d, e, x, s) { \
+ (a) += I((b), (c), (d)) + (x) + 0x8f1bbcdcU; \
+ (a) = ROL((a), (s)) + (e); \
+ (c) = ROL((c), 10); \
+}
+#define JJ(a, b, c, d, e, x, s) { \
+ (a) += J((b), (c), (d)) + (x) + 0xa953fd4eU; \
+ (a) = ROL((a), (s)) + (e); \
+ (c) = ROL((c), 10); \
+}
+#define FFF(a, b, c, d, e, x, s) { \
+ (a) += F((b), (c), (d)) + (x); \
+ (a) = ROL((a), (s)) + (e); \
+ (c) = ROL((c), 10); \
+}
+#define GGG(a, b, c, d, e, x, s) { \
+ (a) += G((b), (c), (d)) + (x) + 0x7a6d76e9U; \
+ (a) = ROL((a), (s)) + (e); \
+ (c) = ROL((c), 10); \
+}
+#define HHH(a, b, c, d, e, x, s) { \
+ (a) += H((b), (c), (d)) + (x) + 0x6d703ef3U; \
+ (a) = ROL((a), (s)) + (e); \
+ (c) = ROL((c), 10); \
+}
+#define III(a, b, c, d, e, x, s) { \
+ (a) += I((b), (c), (d)) + (x) + 0x5c4dd124U; \
+ (a) = ROL((a), (s)) + (e); \
+ (c) = ROL((c), 10); \
+}
+#define JJJ(a, b, c, d, e, x, s) { \
+ (a) += J((b), (c), (d)) + (x) + 0x50a28be6U; \
+ (a) = ROL((a), (s)) + (e); \
+ (c) = ROL((c), 10); \
+}
+
+/********************************************************************/
+
+void RMD160Init(context)
+ RMD160_CTX *context;
+{
+
+ /* ripemd-160 initialization constants */
+ context->state[0] = 0x67452301U;
+ context->state[1] = 0xefcdab89U;
+ context->state[2] = 0x98badcfeU;
+ context->state[3] = 0x10325476U;
+ context->state[4] = 0xc3d2e1f0U;
+ context->length[0] = context->length[1] = 0;
+}
+
+/********************************************************************/
+
+void RMD160Transform(state, block)
+ u_int32_t state[5];
+ const u_int32_t block[16];
+{
+ u_int32_t aa = state[0], bb = state[1], cc = state[2],
+ dd = state[3], ee = state[4];
+ u_int32_t aaa = state[0], bbb = state[1], ccc = state[2],
+ ddd = state[3], eee = state[4];
+
+ /* round 1 */
+ FF(aa, bb, cc, dd, ee, block[ 0], 11);
+ FF(ee, aa, bb, cc, dd, block[ 1], 14);
+ FF(dd, ee, aa, bb, cc, block[ 2], 15);
+ FF(cc, dd, ee, aa, bb, block[ 3], 12);
+ FF(bb, cc, dd, ee, aa, block[ 4], 5);
+ FF(aa, bb, cc, dd, ee, block[ 5], 8);
+ FF(ee, aa, bb, cc, dd, block[ 6], 7);
+ FF(dd, ee, aa, bb, cc, block[ 7], 9);
+ FF(cc, dd, ee, aa, bb, block[ 8], 11);
+ FF(bb, cc, dd, ee, aa, block[ 9], 13);
+ FF(aa, bb, cc, dd, ee, block[10], 14);
+ FF(ee, aa, bb, cc, dd, block[11], 15);
+ FF(dd, ee, aa, bb, cc, block[12], 6);
+ FF(cc, dd, ee, aa, bb, block[13], 7);
+ FF(bb, cc, dd, ee, aa, block[14], 9);
+ FF(aa, bb, cc, dd, ee, block[15], 8);
+
+ /* round 2 */
+ GG(ee, aa, bb, cc, dd, block[ 7], 7);
+ GG(dd, ee, aa, bb, cc, block[ 4], 6);
+ GG(cc, dd, ee, aa, bb, block[13], 8);
+ GG(bb, cc, dd, ee, aa, block[ 1], 13);
+ GG(aa, bb, cc, dd, ee, block[10], 11);
+ GG(ee, aa, bb, cc, dd, block[ 6], 9);
+ GG(dd, ee, aa, bb, cc, block[15], 7);
+ GG(cc, dd, ee, aa, bb, block[ 3], 15);
+ GG(bb, cc, dd, ee, aa, block[12], 7);
+ GG(aa, bb, cc, dd, ee, block[ 0], 12);
+ GG(ee, aa, bb, cc, dd, block[ 9], 15);
+ GG(dd, ee, aa, bb, cc, block[ 5], 9);
+ GG(cc, dd, ee, aa, bb, block[ 2], 11);
+ GG(bb, cc, dd, ee, aa, block[14], 7);
+ GG(aa, bb, cc, dd, ee, block[11], 13);
+ GG(ee, aa, bb, cc, dd, block[ 8], 12);
+
+ /* round 3 */
+ HH(dd, ee, aa, bb, cc, block[ 3], 11);
+ HH(cc, dd, ee, aa, bb, block[10], 13);
+ HH(bb, cc, dd, ee, aa, block[14], 6);
+ HH(aa, bb, cc, dd, ee, block[ 4], 7);
+ HH(ee, aa, bb, cc, dd, block[ 9], 14);
+ HH(dd, ee, aa, bb, cc, block[15], 9);
+ HH(cc, dd, ee, aa, bb, block[ 8], 13);
+ HH(bb, cc, dd, ee, aa, block[ 1], 15);
+ HH(aa, bb, cc, dd, ee, block[ 2], 14);
+ HH(ee, aa, bb, cc, dd, block[ 7], 8);
+ HH(dd, ee, aa, bb, cc, block[ 0], 13);
+ HH(cc, dd, ee, aa, bb, block[ 6], 6);
+ HH(bb, cc, dd, ee, aa, block[13], 5);
+ HH(aa, bb, cc, dd, ee, block[11], 12);
+ HH(ee, aa, bb, cc, dd, block[ 5], 7);
+ HH(dd, ee, aa, bb, cc, block[12], 5);
+
+ /* round 4 */
+ II(cc, dd, ee, aa, bb, block[ 1], 11);
+ II(bb, cc, dd, ee, aa, block[ 9], 12);
+ II(aa, bb, cc, dd, ee, block[11], 14);
+ II(ee, aa, bb, cc, dd, block[10], 15);
+ II(dd, ee, aa, bb, cc, block[ 0], 14);
+ II(cc, dd, ee, aa, bb, block[ 8], 15);
+ II(bb, cc, dd, ee, aa, block[12], 9);
+ II(aa, bb, cc, dd, ee, block[ 4], 8);
+ II(ee, aa, bb, cc, dd, block[13], 9);
+ II(dd, ee, aa, bb, cc, block[ 3], 14);
+ II(cc, dd, ee, aa, bb, block[ 7], 5);
+ II(bb, cc, dd, ee, aa, block[15], 6);
+ II(aa, bb, cc, dd, ee, block[14], 8);
+ II(ee, aa, bb, cc, dd, block[ 5], 6);
+ II(dd, ee, aa, bb, cc, block[ 6], 5);
+ II(cc, dd, ee, aa, bb, block[ 2], 12);
+
+ /* round 5 */
+ JJ(bb, cc, dd, ee, aa, block[ 4], 9);
+ JJ(aa, bb, cc, dd, ee, block[ 0], 15);
+ JJ(ee, aa, bb, cc, dd, block[ 5], 5);
+ JJ(dd, ee, aa, bb, cc, block[ 9], 11);
+ JJ(cc, dd, ee, aa, bb, block[ 7], 6);
+ JJ(bb, cc, dd, ee, aa, block[12], 8);
+ JJ(aa, bb, cc, dd, ee, block[ 2], 13);
+ JJ(ee, aa, bb, cc, dd, block[10], 12);
+ JJ(dd, ee, aa, bb, cc, block[14], 5);
+ JJ(cc, dd, ee, aa, bb, block[ 1], 12);
+ JJ(bb, cc, dd, ee, aa, block[ 3], 13);
+ JJ(aa, bb, cc, dd, ee, block[ 8], 14);
+ JJ(ee, aa, bb, cc, dd, block[11], 11);
+ JJ(dd, ee, aa, bb, cc, block[ 6], 8);
+ JJ(cc, dd, ee, aa, bb, block[15], 5);
+ JJ(bb, cc, dd, ee, aa, block[13], 6);
+
+ /* parallel round 1 */
+ JJJ(aaa, bbb, ccc, ddd, eee, block[ 5], 8);
+ JJJ(eee, aaa, bbb, ccc, ddd, block[14], 9);
+ JJJ(ddd, eee, aaa, bbb, ccc, block[ 7], 9);
+ JJJ(ccc, ddd, eee, aaa, bbb, block[ 0], 11);
+ JJJ(bbb, ccc, ddd, eee, aaa, block[ 9], 13);
+ JJJ(aaa, bbb, ccc, ddd, eee, block[ 2], 15);
+ JJJ(eee, aaa, bbb, ccc, ddd, block[11], 15);
+ JJJ(ddd, eee, aaa, bbb, ccc, block[ 4], 5);
+ JJJ(ccc, ddd, eee, aaa, bbb, block[13], 7);
+ JJJ(bbb, ccc, ddd, eee, aaa, block[ 6], 7);
+ JJJ(aaa, bbb, ccc, ddd, eee, block[15], 8);
+ JJJ(eee, aaa, bbb, ccc, ddd, block[ 8], 11);
+ JJJ(ddd, eee, aaa, bbb, ccc, block[ 1], 14);
+ JJJ(ccc, ddd, eee, aaa, bbb, block[10], 14);
+ JJJ(bbb, ccc, ddd, eee, aaa, block[ 3], 12);
+ JJJ(aaa, bbb, ccc, ddd, eee, block[12], 6);
+
+ /* parallel round 2 */
+ III(eee, aaa, bbb, ccc, ddd, block[ 6], 9);
+ III(ddd, eee, aaa, bbb, ccc, block[11], 13);
+ III(ccc, ddd, eee, aaa, bbb, block[ 3], 15);
+ III(bbb, ccc, ddd, eee, aaa, block[ 7], 7);
+ III(aaa, bbb, ccc, ddd, eee, block[ 0], 12);
+ III(eee, aaa, bbb, ccc, ddd, block[13], 8);
+ III(ddd, eee, aaa, bbb, ccc, block[ 5], 9);
+ III(ccc, ddd, eee, aaa, bbb, block[10], 11);
+ III(bbb, ccc, ddd, eee, aaa, block[14], 7);
+ III(aaa, bbb, ccc, ddd, eee, block[15], 7);
+ III(eee, aaa, bbb, ccc, ddd, block[ 8], 12);
+ III(ddd, eee, aaa, bbb, ccc, block[12], 7);
+ III(ccc, ddd, eee, aaa, bbb, block[ 4], 6);
+ III(bbb, ccc, ddd, eee, aaa, block[ 9], 15);
+ III(aaa, bbb, ccc, ddd, eee, block[ 1], 13);
+ III(eee, aaa, bbb, ccc, ddd, block[ 2], 11);
+
+ /* parallel round 3 */
+ HHH(ddd, eee, aaa, bbb, ccc, block[15], 9);
+ HHH(ccc, ddd, eee, aaa, bbb, block[ 5], 7);
+ HHH(bbb, ccc, ddd, eee, aaa, block[ 1], 15);
+ HHH(aaa, bbb, ccc, ddd, eee, block[ 3], 11);
+ HHH(eee, aaa, bbb, ccc, ddd, block[ 7], 8);
+ HHH(ddd, eee, aaa, bbb, ccc, block[14], 6);
+ HHH(ccc, ddd, eee, aaa, bbb, block[ 6], 6);
+ HHH(bbb, ccc, ddd, eee, aaa, block[ 9], 14);
+ HHH(aaa, bbb, ccc, ddd, eee, block[11], 12);
+ HHH(eee, aaa, bbb, ccc, ddd, block[ 8], 13);
+ HHH(ddd, eee, aaa, bbb, ccc, block[12], 5);
+ HHH(ccc, ddd, eee, aaa, bbb, block[ 2], 14);
+ HHH(bbb, ccc, ddd, eee, aaa, block[10], 13);
+ HHH(aaa, bbb, ccc, ddd, eee, block[ 0], 13);
+ HHH(eee, aaa, bbb, ccc, ddd, block[ 4], 7);
+ HHH(ddd, eee, aaa, bbb, ccc, block[13], 5);
+
+ /* parallel round 4 */
+ GGG(ccc, ddd, eee, aaa, bbb, block[ 8], 15);
+ GGG(bbb, ccc, ddd, eee, aaa, block[ 6], 5);
+ GGG(aaa, bbb, ccc, ddd, eee, block[ 4], 8);
+ GGG(eee, aaa, bbb, ccc, ddd, block[ 1], 11);
+ GGG(ddd, eee, aaa, bbb, ccc, block[ 3], 14);
+ GGG(ccc, ddd, eee, aaa, bbb, block[11], 14);
+ GGG(bbb, ccc, ddd, eee, aaa, block[15], 6);
+ GGG(aaa, bbb, ccc, ddd, eee, block[ 0], 14);
+ GGG(eee, aaa, bbb, ccc, ddd, block[ 5], 6);
+ GGG(ddd, eee, aaa, bbb, ccc, block[12], 9);
+ GGG(ccc, ddd, eee, aaa, bbb, block[ 2], 12);
+ GGG(bbb, ccc, ddd, eee, aaa, block[13], 9);
+ GGG(aaa, bbb, ccc, ddd, eee, block[ 9], 12);
+ GGG(eee, aaa, bbb, ccc, ddd, block[ 7], 5);
+ GGG(ddd, eee, aaa, bbb, ccc, block[10], 15);
+ GGG(ccc, ddd, eee, aaa, bbb, block[14], 8);
+
+ /* parallel round 5 */
+ FFF(bbb, ccc, ddd, eee, aaa, block[12] , 8);
+ FFF(aaa, bbb, ccc, ddd, eee, block[15] , 5);
+ FFF(eee, aaa, bbb, ccc, ddd, block[10] , 12);
+ FFF(ddd, eee, aaa, bbb, ccc, block[ 4] , 9);
+ FFF(ccc, ddd, eee, aaa, bbb, block[ 1] , 12);
+ FFF(bbb, ccc, ddd, eee, aaa, block[ 5] , 5);
+ FFF(aaa, bbb, ccc, ddd, eee, block[ 8] , 14);
+ FFF(eee, aaa, bbb, ccc, ddd, block[ 7] , 6);
+ FFF(ddd, eee, aaa, bbb, ccc, block[ 6] , 8);
+ FFF(ccc, ddd, eee, aaa, bbb, block[ 2] , 13);
+ FFF(bbb, ccc, ddd, eee, aaa, block[13] , 6);
+ FFF(aaa, bbb, ccc, ddd, eee, block[14] , 5);
+ FFF(eee, aaa, bbb, ccc, ddd, block[ 0] , 15);
+ FFF(ddd, eee, aaa, bbb, ccc, block[ 3] , 13);
+ FFF(ccc, ddd, eee, aaa, bbb, block[ 9] , 11);
+ FFF(bbb, ccc, ddd, eee, aaa, block[11] , 11);
+
+ /* combine results */
+ ddd += cc + state[1]; /* final result for state[0] */
+ state[1] = state[2] + dd + eee;
+ state[2] = state[3] + ee + aaa;
+ state[3] = state[4] + aa + bbb;
+ state[4] = state[0] + bb + ccc;
+ state[0] = ddd;
+}
+
+/********************************************************************/
+
+void RMD160Update(context, data, nbytes)
+ RMD160_CTX *context;
+ const u_char *data;
+ u_int32_t nbytes;
+{
+ u_int32_t X[16];
+ u_int32_t i;
+#if BYTE_ORDER != LITTLE_ENDIAN
+ u_int32_t j;
+#endif
+ bzero(X, sizeof(X));
+
+ /* process all complete blocks */
+ for (i = 0; i < (nbytes >> 6); i++) {
+#if BYTE_ORDER == LITTLE_ENDIAN
+ bcopy(data, X, sizeof(X));
+#else
+ for (j=0; j < 16; j++)
+ X[j] = BYTES_TO_DWORD(data + (64 * i) + (4 * j));
+#endif
+ RMD160Transform(context->state, X);
+ }
+
+ /* update length[] */
+ if (context->length[0] + nbytes < context->length[0])
+ context->length[1]++; /* overflow to msb of length */
+ context->length[0] += nbytes;
+
+ /*
+ * Put bytes from data into context's buffer
+ */
+ bzero(context->buffer, 16 * sizeof(u_int32_t));
+ /* extract bytes 6 to 10 inclusive */
+ data += (context->length[0] & 0x3C0);
+ for (i = 0; i < (context->length[0] & 63); i++) {
+ /* byte i goes into word buffer[i div 4] at pos. 8*(i mod 4) */
+ context->buffer[i>>2] ^= (u_int32_t) *data++ << (8 * (i & 3));
+ }
+}
+
+/********************************************************************/
+
+void RMD160Final(digest, context)
+ u_char digest[20];
+ RMD160_CTX *context;
+{
+ u_int32_t i;
+
+ /* append the bit m_n == 1 */
+ context->buffer[(context->length[0] >> 2) & 15] ^=
+ 1U << (8 * (context->length[0] & 3) + 7);
+
+ if ((context->length[0] & 63) > 55) {
+ /* length goes to next block */
+ RMD160Transform(context->state, context->buffer);
+ bzero(context->buffer, 16 * sizeof(u_int32_t));
+ }
+
+ /* append length in bits */
+ context->buffer[14] = context->length[0] << 3;
+ context->buffer[15] = (context->length[0] >> 29) |
+ (context->length[1] << 3);
+ RMD160Transform(context->state, context->buffer);
+
+ if (digest != NULL) {
+ for (i = 0; i < 20; i += 4) {
+ /* extracts the 8 least significant bits. */
+ digest[i] = context->state[i>>2];
+ digest[i + 1] = (context->state[i>>2] >> 8);
+ digest[i + 2] = (context->state[i>>2] >> 16);
+ digest[i + 3] = (context->state[i>>2] >> 24);
+ }
+ }
+}
+
+/************************ end of file rmd160.c **********************/
diff --git a/sys/netinet/ip_rmd160.h b/sys/netinet/ip_rmd160.h
new file mode 100644
index 00000000000..270976300b8
--- /dev/null
+++ b/sys/netinet/ip_rmd160.h
@@ -0,0 +1,47 @@
+/* $OpenBSD: ip_rmd160.h,v 1.1 1997/11/24 19:14:16 provos Exp $ */
+
+/********************************************************************\
+ *
+ * FILE: rmd160.h
+ *
+ * CONTENTS: Header file for a sample C-implementation of the
+ * RIPEMD-160 hash-function.
+ * TARGET: any computer with an ANSI C compiler
+ *
+ * AUTHOR: Antoon Bosselaers, ESAT-COSIC
+ * DATE: 1 March 1996
+ * VERSION: 1.0
+ *
+ * Copyright (c) Katholieke Universiteit Leuven
+ * 1996, All Rights Reserved
+ *
+\********************************************************************/
+
+#ifndef _RMD160_H /* make sure this file is read only once */
+#define _RMD160_H
+
+/********************************************************************/
+
+/* structure definitions */
+
+typedef struct {
+ u_int32_t state[5]; /* state (ABCDE) */
+ u_int32_t length[2]; /* number of bits */
+ u_int32_t buffer[16]; /* input buffer */
+} RMD160_CTX;
+
+/********************************************************************/
+
+/* function prototypes */
+
+void RMD160Init __P((RMD160_CTX *context));
+void RMD160Transform __P((u_int32_t state[5], const u_int32_t block[16]));
+void RMD160Update __P((RMD160_CTX *context, const u_char *data, u_int nbytes));
+void RMD160Final __P((u_char digest[20], RMD160_CTX *context));
+char *RMD160End __P((RMD160_CTX *, char *));
+char *RMD160File __P((char *, char *));
+char *RMD160Data __P((const u_char *, size_t, char *));
+
+#endif /* _RMD160_H */
+
+/*********************** end of file rmd160.h ***********************/