<html><head><meta name="color-scheme" content="light dark"></head><body><pre style="word-wrap: break-word; white-space: pre-wrap;">Index: files/admin/check.c
===================================================================
RCS file: /cvsroot/pkgsrc/pkgtools/pkg_install/files/admin/check.c,v
retrieving revision 1.10
diff -u -r1.10 check.c
--- files/admin/check.c	22 Jan 2010 13:30:41 -0000	1.10
+++ files/admin/check.c	19 Oct 2015 18:14:38 -0000
@@ -71,6 +71,7 @@
 #include &lt;string.h&gt;
 #endif
 
+#include "sha2.h"
 #include "admin.h"
 #include "lib.h"
 
@@ -85,7 +86,8 @@
 	FILE   *f;
 	plist_t *p;
 	package_t Plist;
-	char   *PkgName, *dirp = NULL, *md5file;
+	char   *PkgName, *dirp = NULL;
+	char	digest[DigestSHA512Len + 1];	/* maximum ASCII size of digests used */
 	char    file[MaxPathSize];
 	char   *content;
 
@@ -113,13 +115,19 @@
 
 			if (isfile(file) || islinktodir(file)) {
 				if (p-&gt;next &amp;&amp; p-&gt;next-&gt;type == PLIST_COMMENT) {
-					if (strncmp(p-&gt;next-&gt;name, CHECKSUM_HEADER, ChecksumHeaderLen) == 0) {
-						if ((md5file = MD5File(file, NULL)) != NULL) {
+					if (strncmp(p-&gt;next-&gt;name, CHECKSUM_MD5_HEADER, ChecksumMD5HeaderLen) == 0) {
+						if (MD5File(file, digest) != NULL) {
 							/* Mismatch? */
-							if (strcmp(md5file, p-&gt;next-&gt;name + ChecksumHeaderLen) != 0)
+							if (strcmp(digest, p-&gt;next-&gt;name + ChecksumMD5HeaderLen) != 0)
 								printf("%s fails MD5 checksum\n", file);
 
-							free(md5file);
+						}
+					} else if (strncmp(p-&gt;next-&gt;name, DIGEST_SHA512_HEADER, DigestSHA512HeaderLen) == 0) {
+						if (SHA512_File(file, digest) != NULL) {
+							/* Mismatch? */
+							if (strcmp(digest, p-&gt;next-&gt;name + DigestSHA512HeaderLen) != 0)
+								printf("%s fails SHA512 checksum\n", file);
+
 						}
 					} else if (strncmp(p-&gt;next-&gt;name, SYMLINK_HEADER, SymlinkHeaderLen) == 0) {
 						char	buf[MaxPathSize + SymlinkHeaderLen];
Index: files/create/pl.c
===================================================================
RCS file: /cvsroot/pkgsrc/pkgtools/pkg_install/files/create/pl.c,v
retrieving revision 1.14
diff -u -r1.14 pl.c
--- files/create/pl.c	5 Nov 2009 16:22:32 -0000	1.14
+++ files/create/pl.c	19 Oct 2015 18:14:38 -0000
@@ -40,6 +40,8 @@
 #include &lt;md5.h&gt;
 #endif
 
+#include "sha2.h"
+
 /*
  * Check that any symbolic link is relative to the prefix
  */
@@ -82,7 +84,7 @@
 	struct stat st;
 	plist_t *tmp;
 	plist_t *p;
-	char    buf[ChecksumHeaderLen + LegibleChecksumLen];
+	char    buf[DigestSHA512HeaderLen + DigestSHA512Len + 1];
 	char    target[MaxPathSize + SymlinkHeaderLen];
 	char    name[MaxPathSize];
 	char   *cwd = NULL;
@@ -183,9 +185,9 @@
 				warnx("Warning - block special device `%s' in PLIST", name);
 				break;
 			default:
-				(void) strlcpy(buf, CHECKSUM_HEADER,
+				(void) strlcpy(buf, CHECKSUM_MD5_HEADER,
 				    sizeof(buf));
-				if (MD5File(name, &amp;buf[ChecksumHeaderLen]) != (char *) NULL) {
+				if (MD5File(name, &amp;buf[ChecksumMD5HeaderLen]) != NULL) {
 					tmp = new_plist_entry();
 					tmp-&gt;name = xstrdup(buf);
 					tmp-&gt;type = PLIST_COMMENT;	/* PLIST_MD5 - HF */
@@ -197,6 +199,20 @@
 					p-&gt;next = tmp;
 					p = tmp;
 				}
+				(void) strlcpy(buf, DIGEST_SHA512_HEADER,
+				    sizeof(buf));
+				if (SHA512_File(name, &amp;buf[DigestSHA512HeaderLen]) != NULL) {
+					tmp = new_plist_entry();
+					tmp-&gt;name = xstrdup(buf);
+					tmp-&gt;type = PLIST_COMMENT;
+					tmp-&gt;next = p-&gt;next;
+					tmp-&gt;prev = p;
+					if (p == pkg-&gt;tail) {
+						pkg-&gt;tail = tmp;
+					}
+					p-&gt;next = tmp;
+					p = tmp;
+				}
 				break;
 			}
 			break;
Index: files/lib/Makefile.in
===================================================================
RCS file: /cvsroot/pkgsrc/pkgtools/pkg_install/files/lib/Makefile.in,v
retrieving revision 1.35
diff -u -r1.35 Makefile.in
--- files/lib/Makefile.in	1 Sep 2015 12:14:06 -0000	1.35
+++ files/lib/Makefile.in	19 Oct 2015 18:14:38 -0000
@@ -29,7 +29,8 @@
 OBJS=	automatic.o conflicts.o dewey.o fexec.o file.o \
 	global.o iterate.o license.o lpkg.o opattern.o \
 	parse-config.o pkgdb.o plist.o remove.o \
-	str.o var.o version.o vulnerabilities-file.o xwrapper.o
+	str.o var.o version.o vulnerabilities-file.o xwrapper.o \
+	sha2.o sha2hl.o
 
 CPPFLAGS+=	-DSYSCONFDIR=\"$(sysconfdir)\"
 
Index: files/lib/lib.h
===================================================================
RCS file: /cvsroot/pkgsrc/pkgtools/pkg_install/files/lib/lib.h,v
retrieving revision 1.66
diff -u -r1.66 lib.h
--- files/lib/lib.h	1 Sep 2015 12:14:06 -0000	1.66
+++ files/lib/lib.h	19 Oct 2015 18:14:38 -0000
@@ -203,14 +203,16 @@
 	plist_t *tail;		/* tail of list */
 }       package_t;
 
-#define SYMLINK_HEADER	"Symlink:"
-#define CHECKSUM_HEADER	"MD5:"
+#define SYMLINK_HEADER		"Symlink:"
+#define CHECKSUM_MD5_HEADER	"MD5:"
+#define DIGEST_SHA512_HEADER	"SHA512:"
 
 enum {
-	ChecksumHeaderLen = 4,	/* strlen(CHECKSUM_HEADER) */
-	SymlinkHeaderLen = 8,	/* strlen(SYMLINK_HEADER) */
-	ChecksumLen = 16,
-	LegibleChecksumLen = 33
+	ChecksumMD5HeaderLen = 4,	/* strlen(CHECKSUM_MD5_HEADER) */
+	DigestSHA512HeaderLen = 7,	/* strlen(DIGEST_SHA512_HEADER) */
+	SymlinkHeaderLen = 8,		/* strlen(SYMLINK_HEADER) */
+	LegibleChecksumMD5Len = 32 + 1,
+	DigestSHA512Len = 128 + 1
 };
 
 /* List of files */
Index: files/lib/plist.c
===================================================================
RCS file: /cvsroot/pkgsrc/pkgtools/pkg_install/files/lib/plist.c,v
retrieving revision 1.29
diff -u -r1.29 plist.c
--- files/lib/plist.c	2 Aug 2009 17:56:45 -0000	1.29
+++ files/lib/plist.c	19 Oct 2015 18:14:38 -0000
@@ -71,6 +71,8 @@
 #include &lt;md5.h&gt;
 #endif
 
+#include "sha2.h"
+
 static int     delete_with_parents(const char *, Boolean, Boolean);
 
 /* This struct defines a plist command type */
@@ -600,12 +602,12 @@
 				int     restored = 0;	/* restored from preserve? */
 
 				if (p-&gt;next &amp;&amp; p-&gt;next-&gt;type == PLIST_COMMENT) {
-					if (strncmp(p-&gt;next-&gt;name, CHECKSUM_HEADER, ChecksumHeaderLen) == 0) {
-						char   *cp, buf[LegibleChecksumLen];
+					if (strncmp(p-&gt;next-&gt;name, CHECKSUM_MD5_HEADER, ChecksumMD5HeaderLen) == 0) {
+						char   *cp, buf[LegibleChecksumMD5Len];
 
 						if ((cp = MD5File(tmp, buf)) != NULL) {
 							/* Mismatch? */
-							if (strcmp(cp, p-&gt;next-&gt;name + ChecksumHeaderLen) != 0) {
+							if (strcmp(cp, p-&gt;next-&gt;name + ChecksumMD5HeaderLen) != 0) {
 								printf("original MD5 checksum failed, %s: %s\n",
 								    Force ? "deleting anyway" : "not deleting", tmp);
 								if (!Force) {
@@ -614,6 +616,20 @@
 								}
 							}
 						}
+					} else if (strncmp(p-&gt;next-&gt;name, DIGEST_SHA512_HEADER, DigestSHA512HeaderLen) == 0) {
+						char   *cp, buf[DigestSHA512Len];
+
+						if ((cp = SHA512_File(tmp, buf)) != NULL) {
+							/* Mismatch? */
+							if (strcmp(cp, p-&gt;next-&gt;name + DigestSHA512HeaderLen) != 0) {
+								printf("original SHA512 checksum failed, %s: %s\n",
+								    Force ? "deleting anyway" : "not deleting", tmp);
+								if (!Force) {
+									fail = FAIL;
+									goto pkgdb_cleanup;
+								}
+							}
+						}
 					} else if (strncmp(p-&gt;next-&gt;name, SYMLINK_HEADER, SymlinkHeaderLen) == 0) {
 						char	buf[MaxPathSize + SymlinkHeaderLen];
 						int	cc;
Index: files/lib/version.h
===================================================================
RCS file: /cvsroot/pkgsrc/pkgtools/pkg_install/files/lib/version.h,v
retrieving revision 1.169
diff -u -r1.169 version.h
--- files/lib/version.h	1 Sep 2015 12:14:06 -0000	1.169
+++ files/lib/version.h	19 Oct 2015 18:14:38 -0000
@@ -27,6 +27,6 @@
 #ifndef _INST_LIB_VERSION_H_
 #define _INST_LIB_VERSION_H_
 
-#define PKGTOOLS_VERSION 20150901
+#define PKGTOOLS_VERSION 20151017
 
 #endif /* _INST_LIB_VERSION_H_ */
--- /dev/null	2015-10-19 11:14:38.000000000 -0700
+++ files/lib/sha2.c	2015-10-19 09:43:34.000000000 -0700
@@ -0,0 +1,917 @@
+/*
+ * sha2.c
+ *
+ * Version 1.0.0beta1
+ *
+ * Written by Aaron D. Gifford &lt;me@aarongifford.com&gt;
+ *
+ * Copyright 2000 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(S) 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(S) 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.
+ *
+ */
+
+
+#ifdef HAVE_CONFIG_H
+#include &lt;config.h&gt;
+#endif
+
+#include &lt;stdio.h&gt;
+#include &lt;string.h&gt;	/* memcpy()/memset() or bcopy()/bzero() */
+#include &lt;assert.h&gt;	/* assert() */
+#include "sha2.h"
+
+/*
+ * ASSERT NOTE:
+ * Some sanity checking code is included using assert().  On my FreeBSD
+ * system, this additional code can be removed by compiling with NDEBUG
+ * defined.  Check your own systems manpage on assert() to see how to
+ * compile WITHOUT the sanity checking code on your system.
+ *
+ * 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
+ *
+ */
+
+
+/*** SHA-256/384/512 Machine Architecture Definitions *****************/
+
+/*** SHA-256/384/512 Various Length Definitions ***********************/
+/* NOTE: Most of these are in sha2.h */
+#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 REVERSAL MACROS *******************************************/
+#ifndef WORDS_BIGENDIAN
+#define REVERSE32(w,x)	{ \
+	sha2_word32 tmp = (w); \
+	tmp = (tmp &gt;&gt; 16) | (tmp &lt;&lt; 16); \
+	(x) = ((tmp &amp; 0xff00ff00UL) &gt;&gt; 8) | ((tmp &amp; 0x00ff00ffUL) &lt;&lt; 8); \
+}
+#define REVERSE64(w,x)	{ \
+	sha2_word64 tmp = (w); \
+	tmp = (tmp &gt;&gt; 32) | (tmp &lt;&lt; 32); \
+	tmp = ((tmp &amp; 0xff00ff00ff00ff00ULL) &gt;&gt; 8) | \
+	      ((tmp &amp; 0x00ff00ff00ff00ffULL) &lt;&lt; 8); \
+	(x) = ((tmp &amp; 0xffff0000ffff0000ULL) &gt;&gt; 16) | \
+	      ((tmp &amp; 0x0000ffff0000ffffULL) &lt;&lt; 16); \
+}
+#endif /* WORDS_BIGENDIAN */
+
+/*
+ * 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)	{ \
+	(w)[0] += (sha2_word64)(n); \
+	if ((w)[0] &lt; (n)) { \
+		(w)[1]++; \
+	} \
+}
+
+#if !defined(MEMSET_BZERO) &amp;&amp; !defined(MEMCPY_BCOPY)
+/*
+ * Macros for copying blocks of memory and for zeroing out ranges
+ * of memory.  Using these macros makes it easy to switch from
+ * using memset()/memcpy() and using bzero()/bcopy().
+ *
+ * Please define either SHA2_USE_MEMSET_MEMCPY or define
+ * SHA2_USE_BZERO_BCOPY depending on which function set you
+ * choose to use:
+ */
+#if !defined(SHA2_USE_MEMSET_MEMCPY) &amp;&amp; !defined(SHA2_USE_BZERO_BCOPY)
+/* Default to memset()/memcpy() if no option is specified */
+#define	SHA2_USE_MEMSET_MEMCPY	1
+#endif
+#if defined(SHA2_USE_MEMSET_MEMCPY) &amp;&amp; defined(SHA2_USE_BZERO_BCOPY)
+/* Abort with an error if BOTH options are defined */
+#error Define either SHA2_USE_MEMSET_MEMCPY or SHA2_USE_BZERO_BCOPY, not both!
+#endif
+
+#ifdef SHA2_USE_MEMSET_MEMCPY
+#define MEMSET_BZERO(p,l)	memset((p), 0, (l))
+#define MEMCPY_BCOPY(d,s,l)	memcpy((d), (s), (l))
+#endif
+#ifdef SHA2_USE_BZERO_BCOPY
+#define MEMSET_BZERO(p,l)	bzero((p), (l))
+#define MEMCPY_BCOPY(d,s,l)	bcopy((s), (d), (l))
+#endif
+#endif /* !defined(MEMSET_BZERO) &amp;&amp; !defined(MEMCPY_BCOPY) */
+
+/*** 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-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-256, SHA-384, and SHA-512): */
+#define R(b,x) 		((x) &gt;&gt; (b))
+/* 32-bit Rotate-right (used in SHA-256): */
+#define S32(b,x)	(((x) &gt;&gt; (b)) | ((x) &lt;&lt; (32 - (b))))
+/* 64-bit Rotate-right (used in SHA-384 and SHA-512): */
+#define S64(b,x)	(((x) &gt;&gt; (b)) | ((x) &lt;&lt; (64 - (b))))
+
+/* Two of six logical functions used in SHA-256, SHA-384, and SHA-512: */
+#define Ch(x,y,z)	(((x) &amp; (y)) ^ ((~(x)) &amp; (z)))
+#define Maj(x,y,z)	(((x) &amp; (y)) ^ ((x) &amp; (z)) ^ ((y) &amp; (z)))
+
+/* Four of six logical functions used in 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)))
+
+/*** INTERNAL FUNCTION PROTOTYPES *************************************/
+/* NOTE: These should not be accessed directly from outside this
+ * library -- they are intended for private internal visibility/use
+ * only.
+ */
+void SHA512_Last(SHA512_CTX*);
+void SHA256_Transform(SHA256_CTX*, const sha2_word32*);
+void SHA512_Transform(SHA512_CTX*, const sha2_word64*);
+
+
+/*** SHA-XYZ INITIAL HASH VALUES AND CONSTANTS ************************/
+/* Hash constant words K for SHA-256: */
+const static sha2_word32 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: */
+const static sha2_word32 sha256_initial_hash_value[8] = {
+	0x6a09e667UL,
+	0xbb67ae85UL,
+	0x3c6ef372UL,
+	0xa54ff53aUL,
+	0x510e527fUL,
+	0x9b05688cUL,
+	0x1f83d9abUL,
+	0x5be0cd19UL
+};
+
+/* Hash constant words K for SHA-384 and SHA-512: */
+const static sha2_word64 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-384 */
+const static sha2_word64 sha384_initial_hash_value[8] = {
+	0xcbbb9d5dc1059ed8ULL,
+	0x629a292a367cd507ULL,
+	0x9159015a3070dd17ULL,
+	0x152fecd8f70e5939ULL,
+	0x67332667ffc00b31ULL,
+	0x8eb44a8768581511ULL,
+	0xdb0c2e0d64f98fa7ULL,
+	0x47b5481dbefa4fa4ULL
+};
+
+/* Initial hash value H for SHA-512 */
+const static sha2_word64 sha512_initial_hash_value[8] = {
+	0x6a09e667f3bcc908ULL,
+	0xbb67ae8584caa73bULL,
+	0x3c6ef372fe94f82bULL,
+	0xa54ff53a5f1d36f1ULL,
+	0x510e527fade682d1ULL,
+	0x9b05688c2b3e6c1fULL,
+	0x1f83d9abfb41bd6bULL,
+	0x5be0cd19137e2179ULL
+};
+
+
+/*** SHA-256: *********************************************************/
+void SHA256_Init(SHA256_CTX* context) {
+	if (context == (SHA256_CTX*)0) {
+		return;
+	}
+	MEMCPY_BCOPY(context-&gt;state, sha256_initial_hash_value, SHA256_DIGEST_LENGTH);
+	MEMSET_BZERO(context-&gt;buffer, SHA256_BLOCK_LENGTH);
+	context-&gt;bitcount = 0;
+}
+
+#ifdef SHA2_UNROLL_TRANSFORM
+
+/* Unrolled SHA-256 round macros: */
+
+#ifndef WORDS_BIGENDIAN
+
+#define ROUND256_0_TO_15(a,b,c,d,e,f,g,h)	\
+	REVERSE32(*data++, W256[j]); \
+	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++
+
+
+#else /* WORDS__BIGENDIAN */
+
+#define ROUND256_0_TO_15(a,b,c,d,e,f,g,h)	\
+	T1 = (h) + Sigma1_256(e) + Ch((e), (f), (g)) + \
+	     K256[j] + (W256[j] = *data++); \
+	(d) += T1; \
+	(h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \
+	j++
+
+#endif /* WORDS_BIGENDIAN */
+
+#define ROUND256(a,b,c,d,e,f,g,h)	\
+	s0 = W256[(j+1)&amp;0x0f]; \
+	s0 = sigma0_256(s0); \
+	s1 = W256[(j+14)&amp;0x0f]; \
+	s1 = sigma1_256(s1); \
+	T1 = (h) + Sigma1_256(e) + Ch((e), (f), (g)) + K256[j] + \
+	     (W256[j&amp;0x0f] += s1 + W256[(j+9)&amp;0x0f] + s0); \
+	(d) += T1; \
+	(h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \
+	j++
+
+void SHA256_Transform(SHA256_CTX* context, const sha2_word32* data) {
+	sha2_word32	a, b, c, d, e, f, g, h, s0, s1;
+	sha2_word32	T1, *W256;
+	int		j;
+
+	W256 = (sha2_word32*)context-&gt;buffer;
+
+	/* Initialize registers with the prev. intermediate value */
+	a = context-&gt;state[0];
+	b = context-&gt;state[1];
+	c = context-&gt;state[2];
+	d = context-&gt;state[3];
+	e = context-&gt;state[4];
+	f = context-&gt;state[5];
+	g = context-&gt;state[6];
+	h = context-&gt;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 &lt; 16);
+
+	/* Now for the remaining rounds to 64: */
+	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 &lt; 64);
+
+	/* Compute the current intermediate hash value */
+	context-&gt;state[0] += a;
+	context-&gt;state[1] += b;
+	context-&gt;state[2] += c;
+	context-&gt;state[3] += d;
+	context-&gt;state[4] += e;
+	context-&gt;state[5] += f;
+	context-&gt;state[6] += g;
+	context-&gt;state[7] += h;
+
+	/* Clean up */
+	a = b = c = d = e = f = g = h = T1 = 0;
+}
+
+#else /* SHA2_UNROLL_TRANSFORM */
+
+void SHA256_Transform(SHA256_CTX* context, const sha2_word32* data) {
+	sha2_word32	a, b, c, d, e, f, g, h, s0, s1;
+	sha2_word32	T1, T2, *W256;
+	int		j;
+
+	W256 = (sha2_word32*)context-&gt;buffer;
+
+	/* Initialize registers with the prev. intermediate value */
+	a = context-&gt;state[0];
+	b = context-&gt;state[1];
+	c = context-&gt;state[2];
+	d = context-&gt;state[3];
+	e = context-&gt;state[4];
+	f = context-&gt;state[5];
+	g = context-&gt;state[6];
+	h = context-&gt;state[7];
+
+	j = 0;
+	do {
+#ifndef WORDS_BIGENDIAN
+		/* Copy data while converting to host byte order */
+		REVERSE32(*data++,W256[j]);
+		/* Apply the SHA-256 compression function to update a..h */
+		T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] + W256[j];
+#else /* WORDS_BIGENDIAN */
+		/* Apply the SHA-256 compression function to update a..h with copy */
+		T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] + (W256[j] = *data++);
+#endif /* WORDS_BIGENDIAN */
+		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 &lt; 16);
+
+	do {
+		/* Part of the message block expansion: */
+		s0 = W256[(j+1)&amp;0x0f];
+		s0 = sigma0_256(s0);
+		s1 = W256[(j+14)&amp;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&amp;0x0f] += s1 + W256[(j+9)&amp;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 &lt; 64);
+
+	/* Compute the current intermediate hash value */
+	context-&gt;state[0] += a;
+	context-&gt;state[1] += b;
+	context-&gt;state[2] += c;
+	context-&gt;state[3] += d;
+	context-&gt;state[4] += e;
+	context-&gt;state[5] += f;
+	context-&gt;state[6] += g;
+	context-&gt;state[7] += h;
+
+	/* Clean up */
+	a = b = c = d = e = f = g = h = T1 = T2 = 0;
+}
+
+#endif /* SHA2_UNROLL_TRANSFORM */
+
+void SHA256_Update(SHA256_CTX* context, const uint8_t *data, size_t len)
+{
+	unsigned int	freespace, usedspace;
+
+	if (len == 0) {
+		/* Calling with no data is valid - we do nothing */
+		return;
+	}
+
+	/* Sanity check: */
+	assert(context != NULL &amp;&amp; data != NULL);
+
+	usedspace = (context-&gt;bitcount &gt;&gt; 3) % SHA256_BLOCK_LENGTH;
+	if (usedspace &gt; 0) {
+		/* Calculate how much free space is available in the buffer */
+		freespace = SHA256_BLOCK_LENGTH - usedspace;
+
+		if (len &gt;= freespace) {
+			/* Fill the buffer completely and process it */
+			MEMCPY_BCOPY(&amp;context-&gt;buffer[usedspace], data, freespace);
+			context-&gt;bitcount += freespace &lt;&lt; 3;
+			len -= freespace;
+			data += freespace;
+			SHA256_Transform(context, (sha2_word32*)context-&gt;buffer);
+		} else {
+			/* The buffer is not yet full */
+			MEMCPY_BCOPY(&amp;context-&gt;buffer[usedspace], data, len);
+			context-&gt;bitcount += len &lt;&lt; 3;
+			/* Clean up: */
+			usedspace = freespace = 0;
+			return;
+		}
+	}
+	while (len &gt;= SHA256_BLOCK_LENGTH) {
+		/* Process as many complete blocks as we can */
+		SHA256_Transform(context, (const sha2_word32*)data);
+		context-&gt;bitcount += SHA256_BLOCK_LENGTH &lt;&lt; 3;
+		len -= SHA256_BLOCK_LENGTH;
+		data += SHA256_BLOCK_LENGTH;
+	}
+	if (len &gt; 0) {
+		/* There's left-overs, so save 'em */
+		MEMCPY_BCOPY(context-&gt;buffer, data, len);
+		context-&gt;bitcount += len &lt;&lt; 3;
+	}
+	/* Clean up: */
+	usedspace = freespace = 0;
+}
+
+void SHA256_Final(sha2_byte digest[], SHA256_CTX* context) {
+	sha2_word32	*d = (sha2_word32*)digest;
+	unsigned int	usedspace;
+
+	/* Sanity check: */
+	assert(context != NULL);
+
+	/* If no digest buffer is passed, we don't bother doing this: */
+	if (digest != (sha2_byte*)0) {
+		usedspace = (context-&gt;bitcount &gt;&gt; 3) % SHA256_BLOCK_LENGTH;
+#ifndef WORDS_BIGENDIAN
+		/* Convert FROM host byte order */
+		REVERSE64(context-&gt;bitcount,context-&gt;bitcount);
+#endif
+		if (usedspace &gt; 0) {
+			/* Begin padding with a 1 bit: */
+			context-&gt;buffer[usedspace++] = 0x80;
+
+			if (usedspace &lt;= SHA256_SHORT_BLOCK_LENGTH) {
+				/* Set-up for the last transform: */
+				MEMSET_BZERO(&amp;context-&gt;buffer[usedspace], SHA256_SHORT_BLOCK_LENGTH - usedspace);
+			} else {
+				if (usedspace &lt; SHA256_BLOCK_LENGTH) {
+					MEMSET_BZERO(&amp;context-&gt;buffer[usedspace], SHA256_BLOCK_LENGTH - usedspace);
+				}
+				/* Do second-to-last transform: */
+				SHA256_Transform(context, (sha2_word32*)context-&gt;buffer);
+
+				/* And set-up for the last transform: */
+				MEMSET_BZERO(context-&gt;buffer, SHA256_SHORT_BLOCK_LENGTH);
+			}
+		} else {
+			/* Set-up for the last transform: */
+			MEMSET_BZERO(context-&gt;buffer, SHA256_SHORT_BLOCK_LENGTH);
+
+			/* Begin padding with a 1 bit: */
+			*context-&gt;buffer = 0x80;
+		}
+		/* Set the bit count: */
+		*(sha2_word64*)&amp;context-&gt;buffer[SHA256_SHORT_BLOCK_LENGTH] = context-&gt;bitcount;
+
+		/* Final transform: */
+		SHA256_Transform(context, (sha2_word32*)context-&gt;buffer);
+
+#ifndef WORDS_BIGENDIAN
+		{
+			/* Convert TO host byte order */
+			int	j;
+			for (j = 0; j &lt; 8; j++) {
+				REVERSE32(context-&gt;state[j],context-&gt;state[j]);
+				*d++ = context-&gt;state[j];
+			}
+		}
+#else
+		MEMCPY_BCOPY(d, context-&gt;state, SHA256_DIGEST_LENGTH);
+#endif
+	}
+
+	/* Clean up state data: */
+	MEMSET_BZERO(context, sizeof(SHA256_CTX));
+	usedspace = 0;
+}
+
+/*** SHA-512: *********************************************************/
+void SHA512_Init(SHA512_CTX* context) {
+	if (context == (SHA512_CTX*)0) {
+		return;
+	}
+	MEMCPY_BCOPY(context-&gt;state, sha512_initial_hash_value, SHA512_DIGEST_LENGTH);
+	MEMSET_BZERO(context-&gt;buffer, SHA512_BLOCK_LENGTH);
+	context-&gt;bitcount[0] = context-&gt;bitcount[1] =  0;
+}
+
+#ifdef SHA2_UNROLL_TRANSFORM
+
+/* Unrolled SHA-512 round macros: */
+#ifndef WORDS_BIGENDIAN
+
+#define ROUND512_0_TO_15(a,b,c,d,e,f,g,h)	\
+	REVERSE64(*data++, W512[j]); \
+	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++
+
+
+#else /* !WORDS_BIGENDIAN */
+
+#define ROUND512_0_TO_15(a,b,c,d,e,f,g,h)	\
+	T1 = (h) + Sigma1_512(e) + Ch((e), (f), (g)) + \
+             K512[j] + (W512[j] = *data++); \
+	(d) += T1; \
+	(h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)); \
+	j++
+
+#endif /* WORDS_BIGENDIAN */
+
+#define ROUND512(a,b,c,d,e,f,g,h)	\
+	s0 = W512[(j+1)&amp;0x0f]; \
+	s0 = sigma0_512(s0); \
+	s1 = W512[(j+14)&amp;0x0f]; \
+	s1 = sigma1_512(s1); \
+	T1 = (h) + Sigma1_512(e) + Ch((e), (f), (g)) + K512[j] + \
+             (W512[j&amp;0x0f] += s1 + W512[(j+9)&amp;0x0f] + s0); \
+	(d) += T1; \
+	(h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)); \
+	j++
+
+void SHA512_Transform(SHA512_CTX* context, const sha2_word64* data) {
+	sha2_word64	a, b, c, d, e, f, g, h, s0, s1;
+	sha2_word64	T1, *W512 = (sha2_word64*)context-&gt;buffer;
+	int		j;
+
+	/* Initialize registers with the prev. intermediate value */
+	a = context-&gt;state[0];
+	b = context-&gt;state[1];
+	c = context-&gt;state[2];
+	d = context-&gt;state[3];
+	e = context-&gt;state[4];
+	f = context-&gt;state[5];
+	g = context-&gt;state[6];
+	h = context-&gt;state[7];
+
+	j = 0;
+	do {
+		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 &lt; 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 &lt; 80);
+
+	/* Compute the current intermediate hash value */
+	context-&gt;state[0] += a;
+	context-&gt;state[1] += b;
+	context-&gt;state[2] += c;
+	context-&gt;state[3] += d;
+	context-&gt;state[4] += e;
+	context-&gt;state[5] += f;
+	context-&gt;state[6] += g;
+	context-&gt;state[7] += h;
+
+	/* Clean up */
+	a = b = c = d = e = f = g = h = T1 = 0;
+}
+
+#else /* SHA2_UNROLL_TRANSFORM */
+
+void SHA512_Transform(SHA512_CTX* context, const sha2_word64* data) {
+	sha2_word64	a, b, c, d, e, f, g, h, s0, s1;
+	sha2_word64	T1, T2, *W512 = (sha2_word64*)context-&gt;buffer;
+	int		j;
+
+	/* Initialize registers with the prev. intermediate value */
+	a = context-&gt;state[0];
+	b = context-&gt;state[1];
+	c = context-&gt;state[2];
+	d = context-&gt;state[3];
+	e = context-&gt;state[4];
+	f = context-&gt;state[5];
+	g = context-&gt;state[6];
+	h = context-&gt;state[7];
+
+	j = 0;
+	do {
+#ifndef WORDS_BIGENDIAN
+		/* Convert TO host byte order */
+		REVERSE64(*data++, W512[j]);
+		/* Apply the SHA-512 compression function to update a..h */
+		T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] + W512[j];
+#else
+		/* Apply the SHA-512 compression function to update a..h with copy */
+		T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] + (W512[j] = *data++);
+#endif /* WORDS_BIGENDIAN */
+		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 &lt; 16);
+
+	do {
+		/* Part of the message block expansion: */
+		s0 = W512[(j+1)&amp;0x0f];
+		s0 = sigma0_512(s0);
+		s1 = W512[(j+14)&amp;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&amp;0x0f] += s1 + W512[(j+9)&amp;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 &lt; 80);
+
+	/* Compute the current intermediate hash value */
+	context-&gt;state[0] += a;
+	context-&gt;state[1] += b;
+	context-&gt;state[2] += c;
+	context-&gt;state[3] += d;
+	context-&gt;state[4] += e;
+	context-&gt;state[5] += f;
+	context-&gt;state[6] += g;
+	context-&gt;state[7] += h;
+
+	/* Clean up */
+	a = b = c = d = e = f = g = h = T1 = T2 = 0;
+}
+
+#endif /* SHA2_UNROLL_TRANSFORM */
+
+void
+SHA512_Update(SHA512_CTX* context, const uint8_t *data, size_t len)
+{
+	unsigned int	freespace, usedspace;
+
+	if (len == 0) {
+		/* Calling with no data is valid - we do nothing */
+		return;
+	}
+
+	/* Sanity check: */
+	assert(context != NULL &amp;&amp; data != NULL);
+
+	usedspace = (context-&gt;bitcount[0] &gt;&gt; 3) % SHA512_BLOCK_LENGTH;
+	if (usedspace &gt; 0) {
+		/* Calculate how much free space is available in the buffer */
+		freespace = SHA512_BLOCK_LENGTH - usedspace;
+
+		if (len &gt;= freespace) {
+			/* Fill the buffer completely and process it */
+			MEMCPY_BCOPY(&amp;context-&gt;buffer[usedspace], data, freespace);
+			ADDINC128(context-&gt;bitcount, freespace &lt;&lt; 3);
+			len -= freespace;
+			data += freespace;
+			SHA512_Transform(context, (const sha2_word64*)context-&gt;buffer);
+		} else {
+			/* The buffer is not yet full */
+			MEMCPY_BCOPY(&amp;context-&gt;buffer[usedspace], data, len);
+			ADDINC128(context-&gt;bitcount, len &lt;&lt; 3);
+			/* Clean up: */
+			usedspace = freespace = 0;
+			return;
+		}
+	}
+	while (len &gt;= SHA512_BLOCK_LENGTH) {
+		/* Process as many complete blocks as we can */
+		SHA512_Transform(context, (const sha2_word64*)data);
+		ADDINC128(context-&gt;bitcount, SHA512_BLOCK_LENGTH &lt;&lt; 3);
+		len -= SHA512_BLOCK_LENGTH;
+		data += SHA512_BLOCK_LENGTH;
+	}
+	if (len &gt; 0) {
+		/* There's left-overs, so save 'em */
+		MEMCPY_BCOPY(context-&gt;buffer, data, len);
+		ADDINC128(context-&gt;bitcount, len &lt;&lt; 3);
+	}
+	/* Clean up: */
+	usedspace = freespace = 0;
+}
+
+void SHA512_Last(SHA512_CTX* context) {
+	unsigned int	usedspace;
+
+	usedspace = (context-&gt;bitcount[0] &gt;&gt; 3) % SHA512_BLOCK_LENGTH;
+#ifndef WORDS_BIGENDIAN
+	/* Convert FROM host byte order */
+	REVERSE64(context-&gt;bitcount[0],context-&gt;bitcount[0]);
+	REVERSE64(context-&gt;bitcount[1],context-&gt;bitcount[1]);
+#endif
+	if (usedspace &gt; 0) {
+		/* Begin padding with a 1 bit: */
+		context-&gt;buffer[usedspace++] = 0x80;
+
+		if (usedspace &lt;= SHA512_SHORT_BLOCK_LENGTH) {
+			/* Set-up for the last transform: */
+			MEMSET_BZERO(&amp;context-&gt;buffer[usedspace], SHA512_SHORT_BLOCK_LENGTH - usedspace);
+		} else {
+			if (usedspace &lt; SHA512_BLOCK_LENGTH) {
+				MEMSET_BZERO(&amp;context-&gt;buffer[usedspace], SHA512_BLOCK_LENGTH - usedspace);
+			}
+			/* Do second-to-last transform: */
+			SHA512_Transform(context, (const sha2_word64*)context-&gt;buffer);
+
+			/* And set-up for the last transform: */
+			MEMSET_BZERO(context-&gt;buffer, SHA512_BLOCK_LENGTH - 2);
+		}
+	} else {
+		/* Prepare for final transform: */
+		MEMSET_BZERO(context-&gt;buffer, SHA512_SHORT_BLOCK_LENGTH);
+
+		/* Begin padding with a 1 bit: */
+		*context-&gt;buffer = 0x80;
+	}
+	/* Store the length of input data (in bits): */
+	*(sha2_word64*)&amp;context-&gt;buffer[SHA512_SHORT_BLOCK_LENGTH] = context-&gt;bitcount[1];
+	*(sha2_word64*)&amp;context-&gt;buffer[SHA512_SHORT_BLOCK_LENGTH+8] = context-&gt;bitcount[0];
+
+	/* Final transform: */
+	SHA512_Transform(context, (const sha2_word64*)context-&gt;buffer);
+}
+
+void SHA512_Final(sha2_byte digest[], SHA512_CTX* context) {
+	sha2_word64	*d = (sha2_word64*)digest;
+
+	/* Sanity check: */
+	assert(context != NULL);
+
+	/* If no digest buffer is passed, we don't bother doing this: */
+	if (digest != (sha2_byte*)0) {
+		SHA512_Last(context);
+
+		/* Save the hash data for output: */
+#ifndef WORDS_BIGENDIAN
+		{
+			/* Convert TO host byte order */
+			int	j;
+			for (j = 0; j &lt; 8; j++) {
+				REVERSE64(context-&gt;state[j],context-&gt;state[j]);
+				*d++ = context-&gt;state[j];
+			}
+		}
+#else
+		MEMCPY_BCOPY(d, context-&gt;state, SHA512_DIGEST_LENGTH);
+#endif
+	}
+
+	/* Zero out state data */
+	MEMSET_BZERO(context, sizeof(SHA512_CTX));
+}
+
+
+/*** SHA-384: *********************************************************/
+void SHA384_Init(SHA384_CTX* context) {
+	if (context == (SHA384_CTX*)0) {
+		return;
+	}
+	MEMCPY_BCOPY(context-&gt;state, sha384_initial_hash_value, SHA512_DIGEST_LENGTH);
+	MEMSET_BZERO(context-&gt;buffer, SHA384_BLOCK_LENGTH);
+	context-&gt;bitcount[0] = context-&gt;bitcount[1] = 0;
+}
+
+void SHA384_Update(SHA384_CTX* context, const uint8_t * data, size_t len)
+{
+	SHA512_Update((SHA512_CTX*)context, data, len);
+}
+
+void SHA384_Final(sha2_byte digest[], SHA384_CTX* context) {
+	sha2_word64	*d = (sha2_word64*)digest;
+
+	/* Sanity check: */
+	assert(context != NULL);
+
+	/* If no digest buffer is passed, we don't bother doing this: */
+	if (digest != (sha2_byte*)0) {
+		SHA512_Last((SHA512_CTX*)context);
+
+		/* Save the hash data for output: */
+#ifndef WORDS_BIGENDIAN
+		{
+			/* Convert TO host byte order */
+			int	j;
+			for (j = 0; j &lt; 6; j++) {
+				REVERSE64(context-&gt;state[j],context-&gt;state[j]);
+				*d++ = context-&gt;state[j];
+			}
+		}
+#else
+		MEMCPY_BCOPY(d, context-&gt;state, SHA384_DIGEST_LENGTH);
+#endif
+	}
+
+	/* Zero out state data */
+	MEMSET_BZERO(context, sizeof(SHA384_CTX));
+}
--- /dev/null	2015-10-19 11:14:38.000000000 -0700
+++ files/lib/sha2hl.c	2015-10-19 09:48:56.000000000 -0700
@@ -0,0 +1,254 @@
+/* $NetBSD: sha2hl.c,v 1.8 2013/01/03 10:20:31 dholland Exp $	 */
+
+/*
+ * sha2hl.c
+ * This code includes some functions taken from sha2.c, hence the
+ * following licence reproduction.
+ *
+ * This code is not a verbatim copy, since some routines have been added,
+ * and some bugs have been fixed.
+ *
+ * Version 1.0.0beta1
+ *
+ * Written by Aaron D. Gifford &lt;me@aarongifford.com&gt;
+ *
+ * Copyright 2000 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(S) 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(S) 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.
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include &lt;config.h&gt;
+#endif
+
+#include &lt;assert.h&gt;
+#ifdef HAVE_ERRNO_H
+#include &lt;errno.h&gt;
+#endif
+#include &lt;fcntl.h&gt;
+#include &lt;sha2.h&gt;
+#include &lt;stdio.h&gt;
+#include &lt;string.h&gt;
+#include &lt;stdlib.h&gt;
+#include &lt;unistd.h&gt;
+
+#ifndef _DIAGASSERT
+#define _DIAGASSERT(cond)	assert(cond)
+#endif
+
+#ifndef MEMSET_BZERO
+#define MEMSET_BZERO(p,l)	memset((p), 0, (l))
+#endif
+
+/*
+ * Constant used by SHA256/384/512_End() functions for converting the
+ * digest to a readable hexadecimal character string:
+ */
+static const char sha2_hex_digits[] = "0123456789abcdef";
+
+char           *
+SHA256_File(char *filename, char *buf)
+{
+	uint8_t         buffer[BUFSIZ * 20];
+	SHA256_CTX      ctx;
+	int             fd, oerrno;
+	ssize_t		num;
+
+	_DIAGASSERT(filename != NULL);
+	/* XXX: buf may be NULL ? */
+
+	SHA256_Init(&amp;ctx);
+
+	if ((fd = open(filename, O_RDONLY)) &lt; 0)
+		return (0);
+
+	while ((num = read(fd, buffer, sizeof(buffer))) &gt; 0)
+		SHA256_Update(&amp;ctx, buffer, (size_t) num);
+
+	oerrno = errno;
+	close(fd);
+	errno = oerrno;
+	return (num &lt; 0 ? 0 : SHA256_End(&amp;ctx, buf));
+}
+
+
+char *
+SHA256_End(SHA256_CTX *ctx, char *buffer)
+{
+	uint8_t         digest[SHA256_DIGEST_LENGTH], *d = digest;
+	char	       *ret;
+	int             i;
+
+	/* Sanity check: */
+	assert(ctx != NULL);
+
+	if ((ret = buffer) != NULL) {
+		SHA256_Final(digest, ctx);
+
+		for (i = 0; i &lt; SHA256_DIGEST_LENGTH; i++) {
+			*buffer++ = sha2_hex_digits[(*d &amp; 0xf0) &gt;&gt; 4];
+			*buffer++ = sha2_hex_digits[*d &amp; 0x0f];
+			d++;
+		}
+		*buffer = (char) 0;
+	} else {
+		(void) MEMSET_BZERO(ctx, sizeof(SHA256_CTX));
+	}
+	(void) MEMSET_BZERO(digest, SHA256_DIGEST_LENGTH);
+	return ret;
+}
+
+char *
+SHA256_Data(const uint8_t * data, size_t len, char *digest)
+{
+	SHA256_CTX      ctx;
+
+	SHA256_Init(&amp;ctx);
+	SHA256_Update(&amp;ctx, data, len);
+	return SHA256_End(&amp;ctx, digest);
+}
+
+char           *
+SHA384_File(char *filename, char *buf)
+{
+	SHA384_CTX      ctx;
+	uint8_t         buffer[BUFSIZ * 20];
+	int             fd, oerrno;
+	ssize_t		num;
+
+	_DIAGASSERT(filename != NULL);
+	/* XXX: buf may be NULL ? */
+
+	SHA384_Init(&amp;ctx);
+
+	if ((fd = open(filename, O_RDONLY)) &lt; 0)
+		return (0);
+
+	while ((num = read(fd, buffer, sizeof(buffer))) &gt; 0)
+		SHA384_Update(&amp;ctx, buffer, (size_t) num);
+
+	oerrno = errno;
+	close(fd);
+	errno = oerrno;
+	return (num &lt; 0 ? 0 : SHA384_End(&amp;ctx, buf));
+}
+
+char *
+SHA384_End(SHA384_CTX * ctx, char buffer[])
+{
+	uint8_t         digest[SHA384_DIGEST_LENGTH], *d = digest;
+	char	       *ret;
+	int             i;
+
+	/* Sanity check: */
+	assert(ctx != NULL);
+
+	if ((ret = buffer) != NULL) {
+		SHA384_Final(digest, ctx);
+
+		for (i = 0; i &lt; SHA384_DIGEST_LENGTH; i++) {
+			*buffer++ = sha2_hex_digits[(*d &amp; 0xf0) &gt;&gt; 4];
+			*buffer++ = sha2_hex_digits[*d &amp; 0x0f];
+			d++;
+		}
+		*buffer = (char) 0;
+	} else {
+		(void) MEMSET_BZERO(ctx, sizeof(SHA384_CTX));
+	}
+	(void) MEMSET_BZERO(digest, SHA384_DIGEST_LENGTH);
+	return ret;
+}
+
+char *
+SHA384_Data(const uint8_t * data, size_t len, char digest[SHA384_DIGEST_STRING_LENGTH])
+{
+	SHA384_CTX      ctx;
+
+	SHA384_Init(&amp;ctx);
+	SHA384_Update(&amp;ctx, data, len);
+	return SHA384_End(&amp;ctx, digest);
+}
+
+char *
+SHA512_File(char *filename, char *buf)
+{
+	SHA512_CTX      ctx;
+	uint8_t         buffer[BUFSIZ * 20];
+	int             fd, oerrno;
+	ssize_t		num;
+
+	_DIAGASSERT(filename != NULL);
+	/* XXX: buf may be NULL ? */
+
+	SHA512_Init(&amp;ctx);
+
+	if ((fd = open(filename, O_RDONLY)) &lt; 0)
+		return (0);
+
+	while ((num = read(fd, buffer, sizeof(buffer))) &gt; 0)
+		SHA512_Update(&amp;ctx, buffer, (size_t) num);
+
+	oerrno = errno;
+	close(fd);
+	errno = oerrno;
+	return (num &lt; 0 ? 0 : SHA512_End(&amp;ctx, buf));
+}
+
+char *
+SHA512_End(SHA512_CTX * ctx, char buffer[])
+{
+	uint8_t         digest[SHA512_DIGEST_LENGTH], *d = digest;
+	char	       *ret;
+	int             i;
+
+	/* Sanity check: */
+	assert(ctx != NULL);
+
+	if ((ret = buffer) != NULL) {
+		SHA512_Final(digest, ctx);
+
+		for (i = 0; i &lt; SHA512_DIGEST_LENGTH; i++) {
+			*buffer++ = sha2_hex_digits[(*d &amp; 0xf0) &gt;&gt; 4];
+			*buffer++ = sha2_hex_digits[*d &amp; 0x0f];
+			d++;
+		}
+		*buffer = (char) 0;
+	} else {
+		(void) MEMSET_BZERO(ctx, sizeof(SHA512_CTX));
+	}
+	(void) MEMSET_BZERO(digest, SHA512_DIGEST_LENGTH);
+	return ret;
+}
+
+char *
+SHA512_Data(const uint8_t * data, size_t len, char *digest)
+{
+	SHA512_CTX      ctx;
+
+	SHA512_Init(&amp;ctx);
+	SHA512_Update(&amp;ctx, data, len);
+	return SHA512_End(&amp;ctx, digest);
+}
--- /dev/null	2015-10-19 11:14:38.000000000 -0700
+++ files/lib/sha2.h	2015-10-19 09:43:53.000000000 -0700
@@ -0,0 +1,112 @@
+/*
+ * sha2.h
+ *
+ * Version 1.0.0beta1
+ *
+ * Written by Aaron D. Gifford &lt;me@aarongifford.com&gt;
+ *
+ * Copyright 2000 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(S) 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(S) 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.
+ *
+ */
+
+#ifndef __SHA2_H__
+#define __SHA2_H__
+
+#ifdef HAVE_INTTYPES_H
+#include &lt;inttypes.h&gt;
+#endif
+
+#ifdef HAVE_STDINT_H
+#include &lt;stdint.h&gt;
+#endif
+
+#ifdef HAVE_UNISTD_H
+#include &lt;unistd.h&gt;
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef uint8_t  sha2_byte;    /* Exactly 1 byte */
+typedef uint32_t sha2_word32;  /* Exactly 4 bytes */
+typedef uint64_t sha2_word64;  /* Exactly 8 bytes */
+
+/*** SHA-256/384/512 Various Length Definitions ***********************/
+#define SHA256_BLOCK_LENGTH		64
+#define SHA256_DIGEST_LENGTH		32
+#define SHA256_DIGEST_STRING_LENGTH	(SHA256_DIGEST_LENGTH * 2 + 1)
+#define SHA384_BLOCK_LENGTH		128
+#define SHA384_DIGEST_LENGTH		48
+#define SHA384_DIGEST_STRING_LENGTH	(SHA384_DIGEST_LENGTH * 2 + 1)
+#define SHA512_BLOCK_LENGTH		128
+#define SHA512_DIGEST_LENGTH		64
+#define SHA512_DIGEST_STRING_LENGTH	(SHA512_DIGEST_LENGTH * 2 + 1)
+
+
+/*** SHA-256/384/512 Context Structures *******************************/
+typedef struct _SHA256_CTX {
+	uint32_t	state[8];
+	uint64_t	bitcount;
+	uint8_t	buffer[SHA256_BLOCK_LENGTH];
+} SHA256_CTX;
+typedef struct _SHA512_CTX {
+	uint64_t	state[8];
+	uint64_t	bitcount[2];
+	uint8_t	buffer[SHA512_BLOCK_LENGTH];
+} SHA512_CTX;
+
+typedef SHA512_CTX SHA384_CTX;
+
+
+void SHA256_Init(SHA256_CTX *);
+void SHA256_Update(SHA256_CTX*, const uint8_t*, size_t);
+void SHA256_Final(uint8_t[SHA256_DIGEST_LENGTH], SHA256_CTX*);
+char* SHA256_End(SHA256_CTX*, char[SHA256_DIGEST_STRING_LENGTH]);
+char* SHA256_Data(const uint8_t*, size_t, char[SHA256_DIGEST_STRING_LENGTH]);
+char *SHA256_File(char *, char *);
+
+void SHA384_Init(SHA384_CTX*);
+void SHA384_Update(SHA384_CTX*, const uint8_t*, size_t);
+void SHA384_Final(uint8_t[SHA384_DIGEST_LENGTH], SHA384_CTX*);
+char* SHA384_End(SHA384_CTX*, char[SHA384_DIGEST_STRING_LENGTH]);
+char* SHA384_Data(const uint8_t*, size_t, char[SHA384_DIGEST_STRING_LENGTH]);
+char *SHA384_File(char *, char *);
+
+void SHA512_Init(SHA512_CTX*);
+void SHA512_Update(SHA512_CTX*, const uint8_t*, size_t);
+void SHA512_Final(uint8_t[SHA512_DIGEST_LENGTH], SHA512_CTX*);
+char* SHA512_End(SHA512_CTX*, char[SHA512_DIGEST_STRING_LENGTH]);
+char* SHA512_Data(const uint8_t*, size_t, char[SHA512_DIGEST_STRING_LENGTH]);
+char *SHA512_File(char *, char *);
+
+#ifdef	__cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __SHA2_H__ */
+
</pre></body></html>