aboutsummaryrefslogtreecommitdiff
path: root/lib/libc/hash
diff options
context:
space:
mode:
authorCem Keylan <cem@ckyln.com>2020-10-16 17:41:25 +0300
committerCem Keylan <cem@ckyln.com>2020-10-16 17:41:25 +0300
commite2abcdca396661cbe0ae2ddb13d5c2b85682c13a (patch)
treeacf9b5c80b645617f882c45224c6e07251711842 /lib/libc/hash
downloadotools-e2abcdca396661cbe0ae2ddb13d5c2b85682c13a.tar.gz
initial commit
Diffstat (limited to 'lib/libc/hash')
-rw-r--r--lib/libc/hash/helper.c118
-rw-r--r--lib/libc/hash/md5.c252
-rw-r--r--lib/libc/hash/rmd160.c375
-rw-r--r--lib/libc/hash/sha1.c179
-rw-r--r--lib/libc/hash/sha2.c977
5 files changed, 1901 insertions, 0 deletions
diff --git a/lib/libc/hash/helper.c b/lib/libc/hash/helper.c
new file mode 100644
index 0000000..06e8060
--- /dev/null
+++ b/lib/libc/hash/helper.c
@@ -0,0 +1,118 @@
+/* $OpenBSD: helper.c,v 1.18 2019/06/28 13:32:41 deraadt Exp $ */
+
+/*
+ * Copyright (c) 2000 Poul-Henning Kamp <phk@FreeBSD.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * If we meet some day, and you think this stuff is worth it, you
+ * can buy me a beer in return. Poul-Henning Kamp
+ */
+
+#include <sys/types.h>
+#include <sys/cdefs.h>
+#include <sys/stat.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <hashinc>
+
+#define MINIMUM(a, b) (((a) < (b)) ? (a) : (b))
+
+char *
+HASHEnd(HASH_CTX *ctx, char *buf)
+{
+ int i;
+ u_int8_t digest[HASH_DIGEST_LENGTH];
+ static const char hex[] = "0123456789abcdef";
+
+ if (buf == NULL && (buf = malloc(HASH_DIGEST_STRING_LENGTH)) == NULL)
+ return (NULL);
+
+ HASHFinal(digest, ctx);
+ for (i = 0; i < HASH_DIGEST_LENGTH; i++) {
+ buf[i + i] = hex[digest[i] >> 4];
+ buf[i + i + 1] = hex[digest[i] & 0x0f];
+ }
+ buf[i + i] = '\0';
+ explicit_bzero(digest, sizeof(digest));
+ return (buf);
+}
+DEF_WEAK(HASHEnd);
+
+char *
+HASHFileChunk(const char *filename, char *buf, off_t off, off_t len)
+{
+ struct stat sb;
+ u_char buffer[BUFSIZ];
+ HASH_CTX ctx;
+ int fd, save_errno;
+ ssize_t nr;
+
+ HASHInit(&ctx);
+
+ if ((fd = open(filename, O_RDONLY)) == -1)
+ return (NULL);
+ if (len == 0) {
+ if (fstat(fd, &sb) == -1) {
+ save_errno = errno;
+ close(fd);
+ errno = save_errno;
+ return (NULL);
+ }
+ len = sb.st_size;
+ }
+ if (off > 0 && lseek(fd, off, SEEK_SET) == -1) {
+ save_errno = errno;
+ close(fd);
+ errno = save_errno;
+ return (NULL);
+ }
+
+ while ((nr = read(fd, buffer, MINIMUM(sizeof(buffer), len))) > 0) {
+ HASHUpdate(&ctx, buffer, nr);
+ if (len > 0 && (len -= nr) == 0)
+ break;
+ }
+
+ save_errno = errno;
+ close(fd);
+ errno = save_errno;
+ return (nr == -1 ? NULL : HASHEnd(&ctx, buf));
+}
+DEF_WEAK(HASHFileChunk);
+
+char *
+HASHFile(const char *filename, char *buf)
+{
+ return (HASHFileChunk(filename, buf, 0, 0));
+}
+DEF_WEAK(HASHFile);
+
+char *
+HASHData(const u_char *data, size_t len, char *buf)
+{
+ HASH_CTX ctx;
+
+ HASHInit(&ctx);
+ HASHUpdate(&ctx, data, len);
+ return (HASHEnd(&ctx, buf));
+}
+DEF_WEAK(HASHData);
diff --git a/lib/libc/hash/md5.c b/lib/libc/hash/md5.c
new file mode 100644
index 0000000..97a444d
--- /dev/null
+++ b/lib/libc/hash/md5.c
@@ -0,0 +1,252 @@
+/* $OpenBSD: md5.c,v 1.11 2015/09/11 09:18:27 guenther 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 <sys/cdefs.h>
+#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;
+}
+DEF_WEAK(MD5Init);
+
+/*
+ * 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);
+}
+DEF_WEAK(MD5Update);
+
+/*
+ * 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);
+}
+DEF_WEAK(MD5Pad);
+
+/*
+ * 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]);
+ explicit_bzero(ctx, sizeof(*ctx));
+}
+DEF_WEAK(MD5Final);
+
+
+/* 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;
+}
+DEF_WEAK(MD5Transform);
diff --git a/lib/libc/hash/rmd160.c b/lib/libc/hash/rmd160.c
new file mode 100644
index 0000000..c2e368f
--- /dev/null
+++ b/lib/libc/hash/rmd160.c
@@ -0,0 +1,375 @@
+/*
+ * 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 <sys/cdefs.h>
+#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;
+}
+DEF_WEAK(RMD160Init);
+
+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);
+}
+DEF_WEAK(RMD160Update);
+
+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);
+}
+DEF_WEAK(RMD160Pad);
+
+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]);
+ explicit_bzero(ctx, sizeof (*ctx));
+}
+DEF_WEAK(RMD160Final);
+
+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;
+}
+DEF_WEAK(RMD160Transform);
diff --git a/lib/libc/hash/sha1.c b/lib/libc/hash/sha1.c
new file mode 100644
index 0000000..ef6e2c2
--- /dev/null
+++ b/lib/libc/hash/sha1.c
@@ -0,0 +1,179 @@
+/* $OpenBSD: sha1.c,v 1.27 2019/06/07 22:56:36 dtucker Exp $ */
+
+/*
+ * SHA-1 in C
+ * By Steve Reid <steve@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 <sys/cdefs.h>
+#include <sys/types.h>
+#include <string.h>
+#include <sha1.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;
+}
+DEF_WEAK(SHA1Transform);
+
+
+/*
+ * 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;
+}
+DEF_WEAK(SHA1Init);
+
+
+/*
+ * 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 += ((u_int64_t)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);
+}
+DEF_WEAK(SHA1Update);
+
+
+/*
+ * 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() */
+}
+DEF_WEAK(SHA1Pad);
+
+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);
+ }
+ explicit_bzero(context, sizeof(*context));
+}
+DEF_WEAK(SHA1Final);
diff --git a/lib/libc/hash/sha2.c b/lib/libc/hash/sha2.c
new file mode 100644
index 0000000..3374197
--- /dev/null
+++ b/lib/libc/hash/sha2.c
@@ -0,0 +1,977 @@
+/* $OpenBSD: sha2.c,v 1.28 2019/07/23 12:35:22 dtucker Exp $ */
+
+/*
+ * FILE: sha2.c
+ * AUTHOR: Aaron D. Gifford <me@aarongifford.com>
+ *
+ * Copyright (c) 2000-2001, Aaron D. Gifford
+ * 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.
+ * 3. Neither the name of the copyright holder nor the names of contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTOR(S) ``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 CONTRIBUTOR(S) 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.
+ *
+ * $From: sha2.c,v 1.1 2001/11/08 00:01:51 adg Exp adg $
+ */
+
+#include <sys/types.h>
+#include <sys/cdefs.h>
+#include <sys/compat.h>
+
+#include <string.h>
+#include <sha2.h>
+
+/*
+ * UNROLLED TRANSFORM LOOP NOTE:
+ * You can define SHA2_UNROLL_TRANSFORM to use the unrolled transform
+ * loop version for the hash transform rounds (defined using macros
+ * later in this file). Either define on the command line, for example:
+ *
+ * cc -DSHA2_UNROLL_TRANSFORM -o sha2 sha2.c sha2prog.c
+ *
+ * or define below:
+ *
+ * #define SHA2_UNROLL_TRANSFORM
+ *
+ */
+#ifndef SHA2_SMALL
+#if defined(__amd64__) || defined(__i386__)
+#define SHA2_UNROLL_TRANSFORM
+#endif
+#endif
+
+/*** SHA-224/256/384/512 Machine Architecture Definitions *****************/
+/*
+ * BYTE_ORDER NOTE:
+ *
+ * Please make sure that your system defines BYTE_ORDER. If your
+ * architecture is little-endian, make sure it also defines
+ * LITTLE_ENDIAN and that the two (BYTE_ORDER and LITTLE_ENDIAN) are
+ * equivalent.
+ *
+ * If your system does not define the above, then you can do so by
+ * hand like this:
+ *
+ * #define LITTLE_ENDIAN 1234
+ * #define BIG_ENDIAN 4321
+ *
+ * And for little-endian machines, add:
+ *
+ * #define BYTE_ORDER LITTLE_ENDIAN
+ *
+ * Or for big-endian machines:
+ *
+ * #define BYTE_ORDER BIG_ENDIAN
+ *
+ * The FreeBSD machine this was written on defines BYTE_ORDER
+ * appropriately by including <sys/types.h> (which in turn includes
+ * <machine/endian.h> where the appropriate definitions are actually
+ * made).
+ */
+#if !defined(BYTE_ORDER) || (BYTE_ORDER != LITTLE_ENDIAN && BYTE_ORDER != BIG_ENDIAN)
+#error Define BYTE_ORDER to be equal to either LITTLE_ENDIAN or BIG_ENDIAN
+#endif
+
+
+/*** SHA-224/256/384/512 Various Length Definitions ***********************/
+/* NOTE: Most of these are in sha2.h */
+#define SHA224_SHORT_BLOCK_LENGTH (SHA224_BLOCK_LENGTH - 8)
+#define SHA256_SHORT_BLOCK_LENGTH (SHA256_BLOCK_LENGTH - 8)
+#define SHA384_SHORT_BLOCK_LENGTH (SHA384_BLOCK_LENGTH - 16)
+#define SHA512_SHORT_BLOCK_LENGTH (SHA512_BLOCK_LENGTH - 16)
+
+/*** ENDIAN SPECIFIC COPY MACROS **************************************/
+#define BE_8_TO_32(dst, cp) do { \
+ (dst) = (u_int32_t)(cp)[3] | ((u_int32_t)(cp)[2] << 8) | \
+ ((u_int32_t)(cp)[1] << 16) | ((u_int32_t)(cp)[0] << 24); \
+} while(0)
+
+#define BE_8_TO_64(dst, cp) do { \
+ (dst) = (u_int64_t)(cp)[7] | ((u_int64_t)(cp)[6] << 8) | \
+ ((u_int64_t)(cp)[5] << 16) | ((u_int64_t)(cp)[4] << 24) | \
+ ((u_int64_t)(cp)[3] << 32) | ((u_int64_t)(cp)[2] << 40) | \
+ ((u_int64_t)(cp)[1] << 48) | ((u_int64_t)(cp)[0] << 56); \
+} while (0)
+
+#define BE_64_TO_8(cp, src) do { \
+ (cp)[0] = (src) >> 56; \
+ (cp)[1] = (src) >> 48; \
+ (cp)[2] = (src) >> 40; \
+ (cp)[3] = (src) >> 32; \
+ (cp)[4] = (src) >> 24; \
+ (cp)[5] = (src) >> 16; \
+ (cp)[6] = (src) >> 8; \
+ (cp)[7] = (src); \
+} while (0)
+
+#define BE_32_TO_8(cp, src) do { \
+ (cp)[0] = (src) >> 24; \
+ (cp)[1] = (src) >> 16; \
+ (cp)[2] = (src) >> 8; \
+ (cp)[3] = (src); \
+} while (0)
+
+/*
+ * Macro for incrementally adding the unsigned 64-bit integer n to the
+ * unsigned 128-bit integer (represented using a two-element array of
+ * 64-bit words):
+ */
+#define ADDINC128(w,n) do { \
+ (w)[0] += (u_int64_t)(n); \
+ if ((w)[0] < (n)) { \
+ (w)[1]++; \
+ } \
+} while (0)
+
+/*** THE SIX LOGICAL FUNCTIONS ****************************************/
+/*
+ * Bit shifting and rotation (used by the six SHA-XYZ logical functions:
+ *
+ * NOTE: The naming of R and S appears backwards here (R is a SHIFT and
+ * S is a ROTATION) because the SHA-224/256/384/512 description document
+ * (see http://csrc.nist.gov/cryptval/shs/sha256-384-512.pdf) uses this
+ * same "backwards" definition.
+ */
+/* Shift-right (used in SHA-224, SHA-256, SHA-384, and SHA-512): */
+#define R(b,x) ((x) >> (b))
+/* 32-bit Rotate-right (used in SHA-224 and SHA-256): */
+#define S32(b,x) (((x) >> (b)) | ((x) << (32 - (b))))
+/* 64-bit Rotate-right (used in SHA-384 and SHA-512): */
+#define S64(b,x) (((x) >> (b)) | ((x) << (64 - (b))))
+
+/* Two of six logical functions used in SHA-224, SHA-256, SHA-384, and SHA-512: */
+#define Ch(x,y,z) (((x) & (y)) ^ ((~(x)) & (z)))
+#define Maj(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))
+
+/* Four of six logical functions used in SHA-224 and SHA-256: */
+#define Sigma0_256(x) (S32(2, (x)) ^ S32(13, (x)) ^ S32(22, (x)))
+#define Sigma1_256(x) (S32(6, (x)) ^ S32(11, (x)) ^ S32(25, (x)))
+#define sigma0_256(x) (S32(7, (x)) ^ S32(18, (x)) ^ R(3 , (x)))
+#define sigma1_256(x) (S32(17, (x)) ^ S32(19, (x)) ^ R(10, (x)))
+
+/* Four of six logical functions used in SHA-384 and SHA-512: */
+#define Sigma0_512(x) (S64(28, (x)) ^ S64(34, (x)) ^ S64(39, (x)))
+#define Sigma1_512(x) (S64(14, (x)) ^ S64(18, (x)) ^ S64(41, (x)))
+#define sigma0_512(x) (S64( 1, (x)) ^ S64( 8, (x)) ^ R( 7, (x)))
+#define sigma1_512(x) (S64(19, (x)) ^ S64(61, (x)) ^ R( 6, (x)))
+
+
+/*** SHA-XYZ INITIAL HASH VALUES AND CONSTANTS ************************/
+/* Hash constant words K for SHA-224 and SHA-256: */
+static const u_int32_t K256[64] = {
+ 0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL,
+ 0x3956c25bUL, 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL,
+ 0xd807aa98UL, 0x12835b01UL, 0x243185beUL, 0x550c7dc3UL,
+ 0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL, 0xc19bf174UL,
+ 0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL,
+ 0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL,
+ 0x983e5152UL, 0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL,
+ 0xc6e00bf3UL, 0xd5a79147UL, 0x06ca6351UL, 0x14292967UL,
+ 0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL, 0x53380d13UL,
+ 0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL,
+ 0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL,
+ 0xd192e819UL, 0xd6990624UL, 0xf40e3585UL, 0x106aa070UL,
+ 0x19a4c116UL, 0x1e376c08UL, 0x2748774cUL, 0x34b0bcb5UL,
+ 0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL, 0x682e6ff3UL,
+ 0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL,
+ 0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL
+};
+
+/* Initial hash value H for SHA-256: */
+static const u_int32_t sha256_initial_hash_value[8] = {
+ 0x6a09e667UL,
+ 0xbb67ae85UL,
+ 0x3c6ef372UL,
+ 0xa54ff53aUL,
+ 0x510e527fUL,
+ 0x9b05688cUL,
+ 0x1f83d9abUL,
+ 0x5be0cd19UL
+};
+
+/* Hash constant words K for SHA-384 and SHA-512: */
+static const u_int64_t K512[80] = {
+ 0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL,
+ 0xb5c0fbcfec4d3b2fULL, 0xe9b5dba58189dbbcULL,
+ 0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL,
+ 0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL,
+ 0xd807aa98a3030242ULL, 0x12835b0145706fbeULL,
+ 0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL,
+ 0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL,
+ 0x9bdc06a725c71235ULL, 0xc19bf174cf692694ULL,
+ 0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL,
+ 0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL,
+ 0x2de92c6f592b0275ULL, 0x4a7484aa6ea6e483ULL,
+ 0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL,
+ 0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL,
+ 0xb00327c898fb213fULL, 0xbf597fc7beef0ee4ULL,
+ 0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL,
+ 0x06ca6351e003826fULL, 0x142929670a0e6e70ULL,
+ 0x27b70a8546d22ffcULL, 0x2e1b21385c26c926ULL,
+ 0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL,
+ 0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL,
+ 0x81c2c92e47edaee6ULL, 0x92722c851482353bULL,
+ 0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL,
+ 0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL,
+ 0xd192e819d6ef5218ULL, 0xd69906245565a910ULL,
+ 0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL,
+ 0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL,
+ 0x2748774cdf8eeb99ULL, 0x34b0bcb5e19b48a8ULL,
+ 0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL,
+ 0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL,
+ 0x748f82ee5defb2fcULL, 0x78a5636f43172f60ULL,
+ 0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL,
+ 0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL,
+ 0xbef9a3f7b2c67915ULL, 0xc67178f2e372532bULL,
+ 0xca273eceea26619cULL, 0xd186b8c721c0c207ULL,
+ 0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL,
+ 0x06f067aa72176fbaULL, 0x0a637dc5a2c898a6ULL,
+ 0x113f9804bef90daeULL, 0x1b710b35131c471bULL,
+ 0x28db77f523047d84ULL, 0x32caab7b40c72493ULL,
+ 0x3c9ebe0a15c9bebcULL, 0x431d67c49c100d4cULL,
+ 0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL,
+ 0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL
+};
+
+/* Initial hash value H for SHA-512 */
+static const u_int64_t sha512_initial_hash_value[8] = {
+ 0x6a09e667f3bcc908ULL,
+ 0xbb67ae8584caa73bULL,
+ 0x3c6ef372fe94f82bULL,
+ 0xa54ff53a5f1d36f1ULL,
+ 0x510e527fade682d1ULL,
+ 0x9b05688c2b3e6c1fULL,
+ 0x1f83d9abfb41bd6bULL,
+ 0x5be0cd19137e2179ULL
+};
+
+#if !defined(SHA2_SMALL)
+/* Initial hash value H for SHA-224: */
+static const u_int32_t sha224_initial_hash_value[8] = {
+ 0xc1059ed8UL,
+ 0x367cd507UL,
+ 0x3070dd17UL,
+ 0xf70e5939UL,
+ 0xffc00b31UL,
+ 0x68581511UL,
+ 0x64f98fa7UL,
+ 0xbefa4fa4UL
+};
+
+/* Initial hash value H for SHA-384 */
+static const u_int64_t sha384_initial_hash_value[8] = {
+ 0xcbbb9d5dc1059ed8ULL,
+ 0x629a292a367cd507ULL,
+ 0x9159015a3070dd17ULL,
+ 0x152fecd8f70e5939ULL,
+ 0x67332667ffc00b31ULL,
+ 0x8eb44a8768581511ULL,
+ 0xdb0c2e0d64f98fa7ULL,
+ 0x47b5481dbefa4fa4ULL
+};
+
+/* Initial hash value H for SHA-512-256 */
+static const u_int64_t sha512_256_initial_hash_value[8] = {
+ 0x22312194fc2bf72cULL,
+ 0x9f555fa3c84c64c2ULL,
+ 0x2393b86b6f53b151ULL,
+ 0x963877195940eabdULL,
+ 0x96283ee2a88effe3ULL,
+ 0xbe5e1e2553863992ULL,
+ 0x2b0199fc2c85b8aaULL,
+ 0x0eb72ddc81c52ca2ULL
+};
+
+/*** SHA-224: *********************************************************/
+void
+SHA224Init(SHA2_CTX *context)
+{
+ memcpy(context->state.st32, sha224_initial_hash_value,
+ sizeof(sha224_initial_hash_value));
+ memset(context->buffer, 0, sizeof(context->buffer));
+ context->bitcount[0] = 0;
+}
+DEF_WEAK(SHA224Init);
+
+MAKE_CLONE(SHA224Transform, SHA256Transform);
+MAKE_CLONE(SHA224Update, SHA256Update);
+MAKE_CLONE(SHA224Pad, SHA256Pad);
+DEF_WEAK(SHA224Transform);
+DEF_WEAK(SHA224Update);
+DEF_WEAK(SHA224Pad);
+
+void
+SHA224Final(u_int8_t digest[SHA224_DIGEST_LENGTH], SHA2_CTX *context)
+{
+ SHA224Pad(context);
+
+#if BYTE_ORDER == LITTLE_ENDIAN
+ int i;
+
+ /* Convert TO host byte order */
+ for (i = 0; i < 7; i++)
+ BE_32_TO_8(digest + i * 4, context->state.st32[i]);
+#else
+ memcpy(digest, context->state.st32, SHA224_DIGEST_LENGTH);
+#endif
+ explicit_bzero(context, sizeof(*context));
+}
+DEF_WEAK(SHA224Final);
+#endif /* !defined(SHA2_SMALL) */
+
+/*** SHA-256: *********************************************************/
+void
+SHA256Init(SHA2_CTX *context)
+{
+ memcpy(context->state.st32, sha256_initial_hash_value,
+ sizeof(sha256_initial_hash_value));
+ memset(context->buffer, 0, sizeof(context->buffer));
+ context->bitcount[0] = 0;
+}
+DEF_WEAK(SHA256Init);
+
+#ifdef SHA2_UNROLL_TRANSFORM
+
+/* Unrolled SHA-256 round macros: */
+
+#define ROUND256_0_TO_15(a,b,c,d,e,f,g,h) do { \
+ BE_8_TO_32(W256[j], data); \
+ data += 4; \
+ T1 = (h) + Sigma1_256((e)) + Ch((e), (f), (g)) + K256[j] + W256[j]; \
+ (d) += T1; \
+ (h) = T1 + Sigma0_256((a)) + Maj((a), (b), (c)); \
+ j++; \
+} while(0)
+
+#define ROUND256(a,b,c,d,e,f,g,h) do { \
+ s0 = W256[(j+1)&0x0f]; \
+ s0 = sigma0_256(s0); \
+ s1 = W256[(j+14)&0x0f]; \
+ s1 = sigma1_256(s1); \
+ T1 = (h) + Sigma1_256((e)) + Ch((e), (f), (g)) + K256[j] + \
+ (W256[j&0x0f] += s1 + W256[(j+9)&0x0f] + s0); \
+ (d) += T1; \
+ (h) = T1 + Sigma0_256((a)) + Maj((a), (b), (c)); \
+ j++; \
+} while(0)
+
+void
+SHA256Transform(u_int32_t state[8], const u_int8_t data[SHA256_BLOCK_LENGTH])
+{
+ u_int32_t a, b, c, d, e, f, g, h, s0, s1;
+ u_int32_t T1, W256[16];
+ int j;
+
+ /* Initialize registers with the prev. intermediate value */
+ a = state[0];
+ b = state[1];
+ c = state[2];
+ d = state[3];
+ e = state[4];
+ f = state[5];
+ g = state[6];
+ h = state[7];
+
+ j = 0;
+ do {
+ /* Rounds 0 to 15 (unrolled): */
+ ROUND256_0_TO_15(a,b,c,d,e,f,g,h);
+ ROUND256_0_TO_15(h,a,b,c,d,e,f,g);
+ ROUND256_0_TO_15(g,h,a,b,c,d,e,f);
+ ROUND256_0_TO_15(f,g,h,a,b,c,d,e);
+ ROUND256_0_TO_15(e,f,g,h,a,b,c,d);
+ ROUND256_0_TO_15(d,e,f,g,h,a,b,c);
+ ROUND256_0_TO_15(c,d,e,f,g,h,a,b);
+ ROUND256_0_TO_15(b,c,d,e,f,g,h,a);
+ } while (j < 16);
+
+ /* Now for the remaining rounds up to 63: */
+ do {
+ ROUND256(a,b,c,d,e,f,g,h);
+ ROUND256(h,a,b,c,d,e,f,g);
+ ROUND256(g,h,a,b,c,d,e,f);
+ ROUND256(f,g,h,a,b,c,d,e);
+ ROUND256(e,f,g,h,a,b,c,d);
+ ROUND256(d,e,f,g,h,a,b,c);
+ ROUND256(c,d,e,f,g,h,a,b);
+ ROUND256(b,c,d,e,f,g,h,a);
+ } while (j < 64);
+
+ /* Compute the current intermediate hash value */
+ state[0] += a;
+ state[1] += b;
+ state[2] += c;
+ state[3] += d;
+ state[4] += e;
+ state[5] += f;
+ state[6] += g;
+ state[7] += h;
+
+ /* Clean up */
+ a = b = c = d = e = f = g = h = T1 = 0;
+}
+
+#else /* SHA2_UNROLL_TRANSFORM */
+
+void
+SHA256Transform(u_int32_t state[8], const u_int8_t data[SHA256_BLOCK_LENGTH])
+{
+ u_int32_t a, b, c, d, e, f, g, h, s0, s1;
+ u_int32_t T1, T2, W256[16];
+ int j;
+
+ /* Initialize registers with the prev. intermediate value */
+ a = state[0];
+ b = state[1];
+ c = state[2];
+ d = state[3];
+ e = state[4];
+ f = state[5];
+ g = state[6];
+ h = state[7];
+
+ j = 0;
+ do {
+ BE_8_TO_32(W256[j], data);
+ data += 4;
+ /* Apply the SHA-256 compression function to update a..h */
+ T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] + W256[j];
+ T2 = Sigma0_256(a) + Maj(a, b, c);
+ h = g;
+ g = f;
+ f = e;
+ e = d + T1;
+ d = c;
+ c = b;
+ b = a;
+ a = T1 + T2;
+
+ j++;
+ } while (j < 16);
+
+ do {
+ /* Part of the message block expansion: */
+ s0 = W256[(j+1)&0x0f];
+ s0 = sigma0_256(s0);
+ s1 = W256[(j+14)&0x0f];
+ s1 = sigma1_256(s1);
+
+ /* Apply the SHA-256 compression function to update a..h */
+ T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] +
+ (W256[j&0x0f] += s1 + W256[(j+9)&0x0f] + s0);
+ T2 = Sigma0_256(a) + Maj(a, b, c);
+ h = g;
+ g = f;
+ f = e;
+ e = d + T1;
+ d = c;
+ c = b;
+ b = a;
+ a = T1 + T2;
+
+ j++;
+ } while (j < 64);
+
+ /* Compute the current intermediate hash value */
+ state[0] += a;
+ state[1] += b;
+ state[2] += c;
+ state[3] += d;
+ state[4] += e;
+ state[5] += f;
+ state[6] += g;
+ state[7] += h;
+
+ /* Clean up */
+ a = b = c = d = e = f = g = h = T1 = T2 = 0;
+}
+
+#endif /* SHA2_UNROLL_TRANSFORM */
+DEF_WEAK(SHA256Transform);
+
+void
+SHA256Update(SHA2_CTX *context, const u_int8_t *data, size_t len)
+{
+ u_int64_t freespace, usedspace;
+
+ /* Calling with no data is valid (we do nothing) */
+ if (len == 0)
+ return;
+
+ usedspace = (context->bitcount[0] >> 3) % SHA256_BLOCK_LENGTH;
+ if (usedspace > 0) {
+ /* Calculate how much free space is available in the buffer */
+ freespace = SHA256_BLOCK_LENGTH - usedspace;
+
+ if (len >= freespace) {
+ /* Fill the buffer completely and process it */
+ memcpy(&context->buffer[usedspace], data, freespace);
+ context->bitcount[0] += freespace << 3;
+ len -= freespace;
+ data += freespace;
+ SHA256Transform(context->state.st32, context->buffer);
+ } else {
+ /* The buffer is not yet full */
+ memcpy(&context->buffer[usedspace], data, len);
+ context->bitcount[0] += (u_int64_t)len << 3;
+ /* Clean up: */
+ usedspace = freespace = 0;
+ return;
+ }
+ }
+ while (len >= SHA256_BLOCK_LENGTH) {
+ /* Process as many complete blocks as we can */
+ SHA256Transform(context->state.st32, data);
+ context->bitcount[0] += SHA256_BLOCK_LENGTH << 3;
+ len -= SHA256_BLOCK_LENGTH;
+ data += SHA256_BLOCK_LENGTH;
+ }
+ if (len > 0) {
+ /* There's left-overs, so save 'em */
+ memcpy(context->buffer, data, len);
+ context->bitcount[0] += len << 3;
+ }
+ /* Clean up: */
+ usedspace = freespace = 0;
+}
+DEF_WEAK(SHA256Update);
+
+void
+SHA256Pad(SHA2_CTX *context)
+{
+ unsigned int usedspace;
+
+ usedspace = (context->bitcount[0] >> 3) % SHA256_BLOCK_LENGTH;
+ if (usedspace > 0) {
+ /* Begin padding with a 1 bit: */
+ context->buffer[usedspace++] = 0x80;
+
+ if (usedspace <= SHA256_SHORT_BLOCK_LENGTH) {
+ /* Set-up for the last transform: */
+ memset(&context->buffer[usedspace], 0,
+ SHA256_SHORT_BLOCK_LENGTH - usedspace);
+ } else {
+ if (usedspace < SHA256_BLOCK_LENGTH) {
+ memset(&context->buffer[usedspace], 0,
+ SHA256_BLOCK_LENGTH - usedspace);
+ }
+ /* Do second-to-last transform: */
+ SHA256Transform(context->state.st32, context->buffer);
+
+ /* Prepare for last transform: */
+ memset(context->buffer, 0, SHA256_SHORT_BLOCK_LENGTH);
+ }
+ } else {
+ /* Set-up for the last transform: */
+ memset(context->buffer, 0, SHA256_SHORT_BLOCK_LENGTH);
+
+ /* Begin padding with a 1 bit: */
+ *context->buffer = 0x80;
+ }
+ /* Store the length of input data (in bits) in big endian format: */
+ BE_64_TO_8(&context->buffer[SHA256_SHORT_BLOCK_LENGTH],
+ context->bitcount[0]);
+
+ /* Final transform: */
+ SHA256Transform(context->state.st32, context->buffer);
+
+ /* Clean up: */
+ usedspace = 0;
+}
+DEF_WEAK(SHA256Pad);
+
+void
+SHA256Final(u_int8_t digest[SHA256_DIGEST_LENGTH], SHA2_CTX *context)
+{
+ SHA256Pad(context);
+
+#if BYTE_ORDER == LITTLE_ENDIAN
+ int i;
+
+ /* Convert TO host byte order */
+ for (i = 0; i < 8; i++)
+ BE_32_TO_8(digest + i * 4, context->state.st32[i]);
+#else
+ memcpy(digest, context->state.st32, SHA256_DIGEST_LENGTH);
+#endif
+ explicit_bzero(context, sizeof(*context));
+}
+DEF_WEAK(SHA256Final);
+
+
+/*** SHA-512: *********************************************************/
+void
+SHA512Init(SHA2_CTX *context)
+{
+ memcpy(context->state.st64, sha512_initial_hash_value,
+ sizeof(sha512_initial_hash_value));
+ memset(context->buffer, 0, sizeof(context->buffer));
+ context->bitcount[0] = context->bitcount[1] = 0;
+}
+DEF_WEAK(SHA512Init);
+
+#ifdef SHA2_UNROLL_TRANSFORM
+
+/* Unrolled SHA-512 round macros: */
+
+#define ROUND512_0_TO_15(a,b,c,d,e,f,g,h) do { \
+ BE_8_TO_64(W512[j], data); \
+ data += 8; \
+ T1 = (h) + Sigma1_512((e)) + Ch((e), (f), (g)) + K512[j] + W512[j]; \
+ (d) += T1; \
+ (h) = T1 + Sigma0_512((a)) + Maj((a), (b), (c)); \
+ j++; \
+} while(0)
+
+
+#define ROUND512(a,b,c,d,e,f,g,h) do { \
+ s0 = W512[(j+1)&0x0f]; \
+ s0 = sigma0_512(s0); \
+ s1 = W512[(j+14)&0x0f]; \
+ s1 = sigma1_512(s1); \
+ T1 = (h) + Sigma1_512((e)) + Ch((e), (f), (g)) + K512[j] + \
+ (W512[j&0x0f] += s1 + W512[(j+9)&0x0f] + s0); \
+ (d) += T1; \
+ (h) = T1 + Sigma0_512((a)) + Maj((a), (b), (c)); \
+ j++; \
+} while(0)
+
+void
+SHA512Transform(u_int64_t state[8], const u_int8_t data[SHA512_BLOCK_LENGTH])
+{
+ u_int64_t a, b, c, d, e, f, g, h, s0, s1;
+ u_int64_t T1, W512[16];
+ int j;
+
+ /* Initialize registers with the prev. intermediate value */
+ a = state[0];
+ b = state[1];
+ c = state[2];
+ d = state[3];
+ e = state[4];
+ f = state[5];
+ g = state[6];
+ h = state[7];
+
+ j = 0;
+ do {
+ /* Rounds 0 to 15 (unrolled): */
+ ROUND512_0_TO_15(a,b,c,d,e,f,g,h);
+ ROUND512_0_TO_15(h,a,b,c,d,e,f,g);
+ ROUND512_0_TO_15(g,h,a,b,c,d,e,f);
+ ROUND512_0_TO_15(f,g,h,a,b,c,d,e);
+ ROUND512_0_TO_15(e,f,g,h,a,b,c,d);
+ ROUND512_0_TO_15(d,e,f,g,h,a,b,c);
+ ROUND512_0_TO_15(c,d,e,f,g,h,a,b);
+ ROUND512_0_TO_15(b,c,d,e,f,g,h,a);
+ } while (j < 16);
+
+ /* Now for the remaining rounds up to 79: */
+ do {
+ ROUND512(a,b,c,d,e,f,g,h);
+ ROUND512(h,a,b,c,d,e,f,g);
+ ROUND512(g,h,a,b,c,d,e,f);
+ ROUND512(f,g,h,a,b,c,d,e);
+ ROUND512(e,f,g,h,a,b,c,d);
+ ROUND512(d,e,f,g,h,a,b,c);
+ ROUND512(c,d,e,f,g,h,a,b);
+ ROUND512(b,c,d,e,f,g,h,a);
+ } while (j < 80);
+
+ /* Compute the current intermediate hash value */
+ state[0] += a;
+ state[1] += b;
+ state[2] += c;
+ state[3] += d;
+ state[4] += e;
+ state[5] += f;
+ state[6] += g;
+ state[7] += h;
+
+ /* Clean up */
+ a = b = c = d = e = f = g = h = T1 = 0;
+}
+
+#else /* SHA2_UNROLL_TRANSFORM */
+
+void
+SHA512Transform(u_int64_t state[8], const u_int8_t data[SHA512_BLOCK_LENGTH])
+{
+ u_int64_t a, b, c, d, e, f, g, h, s0, s1;
+ u_int64_t T1, T2, W512[16];
+ int j;
+
+ /* Initialize registers with the prev. intermediate value */
+ a = state[0];
+ b = state[1];
+ c = state[2];
+ d = state[3];
+ e = state[4];
+ f = state[5];
+ g = state[6];
+ h = state[7];
+
+ j = 0;
+ do {
+ BE_8_TO_64(W512[j], data);
+ data += 8;
+ /* Apply the SHA-512 compression function to update a..h */
+ T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] + W512[j];
+ T2 = Sigma0_512(a) + Maj(a, b, c);
+ h = g;
+ g = f;
+ f = e;
+ e = d + T1;
+ d = c;
+ c = b;
+ b = a;
+ a = T1 + T2;
+
+ j++;
+ } while (j < 16);
+
+ do {
+ /* Part of the message block expansion: */
+ s0 = W512[(j+1)&0x0f];
+ s0 = sigma0_512(s0);
+ s1 = W512[(j+14)&0x0f];
+ s1 = sigma1_512(s1);
+
+ /* Apply the SHA-512 compression function to update a..h */
+ T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] +
+ (W512[j&0x0f] += s1 + W512[(j+9)&0x0f] + s0);
+ T2 = Sigma0_512(a) + Maj(a, b, c);
+ h = g;
+ g = f;
+ f = e;
+ e = d + T1;
+ d = c;
+ c = b;
+ b = a;
+ a = T1 + T2;
+
+ j++;
+ } while (j < 80);
+
+ /* Compute the current intermediate hash value */
+ state[0] += a;
+ state[1] += b;
+ state[2] += c;
+ state[3] += d;
+ state[4] += e;
+ state[5] += f;
+ state[6] += g;
+ state[7] += h;
+
+ /* Clean up */
+ a = b = c = d = e = f = g = h = T1 = T2 = 0;
+}
+
+#endif /* SHA2_UNROLL_TRANSFORM */
+DEF_WEAK(SHA512Transform);
+
+void
+SHA512Update(SHA2_CTX *context, const u_int8_t *data, size_t len)
+{
+ size_t freespace, usedspace;
+
+ /* Calling with no data is valid (we do nothing) */
+ if (len == 0)
+ return;
+
+ usedspace = (context->bitcount[0] >> 3) % SHA512_BLOCK_LENGTH;
+ if (usedspace > 0) {
+ /* Calculate how much free space is available in the buffer */
+ freespace = SHA512_BLOCK_LENGTH - usedspace;
+
+ if (len >= freespace) {
+ /* Fill the buffer completely and process it */
+ memcpy(&context->buffer[usedspace], data, freespace);
+ ADDINC128(context->bitcount, freespace << 3);
+ len -= freespace;
+ data += freespace;
+ SHA512Transform(context->state.st64, context->buffer);
+ } else {
+ /* The buffer is not yet full */
+ memcpy(&context->buffer[usedspace], data, len);
+ ADDINC128(context->bitcount, len << 3);
+ /* Clean up: */
+ usedspace = freespace = 0;
+ return;
+ }
+ }
+ while (len >= SHA512_BLOCK_LENGTH) {
+ /* Process as many complete blocks as we can */
+ SHA512Transform(context->state.st64, data);
+ ADDINC128(context->bitcount, SHA512_BLOCK_LENGTH << 3);
+ len -= SHA512_BLOCK_LENGTH;
+ data += SHA512_BLOCK_LENGTH;
+ }
+ if (len > 0) {
+ /* There's left-overs, so save 'em */
+ memcpy(context->buffer, data, len);
+ ADDINC128(context->bitcount, len << 3);
+ }
+ /* Clean up: */
+ usedspace = freespace = 0;
+}
+DEF_WEAK(SHA512Update);
+
+void
+SHA512Pad(SHA2_CTX *context)
+{
+ unsigned int usedspace;
+
+ usedspace = (context->bitcount[0] >> 3) % SHA512_BLOCK_LENGTH;
+ if (usedspace > 0) {
+ /* Begin padding with a 1 bit: */
+ context->buffer[usedspace++] = 0x80;
+
+ if (usedspace <= SHA512_SHORT_BLOCK_LENGTH) {
+ /* Set-up for the last transform: */
+ memset(&context->buffer[usedspace], 0, SHA512_SHORT_BLOCK_LENGTH - usedspace);
+ } else {
+ if (usedspace < SHA512_BLOCK_LENGTH) {
+ memset(&context->buffer[usedspace], 0, SHA512_BLOCK_LENGTH - usedspace);
+ }
+ /* Do second-to-last transform: */
+ SHA512Transform(context->state.st64, context->buffer);
+
+ /* And set-up for the last transform: */
+ memset(context->buffer, 0, SHA512_BLOCK_LENGTH - 2);
+ }
+ } else {
+ /* Prepare for final transform: */
+ memset(context->buffer, 0, SHA512_SHORT_BLOCK_LENGTH);
+
+ /* Begin padding with a 1 bit: */
+ *context->buffer = 0x80;
+ }
+ /* Store the length of input data (in bits) in big endian format: */
+ BE_64_TO_8(&context->buffer[SHA512_SHORT_BLOCK_LENGTH],
+ context->bitcount[1]);
+ BE_64_TO_8(&context->buffer[SHA512_SHORT_BLOCK_LENGTH + 8],
+ context->bitcount[0]);
+
+ /* Final transform: */
+ SHA512Transform(context->state.st64, context->buffer);
+
+ /* Clean up: */
+ usedspace = 0;
+}
+DEF_WEAK(SHA512Pad);
+
+void
+SHA512Final(u_int8_t digest[SHA512_DIGEST_LENGTH], SHA2_CTX *context)
+{
+ SHA512Pad(context);
+
+#if BYTE_ORDER == LITTLE_ENDIAN
+ int i;
+
+ /* Convert TO host byte order */
+ for (i = 0; i < 8; i++)
+ BE_64_TO_8(digest + i * 8, context->state.st64[i]);
+#else
+ memcpy(digest, context->state.st64, SHA512_DIGEST_LENGTH);
+#endif
+ explicit_bzero(context, sizeof(*context));
+}
+DEF_WEAK(SHA512Final);
+
+#if !defined(SHA2_SMALL)
+
+/*** SHA-384: *********************************************************/
+void
+SHA384Init(SHA2_CTX *context)
+{
+ memcpy(context->state.st64, sha384_initial_hash_value,
+ sizeof(sha384_initial_hash_value));
+ memset(context->buffer, 0, sizeof(context->buffer));
+ context->bitcount[0] = context->bitcount[1] = 0;
+}
+DEF_WEAK(SHA384Init);
+
+MAKE_CLONE(SHA384Transform, SHA512Transform);
+MAKE_CLONE(SHA384Update, SHA512Update);
+MAKE_CLONE(SHA384Pad, SHA512Pad);
+DEF_WEAK(SHA384Transform);
+DEF_WEAK(SHA384Update);
+DEF_WEAK(SHA384Pad);
+
+void
+SHA384Final(u_int8_t digest[SHA384_DIGEST_LENGTH], SHA2_CTX *context)
+{
+ SHA384Pad(context);
+
+#if BYTE_ORDER == LITTLE_ENDIAN
+ int i;
+
+ /* Convert TO host byte order */
+ for (i = 0; i < 6; i++)
+ BE_64_TO_8(digest + i * 8, context->state.st64[i]);
+#else
+ memcpy(digest, context->state.st64, SHA384_DIGEST_LENGTH);
+#endif
+ /* Zero out state data */
+ explicit_bzero(context, sizeof(*context));
+}
+DEF_WEAK(SHA384Final);
+
+/*** SHA-512/256: *********************************************************/
+void
+SHA512_256Init(SHA2_CTX *context)
+{
+ memcpy(context->state.st64, sha512_256_initial_hash_value,
+ sizeof(sha512_256_initial_hash_value));
+ memset(context->buffer, 0, sizeof(context->buffer));
+ context->bitcount[0] = context->bitcount[1] = 0;
+}
+DEF_WEAK(SHA512_256Init);
+
+MAKE_CLONE(SHA512_256Transform, SHA512Transform);
+MAKE_CLONE(SHA512_256Update, SHA512Update);
+MAKE_CLONE(SHA512_256Pad, SHA512Pad);
+DEF_WEAK(SHA512_256Transform);
+DEF_WEAK(SHA512_256Update);
+DEF_WEAK(SHA512_256Pad);
+
+void
+SHA512_256Final(u_int8_t digest[SHA512_256_DIGEST_LENGTH], SHA2_CTX *context)
+{
+ SHA512_256Pad(context);
+
+#if BYTE_ORDER == LITTLE_ENDIAN
+ int i;
+
+ /* Convert TO host byte order */
+ for (i = 0; i < 4; i++)
+ BE_64_TO_8(digest + i * 8, context->state.st64[i]);
+#else
+ memcpy(digest, context->state.st64, SHA512_256_DIGEST_LENGTH);
+#endif
+ /* Zero out state data */
+ explicit_bzero(context, sizeof(*context));
+}
+DEF_WEAK(SHA512_256Final);
+#endif /* !defined(SHA2_SMALL) */