[openssh-commits] [openssh] 01/01: support --without-openssl at configure time

git+noreply at mindrot.org git+noreply at mindrot.org
Wed Jan 14 21:50:10 EST 2015


This is an automated email from the git hooks/post-receive script.

djm pushed a commit to branch master
in repository openssh.

commit 81bfbd0bd35683de5d7f2238b985e5f8150a9180
Author: Damien Miller <djm at mindrot.org>
Date:   Wed Jan 14 21:48:18 2015 +1100

    support --without-openssl at configure time
    
    Disables and removes dependency on OpenSSL. Many features don't
    work and the set of crypto options is greatly restricted. This
    will only work on system with native arc4random or /dev/urandom.
    
    Considered highly experimental for now.
---
 openbsd-compat/md5.c    | 251 ++++++++++++++++++++++++++++++++
 openbsd-compat/md5.h    |  51 +++++++
 openbsd-compat/rmd160.c | 376 ++++++++++++++++++++++++++++++++++++++++++++++++
 openbsd-compat/rmd160.h |  61 ++++++++
 openbsd-compat/sha1.c   | 177 +++++++++++++++++++++++
 openbsd-compat/sha1.h   |  58 ++++++++
 6 files changed, 974 insertions(+)

diff --git a/openbsd-compat/md5.c b/openbsd-compat/md5.c
new file mode 100644
index 0000000..195ab51
--- /dev/null
+++ b/openbsd-compat/md5.c
@@ -0,0 +1,251 @@
+/*	$OpenBSD: md5.c,v 1.9 2014/01/08 06:14:57 tedu Exp $	*/
+
+/*
+ * This code implements the MD5 message-digest algorithm.
+ * The algorithm is due to Ron Rivest.	This code was
+ * written by Colin Plumb in 1993, no copyright is claimed.
+ * This code is in the public domain; do with it what you wish.
+ *
+ * Equivalent code is available from RSA Data Security, Inc.
+ * This code has been tested against that, and is equivalent,
+ * except that you don't need to include two pages of legalese
+ * with every copy.
+ *
+ * To compute the message digest of a chunk of bytes, declare an
+ * MD5Context structure, pass it to MD5Init, call MD5Update as
+ * needed on buffers full of bytes, and then call MD5Final, which
+ * will fill a supplied 16-byte array with the digest.
+ */
+
+#include "includes.h"
+
+#ifndef WITH_OPENSSL
+
+#include <sys/types.h>
+#include <string.h>
+#include "md5.h"
+
+#define PUT_64BIT_LE(cp, value) do {					\
+	(cp)[7] = (value) >> 56;					\
+	(cp)[6] = (value) >> 48;					\
+	(cp)[5] = (value) >> 40;					\
+	(cp)[4] = (value) >> 32;					\
+	(cp)[3] = (value) >> 24;					\
+	(cp)[2] = (value) >> 16;					\
+	(cp)[1] = (value) >> 8;						\
+	(cp)[0] = (value); } while (0)
+
+#define PUT_32BIT_LE(cp, value) do {					\
+	(cp)[3] = (value) >> 24;					\
+	(cp)[2] = (value) >> 16;					\
+	(cp)[1] = (value) >> 8;						\
+	(cp)[0] = (value); } while (0)
+
+static u_int8_t PADDING[MD5_BLOCK_LENGTH] = {
+	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
+};
+
+/*
+ * Start MD5 accumulation.  Set bit count to 0 and buffer to mysterious
+ * initialization constants.
+ */
+void
+MD5Init(MD5_CTX *ctx)
+{
+	ctx->count = 0;
+	ctx->state[0] = 0x67452301;
+	ctx->state[1] = 0xefcdab89;
+	ctx->state[2] = 0x98badcfe;
+	ctx->state[3] = 0x10325476;
+}
+
+/*
+ * Update context to reflect the concatenation of another buffer full
+ * of bytes.
+ */
+void
+MD5Update(MD5_CTX *ctx, const unsigned char *input, size_t len)
+{
+	size_t have, need;
+
+	/* Check how many bytes we already have and how many more we need. */
+	have = (size_t)((ctx->count >> 3) & (MD5_BLOCK_LENGTH - 1));
+	need = MD5_BLOCK_LENGTH - have;
+
+	/* Update bitcount */
+	ctx->count += (u_int64_t)len << 3;
+
+	if (len >= need) {
+		if (have != 0) {
+			memcpy(ctx->buffer + have, input, need);
+			MD5Transform(ctx->state, ctx->buffer);
+			input += need;
+			len -= need;
+			have = 0;
+		}
+
+		/* Process data in MD5_BLOCK_LENGTH-byte chunks. */
+		while (len >= MD5_BLOCK_LENGTH) {
+			MD5Transform(ctx->state, input);
+			input += MD5_BLOCK_LENGTH;
+			len -= MD5_BLOCK_LENGTH;
+		}
+	}
+
+	/* Handle any remaining bytes of data. */
+	if (len != 0)
+		memcpy(ctx->buffer + have, input, len);
+}
+
+/*
+ * Pad pad to 64-byte boundary with the bit pattern
+ * 1 0* (64-bit count of bits processed, MSB-first)
+ */
+void
+MD5Pad(MD5_CTX *ctx)
+{
+	u_int8_t count[8];
+	size_t padlen;
+
+	/* Convert count to 8 bytes in little endian order. */
+	PUT_64BIT_LE(count, ctx->count);
+
+	/* Pad out to 56 mod 64. */
+	padlen = MD5_BLOCK_LENGTH -
+	    ((ctx->count >> 3) & (MD5_BLOCK_LENGTH - 1));
+	if (padlen < 1 + 8)
+		padlen += MD5_BLOCK_LENGTH;
+	MD5Update(ctx, PADDING, padlen - 8);		/* padlen - 8 <= 64 */
+	MD5Update(ctx, count, 8);
+}
+
+/*
+ * Final wrapup--call MD5Pad, fill in digest and zero out ctx.
+ */
+void
+MD5Final(unsigned char digest[MD5_DIGEST_LENGTH], MD5_CTX *ctx)
+{
+	int i;
+
+	MD5Pad(ctx);
+	for (i = 0; i < 4; i++)
+		PUT_32BIT_LE(digest + i * 4, ctx->state[i]);
+	memset(ctx, 0, sizeof(*ctx));
+}
+
+
+/* The four core functions - F1 is optimized somewhat */
+
+/* #define F1(x, y, z) (x & y | ~x & z) */
+#define F1(x, y, z) (z ^ (x & (y ^ z)))
+#define F2(x, y, z) F1(z, x, y)
+#define F3(x, y, z) (x ^ y ^ z)
+#define F4(x, y, z) (y ^ (x | ~z))
+
+/* This is the central step in the MD5 algorithm. */
+#define MD5STEP(f, w, x, y, z, data, s) \
+	( w += f(x, y, z) + data,  w = w<<s | w>>(32-s),  w += x )
+
+/*
+ * The core of the MD5 algorithm, this alters an existing MD5 hash to
+ * reflect the addition of 16 longwords of new data.  MD5Update blocks
+ * the data and converts bytes into longwords for this routine.
+ */
+void
+MD5Transform(u_int32_t state[4], const u_int8_t block[MD5_BLOCK_LENGTH])
+{
+	u_int32_t a, b, c, d, in[MD5_BLOCK_LENGTH / 4];
+
+#if BYTE_ORDER == LITTLE_ENDIAN
+	memcpy(in, block, sizeof(in));
+#else
+	for (a = 0; a < MD5_BLOCK_LENGTH / 4; a++) {
+		in[a] = (u_int32_t)(
+		    (u_int32_t)(block[a * 4 + 0]) |
+		    (u_int32_t)(block[a * 4 + 1]) <<  8 |
+		    (u_int32_t)(block[a * 4 + 2]) << 16 |
+		    (u_int32_t)(block[a * 4 + 3]) << 24);
+	}
+#endif
+
+	a = state[0];
+	b = state[1];
+	c = state[2];
+	d = state[3];
+
+	MD5STEP(F1, a, b, c, d, in[ 0] + 0xd76aa478,  7);
+	MD5STEP(F1, d, a, b, c, in[ 1] + 0xe8c7b756, 12);
+	MD5STEP(F1, c, d, a, b, in[ 2] + 0x242070db, 17);
+	MD5STEP(F1, b, c, d, a, in[ 3] + 0xc1bdceee, 22);
+	MD5STEP(F1, a, b, c, d, in[ 4] + 0xf57c0faf,  7);
+	MD5STEP(F1, d, a, b, c, in[ 5] + 0x4787c62a, 12);
+	MD5STEP(F1, c, d, a, b, in[ 6] + 0xa8304613, 17);
+	MD5STEP(F1, b, c, d, a, in[ 7] + 0xfd469501, 22);
+	MD5STEP(F1, a, b, c, d, in[ 8] + 0x698098d8,  7);
+	MD5STEP(F1, d, a, b, c, in[ 9] + 0x8b44f7af, 12);
+	MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17);
+	MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22);
+	MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122,  7);
+	MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12);
+	MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17);
+	MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22);
+
+	MD5STEP(F2, a, b, c, d, in[ 1] + 0xf61e2562,  5);
+	MD5STEP(F2, d, a, b, c, in[ 6] + 0xc040b340,  9);
+	MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14);
+	MD5STEP(F2, b, c, d, a, in[ 0] + 0xe9b6c7aa, 20);
+	MD5STEP(F2, a, b, c, d, in[ 5] + 0xd62f105d,  5);
+	MD5STEP(F2, d, a, b, c, in[10] + 0x02441453,  9);
+	MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14);
+	MD5STEP(F2, b, c, d, a, in[ 4] + 0xe7d3fbc8, 20);
+	MD5STEP(F2, a, b, c, d, in[ 9] + 0x21e1cde6,  5);
+	MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6,  9);
+	MD5STEP(F2, c, d, a, b, in[ 3] + 0xf4d50d87, 14);
+	MD5STEP(F2, b, c, d, a, in[ 8] + 0x455a14ed, 20);
+	MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905,  5);
+	MD5STEP(F2, d, a, b, c, in[ 2] + 0xfcefa3f8,  9);
+	MD5STEP(F2, c, d, a, b, in[ 7] + 0x676f02d9, 14);
+	MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20);
+
+	MD5STEP(F3, a, b, c, d, in[ 5] + 0xfffa3942,  4);
+	MD5STEP(F3, d, a, b, c, in[ 8] + 0x8771f681, 11);
+	MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16);
+	MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23);
+	MD5STEP(F3, a, b, c, d, in[ 1] + 0xa4beea44,  4);
+	MD5STEP(F3, d, a, b, c, in[ 4] + 0x4bdecfa9, 11);
+	MD5STEP(F3, c, d, a, b, in[ 7] + 0xf6bb4b60, 16);
+	MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23);
+	MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6,  4);
+	MD5STEP(F3, d, a, b, c, in[ 0] + 0xeaa127fa, 11);
+	MD5STEP(F3, c, d, a, b, in[ 3] + 0xd4ef3085, 16);
+	MD5STEP(F3, b, c, d, a, in[ 6] + 0x04881d05, 23);
+	MD5STEP(F3, a, b, c, d, in[ 9] + 0xd9d4d039,  4);
+	MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11);
+	MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16);
+	MD5STEP(F3, b, c, d, a, in[2 ] + 0xc4ac5665, 23);
+
+	MD5STEP(F4, a, b, c, d, in[ 0] + 0xf4292244,  6);
+	MD5STEP(F4, d, a, b, c, in[7 ] + 0x432aff97, 10);
+	MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15);
+	MD5STEP(F4, b, c, d, a, in[5 ] + 0xfc93a039, 21);
+	MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3,  6);
+	MD5STEP(F4, d, a, b, c, in[3 ] + 0x8f0ccc92, 10);
+	MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15);
+	MD5STEP(F4, b, c, d, a, in[1 ] + 0x85845dd1, 21);
+	MD5STEP(F4, a, b, c, d, in[8 ] + 0x6fa87e4f,  6);
+	MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10);
+	MD5STEP(F4, c, d, a, b, in[6 ] + 0xa3014314, 15);
+	MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21);
+	MD5STEP(F4, a, b, c, d, in[4 ] + 0xf7537e82,  6);
+	MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10);
+	MD5STEP(F4, c, d, a, b, in[2 ] + 0x2ad7d2bb, 15);
+	MD5STEP(F4, b, c, d, a, in[9 ] + 0xeb86d391, 21);
+
+	state[0] += a;
+	state[1] += b;
+	state[2] += c;
+	state[3] += d;
+}
+#endif /* !WITH_OPENSSL */
diff --git a/openbsd-compat/md5.h b/openbsd-compat/md5.h
new file mode 100644
index 0000000..c83c19d
--- /dev/null
+++ b/openbsd-compat/md5.h
@@ -0,0 +1,51 @@
+/*	$OpenBSD: md5.h,v 1.17 2012/12/05 23:19:57 deraadt Exp $	*/
+
+/*
+ * This code implements the MD5 message-digest algorithm.
+ * The algorithm is due to Ron Rivest.  This code was
+ * written by Colin Plumb in 1993, no copyright is claimed.
+ * This code is in the public domain; do with it what you wish.
+ *
+ * Equivalent code is available from RSA Data Security, Inc.
+ * This code has been tested against that, and is equivalent,
+ * except that you don't need to include two pages of legalese
+ * with every copy.
+ */
+
+#ifndef _MD5_H_
+#define _MD5_H_
+
+#ifndef WITH_OPENSSL
+
+#define	MD5_BLOCK_LENGTH		64
+#define	MD5_DIGEST_LENGTH		16
+#define	MD5_DIGEST_STRING_LENGTH	(MD5_DIGEST_LENGTH * 2 + 1)
+
+typedef struct MD5Context {
+	u_int32_t state[4];			/* state */
+	u_int64_t count;			/* number of bits, mod 2^64 */
+	u_int8_t buffer[MD5_BLOCK_LENGTH];	/* input buffer */
+} MD5_CTX;
+
+void	 MD5Init(MD5_CTX *);
+void	 MD5Update(MD5_CTX *, const u_int8_t *, size_t)
+		__attribute__((__bounded__(__string__,2,3)));
+void	 MD5Pad(MD5_CTX *);
+void	 MD5Final(u_int8_t [MD5_DIGEST_LENGTH], MD5_CTX *)
+		__attribute__((__bounded__(__minbytes__,1,MD5_DIGEST_LENGTH)));
+void	 MD5Transform(u_int32_t [4], const u_int8_t [MD5_BLOCK_LENGTH])
+		__attribute__((__bounded__(__minbytes__,1,4)))
+		__attribute__((__bounded__(__minbytes__,2,MD5_BLOCK_LENGTH)));
+char	*MD5End(MD5_CTX *, char *)
+		__attribute__((__bounded__(__minbytes__,2,MD5_DIGEST_STRING_LENGTH)));
+char	*MD5File(const char *, char *)
+		__attribute__((__bounded__(__minbytes__,2,MD5_DIGEST_STRING_LENGTH)));
+char	*MD5FileChunk(const char *, char *, off_t, off_t)
+		__attribute__((__bounded__(__minbytes__,2,MD5_DIGEST_STRING_LENGTH)));
+char	*MD5Data(const u_int8_t *, size_t, char *)
+		__attribute__((__bounded__(__string__,1,2)))
+		__attribute__((__bounded__(__minbytes__,3,MD5_DIGEST_STRING_LENGTH)));
+
+#endif /* !WITH_OPENSSL */
+
+#endif /* _MD5_H_ */
diff --git a/openbsd-compat/rmd160.c b/openbsd-compat/rmd160.c
new file mode 100644
index 0000000..2a14dd7
--- /dev/null
+++ b/openbsd-compat/rmd160.c
@@ -0,0 +1,376 @@
+/*
+ * Copyright (c) 2001 Markus Friedl.  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 ``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 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.
+ */
+/*
+ * Preneel, Bosselaers, Dobbertin, "The Cryptographic Hash Function RIPEMD-160",
+ * RSA Laboratories, CryptoBytes, Volume 3, Number 2, Autumn 1997,
+ * ftp://ftp.rsasecurity.com/pub/cryptobytes/crypto3n2.pdf
+ */
+
+#include "includes.h"
+
+#ifndef WITH_OPENSSL
+
+#include <sys/types.h>
+#include <endian.h>
+#include <string.h>
+#include <rmd160.h>
+
+#define PUT_64BIT_LE(cp, value) do {                                    \
+	(cp)[7] = (value) >> 56;                                        \
+	(cp)[6] = (value) >> 48;                                        \
+	(cp)[5] = (value) >> 40;                                        \
+	(cp)[4] = (value) >> 32;                                        \
+	(cp)[3] = (value) >> 24;                                        \
+	(cp)[2] = (value) >> 16;                                        \
+	(cp)[1] = (value) >> 8;                                         \
+	(cp)[0] = (value); } while (0)
+
+#define PUT_32BIT_LE(cp, value) do {                                    \
+	(cp)[3] = (value) >> 24;                                        \
+	(cp)[2] = (value) >> 16;                                        \
+	(cp)[1] = (value) >> 8;                                         \
+	(cp)[0] = (value); } while (0)
+
+#define	H0	0x67452301U
+#define	H1	0xEFCDAB89U
+#define	H2	0x98BADCFEU
+#define	H3	0x10325476U
+#define	H4	0xC3D2E1F0U
+
+#define	K0	0x00000000U
+#define	K1	0x5A827999U
+#define	K2	0x6ED9EBA1U
+#define	K3	0x8F1BBCDCU
+#define	K4	0xA953FD4EU
+
+#define	KK0	0x50A28BE6U
+#define	KK1	0x5C4DD124U
+#define	KK2	0x6D703EF3U
+#define	KK3	0x7A6D76E9U
+#define	KK4	0x00000000U
+
+/* rotate x left n bits.  */
+#define ROL(n, x) (((x) << (n)) | ((x) >> (32-(n))))
+
+#define F0(x, y, z) ((x) ^ (y) ^ (z))
+#define F1(x, y, z) (((x) & (y)) | ((~x) & (z)))
+#define F2(x, y, z) (((x) | (~y)) ^ (z))
+#define F3(x, y, z) (((x) & (z)) | ((y) & (~z)))
+#define F4(x, y, z) ((x) ^ ((y) | (~z)))
+
+#define R(a, b, c, d, e, Fj, Kj, sj, rj)                                \
+	do {                                                            \
+		a = ROL(sj, a + Fj(b,c,d) + X(rj) + Kj) + e;            \
+		c = ROL(10, c);                                         \
+	} while(0)
+
+#define X(i)	x[i]
+
+static u_int8_t PADDING[RMD160_BLOCK_LENGTH] = {
+	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
+};
+
+void
+RMD160Init(RMD160_CTX *ctx)
+{
+	ctx->count = 0;
+	ctx->state[0] = H0;
+	ctx->state[1] = H1;
+	ctx->state[2] = H2;
+	ctx->state[3] = H3;
+	ctx->state[4] = H4;
+}
+
+void
+RMD160Update(RMD160_CTX *ctx, const u_int8_t *input, size_t len)
+{
+	size_t have, off, need;
+
+	have = (ctx->count / 8) % RMD160_BLOCK_LENGTH;
+	need = RMD160_BLOCK_LENGTH - have;
+	ctx->count += 8 * len;
+	off = 0;
+
+	if (len >= need) {
+		if (have) {
+			memcpy(ctx->buffer + have, input, need);
+			RMD160Transform(ctx->state, ctx->buffer);
+			off = need;
+			have = 0;
+		}
+		/* now the buffer is empty */
+		while (off + RMD160_BLOCK_LENGTH <= len) {
+			RMD160Transform(ctx->state, input+off);
+			off += RMD160_BLOCK_LENGTH;
+		}
+	}
+	if (off < len)
+		memcpy(ctx->buffer + have, input+off, len-off);
+}
+
+void
+RMD160Pad(RMD160_CTX *ctx)
+{
+	u_int8_t size[8];
+	size_t padlen;
+
+	PUT_64BIT_LE(size, ctx->count);
+
+	/*
+	 * pad to RMD160_BLOCK_LENGTH byte blocks, at least one byte from
+	 * PADDING plus 8 bytes for the size
+	 */
+	padlen = RMD160_BLOCK_LENGTH - ((ctx->count / 8) % RMD160_BLOCK_LENGTH);
+	if (padlen < 1 + 8)
+		padlen += RMD160_BLOCK_LENGTH;
+	RMD160Update(ctx, PADDING, padlen - 8);		/* padlen - 8 <= 64 */
+	RMD160Update(ctx, size, 8);
+}
+
+void
+RMD160Final(u_int8_t digest[RMD160_DIGEST_LENGTH], RMD160_CTX *ctx)
+{
+	int i;
+
+	RMD160Pad(ctx);
+	for (i = 0; i < 5; i++)
+		PUT_32BIT_LE(digest + i*4, ctx->state[i]);
+	memset(ctx, 0, sizeof (*ctx));
+}
+
+void
+RMD160Transform(u_int32_t state[5], const u_int8_t block[RMD160_BLOCK_LENGTH])
+{
+	u_int32_t a, b, c, d, e, aa, bb, cc, dd, ee, t, x[16];
+
+#if BYTE_ORDER == LITTLE_ENDIAN
+	memcpy(x, block, RMD160_BLOCK_LENGTH);
+#else
+	int i;
+
+	for (i = 0; i < 16; i++)
+		x[i] = (u_int32_t)(
+		    (u_int32_t)(block[i*4 + 0]) |
+		    (u_int32_t)(block[i*4 + 1]) <<  8 |
+		    (u_int32_t)(block[i*4 + 2]) << 16 |
+		    (u_int32_t)(block[i*4 + 3]) << 24);
+#endif
+
+	a = state[0];
+	b = state[1];
+	c = state[2];
+	d = state[3];
+	e = state[4];
+
+	/* Round 1 */
+	R(a, b, c, d, e, F0, K0, 11,  0);
+	R(e, a, b, c, d, F0, K0, 14,  1);
+	R(d, e, a, b, c, F0, K0, 15,  2);
+	R(c, d, e, a, b, F0, K0, 12,  3);
+	R(b, c, d, e, a, F0, K0,  5,  4);
+	R(a, b, c, d, e, F0, K0,  8,  5);
+	R(e, a, b, c, d, F0, K0,  7,  6);
+	R(d, e, a, b, c, F0, K0,  9,  7);
+	R(c, d, e, a, b, F0, K0, 11,  8);
+	R(b, c, d, e, a, F0, K0, 13,  9);
+	R(a, b, c, d, e, F0, K0, 14, 10);
+	R(e, a, b, c, d, F0, K0, 15, 11);
+	R(d, e, a, b, c, F0, K0,  6, 12);
+	R(c, d, e, a, b, F0, K0,  7, 13);
+	R(b, c, d, e, a, F0, K0,  9, 14);
+	R(a, b, c, d, e, F0, K0,  8, 15); /* #15 */
+	/* Round 2 */
+	R(e, a, b, c, d, F1, K1,  7,  7);
+	R(d, e, a, b, c, F1, K1,  6,  4);
+	R(c, d, e, a, b, F1, K1,  8, 13);
+	R(b, c, d, e, a, F1, K1, 13,  1);
+	R(a, b, c, d, e, F1, K1, 11, 10);
+	R(e, a, b, c, d, F1, K1,  9,  6);
+	R(d, e, a, b, c, F1, K1,  7, 15);
+	R(c, d, e, a, b, F1, K1, 15,  3);
+	R(b, c, d, e, a, F1, K1,  7, 12);
+	R(a, b, c, d, e, F1, K1, 12,  0);
+	R(e, a, b, c, d, F1, K1, 15,  9);
+	R(d, e, a, b, c, F1, K1,  9,  5);
+	R(c, d, e, a, b, F1, K1, 11,  2);
+	R(b, c, d, e, a, F1, K1,  7, 14);
+	R(a, b, c, d, e, F1, K1, 13, 11);
+	R(e, a, b, c, d, F1, K1, 12,  8); /* #31 */
+	/* Round 3 */
+	R(d, e, a, b, c, F2, K2, 11,  3);
+	R(c, d, e, a, b, F2, K2, 13, 10);
+	R(b, c, d, e, a, F2, K2,  6, 14);
+	R(a, b, c, d, e, F2, K2,  7,  4);
+	R(e, a, b, c, d, F2, K2, 14,  9);
+	R(d, e, a, b, c, F2, K2,  9, 15);
+	R(c, d, e, a, b, F2, K2, 13,  8);
+	R(b, c, d, e, a, F2, K2, 15,  1);
+	R(a, b, c, d, e, F2, K2, 14,  2);
+	R(e, a, b, c, d, F2, K2,  8,  7);
+	R(d, e, a, b, c, F2, K2, 13,  0);
+	R(c, d, e, a, b, F2, K2,  6,  6);
+	R(b, c, d, e, a, F2, K2,  5, 13);
+	R(a, b, c, d, e, F2, K2, 12, 11);
+	R(e, a, b, c, d, F2, K2,  7,  5);
+	R(d, e, a, b, c, F2, K2,  5, 12); /* #47 */
+	/* Round 4 */
+	R(c, d, e, a, b, F3, K3, 11,  1);
+	R(b, c, d, e, a, F3, K3, 12,  9);
+	R(a, b, c, d, e, F3, K3, 14, 11);
+	R(e, a, b, c, d, F3, K3, 15, 10);
+	R(d, e, a, b, c, F3, K3, 14,  0);
+	R(c, d, e, a, b, F3, K3, 15,  8);
+	R(b, c, d, e, a, F3, K3,  9, 12);
+	R(a, b, c, d, e, F3, K3,  8,  4);
+	R(e, a, b, c, d, F3, K3,  9, 13);
+	R(d, e, a, b, c, F3, K3, 14,  3);
+	R(c, d, e, a, b, F3, K3,  5,  7);
+	R(b, c, d, e, a, F3, K3,  6, 15);
+	R(a, b, c, d, e, F3, K3,  8, 14);
+	R(e, a, b, c, d, F3, K3,  6,  5);
+	R(d, e, a, b, c, F3, K3,  5,  6);
+	R(c, d, e, a, b, F3, K3, 12,  2); /* #63 */
+	/* Round 5 */
+	R(b, c, d, e, a, F4, K4,  9,  4);
+	R(a, b, c, d, e, F4, K4, 15,  0);
+	R(e, a, b, c, d, F4, K4,  5,  5);
+	R(d, e, a, b, c, F4, K4, 11,  9);
+	R(c, d, e, a, b, F4, K4,  6,  7);
+	R(b, c, d, e, a, F4, K4,  8, 12);
+	R(a, b, c, d, e, F4, K4, 13,  2);
+	R(e, a, b, c, d, F4, K4, 12, 10);
+	R(d, e, a, b, c, F4, K4,  5, 14);
+	R(c, d, e, a, b, F4, K4, 12,  1);
+	R(b, c, d, e, a, F4, K4, 13,  3);
+	R(a, b, c, d, e, F4, K4, 14,  8);
+	R(e, a, b, c, d, F4, K4, 11, 11);
+	R(d, e, a, b, c, F4, K4,  8,  6);
+	R(c, d, e, a, b, F4, K4,  5, 15);
+	R(b, c, d, e, a, F4, K4,  6, 13); /* #79 */
+
+	aa = a ; bb = b; cc = c; dd = d; ee = e;
+
+	a = state[0];
+	b = state[1];
+	c = state[2];
+	d = state[3];
+	e = state[4];
+
+	/* Parallel round 1 */
+	R(a, b, c, d, e, F4, KK0,  8,  5);
+	R(e, a, b, c, d, F4, KK0,  9, 14);
+	R(d, e, a, b, c, F4, KK0,  9,  7);
+	R(c, d, e, a, b, F4, KK0, 11,  0);
+	R(b, c, d, e, a, F4, KK0, 13,  9);
+	R(a, b, c, d, e, F4, KK0, 15,  2);
+	R(e, a, b, c, d, F4, KK0, 15, 11);
+	R(d, e, a, b, c, F4, KK0,  5,  4);
+	R(c, d, e, a, b, F4, KK0,  7, 13);
+	R(b, c, d, e, a, F4, KK0,  7,  6);
+	R(a, b, c, d, e, F4, KK0,  8, 15);
+	R(e, a, b, c, d, F4, KK0, 11,  8);
+	R(d, e, a, b, c, F4, KK0, 14,  1);
+	R(c, d, e, a, b, F4, KK0, 14, 10);
+	R(b, c, d, e, a, F4, KK0, 12,  3);
+	R(a, b, c, d, e, F4, KK0,  6, 12); /* #15 */
+	/* Parallel round 2 */
+	R(e, a, b, c, d, F3, KK1,  9,  6);
+	R(d, e, a, b, c, F3, KK1, 13, 11);
+	R(c, d, e, a, b, F3, KK1, 15,  3);
+	R(b, c, d, e, a, F3, KK1,  7,  7);
+	R(a, b, c, d, e, F3, KK1, 12,  0);
+	R(e, a, b, c, d, F3, KK1,  8, 13);
+	R(d, e, a, b, c, F3, KK1,  9,  5);
+	R(c, d, e, a, b, F3, KK1, 11, 10);
+	R(b, c, d, e, a, F3, KK1,  7, 14);
+	R(a, b, c, d, e, F3, KK1,  7, 15);
+	R(e, a, b, c, d, F3, KK1, 12,  8);
+	R(d, e, a, b, c, F3, KK1,  7, 12);
+	R(c, d, e, a, b, F3, KK1,  6,  4);
+	R(b, c, d, e, a, F3, KK1, 15,  9);
+	R(a, b, c, d, e, F3, KK1, 13,  1);
+	R(e, a, b, c, d, F3, KK1, 11,  2); /* #31 */
+	/* Parallel round 3 */
+	R(d, e, a, b, c, F2, KK2,  9, 15);
+	R(c, d, e, a, b, F2, KK2,  7,  5);
+	R(b, c, d, e, a, F2, KK2, 15,  1);
+	R(a, b, c, d, e, F2, KK2, 11,  3);
+	R(e, a, b, c, d, F2, KK2,  8,  7);
+	R(d, e, a, b, c, F2, KK2,  6, 14);
+	R(c, d, e, a, b, F2, KK2,  6,  6);
+	R(b, c, d, e, a, F2, KK2, 14,  9);
+	R(a, b, c, d, e, F2, KK2, 12, 11);
+	R(e, a, b, c, d, F2, KK2, 13,  8);
+	R(d, e, a, b, c, F2, KK2,  5, 12);
+	R(c, d, e, a, b, F2, KK2, 14,  2);
+	R(b, c, d, e, a, F2, KK2, 13, 10);
+	R(a, b, c, d, e, F2, KK2, 13,  0);
+	R(e, a, b, c, d, F2, KK2,  7,  4);
+	R(d, e, a, b, c, F2, KK2,  5, 13); /* #47 */
+	/* Parallel round 4 */
+	R(c, d, e, a, b, F1, KK3, 15,  8);
+	R(b, c, d, e, a, F1, KK3,  5,  6);
+	R(a, b, c, d, e, F1, KK3,  8,  4);
+	R(e, a, b, c, d, F1, KK3, 11,  1);
+	R(d, e, a, b, c, F1, KK3, 14,  3);
+	R(c, d, e, a, b, F1, KK3, 14, 11);
+	R(b, c, d, e, a, F1, KK3,  6, 15);
+	R(a, b, c, d, e, F1, KK3, 14,  0);
+	R(e, a, b, c, d, F1, KK3,  6,  5);
+	R(d, e, a, b, c, F1, KK3,  9, 12);
+	R(c, d, e, a, b, F1, KK3, 12,  2);
+	R(b, c, d, e, a, F1, KK3,  9, 13);
+	R(a, b, c, d, e, F1, KK3, 12,  9);
+	R(e, a, b, c, d, F1, KK3,  5,  7);
+	R(d, e, a, b, c, F1, KK3, 15, 10);
+	R(c, d, e, a, b, F1, KK3,  8, 14); /* #63 */
+	/* Parallel round 5 */
+	R(b, c, d, e, a, F0, KK4,  8, 12);
+	R(a, b, c, d, e, F0, KK4,  5, 15);
+	R(e, a, b, c, d, F0, KK4, 12, 10);
+	R(d, e, a, b, c, F0, KK4,  9,  4);
+	R(c, d, e, a, b, F0, KK4, 12,  1);
+	R(b, c, d, e, a, F0, KK4,  5,  5);
+	R(a, b, c, d, e, F0, KK4, 14,  8);
+	R(e, a, b, c, d, F0, KK4,  6,  7);
+	R(d, e, a, b, c, F0, KK4,  8,  6);
+	R(c, d, e, a, b, F0, KK4, 13,  2);
+	R(b, c, d, e, a, F0, KK4,  6, 13);
+	R(a, b, c, d, e, F0, KK4,  5, 14);
+	R(e, a, b, c, d, F0, KK4, 15,  0);
+	R(d, e, a, b, c, F0, KK4, 13,  3);
+	R(c, d, e, a, b, F0, KK4, 11,  9);
+	R(b, c, d, e, a, F0, KK4, 11, 11); /* #79 */
+
+	t =        state[1] + cc + d;
+	state[1] = state[2] + dd + e;
+	state[2] = state[3] + ee + a;
+	state[3] = state[4] + aa + b;
+	state[4] = state[0] + bb + c;
+	state[0] = t;
+}
+
+#endif /* !WITH_OPENSSL */
diff --git a/openbsd-compat/rmd160.h b/openbsd-compat/rmd160.h
new file mode 100644
index 0000000..99c1dcd
--- /dev/null
+++ b/openbsd-compat/rmd160.h
@@ -0,0 +1,61 @@
+/*	$OpenBSD: rmd160.h,v 1.17 2012/12/05 23:19:57 deraadt Exp $	*/
+/*
+ * Copyright (c) 2001 Markus Friedl.  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 ``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 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  _RMD160_H
+#define  _RMD160_H
+
+#ifndef WITH_OPENSSL
+
+#define	RMD160_BLOCK_LENGTH		64
+#define	RMD160_DIGEST_LENGTH		20
+#define	RMD160_DIGEST_STRING_LENGTH	(RMD160_DIGEST_LENGTH * 2 + 1)
+
+/* RMD160 context. */
+typedef struct RMD160Context {
+	u_int32_t state[5];			/* state */
+	u_int64_t count;			/* number of bits, mod 2^64 */
+	u_int8_t buffer[RMD160_BLOCK_LENGTH];	/* input buffer */
+} RMD160_CTX;
+
+void	 RMD160Init(RMD160_CTX *);
+void	 RMD160Transform(u_int32_t [5], const u_int8_t [RMD160_BLOCK_LENGTH])
+		__attribute__((__bounded__(__minbytes__,1,5)))
+		__attribute__((__bounded__(__minbytes__,2,RMD160_BLOCK_LENGTH)));
+void	 RMD160Update(RMD160_CTX *, const u_int8_t *, size_t)
+		__attribute__((__bounded__(__string__,2,3)));
+void	 RMD160Pad(RMD160_CTX *);
+void	 RMD160Final(u_int8_t [RMD160_DIGEST_LENGTH], RMD160_CTX *)
+		__attribute__((__bounded__(__minbytes__,1,RMD160_DIGEST_LENGTH)));
+char	*RMD160End(RMD160_CTX *, char *)
+		__attribute__((__bounded__(__minbytes__,2,RMD160_DIGEST_STRING_LENGTH)));
+char	*RMD160File(const char *, char *)
+		__attribute__((__bounded__(__minbytes__,2,RMD160_DIGEST_STRING_LENGTH)));
+char	*RMD160FileChunk(const char *, char *, off_t, off_t)
+		__attribute__((__bounded__(__minbytes__,2,RMD160_DIGEST_STRING_LENGTH)));
+char	*RMD160Data(const u_int8_t *, size_t, char *)
+		__attribute__((__bounded__(__string__,1,2)))
+		__attribute__((__bounded__(__minbytes__,3,RMD160_DIGEST_STRING_LENGTH)));
+
+#endif /* !WITH_OPENSSL */
+#endif  /* _RMD160_H */
diff --git a/openbsd-compat/sha1.c b/openbsd-compat/sha1.c
new file mode 100644
index 0000000..4b5381f
--- /dev/null
+++ b/openbsd-compat/sha1.c
@@ -0,0 +1,177 @@
+/*	$OpenBSD: sha1.c,v 1.23 2014/01/08 06:14:57 tedu Exp $	*/
+
+/*
+ * SHA-1 in C
+ * By Steve Reid <steve at edmweb.com>
+ * 100% Public Domain
+ *
+ * Test Vectors (from FIPS PUB 180-1)
+ * "abc"
+ *   A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D
+ * "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
+ *   84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1
+ * A million repetitions of "a"
+ *   34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F
+ */
+
+#include "includes.h"
+
+#ifndef WITH_OPENSSL
+
+#include <sys/param.h>
+#include <string.h>
+
+#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))
+
+/*
+ * blk0() and blk() perform the initial expand.
+ * I got the idea of expanding during the round function from SSLeay
+ */
+#if BYTE_ORDER == LITTLE_ENDIAN
+# define blk0(i) (block->l[i] = (rol(block->l[i],24)&0xFF00FF00) \
+    |(rol(block->l[i],8)&0x00FF00FF))
+#else
+# define blk0(i) block->l[i]
+#endif
+#define blk(i) (block->l[i&15] = rol(block->l[(i+13)&15]^block->l[(i+8)&15] \
+    ^block->l[(i+2)&15]^block->l[i&15],1))
+
+/*
+ * (R0+R1), R2, R3, R4 are the different operations (rounds) used in SHA1
+ */
+#define R0(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rol(v,5);w=rol(w,30);
+#define R1(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=rol(w,30);
+#define R2(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30);
+#define R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30);
+#define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30);
+
+typedef union {
+	u_int8_t c[64];
+	u_int32_t l[16];
+} CHAR64LONG16;
+
+/*
+ * Hash a single 512-bit block. This is the core of the algorithm.
+ */
+void
+SHA1Transform(u_int32_t state[5], const u_int8_t buffer[SHA1_BLOCK_LENGTH])
+{
+	u_int32_t a, b, c, d, e;
+	u_int8_t workspace[SHA1_BLOCK_LENGTH];
+	CHAR64LONG16 *block = (CHAR64LONG16 *)workspace;
+
+	(void)memcpy(block, buffer, SHA1_BLOCK_LENGTH);
+
+	/* Copy context->state[] to working vars */
+	a = state[0];
+	b = state[1];
+	c = state[2];
+	d = state[3];
+	e = state[4];
+
+	/* 4 rounds of 20 operations each. Loop unrolled. */
+	R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3);
+	R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7);
+	R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11);
+	R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15);
+	R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19);
+	R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23);
+	R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27);
+	R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31);
+	R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35);
+	R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39);
+	R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43);
+	R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47);
+	R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51);
+	R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55);
+	R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59);
+	R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63);
+	R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67);
+	R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71);
+	R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75);
+	R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79);
+
+	/* Add the working vars back into context.state[] */
+	state[0] += a;
+	state[1] += b;
+	state[2] += c;
+	state[3] += d;
+	state[4] += e;
+
+	/* Wipe variables */
+	a = b = c = d = e = 0;
+}
+
+
+/*
+ * SHA1Init - Initialize new context
+ */
+void
+SHA1Init(SHA1_CTX *context)
+{
+
+	/* SHA1 initialization constants */
+	context->count = 0;
+	context->state[0] = 0x67452301;
+	context->state[1] = 0xEFCDAB89;
+	context->state[2] = 0x98BADCFE;
+	context->state[3] = 0x10325476;
+	context->state[4] = 0xC3D2E1F0;
+}
+
+
+/*
+ * Run your data through this.
+ */
+void
+SHA1Update(SHA1_CTX *context, const u_int8_t *data, size_t len)
+{
+	size_t i, j;
+
+	j = (size_t)((context->count >> 3) & 63);
+	context->count += (len << 3);
+	if ((j + len) > 63) {
+		(void)memcpy(&context->buffer[j], data, (i = 64-j));
+		SHA1Transform(context->state, context->buffer);
+		for ( ; i + 63 < len; i += 64)
+			SHA1Transform(context->state, (u_int8_t *)&data[i]);
+		j = 0;
+	} else {
+		i = 0;
+	}
+	(void)memcpy(&context->buffer[j], &data[i], len - i);
+}
+
+
+/*
+ * Add padding and return the message digest.
+ */
+void
+SHA1Pad(SHA1_CTX *context)
+{
+	u_int8_t finalcount[8];
+	u_int i;
+
+	for (i = 0; i < 8; i++) {
+		finalcount[i] = (u_int8_t)((context->count >>
+		    ((7 - (i & 7)) * 8)) & 255);	/* Endian independent */
+	}
+	SHA1Update(context, (u_int8_t *)"\200", 1);
+	while ((context->count & 504) != 448)
+		SHA1Update(context, (u_int8_t *)"\0", 1);
+	SHA1Update(context, finalcount, 8); /* Should cause a SHA1Transform() */
+}
+
+void
+SHA1Final(u_int8_t digest[SHA1_DIGEST_LENGTH], SHA1_CTX *context)
+{
+	u_int i;
+
+	SHA1Pad(context);
+	for (i = 0; i < SHA1_DIGEST_LENGTH; i++) {
+		digest[i] = (u_int8_t)
+		   ((context->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255);
+	}
+	memset(context, 0, sizeof(*context));
+}
+#endif /* !WITH_OPENSSL */
diff --git a/openbsd-compat/sha1.h b/openbsd-compat/sha1.h
new file mode 100644
index 0000000..327d94c
--- /dev/null
+++ b/openbsd-compat/sha1.h
@@ -0,0 +1,58 @@
+/*	$OpenBSD: sha1.h,v 1.24 2012/12/05 23:19:57 deraadt Exp $	*/
+
+/*
+ * SHA-1 in C
+ * By Steve Reid <steve at edmweb.com>
+ * 100% Public Domain
+ */
+
+#ifndef _SHA1_H
+#define _SHA1_H
+
+#ifndef WITH_OPENSSL
+
+#define	SHA1_BLOCK_LENGTH		64
+#define	SHA1_DIGEST_LENGTH		20
+#define	SHA1_DIGEST_STRING_LENGTH	(SHA1_DIGEST_LENGTH * 2 + 1)
+
+typedef struct {
+    u_int32_t state[5];
+    u_int64_t count;
+    u_int8_t buffer[SHA1_BLOCK_LENGTH];
+} SHA1_CTX;
+
+void SHA1Init(SHA1_CTX *);
+void SHA1Pad(SHA1_CTX *);
+void SHA1Transform(u_int32_t [5], const u_int8_t [SHA1_BLOCK_LENGTH])
+	__attribute__((__bounded__(__minbytes__,1,5)))
+	__attribute__((__bounded__(__minbytes__,2,SHA1_BLOCK_LENGTH)));
+void SHA1Update(SHA1_CTX *, const u_int8_t *, size_t)
+	__attribute__((__bounded__(__string__,2,3)));
+void SHA1Final(u_int8_t [SHA1_DIGEST_LENGTH], SHA1_CTX *)
+	__attribute__((__bounded__(__minbytes__,1,SHA1_DIGEST_LENGTH)));
+char *SHA1End(SHA1_CTX *, char *)
+	__attribute__((__bounded__(__minbytes__,2,SHA1_DIGEST_STRING_LENGTH)));
+char *SHA1File(const char *, char *)
+	__attribute__((__bounded__(__minbytes__,2,SHA1_DIGEST_STRING_LENGTH)));
+char *SHA1FileChunk(const char *, char *, off_t, off_t)
+	__attribute__((__bounded__(__minbytes__,2,SHA1_DIGEST_STRING_LENGTH)));
+char *SHA1Data(const u_int8_t *, size_t, char *)
+	__attribute__((__bounded__(__string__,1,2)))
+	__attribute__((__bounded__(__minbytes__,3,SHA1_DIGEST_STRING_LENGTH)));
+
+#define HTONDIGEST(x) do {                                              \
+        x[0] = htonl(x[0]);                                             \
+        x[1] = htonl(x[1]);                                             \
+        x[2] = htonl(x[2]);                                             \
+        x[3] = htonl(x[3]);                                             \
+        x[4] = htonl(x[4]); } while (0)
+
+#define NTOHDIGEST(x) do {                                              \
+        x[0] = ntohl(x[0]);                                             \
+        x[1] = ntohl(x[1]);                                             \
+        x[2] = ntohl(x[2]);                                             \
+        x[3] = ntohl(x[3]);                                             \
+        x[4] = ntohl(x[4]); } while (0)
+
+#endif /* !WITH_OPENSSL */
+#endif /* _SHA1_H */

-- 
To stop receiving notification emails like this one, please contact
djm at mindrot.org.


More information about the openssh-commits mailing list