summaryrefslogtreecommitdiff
path: root/src/lib/libsum
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/libsum')
-rw-r--r--src/lib/libsum/Makefile11
-rw-r--r--src/lib/libsum/Mamfile245
-rw-r--r--src/lib/libsum/RELEASE16
-rw-r--r--src/lib/libsum/features/sum4
-rw-r--r--src/lib/libsum/sum-ast4.c120
-rw-r--r--src/lib/libsum/sum-att.c60
-rw-r--r--src/lib/libsum/sum-bsd.c48
-rw-r--r--src/lib/libsum/sum-crc.c191
-rw-r--r--src/lib/libsum/sum-lmd.c330
-rw-r--r--src/lib/libsum/sum-md5.c355
-rw-r--r--src/lib/libsum/sum-prng.c113
-rw-r--r--src/lib/libsum/sum-sha1.c323
-rw-r--r--src/lib/libsum/sum-sha2.c1229
-rw-r--r--src/lib/libsum/sum.h65
-rw-r--r--src/lib/libsum/sumlib.c376
15 files changed, 3486 insertions, 0 deletions
diff --git a/src/lib/libsum/Makefile b/src/lib/libsum/Makefile
new file mode 100644
index 0000000..31de0de
--- /dev/null
+++ b/src/lib/libsum/Makefile
@@ -0,0 +1,11 @@
+:PACKAGE: ast
+
+LICENSE = since=1996,author=gsf
+
+CCFLAGS = $(CC.OPTIMIZE) $(CC.PIC)
+
+sum 1.0 :LIBRARY: sum.h sumlib.c -lmd
+
+$(INCLUDEDIR) :INSTALLPROTO: sum.h
+
+:: RELEASE
diff --git a/src/lib/libsum/Mamfile b/src/lib/libsum/Mamfile
new file mode 100644
index 0000000..c52e277
--- /dev/null
+++ b/src/lib/libsum/Mamfile
@@ -0,0 +1,245 @@
+info mam static 00000 1994-07-17 make (AT&T Research) 5.7 2012-02-29
+setv INSTALLROOT ../../..
+setv PACKAGE_ast_INCLUDE ${INSTALLROOT}/include/ast
+setv PACKAGE_ast_LIB ${INSTALLROOT}/lib
+setv PACKAGEROOT ../../../../..
+setv AR ${mam_cc_AR} ${mam_cc_AR_ARFLAGS}
+setv ARFLAGS rc
+setv AS as
+setv ASFLAGS
+setv CC cc
+setv mam_cc_FLAGS ${mam_cc_PIC}
+setv CCFLAGS ${-debug-symbols?1?${mam_cc_DEBUG} -D_BLD_DEBUG?${mam_cc_OPTIMIZE}?}
+setv CCLDFLAGS ${-strip-symbols?1?${mam_cc_LD_STRIP}??}
+setv COTEMP $$
+setv CPIO cpio
+setv CPIOFLAGS
+setv CPP "${CC} -E"
+setv F77 f77
+setv HOSTCC ${CC}
+setv IGNORE
+setv LD ld
+setv LDFLAGS
+setv LEX lex
+setv LEXFLAGS
+setv LPR lpr
+setv LPRFLAGS
+setv M4FLAGS
+setv NMAKE nmake
+setv NMAKEFLAGS
+setv PR pr
+setv PRFLAGS
+setv SHELL /bin/sh
+setv SILENT
+setv TAR tar
+setv YACC yacc
+setv YACCFLAGS -d
+make ${PACKAGEROOT}/lib/package/ast.lic
+done ${PACKAGEROOT}/lib/package/ast.lic
+make install
+make sum
+make libsum.a archive
+make sum.req
+exec - set -
+exec - echo 'int main(){return 0;}' > 1.${COTEMP}.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -c 1.${COTEMP}.c &&
+exec - x=`${CC} ${mam_cc_FLAGS} ${CCFLAGS} ${LDFLAGS} -o 1.${COTEMP}.x 1.${COTEMP}.o -l'*' 2>&1 | sed -e 's/[][()+@?]/#/g' || :` &&
+exec - {
+exec - case "" in
+exec - *?) echo " " ;;
+exec - esac
+exec - for i in sum md ast
+exec - do case $i in
+exec - "sum"|sum)
+exec - ;;
+exec - *) if test -f ${INSTALLROOT}/lib/lib/$i
+exec - then y=`cat ${INSTALLROOT}/lib/lib/$i`
+exec - case $y in
+exec - *-?*) echo "" $y ;;
+exec - esac
+exec - continue
+exec - elif test ! -f ${INSTALLROOT}/lib/lib$i.a
+exec - then case `{ ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -L${INSTALLROOT}/lib ${LDFLAGS} -o 1.${COTEMP}.x 1.${COTEMP}.o -l$i 2>&1 || echo '' $x ;} | sed -e 's/[][()+@?]/#/g' || :` in
+exec - *$x*) case `{ ${CC} ${mam_cc_FLAGS} ${CCFLAGS} ${LDFLAGS} -o 1.${COTEMP}.x 1.${COTEMP}.o -l$i 2>&1 || echo '' $x ;} | sed -e 's/[][()+@?]/#/g' || :` in
+exec - *$x*) continue ;;
+exec - esac
+exec - ;;
+exec - esac
+exec - fi
+exec - ;;
+exec - esac
+exec - echo " -l$i"
+exec - done
+exec - } > sum.req
+exec - rm -f 1.${COTEMP}.*
+done sum.req generated
+make sumlib.o
+make sumlib.c
+make sum-sha2.c implicit
+make ${PACKAGE_ast_INCLUDE}/endian.h implicit
+make ${PACKAGE_ast_INCLUDE}/bytesex.h implicit
+make ${PACKAGE_ast_INCLUDE}/ast_common.h implicit
+make ${PACKAGE_ast_INCLUDE}/ast_map.h implicit
+done ${PACKAGE_ast_INCLUDE}/ast_map.h dontcare
+prev ${PACKAGE_ast_INCLUDE}/endian.h implicit
+done ${PACKAGE_ast_INCLUDE}/ast_common.h dontcare
+done ${PACKAGE_ast_INCLUDE}/bytesex.h dontcare
+done ${PACKAGE_ast_INCLUDE}/endian.h dontcare
+done sum-sha2.c dontcare
+make sum-sha1.c implicit
+done sum-sha1.c dontcare
+make sum-md5.c implicit
+done sum-md5.c dontcare
+make sum-lmd.c implicit
+make sha2.h implicit
+done sha2.h dontcare virtual
+make sha1.h implicit
+done sha1.h dontcare virtual
+make md5.h implicit
+done md5.h dontcare virtual
+make md4.h implicit
+done md4.h dontcare virtual
+done sum-lmd.c dontcare
+make sum-prng.c implicit
+make ${PACKAGE_ast_INCLUDE}/fnv.h implicit
+prev ${PACKAGE_ast_INCLUDE}/ast_common.h implicit
+make ${PACKAGE_ast_INCLUDE}/prototyped.h implicit
+make ${INSTALLROOT}/include/prototyped.h implicit
+done ${INSTALLROOT}/include/prototyped.h dontcare
+done ${PACKAGE_ast_INCLUDE}/prototyped.h dontcare
+done ${PACKAGE_ast_INCLUDE}/fnv.h
+done sum-prng.c
+make sum-crc.c implicit
+done sum-crc.c
+make sum-bsd.c implicit
+done sum-bsd.c
+make sum-ast4.c implicit
+done sum-ast4.c
+make sum-att.c implicit
+done sum-att.c
+make FEATURE/sum implicit
+meta FEATURE/sum features/%>FEATURE/% features/sum sum
+make features/sum
+done features/sum
+bind -last
+exec - iffe -v -c '${CC} ${mam_cc_FLAGS} ${CCFLAGS} ${LDFLAGS} ' ref ${mam_cc_L+-L${INSTALLROOT}/lib} -I${PACKAGE_ast_INCLUDE} -I${INSTALLROOT}/include ${mam_libast} : run features/sum
+done FEATURE/sum generated
+make ${PACKAGE_ast_INCLUDE}/hashpart.h implicit
+prev ${PACKAGE_ast_INCLUDE}/prototyped.h implicit
+done ${PACKAGE_ast_INCLUDE}/hashpart.h
+make ${PACKAGE_ast_INCLUDE}/swap.h implicit
+prev ${PACKAGE_ast_INCLUDE}/ast_common.h implicit
+prev ${PACKAGE_ast_INCLUDE}/prototyped.h implicit
+done ${PACKAGE_ast_INCLUDE}/swap.h
+prev ${PACKAGE_ast_INCLUDE}/endian.h implicit
+make sum.h implicit
+make ${PACKAGE_ast_INCLUDE}/ast.h implicit
+make ${PACKAGE_ast_INCLUDE}/ast_api.h implicit
+done ${PACKAGE_ast_INCLUDE}/ast_api.h dontcare
+make ${PACKAGE_ast_INCLUDE}/vmalloc.h implicit
+prev ${PACKAGE_ast_INCLUDE}/ast_common.h implicit
+make ${PACKAGE_ast_INCLUDE}/ast_std.h implicit
+make ${PACKAGE_ast_INCLUDE}/regex.h implicit
+make ${PACKAGE_ast_INCLUDE}/ast_wchar.h implicit
+make ${PACKAGE_ast_INCLUDE}/wctype.h implicit
+make ${PACKAGE_ast_INCLUDE}/ast_wctype.h implicit
+prev ${PACKAGE_ast_INCLUDE}/endian.h implicit
+done ${PACKAGE_ast_INCLUDE}/ast_wctype.h dontcare
+done ${PACKAGE_ast_INCLUDE}/wctype.h dontcare
+make ${PACKAGE_ast_INCLUDE}/stdio.h implicit
+make ${PACKAGE_ast_INCLUDE}/ast_stdio.h implicit
+make ${PACKAGE_ast_INCLUDE}/sfio_s.h implicit
+done ${PACKAGE_ast_INCLUDE}/sfio_s.h dontcare
+prev ${PACKAGE_ast_INCLUDE}/ast_std.h implicit
+done ${PACKAGE_ast_INCLUDE}/ast_stdio.h dontcare
+done ${PACKAGE_ast_INCLUDE}/stdio.h dontcare
+prev ${PACKAGE_ast_INCLUDE}/stdio.h implicit
+prev ${PACKAGE_ast_INCLUDE}/ast_common.h implicit
+done ${PACKAGE_ast_INCLUDE}/ast_wchar.h dontcare
+prev ${PACKAGE_ast_INCLUDE}/ast_common.h implicit
+prev ${PACKAGE_ast_INCLUDE}/prototyped.h implicit
+done ${PACKAGE_ast_INCLUDE}/regex.h dontcare
+make ${PACKAGE_ast_INCLUDE}/getopt.h implicit
+make ${PACKAGE_ast_INCLUDE}/ast_getopt.h implicit
+prev ${PACKAGE_ast_INCLUDE}/prototyped.h implicit
+done ${PACKAGE_ast_INCLUDE}/ast_getopt.h dontcare
+prev ${PACKAGE_ast_INCLUDE}/prototyped.h implicit
+done ${PACKAGE_ast_INCLUDE}/getopt.h dontcare
+prev ${PACKAGE_ast_INCLUDE}/ast_map.h implicit
+make ${PACKAGE_ast_INCLUDE}/ast_botch.h implicit
+done ${PACKAGE_ast_INCLUDE}/ast_botch.h dontcare
+make ${PACKAGE_ast_INCLUDE}/ast_limits.h implicit
+done ${PACKAGE_ast_INCLUDE}/ast_limits.h dontcare
+make ${PACKAGE_ast_INCLUDE}/ast_fcntl.h implicit
+make ${PACKAGE_ast_INCLUDE}/ast_fs.h implicit
+done ${PACKAGE_ast_INCLUDE}/ast_fs.h dontcare
+done ${PACKAGE_ast_INCLUDE}/ast_fcntl.h dontcare
+prev ${PACKAGE_ast_INCLUDE}/ast_getopt.h implicit
+make ${PACKAGE_ast_INCLUDE}/ast_sys.h implicit
+prev ${PACKAGE_ast_INCLUDE}/getopt.h implicit
+prev ${PACKAGE_ast_INCLUDE}/endian.h implicit
+prev ${PACKAGE_ast_INCLUDE}/endian.h implicit
+done ${PACKAGE_ast_INCLUDE}/ast_sys.h dontcare
+make ${PACKAGE_ast_INCLUDE}/ast_lib.h implicit
+done ${PACKAGE_ast_INCLUDE}/ast_lib.h dontcare
+prev ${PACKAGE_ast_INCLUDE}/ast_common.h implicit
+prev ${PACKAGE_ast_INCLUDE}/prototyped.h implicit
+done ${PACKAGE_ast_INCLUDE}/ast_std.h dontcare
+done ${PACKAGE_ast_INCLUDE}/vmalloc.h dontcare
+make ${PACKAGE_ast_INCLUDE}/sfio.h implicit
+prev ${PACKAGE_ast_INCLUDE}/sfio_s.h implicit
+prev ${PACKAGE_ast_INCLUDE}/ast_common.h implicit
+prev ${PACKAGE_ast_INCLUDE}/ast_std.h implicit
+done ${PACKAGE_ast_INCLUDE}/sfio.h dontcare
+prev ${PACKAGE_ast_INCLUDE}/ast_std.h implicit
+prev ${PACKAGE_ast_INCLUDE}/prototyped.h implicit
+done ${PACKAGE_ast_INCLUDE}/ast.h dontcare
+done sum.h
+done sumlib.c
+meta sumlib.o %.c>%.o sumlib.c sumlib
+prev sumlib.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -I${PACKAGE_ast_INCLUDE} -D_PACKAGE_ast -c sumlib.c
+done sumlib.o generated
+exec - ${AR} rc libsum.a sumlib.o
+exec - (ranlib libsum.a) >/dev/null 2>&1 || true
+done libsum.a generated
+done sum virtual
+prev libsum.a archive
+make ${INSTALLROOT}/lib
+exec - if silent test ! -d ${INSTALLROOT}/lib
+exec - then mkdir -p ${INSTALLROOT}/lib
+exec - fi
+done ${INSTALLROOT}/lib generated
+make ${INSTALLROOT}/lib/libsum.a archive
+prev ${INSTALLROOT}/lib
+prev libsum.a archive
+exec - test '' = 'libsum.a' || ${STDCMP} 2>/dev/null -s libsum.a ${INSTALLROOT}/lib/libsum.a || { ${STDMV} ${INSTALLROOT}/lib/libsum.a ${INSTALLROOT}/lib/libsum.a.old 2>/dev/null || true; ${STDCP} libsum.a ${INSTALLROOT}/lib/libsum.a ;}
+exec - (ranlib ${INSTALLROOT}/lib/libsum.a) >/dev/null 2>&1 || true
+done ${INSTALLROOT}/lib/libsum.a generated
+make ${INSTALLROOT}/lib/lib
+exec - if silent test ! -d ${INSTALLROOT}/lib/lib
+exec - then mkdir -p ${INSTALLROOT}/lib/lib
+exec - fi
+done ${INSTALLROOT}/lib/lib generated
+make ${INSTALLROOT}/lib/lib/sum
+prev ${INSTALLROOT}/lib/lib
+prev sum.req
+exec - test '' = 'sum.req' || ${STDCMP} 2>/dev/null -s sum.req ${INSTALLROOT}/lib/lib/sum || { ${STDMV} ${INSTALLROOT}/lib/lib/sum ${INSTALLROOT}/lib/lib/sum.old 2>/dev/null || true; ${STDCP} sum.req ${INSTALLROOT}/lib/lib/sum ;}
+done ${INSTALLROOT}/lib/lib/sum generated
+make ${PACKAGE_ast_INCLUDE}
+exec - if silent test ! -d ${PACKAGE_ast_INCLUDE}
+exec - then mkdir -p ${PACKAGE_ast_INCLUDE}
+exec - fi
+done ${PACKAGE_ast_INCLUDE} generated
+make ${PACKAGE_ast_INCLUDE}/sum.h
+prev ${PACKAGE_ast_INCLUDE}
+prev sum.h
+exec - proto -p -s -l ${PACKAGEROOT}/lib/package/ast.lic '-o since=1996,author=gsf' sum.h > 1.${COTEMP}.x
+exec - if cmp 2>/dev/null -s ${PACKAGE_ast_INCLUDE}/sum.h 1.${COTEMP}.x
+exec - then rm -f 1.${COTEMP}.x
+exec - else mv 1.${COTEMP}.x ${PACKAGE_ast_INCLUDE}/sum.h
+exec - fi
+done ${PACKAGE_ast_INCLUDE}/sum.h generated
+done install virtual
+make test
+done test dontcare virtual
diff --git a/src/lib/libsum/RELEASE b/src/lib/libsum/RELEASE
new file mode 100644
index 0000000..e8d899a
--- /dev/null
+++ b/src/lib/libsum/RELEASE
@@ -0,0 +1,16 @@
+12-02-29 sum-sha2.c: bitcount[] order reversed to allow a single noalias buffer copy
+09-09-28 sumlib.c: use simple (faster) method name match function
+08-06-05 sum-lmd.c: align context to largest int
+08-05-01 sumlib.c: add some -lmd verification checks
+08-02-11 sum-lmd.c,features/sum: add wrapper for solaris -lmd
+07-10-29 sum.h,sumlib.c: add SUM_LEGACY for legacy output format
+07-09-21 sum-sha1.c: reinstate Steve Reid's public domain implementation
+07-07-26 sumlib.c: drop GPL sum-sha1.c
+05-02-14 sumlib.c: split into sum-*.c
+05-02-14 sum-sha2.c: add SHA { 256 384 512 }
+04-02-29 Makefile: compile with $(CC.PIC) for codexlib/sum $(CC.DLL)
+03-12-16 add { crc prng } generic methods and maps[] to these methods
+03-12-16 sum.h,sumlib.c: add sumdata()
+03-09-29 sumlib.c: fix FNV to use ^ instead of +
+03-04-28 sumlib.c: drop md5 `zeroize' for performance
+ sumlib.c: add FIPS 180-1 SHA-1
diff --git a/src/lib/libsum/features/sum b/src/lib/libsum/features/sum
new file mode 100644
index 0000000..ce15b49
--- /dev/null
+++ b/src/lib/libsum/features/sum
@@ -0,0 +1,4 @@
+lib MD4Init md4.h -lmd
+lib MD5Init md5.h -lmd
+lib SHA1Init sha1.h -lmd
+lib SHA2Init sha2.h -lmd
diff --git a/src/lib/libsum/sum-ast4.c b/src/lib/libsum/sum-ast4.c
new file mode 100644
index 0000000..763b18a
--- /dev/null
+++ b/src/lib/libsum/sum-ast4.c
@@ -0,0 +1,120 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1996-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+/*
+ * ast4
+ */
+
+#define ast4_description \
+ "The \bast\b 128 bit PRNG hash generated by catenating 4 separate 32 \
+ bit PNRG hashes. The block count is not printed."
+#define ast4_options 0
+#define ast4_match "ast4|32x4|tw"
+#define ast4_done long_done
+#define ast4_scale 0
+
+typedef struct Ast4_sum_s
+{
+ uint32_t sum0;
+ uint32_t sum1;
+ uint32_t sum2;
+ uint32_t sum3;
+} Ast4_sum_t;
+
+typedef struct Ast4_s
+{
+ _SUM_PUBLIC_
+ _SUM_PRIVATE_
+ Ast4_sum_t cur;
+ Ast4_sum_t tot;
+ unsigned char buf[sizeof(Ast4_sum_t)];
+} Ast4_t;
+
+static int
+ast4_init(Sum_t* p)
+{
+ register Ast4_t* a = (Ast4_t*)p;
+
+ a->tot.sum0 ^= a->cur.sum0;
+ a->cur.sum0 = 0;
+ a->tot.sum1 ^= a->cur.sum1;
+ a->cur.sum1 = 0;
+ a->tot.sum2 ^= a->cur.sum2;
+ a->cur.sum2 = 0;
+ a->tot.sum3 ^= a->cur.sum3;
+ a->cur.sum3 = 0;
+ return 0;
+}
+
+static Sum_t*
+ast4_open(const Method_t* method, const char* name)
+{
+ Ast4_t* p;
+
+ if (p = newof(0, Ast4_t, 1, 0))
+ {
+ p->method = (Method_t*)method;
+ p->name = name;
+ }
+ return (Sum_t*)p;
+}
+
+static int
+ast4_block(Sum_t* p, const void* s, size_t n)
+{
+ register Ast4_sum_t* a = &((Ast4_t*)p)->cur;
+ register unsigned char* b = (unsigned char*)s;
+ register unsigned char* e = b + n;
+ register int c;
+
+ while (b < e)
+ {
+ c = *b++;
+ a->sum0 = a->sum0 * 0x63c63cd9 + 0x9c39c33d + c;
+ a->sum1 = a->sum1 * 0x00000011 + 0x00017cfb + c;
+ a->sum2 = a->sum2 * 0x12345679 + 0x3ade68b1 + c;
+ a->sum3 = a->sum3 * 0xf1eac01d + 0xcafe10af + c;
+ }
+ return 0;
+}
+
+static int
+ast4_print(Sum_t* p, Sfio_t* sp, int flags, size_t scale)
+{
+ register Ast4_sum_t* a;
+
+ a = (flags & SUM_TOTAL) ? &((Ast4_t*)p)->tot : &((Ast4_t*)p)->cur;
+ sfprintf(sp, "%06..64u%06..64u%06..64u%06..64u", a->sum0, a->sum1, a->sum2, a->sum3);
+ return 0;
+}
+
+static int
+ast4_data(Sum_t* p, Sumdata_t* data)
+{
+ data->size = sizeof(((Ast4_t*)p)->cur);
+ data->num = 0;
+#if _ast_intswap
+ swapmem(_ast_intswap, data->buf = ((Ast4_t*)p)->buf, &((Ast4_t*)p)->cur, sizeof(((Ast4_t*)p)->cur));
+#else
+ data->buf = &((Ast4_t*)p)->cur;
+#endif
+ return 0;
+}
diff --git a/src/lib/libsum/sum-att.c b/src/lib/libsum/sum-att.c
new file mode 100644
index 0000000..eb4b44c
--- /dev/null
+++ b/src/lib/libsum/sum-att.c
@@ -0,0 +1,60 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1996-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+/*
+ * att
+ */
+
+#define att_description \
+ "The system 5 release 4 checksum. This is the default for \bsum\b \
+ when \bgetconf UNIVERSE\b is \batt\b. This is the only true sum; \
+ all of the other methods are order dependent."
+#define att_options 0
+#define att_match "att|sys5|s5|default"
+#define att_open long_open
+#define att_init long_init
+#define att_print long_print
+#define att_data long_data
+#define att_scale 512
+
+static int
+att_block(register Sum_t* p, const void* s, size_t n)
+{
+ register uint32_t c = ((Integral_t*)p)->sum;
+ register unsigned char* b = (unsigned char*)s;
+ register unsigned char* e = b + n;
+
+ while (b < e)
+ c += *b++;
+ ((Integral_t*)p)->sum = c;
+ return 0;
+}
+
+static int
+att_done(Sum_t* p)
+{
+ register uint32_t c = ((Integral_t*)p)->sum;
+
+ c = (c & 0xffff) + ((c >> 16) & 0xffff);
+ c = (c & 0xffff) + (c >> 16);
+ ((Integral_t*)p)->sum = c & 0xffff;
+ return short_done(p);
+}
diff --git a/src/lib/libsum/sum-bsd.c b/src/lib/libsum/sum-bsd.c
new file mode 100644
index 0000000..e54c00e
--- /dev/null
+++ b/src/lib/libsum/sum-bsd.c
@@ -0,0 +1,48 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1996-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+/*
+ * bsd
+ */
+
+#define bsd_description \
+ "The BSD checksum."
+#define bsd_options 0
+#define bsd_match "bsd|ucb"
+#define bsd_open long_open
+#define bsd_init long_init
+#define bsd_done short_done
+#define bsd_print long_print
+#define bsd_data long_data
+#define bsd_scale 1024
+
+static int
+bsd_block(register Sum_t* p, const void* s, size_t n)
+{
+ register uint32_t c = ((Integral_t*)p)->sum;
+ register unsigned char* b = (unsigned char*)s;
+ register unsigned char* e = b + n;
+
+ while (b < e)
+ c = ((c >> 1) + *b++ + ((c & 01) ? 0x8000 : 0)) & 0xffff;
+ ((Integral_t*)p)->sum = c;
+ return 0;
+}
diff --git a/src/lib/libsum/sum-crc.c b/src/lib/libsum/sum-crc.c
new file mode 100644
index 0000000..371cd99
--- /dev/null
+++ b/src/lib/libsum/sum-crc.c
@@ -0,0 +1,191 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1996-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+/*
+ * crc
+ */
+
+#define crc_description \
+ "32 bit CRC (cyclic redundancy check)."
+#define crc_options "\
+[+polynomial?The 32 bit crc polynomial bitmask with implicit bit 32.]:[mask:=0xedb88320]\
+[+done?XOR the final crc value with \anumber\a. 0xffffffff is used if \anumber\a is omitted.]:?[number:=0]\
+[+init?The initial crc value. 0xffffffff is used if \anumber\a is omitted.]:?[number:=0]\
+[+rotate?XOR each input character with the high order crc byte (instead of the low order).]\
+[+size?Include the total number of bytes in the crc. \anumber\a, if specified, is first XOR'd into the size.]:?[number:=0]\
+"
+#define crc_match "crc"
+#define crc_open crc_open
+#define crc_print long_print
+#define crc_data long_data
+#define crc_scale 0
+
+typedef uint32_t Crcnum_t;
+
+typedef struct Crc_s
+{
+ _SUM_PUBLIC_
+ _SUM_PRIVATE_
+ _INTEGRAL_PRIVATE_
+ Crcnum_t init;
+ Crcnum_t done;
+ Crcnum_t xorsize;
+ Crcnum_t tab[256];
+ unsigned int addsize;
+ unsigned int rotate;
+} Crc_t;
+
+#define CRC(p,s,c) (s = (s >> 8) ^ (p)->tab[(s ^ (c)) & 0xff])
+#define CRCROTATE(p,s,c) (s = (s << 8) ^ (p)->tab[((s >> 24) ^ (c)) & 0xff])
+
+static Sum_t*
+crc_open(const Method_t* method, const char* name)
+{
+ register Crc_t* sum;
+ register const char* s;
+ register const char* t;
+ register const char* v;
+ register int i;
+ register int j;
+ Crcnum_t polynomial;
+ Crcnum_t x;
+
+ if (sum = newof(0, Crc_t, 1, 0))
+ {
+ sum->method = (Method_t*)method;
+ sum->name = name;
+ }
+ polynomial = 0xedb88320;
+ s = name;
+ while (*(t = s))
+ {
+ for (t = s, v = 0; *s && *s != '-'; s++)
+ if (*s == '=' && !v)
+ v = s;
+ i = (v ? v : s) - t;
+ if (isdigit(*t) || v && i >= 4 && strneq(t, "poly", 4) && (t = v + 1))
+ polynomial = strtoul(t, NiL, 0);
+ else if (strneq(t, "done", i))
+ sum->done = v ? strtoul(v + 1, NiL, 0) : ~sum->done;
+ else if (strneq(t, "init", i))
+ sum->init = v ? strtoul(v + 1, NiL, 0) : ~sum->init;
+ else if (strneq(t, "rotate", i))
+ sum->rotate = 1;
+ else if (strneq(t, "size", i))
+ {
+ sum->addsize = 1;
+ if (v)
+ sum->xorsize = strtoul(v + 1, NiL, 0);
+ }
+ if (*s == '-')
+ s++;
+ }
+ if (sum->rotate)
+ {
+ Crcnum_t t;
+ Crcnum_t p[8];
+
+ p[0] = polynomial;
+ for (i = 1; i < 8; i++)
+ p[i] = (p[i-1] << 1) ^ ((p[i-1] & 0x80000000) ? polynomial : 0);
+ for (i = 0; i < elementsof(sum->tab); i++)
+ {
+ t = 0;
+ x = i;
+ for (j = 0; j < 8; j++)
+ {
+ if (x & 1)
+ t ^= p[j];
+ x >>= 1;
+ }
+ sum->tab[i] = t;
+ }
+ }
+ else
+ {
+ for (i = 0; i < elementsof(sum->tab); i++)
+ {
+ x = i;
+ for (j = 0; j < 8; j++)
+ x = (x>>1) ^ ((x & 1) ? polynomial : 0);
+ sum->tab[i] = x;
+ }
+ }
+ return (Sum_t*)sum;
+}
+
+static int
+crc_init(Sum_t* p)
+{
+ Crc_t* sum = (Crc_t*)p;
+
+ sum->sum = sum->init;
+ return 0;
+}
+
+static int
+crc_block(Sum_t* p, const void* s, size_t n)
+{
+ Crc_t* sum = (Crc_t*)p;
+ register Crcnum_t c = sum->sum;
+ register unsigned char* b = (unsigned char*)s;
+ register unsigned char* e = b + n;
+
+ if (sum->rotate)
+ while (b < e)
+ CRCROTATE(sum, c, *b++);
+ else
+ while (b < e)
+ CRC(sum, c, *b++);
+ sum->sum = c;
+ return 0;
+}
+
+static int
+crc_done(Sum_t* p)
+{
+ register Crc_t* sum = (Crc_t*)p;
+ register Crcnum_t c;
+ register uintmax_t n;
+ int i;
+ int j;
+
+ c = sum->sum;
+ if (sum->addsize)
+ {
+ n = sum->size ^ sum->xorsize;
+ if (sum->rotate)
+ while (n)
+ {
+ CRCROTATE(sum, c, n);
+ n >>= 8;
+ }
+ else
+ for (i = 0, j = 32; i < 4; i++)
+ {
+ j -= 8;
+ CRC(sum, c, n >> j);
+ }
+ }
+ sum->sum = c ^ sum->done;
+ sum->total_sum ^= (sum->sum &= 0xffffffff);
+ return 0;
+}
diff --git a/src/lib/libsum/sum-lmd.c b/src/lib/libsum/sum-lmd.c
new file mode 100644
index 0000000..b733a9f
--- /dev/null
+++ b/src/lib/libsum/sum-lmd.c
@@ -0,0 +1,330 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1996-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+/*
+ * sum(3) wrapper for solaris -lmd message digest library
+ */
+
+typedef void (*Lmd_init_f)(void*);
+typedef void (*Lmd_update_f)(void*, const void*, size_t);
+typedef void (*Lmd_final_f)(unsigned char*, void*);
+
+#define _SUM_LMD_ \
+ _SUM_PUBLIC_ \
+ _SUM_PRIVATE_ \
+ Lmd_init_f initf; \
+ Lmd_update_f updatef; \
+ Lmd_final_f finalf; \
+ unsigned int datasize; \
+ unsigned char total[64]; \
+ unsigned char data[64];
+
+typedef struct Lmd_s
+{
+ _SUM_LMD_
+ struct
+ {
+ uintmax_t context;
+ } context;
+} Lmd_t;
+
+static int
+lmd_init(Sum_t* p)
+{
+ Lmd_t* lmd = (Lmd_t*)p;
+
+ (*lmd->initf)(&lmd->context);
+ return 0;
+}
+
+static int
+lmd_block(Sum_t* p, const void* s, size_t n)
+{
+ Lmd_t* lmd = (Lmd_t*)p;
+
+ (*lmd->updatef)(&lmd->context, s, n);
+ return 0;
+}
+
+static int
+lmd_done(Sum_t* p)
+{
+ register Lmd_t* lmd = (Lmd_t*)p;
+ register int i;
+
+ (*lmd->finalf)(lmd->data, &lmd->context);
+ for (i = 0; i < lmd->datasize; i++)
+ lmd->total[i] ^= lmd->data[i];
+ return 0;
+}
+
+static int
+lmd_print(Sum_t* p, Sfio_t* sp, register int flags, size_t scale)
+{
+ register Lmd_t* lmd = (Lmd_t*)p;
+ register unsigned char* d;
+ register int i;
+
+ d = (flags & SUM_TOTAL) ? lmd->total : lmd->data;
+ for (i = 0; i < lmd->datasize; i++)
+ sfprintf(sp, "%02x", d[i]);
+ return 0;
+}
+
+static int
+lmd_data(Sum_t* p, Sumdata_t* data)
+{
+ Lmd_t* lmd = (Lmd_t*)p;
+
+ data->size = lmd->datasize;
+ data->num = 0;
+ data->buf = lmd->data;
+ return 0;
+}
+
+#if _lib_MD4Init && _hdr_md4
+
+#include <md4.h>
+
+#define md4_description "RFC1320 MD4 message digest. Cryptographically weak. The block count is not printed."
+#define md4_options "[+(version)?md4 (solaris -lmd) 2005-07-26]"
+#define md4_match "md4|MD4"
+#define md4_scale 0
+#define md4_init lmd_init
+#define md4_block lmd_block
+#define md4_done lmd_done
+#define md4_print lmd_print
+#define md4_data lmd_data
+
+typedef struct Md4_s
+{
+ _SUM_LMD_
+ MD4_CTX context;
+} Md4_t;
+
+static Sum_t*
+md4_open(const Method_t* method, const char* name)
+{
+ Md4_t* lmd;
+
+ if (lmd = newof(0, Md4_t, 1, 0))
+ {
+ lmd->method = (Method_t*)method;
+ lmd->name = name;
+ lmd->datasize = 16;
+ lmd->initf = (Lmd_init_f)MD4Init;
+ lmd->updatef = (Lmd_update_f)MD4Update;
+ lmd->finalf = (Lmd_final_f)MD4Final;
+ md4_init((Sum_t*)lmd);
+ }
+ return (Sum_t*)lmd;
+}
+
+#endif
+
+#if _lib_MD5Init && _hdr_md5
+
+#include <md5.h>
+
+#define md5_description "RFC1321 MD5 message digest. Cryptographically weak. The block count is not printed."
+#define md5_options "[+(version)?md5 (solaris -lmd) 2005-07-26]"
+#define md5_match "md5|MD5"
+#define md5_scale 0
+#define md5_init lmd_init
+#define md5_block lmd_block
+#define md5_done lmd_done
+#define md5_print lmd_print
+#define md5_data lmd_data
+
+typedef struct Md5_s
+{
+ _SUM_LMD_
+ MD5_CTX context;
+} Md5_t;
+
+static Sum_t*
+md5_open(const Method_t* method, const char* name)
+{
+ Md5_t* lmd;
+
+ if (lmd = newof(0, Md5_t, 1, 0))
+ {
+ lmd->method = (Method_t*)method;
+ lmd->name = name;
+ lmd->datasize = 16;
+ lmd->initf = (Lmd_init_f)MD5Init;
+ lmd->updatef = (Lmd_update_f)MD5Update;
+ lmd->finalf = (Lmd_final_f)MD5Final;
+ md5_init((Sum_t*)lmd);
+ }
+ return (Sum_t*)lmd;
+}
+
+#endif
+
+#if _lib_SHA1Init && _hdr_sha1
+
+#include <sha1.h>
+
+#define sha1_description "RFC3174 / FIPS 180-1 SHA-1 secure hash algorithm 1. Cryptographically weak. The block count is not printed."
+#define sha1_options "[+(version)?sha1 (solaris -lmd) 2005-07-26]"
+#define sha1_match "sha1|SHA1|sha-1|SHA-1"
+#define sha1_scale 0
+#define sha1_init lmd_init
+#define sha1_block lmd_block
+#define sha1_done lmd_done
+#define sha1_print lmd_print
+#define sha1_data lmd_data
+
+typedef struct Sha1_s
+{
+ _SUM_LMD_
+ SHA1_CTX context;
+ unsigned char pad[1024]; /* XXX: who's bug is it? */
+} Sha1_t;
+
+static Sum_t*
+sha1_open(const Method_t* method, const char* name)
+{
+ Sha1_t* lmd;
+
+ if (lmd = newof(0, Sha1_t, 1, 0))
+ {
+ lmd->method = (Method_t*)method;
+ lmd->name = name;
+ lmd->datasize = 20;
+ lmd->initf = (Lmd_init_f)SHA1Init;
+ lmd->updatef = (Lmd_update_f)SHA1Update;
+ lmd->finalf = (Lmd_final_f)SHA1Final;
+ sha1_init((Sum_t*)lmd);
+ }
+ return (Sum_t*)lmd;
+}
+
+#endif
+
+#if _lib_SHA2Init && _hdr_sha2
+
+#include <sha2.h>
+
+#define sha256_description "FIPS 180-2 SHA256 secure hash algorithm. The block count is not printed."
+#define sha256_options "[+(version)?sha256 (solaris -lmd) 2005-07-26]"
+#define sha256_match "sha256|sha-256|SHA256|SHA-256"
+#define sha256_scale 0
+#define sha256_init lmd_init
+#define sha256_block lmd_block
+#define sha256_done lmd_done
+#define sha256_print lmd_print
+#define sha256_data lmd_data
+
+typedef struct Sha256_s
+{
+ _SUM_LMD_
+ SHA256_CTX context;
+} Sha256_t;
+
+static Sum_t*
+sha256_open(const Method_t* method, const char* name)
+{
+ Sha256_t* lmd;
+
+ if (lmd = newof(0, Sha256_t, 1, 0))
+ {
+ lmd->method = (Method_t*)method;
+ lmd->name = name;
+ lmd->datasize = 32;
+ lmd->initf = (Lmd_init_f)SHA256Init;
+ lmd->updatef = (Lmd_update_f)SHA256Update;
+ lmd->finalf = (Lmd_final_f)SHA256Final;
+ sha256_init((Sum_t*)lmd);
+ }
+ return (Sum_t*)lmd;
+}
+
+#define sha384_description "FIPS 180-2 SHA384 secure hash algorithm. The block count is not printed."
+#define sha384_options "[+(version)?sha384 (solaris -lmd) 2005-07-26]"
+#define sha384_match "sha384|sha-384|SHA384|SHA-384"
+#define sha384_scale 0
+#define sha384_init lmd_init
+#define sha384_block lmd_block
+#define sha384_done lmd_done
+#define sha384_print lmd_print
+#define sha384_data lmd_data
+
+typedef struct Sha384_s
+{
+ _SUM_LMD_
+ SHA384_CTX context;
+} Sha384_t;
+
+static Sum_t*
+sha384_open(const Method_t* method, const char* name)
+{
+ Sha384_t* lmd;
+
+ if (lmd = newof(0, Sha384_t, 1, 0))
+ {
+ lmd->method = (Method_t*)method;
+ lmd->name = name;
+ lmd->datasize = 48;
+ lmd->initf = (Lmd_init_f)SHA384Init;
+ lmd->updatef = (Lmd_update_f)SHA384Update;
+ lmd->finalf = (Lmd_final_f)SHA384Final;
+ sha384_init((Sum_t*)lmd);
+ }
+ return (Sum_t*)lmd;
+}
+
+#define sha512_description "FIPS 180-2 SHA512 secure hash algorithm. The block count is not printed."
+#define sha512_options "[+(version)?sha512 (solaris -lmd) 2005-07-26]"
+#define sha512_match "sha512|sha-512|SHA512|SHA-512"
+#define sha512_scale 0
+#define sha512_init lmd_init
+#define sha512_block lmd_block
+#define sha512_done lmd_done
+#define sha512_print lmd_print
+#define sha512_data lmd_data
+
+typedef struct Sha512_s
+{
+ _SUM_LMD_
+ SHA512_CTX context;
+} Sha512_t;
+
+static Sum_t*
+sha512_open(const Method_t* method, const char* name)
+{
+ Sha512_t* lmd;
+
+ if (lmd = newof(0, Sha512_t, 1, 0))
+ {
+ lmd->method = (Method_t*)method;
+ lmd->name = name;
+ lmd->datasize = 64;
+ lmd->initf = (Lmd_init_f)SHA512Init;
+ lmd->updatef = (Lmd_update_f)SHA512Update;
+ lmd->finalf = (Lmd_final_f)SHA512Final;
+ sha512_init((Sum_t*)lmd);
+ }
+ return (Sum_t*)lmd;
+}
+
+#endif
diff --git a/src/lib/libsum/sum-md5.c b/src/lib/libsum/sum-md5.c
new file mode 100644
index 0000000..8f3b7f6
--- /dev/null
+++ b/src/lib/libsum/sum-md5.c
@@ -0,0 +1,355 @@
+#pragma prototyped
+
+/*
+ * md5
+ */
+
+/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
+ rights reserved.
+
+ License to copy and use this software is granted provided that it
+ is identified as the "RSA Data Security, Inc. MD5 Message-Digest
+ Method" in all material mentioning or referencing this software
+ or this function.
+
+ License is also granted to make and use derivative works provided
+ that such works are identified as "derived from the RSA Data
+ Security, Inc. MD5 Message-Digest Method" in all material
+ mentioning or referencing the derived work.
+
+ RSA Data Security, Inc. makes no representations concerning either
+ the merchantability of this software or the suitability of this
+ software for any particular purpose. It is provided "as is"
+ without express or implied warranty of any kind.
+
+ These notices must be retained in any copies of any part of this
+ documentation and/or software.
+ */
+
+#define md5_description \
+ "The RSA Data Security, Inc. MD5 Message-Digest Method, 1991-2, \
+ used with permission. The block count is not printed."
+#define md5_options "[+(version)?md5 (RSA Data Security, Inc. MD5 Message-Digest, 1991-2) 1996-02-29]"
+#define md5_match "md5|MD5"
+#define md5_scale 0
+
+typedef uint32_t UINT4;
+
+typedef struct Md5_s
+{
+ _SUM_PUBLIC_
+ _SUM_PRIVATE_
+ UINT4 state[4]; /* state (ABCD) */
+ UINT4 count[2]; /* # bits handled mod 2^64 (lsb)*/
+ unsigned char buffer[64]; /* input buffer */
+ unsigned char digest[16]; /* final digest */
+ unsigned char digest_sum[16]; /* sum of all digests */
+} Md5_t;
+
+static const unsigned char md5_pad[] =
+{
+ 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+
+/*
+ * encode input into output
+ * len must be a multiple of 4
+ */
+
+static void
+md5_encode(register unsigned char* output, register UINT4* input, unsigned int len)
+{
+ register unsigned int i;
+ register unsigned int j;
+
+ for (i = j = 0; j < len; i++, j += 4)
+ {
+ output[j] = (unsigned char)(input[i] & 0xff);
+ output[j+1] = (unsigned char)((input[i] >> 8) & 0xff);
+ output[j+2] = (unsigned char)((input[i] >> 16) & 0xff);
+ output[j+3] = (unsigned char)((input[i] >> 24) & 0xff);
+ }
+}
+
+/*
+ * decode input into output
+ * len must be a multiple of 4
+ */
+
+static void
+md5_decode(register UINT4* output, register unsigned char* input, unsigned int len)
+{
+ unsigned int i;
+ unsigned int j;
+
+ for (i = j = 0; j < len; i++, j += 4)
+ output[i] = ((UINT4)input[j]) |
+ (((UINT4)input[j+1]) << 8) |
+ (((UINT4)input[j+2]) << 16) |
+ (((UINT4)input[j+3]) << 24);
+}
+
+static int
+md5_init(Sum_t* p)
+{
+ register Md5_t* context = (Md5_t*)p;
+
+ context->count[0] = context->count[1] = 0;
+ context->state[0] = 0x67452301;
+ context->state[1] = 0xefcdab89;
+ context->state[2] = 0x98badcfe;
+ context->state[3] = 0x10325476;
+ return 0;
+}
+
+static Sum_t*
+md5_open(const Method_t* method, const char* name)
+{
+ Md5_t* p;
+
+ if (p = newof(0, Md5_t, 1, 0))
+ {
+ p->method = (Method_t*)method;
+ p->name = name;
+ md5_init((Sum_t*)p);
+ }
+ return (Sum_t*)p;
+}
+
+/*
+ * basic MD5 step -- transforms buf based on in
+ */
+
+#define S11 7
+#define S12 12
+#define S13 17
+#define S14 22
+#define S21 5
+#define S22 9
+#define S23 14
+#define S24 20
+#define S31 4
+#define S32 11
+#define S33 16
+#define S34 23
+#define S41 6
+#define S42 10
+#define S43 15
+#define S44 21
+
+/* F, G, H and I are basic MD5 functions */
+#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
+#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
+#define H(x, y, z) ((x) ^ (y) ^ (z))
+#define I(x, y, z) ((y) ^ ((x) | (~z)))
+
+/* ROTATE_LEFT rotates x left n bits */
+#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
+
+/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4 */
+/* Rotation is separate from addition to prevent recomputation */
+#define FF(a, b, c, d, x, s, ac) { \
+ (a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \
+ (a) = ROTATE_LEFT ((a), (s)); \
+ (a) += (b); \
+ }
+#define GG(a, b, c, d, x, s, ac) { \
+ (a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \
+ (a) = ROTATE_LEFT ((a), (s)); \
+ (a) += (b); \
+ }
+#define HH(a, b, c, d, x, s, ac) { \
+ (a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \
+ (a) = ROTATE_LEFT ((a), (s)); \
+ (a) += (b); \
+ }
+#define II(a, b, c, d, x, s, ac) { \
+ (a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \
+ (a) = ROTATE_LEFT ((a), (s)); \
+ (a) += (b); \
+ }
+
+static void
+md5_transform(UINT4 state[4], unsigned char block[64])
+{
+ UINT4 a = state[0];
+ UINT4 b = state[1];
+ UINT4 c = state[2];
+ UINT4 d = state[3];
+ UINT4 x[16];
+
+ md5_decode(x, block, 64);
+
+ /* round 1 */
+ FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
+ FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
+ FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
+ FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
+ FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
+ FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
+ FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
+ FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
+ FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
+ FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
+ FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
+ FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
+ FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
+ FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
+ FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
+ FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
+
+ /* round 2 */
+ GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
+ GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
+ GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
+ GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
+ GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
+ GG (d, a, b, c, x[10], S22, 0x02441453); /* 22 */
+ GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
+ GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
+ GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
+ GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
+ GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
+ GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
+ GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
+ GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
+ GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
+ GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
+
+ /* round 3 */
+ HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
+ HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
+ HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
+ HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
+ HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
+ HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
+ HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
+ HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
+ HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
+ HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
+ HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
+ HH (b, c, d, a, x[ 6], S34, 0x04881d05); /* 44 */
+ HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
+ HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
+ HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
+ HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
+
+ /* round 4 */
+ II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
+ II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
+ II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
+ II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
+ II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
+ II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
+ II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
+ II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
+ II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
+ II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
+ II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
+ II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
+ II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
+ II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
+ II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
+ II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
+
+ state[0] += a;
+ state[1] += b;
+ state[2] += c;
+ state[3] += d;
+}
+
+static int
+md5_block(Sum_t* p, const void* s, size_t inputLen)
+{
+ register Md5_t* context = (Md5_t*)p;
+ unsigned char* input = (unsigned char*)s;
+ unsigned int i;
+ unsigned int index;
+ unsigned int partLen;
+
+ /* compute number of bytes mod 64 */
+ index = (unsigned int)((context->count[0] >> 3) & 0x3f);
+
+ /* update number of bits */
+ if ((context->count[0] += ((UINT4)inputLen << 3)) < ((UINT4)inputLen << 3))
+ context->count[1]++;
+ context->count[1] += ((UINT4)inputLen >> 29);
+ partLen = 64 - index;
+
+ /* transform as many times as possible */
+ if (inputLen >= partLen)
+ {
+ memcpy(&context->buffer[index], input, partLen);
+ md5_transform(context->state, context->buffer);
+ for (i = partLen; i + 63 < inputLen; i += 64)
+ md5_transform(context->state, &input[i]);
+ index = 0;
+ }
+ else
+ i = 0;
+
+ /* buffer remaining input */
+ memcpy(&context->buffer[index], &input[i], inputLen - i);
+
+ return 0;
+}
+
+static int
+md5_done(Sum_t* p)
+{
+ register Md5_t* context = (Md5_t*)p;
+ unsigned char bits[8];
+ unsigned int index;
+ unsigned int padLen;
+
+ /* save number of bits */
+ md5_encode(bits, context->count, sizeof(bits));
+
+ /* pad out to 56 mod 64 */
+ index = (unsigned int)((context->count[0] >> 3) & 0x3f);
+ padLen = (index < 56) ? (56 - index) : (120 - index);
+ md5_block(p, md5_pad, padLen);
+
+ /* append length (before padding) */
+ md5_block(p, bits, sizeof(bits));
+
+ /* store state in digest */
+ md5_encode(context->digest, context->state, sizeof(context->digest));
+
+ /* accumulate the digests */
+ for (index = 0; index < elementsof(context->digest); index++)
+ context->digest_sum[index] ^= context->digest[index];
+
+ return 0;
+}
+
+static int
+md5_print(Sum_t* p, Sfio_t* sp, register int flags, size_t scale)
+{
+ register Md5_t* x = (Md5_t*)p;
+ register unsigned char* d;
+ register int n;
+
+ d = (flags & SUM_TOTAL) ? x->digest_sum : x->digest;
+ for (n = 0; n < elementsof(x->digest); n++)
+ sfprintf(sp, "%02x", d[n]);
+ return 0;
+}
+
+static int
+md5_data(Sum_t* p, Sumdata_t* data)
+{
+ register Md5_t* x = (Md5_t*)p;
+
+ data->size = elementsof(x->digest);
+ data->num = 0;
+ data->buf = x->digest;
+ return 0;
+}
diff --git a/src/lib/libsum/sum-prng.c b/src/lib/libsum/sum-prng.c
new file mode 100644
index 0000000..8a85e47
--- /dev/null
+++ b/src/lib/libsum/sum-prng.c
@@ -0,0 +1,113 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1996-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+/*
+ * prng
+ */
+
+#include <fnv.h>
+
+#define prng_description \
+ "32 bit PRNG (pseudo random number generator) hash."
+#define prng_options "\
+[+mpy?The 32 bit PRNG multiplier.]:[number:=0x01000193]\
+[+add?The 32 bit PRNG addend.]:[number:=0]\
+[+init?The PRNG initial value. 0xffffffff is used if \anumber\a is omitted.]:?[number:=0x811c9dc5]\
+"
+#define prng_match "prng"
+#define prng_done long_done
+#define prng_print long_print
+#define prng_data long_data
+#define prng_scale 0
+
+typedef uint32_t Prngnum_t;
+
+typedef struct Prng_s
+{
+ _SUM_PUBLIC_
+ _SUM_PRIVATE_
+ _INTEGRAL_PRIVATE_
+ Prngnum_t init;
+ Prngnum_t mpy;
+ Prngnum_t add;
+} Prng_t;
+
+static Sum_t*
+prng_open(const Method_t* method, const char* name)
+{
+ register Prng_t* sum;
+ register const char* s;
+ register const char* t;
+ register const char* v;
+ register int i;
+
+ if (sum = newof(0, Prng_t, 1, 0))
+ {
+ sum->method = (Method_t*)method;
+ sum->name = name;
+ }
+ s = name;
+ while (*(t = s))
+ {
+ for (t = s, v = 0; *s && *s != '-'; s++)
+ if (*s == '=' && !v)
+ v = s;
+ i = (v ? v : s) - t;
+ if (isdigit(*t) || v && strneq(t, "mpy", i) && (t = v + 1))
+ sum->mpy = strtoul(t, NiL, 0);
+ else if (strneq(t, "add", i))
+ sum->add = v ? strtoul(v + 1, NiL, 0) : ~sum->add;
+ else if (strneq(t, "init", i))
+ sum->init = v ? strtoul(v + 1, NiL, 0) : ~sum->init;
+ if (*s == '-')
+ s++;
+ }
+ if (!sum->mpy)
+ {
+ sum->mpy = FNV_MULT;
+ if (!sum->init)
+ sum->init = FNV_INIT;
+ }
+ return (Sum_t*)sum;
+}
+
+static int
+prng_init(Sum_t* p)
+{
+ Prng_t* sum = (Prng_t*)p;
+
+ sum->sum = sum->init;
+ return 0;
+}
+
+static int
+prng_block(Sum_t* p, const void* s, size_t n)
+{
+ Prng_t* sum = (Prng_t*)p;
+ register Prngnum_t c = sum->sum;
+ register unsigned char* b = (unsigned char*)s;
+ register unsigned char* e = b + n;
+
+ while (b < e)
+ c = c * sum->mpy + sum->add + *b++;
+ sum->sum = c;
+ return 0;
+}
diff --git a/src/lib/libsum/sum-sha1.c b/src/lib/libsum/sum-sha1.c
new file mode 100644
index 0000000..76723fd
--- /dev/null
+++ b/src/lib/libsum/sum-sha1.c
@@ -0,0 +1,323 @@
+#pragma prototyped
+
+/*
+ * 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
+ */
+
+#define sha1_description "FIPS 180-1 SHA-1 secure hash algorithm 1."
+#define sha1_options "[+(version)?sha1 (FIPS 180-1) 1996-09-26]\
+ [+(author)?Steve Reid <steve@edmweb.com>]"
+#define sha1_match "sha1|SHA1|sha-1|SHA-1"
+#define sha1_scale 0
+
+#define sha1_padding md5_pad
+
+typedef struct Sha1_s
+{
+ _SUM_PUBLIC_
+ _SUM_PRIVATE_
+ uint32_t count[2];
+ uint32_t state[5];
+ uint8_t buffer[64];
+ uint8_t digest[20];
+ uint8_t digest_sum[20];
+} Sha1_t;
+
+#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 _ast_intswap
+# 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 {
+ unsigned char c[64];
+ unsigned int l[16];
+} CHAR64LONG16;
+
+#ifdef __sparc_v9__
+static void do_R01(uint32_t *a, uint32_t *b, uint32_t *c,
+ uint32_t *d, uint32_t *e, CHAR64LONG16 *);
+static void do_R2(uint32_t *a, uint32_t *b, uint32_t *c,
+ uint32_t *d, uint32_t *e, CHAR64LONG16 *);
+static void do_R3(uint32_t *a, uint32_t *b, uint32_t *c,
+ uint32_t *d, uint32_t *e, CHAR64LONG16 *);
+static void do_R4(uint32_t *a, uint32_t *b, uint32_t *c,
+ uint32_t *d, uint32_t *e, CHAR64LONG16 *);
+
+#define nR0(v,w,x,y,z,i) R0(*v,*w,*x,*y,*z,i)
+#define nR1(v,w,x,y,z,i) R1(*v,*w,*x,*y,*z,i)
+#define nR2(v,w,x,y,z,i) R2(*v,*w,*x,*y,*z,i)
+#define nR3(v,w,x,y,z,i) R3(*v,*w,*x,*y,*z,i)
+#define nR4(v,w,x,y,z,i) R4(*v,*w,*x,*y,*z,i)
+
+static void
+do_R01(uint32_t *a, uint32_t *b, uint32_t *c, uint32_t *d,
+ uint32_t *e, CHAR64LONG16 *block)
+{
+ nR0(a,b,c,d,e, 0); nR0(e,a,b,c,d, 1); nR0(d,e,a,b,c, 2);
+ nR0(c,d,e,a,b, 3); nR0(b,c,d,e,a, 4); nR0(a,b,c,d,e, 5);
+ nR0(e,a,b,c,d, 6); nR0(d,e,a,b,c, 7); nR0(c,d,e,a,b, 8);
+ nR0(b,c,d,e,a, 9); nR0(a,b,c,d,e,10); nR0(e,a,b,c,d,11);
+ nR0(d,e,a,b,c,12); nR0(c,d,e,a,b,13); nR0(b,c,d,e,a,14);
+ nR0(a,b,c,d,e,15); nR1(e,a,b,c,d,16); nR1(d,e,a,b,c,17);
+ nR1(c,d,e,a,b,18); nR1(b,c,d,e,a,19);
+}
+
+static void
+do_R2(uint32_t *a, uint32_t *b, uint32_t *c, uint32_t *d,
+ uint32_t *e, CHAR64LONG16 *block)
+{
+ nR2(a,b,c,d,e,20); nR2(e,a,b,c,d,21); nR2(d,e,a,b,c,22);
+ nR2(c,d,e,a,b,23); nR2(b,c,d,e,a,24); nR2(a,b,c,d,e,25);
+ nR2(e,a,b,c,d,26); nR2(d,e,a,b,c,27); nR2(c,d,e,a,b,28);
+ nR2(b,c,d,e,a,29); nR2(a,b,c,d,e,30); nR2(e,a,b,c,d,31);
+ nR2(d,e,a,b,c,32); nR2(c,d,e,a,b,33); nR2(b,c,d,e,a,34);
+ nR2(a,b,c,d,e,35); nR2(e,a,b,c,d,36); nR2(d,e,a,b,c,37);
+ nR2(c,d,e,a,b,38); nR2(b,c,d,e,a,39);
+}
+
+static void
+do_R3(uint32_t *a, uint32_t *b, uint32_t *c, uint32_t *d,
+ uint32_t *e, CHAR64LONG16 *block)
+{
+ nR3(a,b,c,d,e,40); nR3(e,a,b,c,d,41); nR3(d,e,a,b,c,42);
+ nR3(c,d,e,a,b,43); nR3(b,c,d,e,a,44); nR3(a,b,c,d,e,45);
+ nR3(e,a,b,c,d,46); nR3(d,e,a,b,c,47); nR3(c,d,e,a,b,48);
+ nR3(b,c,d,e,a,49); nR3(a,b,c,d,e,50); nR3(e,a,b,c,d,51);
+ nR3(d,e,a,b,c,52); nR3(c,d,e,a,b,53); nR3(b,c,d,e,a,54);
+ nR3(a,b,c,d,e,55); nR3(e,a,b,c,d,56); nR3(d,e,a,b,c,57);
+ nR3(c,d,e,a,b,58); nR3(b,c,d,e,a,59);
+}
+
+static void
+do_R4(uint32_t *a, uint32_t *b, uint32_t *c, uint32_t *d,
+ uint32_t *e, CHAR64LONG16 *block)
+{
+ nR4(a,b,c,d,e,60); nR4(e,a,b,c,d,61); nR4(d,e,a,b,c,62);
+ nR4(c,d,e,a,b,63); nR4(b,c,d,e,a,64); nR4(a,b,c,d,e,65);
+ nR4(e,a,b,c,d,66); nR4(d,e,a,b,c,67); nR4(c,d,e,a,b,68);
+ nR4(b,c,d,e,a,69); nR4(a,b,c,d,e,70); nR4(e,a,b,c,d,71);
+ nR4(d,e,a,b,c,72); nR4(c,d,e,a,b,73); nR4(b,c,d,e,a,74);
+ nR4(a,b,c,d,e,75); nR4(e,a,b,c,d,76); nR4(d,e,a,b,c,77);
+ nR4(c,d,e,a,b,78); nR4(b,c,d,e,a,79);
+}
+#endif
+
+/*
+ * Hash a single 512-bit block. This is the core of the algorithm.
+ */
+static void
+sha1_transform(uint32_t state[5], const unsigned char buffer[64]) {
+ uint32_t a, b, c, d, e;
+ CHAR64LONG16 *block;
+ CHAR64LONG16 workspace;
+
+ block = &workspace;
+ (void)memcpy(block, buffer, 64);
+
+ /* Copy sha->state[] to working vars */
+ a = state[0];
+ b = state[1];
+ c = state[2];
+ d = state[3];
+ e = state[4];
+
+#ifdef __sparc_v9__
+ do_R01(&a, &b, &c, &d, &e, block);
+ do_R2(&a, &b, &c, &d, &e, block);
+ do_R3(&a, &b, &c, &d, &e, block);
+ do_R4(&a, &b, &c, &d, &e, block);
+#else
+ /* 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);
+#endif
+
+ /* 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;
+}
+
+static int
+sha1_block(register Sum_t* p, const void* s, size_t len)
+{
+ Sha1_t* sha = (Sha1_t*)p;
+ uint8_t* data = (uint8_t*)s;
+ unsigned int i, j;
+
+ if (len) {
+ j = sha->count[0];
+ if ((sha->count[0] += len << 3) < j)
+ sha->count[1] += (len >> 29) + 1;
+ j = (j >> 3) & 63;
+ if ((j + len) > 63) {
+ (void)memcpy(&sha->buffer[j], data, (i = 64 - j));
+ sha1_transform(sha->state, sha->buffer);
+ for ( ; i + 63 < len; i += 64)
+ sha1_transform(sha->state, &data[i]);
+ j = 0;
+ } else {
+ i = 0;
+ }
+
+ (void)memcpy(&sha->buffer[j], &data[i], len - i);
+ }
+ return 0;
+}
+
+static int
+sha1_init(Sum_t* p)
+{
+ register Sha1_t* sha = (Sha1_t*)p;
+
+ sha->count[0] = sha->count[1] = 0;
+ sha->state[0] = 0x67452301;
+ sha->state[1] = 0xEFCDAB89;
+ sha->state[2] = 0x98BADCFE;
+ sha->state[3] = 0x10325476;
+ sha->state[4] = 0xC3D2E1F0;
+
+ return 0;
+}
+
+static Sum_t*
+sha1_open(const Method_t* method, const char* name)
+{
+ Sha1_t* sha;
+
+ if (sha = newof(0, Sha1_t, 1, 0))
+ {
+ sha->method = (Method_t*)method;
+ sha->name = name;
+ sha1_init((Sum_t*)sha);
+ }
+ return (Sum_t*)sha;
+}
+
+/*
+ * Add padding and return the message digest.
+ */
+
+static const unsigned char final_200 = 128;
+static const unsigned char final_0 = 0;
+
+static int
+sha1_done(Sum_t* p)
+{
+ Sha1_t* sha = (Sha1_t*)p;
+ unsigned int i;
+ unsigned char finalcount[8];
+
+ for (i = 0; i < 8; i++) {
+ /* Endian independent */
+ finalcount[i] = (unsigned char)
+ ((sha->count[(i >= 4 ? 0 : 1)]
+ >> ((3 - (i & 3)) * 8)) & 255);
+ }
+
+ sha1_block(p, &final_200, 1);
+ while ((sha->count[0] & 504) != 448)
+ sha1_block(p, &final_0, 1);
+ /* The next Update should cause a sha1_transform() */
+ sha1_block(p, finalcount, 8);
+
+ for (i = 0; i < elementsof(sha->digest); i++)
+ {
+ sha->digest[i] = (unsigned char)((sha->state[i >> 2] >> ((3 - (i & 3)) * 8)) & 255);
+ sha->digest_sum[i] ^= sha->digest[i];
+ }
+ memset(sha->count, 0, sizeof(sha->count));
+ memset(sha->state, 0, sizeof(sha->state));
+ memset(sha->buffer, 0, sizeof(sha->buffer));
+ return 0;
+}
+
+static int
+sha1_print(Sum_t* p, Sfio_t* sp, register int flags, size_t scale)
+{
+ register Sha1_t* sha = (Sha1_t*)p;
+ register unsigned char* d;
+ register int n;
+
+ d = (flags & SUM_TOTAL) ? sha->digest_sum : sha->digest;
+ for (n = 0; n < elementsof(sha->digest); n++)
+ sfprintf(sp, "%02x", d[n]);
+ return 0;
+}
+
+static int
+sha1_data(Sum_t* p, Sumdata_t* data)
+{
+ register Sha1_t* sha = (Sha1_t*)p;
+
+ data->size = elementsof(sha->digest);
+ data->num = 0;
+ data->buf = sha->digest;
+ return 0;
+}
diff --git a/src/lib/libsum/sum-sha2.c b/src/lib/libsum/sum-sha2.c
new file mode 100644
index 0000000..9dd52e7
--- /dev/null
+++ b/src/lib/libsum/sum-sha2.c
@@ -0,0 +1,1229 @@
+#pragma prototyped
+
+#if _typ_int64_t
+
+/*
+ * Aaron D. Gifford's SHA {256,384,512} code transcribed into a -lsum method
+ * with bitcount[] order reversed to allow a single noalias buffer copy
+ */
+
+/*
+ * 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.
+ */
+
+/*
+ * 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 *****************/
+
+#if _PACKAGE_ast
+
+#ifndef __USE_BSD
+#define __undef__USE_BSD
+#define __USE_BSD
+#endif
+#include <endian.h>
+#ifdef __undef__USE_BSD
+#undef __undef__USE_BSD
+#undef __USE_BSD
+#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 */
+
+#define assert(x)
+
+#undef R
+#undef S32
+#undef S64
+
+#else /* _PACKAGE_ast */
+
+/*
+ * 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
+ * equivilent.
+ *
+ * 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
+
+/*
+ * Define the following sha2_* types to types of the correct length on
+ * the native archtecture. Most BSD systems and Linux define u_intXX_t
+ * types. Machines with very recent ANSI C headers, can use the
+ * uintXX_t definintions from inttypes.h by defining SHA2_USE_INTTYPES_H
+ * during compile or in the sha.h header file.
+ *
+ * Machines that support neither u_intXX_t nor inttypes.h's uintXX_t
+ * will need to define these three typedefs below (and the appropriate
+ * ones in sha.h too) by hand according to their system architecture.
+ *
+ * Thank you, Jun-ichiro itojun Hagino, for suggesting using u_intXX_t
+ * types and pointing out recent ANSI C support for uintXX_t in inttypes.h.
+ */
+
+#ifdef SHA2_USE_INTTYPES_H
+
+typedef uint8_t sha2_byte; /* Exactly 1 byte */
+typedef uint32_t sha2_word32; /* Exactly 4 bytes */
+typedef uint64_t sha2_word64; /* Exactly 8 bytes */
+
+#else /* SHA2_USE_INTTYPES_H */
+
+typedef u_int8_t sha2_byte; /* Exactly 1 byte */
+typedef u_int32_t sha2_word32; /* Exactly 4 bytes */
+typedef u_int64_t sha2_word64; /* Exactly 8 bytes */
+
+#endif /* SHA2_USE_INTTYPES_H */
+
+#endif /* _PACKAGE_ast */
+
+/*** SHA-256/384/512 Various Length Definitions ***********************/
+
+#define SHA256_BLOCK_LENGTH 64
+#define SHA256_DIGEST_LENGTH 32
+#define SHA384_BLOCK_LENGTH 128
+#define SHA384_DIGEST_LENGTH 48
+#define SHA512_BLOCK_LENGTH 128
+#define SHA512_DIGEST_LENGTH 64
+
+#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 *******************************************/
+#if BYTE_ORDER == LITTLE_ENDIAN
+#define REVERSE32(w,x) { \
+ sha2_word32 tmp = (w); \
+ tmp = (tmp >> 16) | (tmp << 16); \
+ (x) = ((tmp & 0xff00ff00UL) >> 8) | ((tmp & 0x00ff00ffUL) << 8); \
+}
+#if _ast_LL
+#define REVERSE64(w,x) { \
+ sha2_word64 tmp = (w); \
+ tmp = (tmp >> 32) | (tmp << 32); \
+ tmp = ((tmp & 0xff00ff00ff00ff00ULL) >> 8) | \
+ ((tmp & 0x00ff00ff00ff00ffULL) << 8); \
+ (x) = ((tmp & 0xffff0000ffff0000ULL) >> 16) | \
+ ((tmp & 0x0000ffff0000ffffULL) << 16); \
+}
+#else
+#define REVERSE64(w,x) { \
+ sha2_word64 tmp = (w); \
+ tmp = (tmp >> 32) | (tmp << 32); \
+ tmp = ((tmp & ((sha2_word64)0xff00ff00ff00ff00)) >> 8) | \
+ ((tmp & ((sha2_word64)0x00ff00ff00ff00ff)) << 8); \
+ (x) = ((tmp & ((sha2_word64)0xffff0000ffff0000)) >> 16) | \
+ ((tmp & ((sha2_word64)0x0000ffff0000ffff)) << 16); \
+}
+#endif
+#endif /* BYTE_ORDER == LITTLE_ENDIAN */
+
+/*
+ * 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)[1] += (sha2_word64)(n); \
+ if ((w)[1] < (n)) { \
+ (w)[0]++; \
+ } \
+}
+
+/*
+ * 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) && !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) && 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
+
+
+/*** 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) >> (b))
+/* 32-bit Rotate-right (used in 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-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-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-256: */
+static const 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: */
+static const 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: */
+static const sha2_word64 K512[80] = {
+#if _ast_LL
+ 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
+#else
+ ((sha2_word64)0x428a2f98d728ae22), ((sha2_word64)0x7137449123ef65cd),
+ ((sha2_word64)0xb5c0fbcfec4d3b2f), ((sha2_word64)0xe9b5dba58189dbbc),
+ ((sha2_word64)0x3956c25bf348b538), ((sha2_word64)0x59f111f1b605d019),
+ ((sha2_word64)0x923f82a4af194f9b), ((sha2_word64)0xab1c5ed5da6d8118),
+ ((sha2_word64)0xd807aa98a3030242), ((sha2_word64)0x12835b0145706fbe),
+ ((sha2_word64)0x243185be4ee4b28c), ((sha2_word64)0x550c7dc3d5ffb4e2),
+ ((sha2_word64)0x72be5d74f27b896f), ((sha2_word64)0x80deb1fe3b1696b1),
+ ((sha2_word64)0x9bdc06a725c71235), ((sha2_word64)0xc19bf174cf692694),
+ ((sha2_word64)0xe49b69c19ef14ad2), ((sha2_word64)0xefbe4786384f25e3),
+ ((sha2_word64)0x0fc19dc68b8cd5b5), ((sha2_word64)0x240ca1cc77ac9c65),
+ ((sha2_word64)0x2de92c6f592b0275), ((sha2_word64)0x4a7484aa6ea6e483),
+ ((sha2_word64)0x5cb0a9dcbd41fbd4), ((sha2_word64)0x76f988da831153b5),
+ ((sha2_word64)0x983e5152ee66dfab), ((sha2_word64)0xa831c66d2db43210),
+ ((sha2_word64)0xb00327c898fb213f), ((sha2_word64)0xbf597fc7beef0ee4),
+ ((sha2_word64)0xc6e00bf33da88fc2), ((sha2_word64)0xd5a79147930aa725),
+ ((sha2_word64)0x06ca6351e003826f), ((sha2_word64)0x142929670a0e6e70),
+ ((sha2_word64)0x27b70a8546d22ffc), ((sha2_word64)0x2e1b21385c26c926),
+ ((sha2_word64)0x4d2c6dfc5ac42aed), ((sha2_word64)0x53380d139d95b3df),
+ ((sha2_word64)0x650a73548baf63de), ((sha2_word64)0x766a0abb3c77b2a8),
+ ((sha2_word64)0x81c2c92e47edaee6), ((sha2_word64)0x92722c851482353b),
+ ((sha2_word64)0xa2bfe8a14cf10364), ((sha2_word64)0xa81a664bbc423001),
+ ((sha2_word64)0xc24b8b70d0f89791), ((sha2_word64)0xc76c51a30654be30),
+ ((sha2_word64)0xd192e819d6ef5218), ((sha2_word64)0xd69906245565a910),
+ ((sha2_word64)0xf40e35855771202a), ((sha2_word64)0x106aa07032bbd1b8),
+ ((sha2_word64)0x19a4c116b8d2d0c8), ((sha2_word64)0x1e376c085141ab53),
+ ((sha2_word64)0x2748774cdf8eeb99), ((sha2_word64)0x34b0bcb5e19b48a8),
+ ((sha2_word64)0x391c0cb3c5c95a63), ((sha2_word64)0x4ed8aa4ae3418acb),
+ ((sha2_word64)0x5b9cca4f7763e373), ((sha2_word64)0x682e6ff3d6b2b8a3),
+ ((sha2_word64)0x748f82ee5defb2fc), ((sha2_word64)0x78a5636f43172f60),
+ ((sha2_word64)0x84c87814a1f0ab72), ((sha2_word64)0x8cc702081a6439ec),
+ ((sha2_word64)0x90befffa23631e28), ((sha2_word64)0xa4506cebde82bde9),
+ ((sha2_word64)0xbef9a3f7b2c67915), ((sha2_word64)0xc67178f2e372532b),
+ ((sha2_word64)0xca273eceea26619c), ((sha2_word64)0xd186b8c721c0c207),
+ ((sha2_word64)0xeada7dd6cde0eb1e), ((sha2_word64)0xf57d4f7fee6ed178),
+ ((sha2_word64)0x06f067aa72176fba), ((sha2_word64)0x0a637dc5a2c898a6),
+ ((sha2_word64)0x113f9804bef90dae), ((sha2_word64)0x1b710b35131c471b),
+ ((sha2_word64)0x28db77f523047d84), ((sha2_word64)0x32caab7b40c72493),
+ ((sha2_word64)0x3c9ebe0a15c9bebc), ((sha2_word64)0x431d67c49c100d4c),
+ ((sha2_word64)0x4cc5d4becb3e42b6), ((sha2_word64)0x597f299cfc657e2a),
+ ((sha2_word64)0x5fcb6fab3ad6faec), ((sha2_word64)0x6c44198c4a475817)
+#endif
+};
+
+/* Initial hash value H for SHA-384 */
+static const sha2_word64 sha384_initial_hash_value[8] = {
+#if _ast_LL
+ 0xcbbb9d5dc1059ed8ULL,
+ 0x629a292a367cd507ULL,
+ 0x9159015a3070dd17ULL,
+ 0x152fecd8f70e5939ULL,
+ 0x67332667ffc00b31ULL,
+ 0x8eb44a8768581511ULL,
+ 0xdb0c2e0d64f98fa7ULL,
+ 0x47b5481dbefa4fa4ULL
+#else
+ ((sha2_word64)0xcbbb9d5dc1059ed8),
+ ((sha2_word64)0x629a292a367cd507),
+ ((sha2_word64)0x9159015a3070dd17),
+ ((sha2_word64)0x152fecd8f70e5939),
+ ((sha2_word64)0x67332667ffc00b31),
+ ((sha2_word64)0x8eb44a8768581511),
+ ((sha2_word64)0xdb0c2e0d64f98fa7),
+ ((sha2_word64)0x47b5481dbefa4fa4)
+#endif
+};
+
+/* Initial hash value H for SHA-512 */
+static const sha2_word64 sha512_initial_hash_value[8] = {
+#if _ast_LL
+ 0x6a09e667f3bcc908ULL,
+ 0xbb67ae8584caa73bULL,
+ 0x3c6ef372fe94f82bULL,
+ 0xa54ff53a5f1d36f1ULL,
+ 0x510e527fade682d1ULL,
+ 0x9b05688c2b3e6c1fULL,
+ 0x1f83d9abfb41bd6bULL,
+ 0x5be0cd19137e2179ULL
+#else
+ ((sha2_word64)0x6a09e667f3bcc908),
+ ((sha2_word64)0xbb67ae8584caa73b),
+ ((sha2_word64)0x3c6ef372fe94f82b),
+ ((sha2_word64)0xa54ff53a5f1d36f1),
+ ((sha2_word64)0x510e527fade682d1),
+ ((sha2_word64)0x9b05688c2b3e6c1f),
+ ((sha2_word64)0x1f83d9abfb41bd6b),
+ ((sha2_word64)0x5be0cd19137e2179)
+#endif
+};
+
+/*** SHA-256: *********************************************************/
+
+#define sha256_description "FIPS SHA-256 secure hash algorithm."
+#define sha256_options "\
+[+(version)?sha-256 (FIPS) 2000-01-01]\
+[+(author)?Aaron D. Gifford]\
+"
+#define sha256_match "sha256|sha-256|SHA256|SHA-256"
+#define sha256_scale 0
+
+#define sha256_padding md5_pad
+
+#define SHA256_CTX Sha256_t
+
+typedef struct Sha256_s
+{
+ _SUM_PUBLIC_
+ _SUM_PRIVATE_
+ sha2_byte digest[SHA256_DIGEST_LENGTH];
+ sha2_byte digest_sum[SHA256_DIGEST_LENGTH];
+ sha2_word32 state[8];
+ sha2_word64 bitcount;
+ sha2_byte buffer[SHA256_BLOCK_LENGTH];
+} Sha256_t;
+
+#ifdef SHA2_UNROLL_TRANSFORM
+
+/* Unrolled SHA-256 round macros: */
+
+#if BYTE_ORDER == LITTLE_ENDIAN
+
+#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 /* BYTE_ORDER == LITTLE_ENDIAN */
+
+#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 /* BYTE_ORDER == LITTLE_ENDIAN */
+
+#define ROUND256(a,b,c,d,e,f,g,h) \
+ 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++
+
+static void SHA256_Transform(SHA256_CTX* sha, 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*)sha->buffer;
+
+ /* Initialize registers with the prev. intermediate value */
+ a = sha->state[0];
+ b = sha->state[1];
+ c = sha->state[2];
+ d = sha->state[3];
+ e = sha->state[4];
+ f = sha->state[5];
+ g = sha->state[6];
+ h = sha->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 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 < 64);
+
+ /* Compute the current intermediate hash value */
+ sha->state[0] += a;
+ sha->state[1] += b;
+ sha->state[2] += c;
+ sha->state[3] += d;
+ sha->state[4] += e;
+ sha->state[5] += f;
+ sha->state[6] += g;
+ sha->state[7] += h;
+
+ /* Clean up */
+ a = b = c = d = e = f = g = h = T1 = 0;
+}
+
+#else /* SHA2_UNROLL_TRANSFORM */
+
+static void SHA256_Transform(SHA256_CTX* sha, 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*)sha->buffer;
+
+ /* Initialize registers with the prev. intermediate value */
+ a = sha->state[0];
+ b = sha->state[1];
+ c = sha->state[2];
+ d = sha->state[3];
+ e = sha->state[4];
+ f = sha->state[5];
+ g = sha->state[6];
+ h = sha->state[7];
+
+ j = 0;
+ do {
+#if BYTE_ORDER == LITTLE_ENDIAN
+ /* 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 /* BYTE_ORDER == LITTLE_ENDIAN */
+ /* 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 /* BYTE_ORDER == LITTLE_ENDIAN */
+ 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 */
+ sha->state[0] += a;
+ sha->state[1] += b;
+ sha->state[2] += c;
+ sha->state[3] += d;
+ sha->state[4] += e;
+ sha->state[5] += f;
+ sha->state[6] += g;
+ sha->state[7] += h;
+
+ /* Clean up */
+ a = b = c = d = e = f = g = h = T1 = T2 = 0;
+}
+
+#endif /* SHA2_UNROLL_TRANSFORM */
+
+static int
+sha256_block(register Sum_t* p, const void* s, size_t len)
+{
+ Sha256_t* sha = (Sha256_t*)p;
+ sha2_byte* data = (sha2_byte*)s;
+ unsigned int freespace, usedspace;
+
+ if (!len)
+ return 0;
+ usedspace = (sha->bitcount >> 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_BCOPY(&sha->buffer[usedspace], data, freespace);
+ sha->bitcount += freespace << 3;
+ len -= freespace;
+ data += freespace;
+ SHA256_Transform(sha, (sha2_word32*)sha->buffer);
+ } else {
+ /* The buffer is not yet full */
+ MEMCPY_BCOPY(&sha->buffer[usedspace], data, len);
+ sha->bitcount += len << 3;
+ /* Clean up: */
+ usedspace = freespace = 0;
+ return 0;
+ }
+ }
+ while (len >= SHA256_BLOCK_LENGTH) {
+ /* Process as many complete blocks as we can */
+ SHA256_Transform(sha, (sha2_word32*)data);
+ sha->bitcount += SHA256_BLOCK_LENGTH << 3;
+ len -= SHA256_BLOCK_LENGTH;
+ data += SHA256_BLOCK_LENGTH;
+ }
+ if (len > 0) {
+ /* There's left-overs, so save 'em */
+ MEMCPY_BCOPY(sha->buffer, data, len);
+ sha->bitcount += len << 3;
+ }
+ /* Clean up: */
+ usedspace = freespace = 0;
+
+ return 0;
+}
+
+static int
+sha256_init(Sum_t* p)
+{
+ register Sha256_t* sha = (Sha256_t*)p;
+
+ MEMCPY_BCOPY(sha->state, sha256_initial_hash_value, SHA256_DIGEST_LENGTH);
+ MEMSET_BZERO(sha->buffer, SHA256_BLOCK_LENGTH);
+ sha->bitcount = 0;
+
+ return 0;
+}
+
+static Sum_t*
+sha256_open(const Method_t* method, const char* name)
+{
+ Sha256_t* sha;
+
+ if (sha = newof(0, Sha256_t, 1, 0))
+ {
+ sha->method = (Method_t*)method;
+ sha->name = name;
+ sha256_init((Sum_t*)sha);
+ }
+ return (Sum_t*)sha;
+}
+
+static int
+sha256_done(Sum_t* p)
+{
+ Sha256_t* sha = (Sha256_t*)p;
+ unsigned int usedspace;
+ register int i;
+
+ /* Sanity check: */
+ assert(sha != (SHA256_CTX*)0);
+
+ usedspace = (sha->bitcount >> 3) % SHA256_BLOCK_LENGTH;
+#if BYTE_ORDER == LITTLE_ENDIAN
+ /* Convert FROM host byte order */
+ REVERSE64(sha->bitcount,sha->bitcount);
+#endif
+ if (usedspace > 0) {
+ /* Begin padding with a 1 bit: */
+ sha->buffer[usedspace++] = 0x80;
+
+ if (usedspace <= SHA256_SHORT_BLOCK_LENGTH) {
+ /* Set-up for the last transform: */
+ MEMSET_BZERO(&sha->buffer[usedspace], SHA256_SHORT_BLOCK_LENGTH - usedspace);
+ } else {
+ if (usedspace < SHA256_BLOCK_LENGTH) {
+ MEMSET_BZERO(&sha->buffer[usedspace], SHA256_BLOCK_LENGTH - usedspace);
+ }
+ /* Do second-to-last transform: */
+ SHA256_Transform(sha, (sha2_word32*)sha->buffer);
+
+ /* And set-up for the last transform: */
+ MEMSET_BZERO(sha->buffer, SHA256_SHORT_BLOCK_LENGTH);
+ }
+ } else {
+ /* Set-up for the last transform: */
+ MEMSET_BZERO(sha->buffer, SHA256_SHORT_BLOCK_LENGTH);
+
+ /* Begin padding with a 1 bit: */
+ *sha->buffer = 0x80;
+ }
+ /* Store the length of input data (in bits): */
+ MEMCPY_BCOPY(&sha->buffer[SHA256_SHORT_BLOCK_LENGTH], &sha->bitcount, 8);
+
+ /* Final transform: */
+ SHA256_Transform(sha, (sha2_word32*)sha->buffer);
+
+#if BYTE_ORDER == LITTLE_ENDIAN
+ {
+ /* Convert TO host byte order */
+ int j;
+ sha2_word32* d = (sha2_word32*)sha->digest;
+ for (j = 0; j < 8; j++) {
+ REVERSE32(sha->state[j],sha->state[j]);
+ *d++ = sha->state[j];
+ }
+ }
+#else
+ MEMCPY_BCOPY(sha->digest, sha->state, SHA256_DIGEST_LENGTH);
+#endif
+
+ /* accumulate the digests */
+ for (i = 0; i < SHA256_DIGEST_LENGTH; i++)
+ sha->digest_sum[i] ^= sha->digest[i];
+
+ /* Clean up state data: */
+ MEMSET_BZERO(&sha->state, sizeof(*sha) - offsetof(Sha256_t, state));
+ usedspace = 0;
+
+ return 0;
+}
+
+static int
+sha256_print(Sum_t* p, Sfio_t* sp, register int flags, size_t scale)
+{
+ register Sha256_t* sha = (Sha256_t*)p;
+ register sha2_byte* d;
+ register sha2_byte* e;
+
+ d = (flags & SUM_TOTAL) ? sha->digest_sum : sha->digest;
+ e = d + SHA256_DIGEST_LENGTH;
+ while (d < e)
+ sfprintf(sp, "%02x", *d++);
+ return 0;
+}
+
+static int
+sha256_data(Sum_t* p, Sumdata_t* data)
+{
+ register Sha256_t* sha = (Sha256_t*)p;
+
+ data->size = SHA256_DIGEST_LENGTH;
+ data->num = 0;
+ data->buf = sha->digest;
+ return 0;
+}
+
+/*** SHA-512: *********************************************************/
+
+#define sha512_description "FIPS SHA-512 secure hash algorithm."
+#define sha512_options "\
+[+(version)?sha-512 (FIPS) 2000-01-01]\
+[+(author)?Aaron D. Gifford]\
+"
+#define sha512_match "sha512|sha-512|SHA512|SHA-512"
+#define sha512_scale 0
+
+#define sha512_padding md5_pad
+
+#define SHA512_CTX Sha512_t
+
+typedef struct Sha512_s
+{
+ _SUM_PUBLIC_
+ _SUM_PRIVATE_
+ sha2_byte digest[SHA512_DIGEST_LENGTH];
+ sha2_byte digest_sum[SHA512_DIGEST_LENGTH];
+ sha2_word64 state[8];
+ sha2_word64 bitcount[2];
+ sha2_byte buffer[SHA512_BLOCK_LENGTH];
+} Sha512_t;
+
+#ifdef SHA2_UNROLL_TRANSFORM
+
+/* Unrolled SHA-512 round macros: */
+#if BYTE_ORDER == LITTLE_ENDIAN
+
+#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 /* BYTE_ORDER == LITTLE_ENDIAN */
+
+#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 /* BYTE_ORDER == LITTLE_ENDIAN */
+
+#define ROUND512(a,b,c,d,e,f,g,h) \
+ 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++
+
+static void SHA512_Transform(SHA512_CTX* sha, const sha2_word64* data) {
+ sha2_word64 a, b, c, d, e, f, g, h, s0, s1;
+ sha2_word64 T1, *W512 = (sha2_word64*)sha->buffer;
+ int j;
+
+ /* Initialize registers with the prev. intermediate value */
+ a = sha->state[0];
+ b = sha->state[1];
+ c = sha->state[2];
+ d = sha->state[3];
+ e = sha->state[4];
+ f = sha->state[5];
+ g = sha->state[6];
+ h = sha->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 < 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 */
+ sha->state[0] += a;
+ sha->state[1] += b;
+ sha->state[2] += c;
+ sha->state[3] += d;
+ sha->state[4] += e;
+ sha->state[5] += f;
+ sha->state[6] += g;
+ sha->state[7] += h;
+
+ /* Clean up */
+ a = b = c = d = e = f = g = h = T1 = 0;
+}
+
+#else /* SHA2_UNROLL_TRANSFORM */
+
+static void SHA512_Transform(SHA512_CTX* sha, const sha2_word64* data) {
+ sha2_word64 a, b, c, d, e, f, g, h, s0, s1;
+ sha2_word64 T1, T2, *W512 = (sha2_word64*)sha->buffer;
+ int j;
+
+ /* Initialize registers with the prev. intermediate value */
+ a = sha->state[0];
+ b = sha->state[1];
+ c = sha->state[2];
+ d = sha->state[3];
+ e = sha->state[4];
+ f = sha->state[5];
+ g = sha->state[6];
+ h = sha->state[7];
+
+ j = 0;
+ do {
+#if BYTE_ORDER == LITTLE_ENDIAN
+ /* 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 /* BYTE_ORDER == LITTLE_ENDIAN */
+ /* 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 /* BYTE_ORDER == LITTLE_ENDIAN */
+ 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 */
+ sha->state[0] += a;
+ sha->state[1] += b;
+ sha->state[2] += c;
+ sha->state[3] += d;
+ sha->state[4] += e;
+ sha->state[5] += f;
+ sha->state[6] += g;
+ sha->state[7] += h;
+
+ /* Clean up */
+ a = b = c = d = e = f = g = h = T1 = T2 = 0;
+}
+
+#endif /* SHA2_UNROLL_TRANSFORM */
+
+static int
+sha512_block(register Sum_t* p, const void* s, size_t len)
+{
+ Sha512_t* sha = (Sha512_t*)p;
+ sha2_byte* data = (sha2_byte*)s;
+ unsigned int freespace, usedspace;
+
+ if (!len)
+ return 0;
+ usedspace = (sha->bitcount[1] >> 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_BCOPY(&sha->buffer[usedspace], data, freespace);
+ ADDINC128(sha->bitcount, freespace << 3);
+ len -= freespace;
+ data += freespace;
+ SHA512_Transform(sha, (sha2_word64*)sha->buffer);
+ } else {
+ /* The buffer is not yet full */
+ MEMCPY_BCOPY(&sha->buffer[usedspace], data, len);
+ ADDINC128(sha->bitcount, len << 3);
+ /* Clean up: */
+ usedspace = freespace = 0;
+ return 0;
+ }
+ }
+ while (len >= SHA512_BLOCK_LENGTH) {
+ /* Process as many complete blocks as we can */
+ SHA512_Transform(sha, (sha2_word64*)data);
+ ADDINC128(sha->bitcount, SHA512_BLOCK_LENGTH << 3);
+ len -= SHA512_BLOCK_LENGTH;
+ data += SHA512_BLOCK_LENGTH;
+ }
+ if (len > 0) {
+ /* There's left-overs, so save 'em */
+ MEMCPY_BCOPY(sha->buffer, data, len);
+ ADDINC128(sha->bitcount, len << 3);
+ }
+ /* Clean up: */
+ usedspace = freespace = 0;
+
+ return 0;
+}
+
+static int
+sha512_init(Sum_t* p)
+{
+ register Sha512_t* sha = (Sha512_t*)p;
+
+ MEMCPY_BCOPY(sha->state, sha512_initial_hash_value, SHA512_DIGEST_LENGTH);
+ MEMSET_BZERO(sha->buffer, SHA512_BLOCK_LENGTH);
+ sha->bitcount[0] = sha->bitcount[1] = 0;
+
+ return 0;
+}
+
+static Sum_t*
+sha512_open(const Method_t* method, const char* name)
+{
+ Sha512_t* sha;
+
+ if (sha = newof(0, Sha512_t, 1, 0))
+ {
+ sha->method = (Method_t*)method;
+ sha->name = name;
+ sha512_init((Sum_t*)sha);
+ }
+ return (Sum_t*)sha;
+}
+
+static int
+sha512_done(Sum_t* p)
+{
+ Sha512_t* sha = (Sha512_t*)p;
+ unsigned int usedspace;
+ register int i;
+
+ usedspace = (sha->bitcount[1] >> 3) % SHA512_BLOCK_LENGTH;
+#if BYTE_ORDER == LITTLE_ENDIAN
+ /* Convert FROM host byte order */
+ REVERSE64(sha->bitcount[0],sha->bitcount[0]);
+ REVERSE64(sha->bitcount[1],sha->bitcount[1]);
+#endif
+ if (usedspace > 0) {
+ /* Begin padding with a 1 bit: */
+ sha->buffer[usedspace++] = 0x80;
+
+ if (usedspace <= SHA512_SHORT_BLOCK_LENGTH) {
+ /* Set-up for the last transform: */
+ MEMSET_BZERO(&sha->buffer[usedspace], SHA512_SHORT_BLOCK_LENGTH - usedspace);
+ } else {
+ if (usedspace < SHA512_BLOCK_LENGTH) {
+ MEMSET_BZERO(&sha->buffer[usedspace], SHA512_BLOCK_LENGTH - usedspace);
+ }
+ /* Do second-to-last transform: */
+ SHA512_Transform(sha, (sha2_word64*)sha->buffer);
+
+ /* And set-up for the last transform: */
+ MEMSET_BZERO(sha->buffer, SHA512_BLOCK_LENGTH - 2);
+ }
+ } else {
+ /* Prepare for final transform: */
+ MEMSET_BZERO(sha->buffer, SHA512_SHORT_BLOCK_LENGTH);
+
+ /* Begin padding with a 1 bit: */
+ *sha->buffer = 0x80;
+ }
+ /* Store the length of input data (in bits): */
+ MEMCPY_BCOPY(&sha->buffer[SHA512_SHORT_BLOCK_LENGTH], &sha->bitcount[0], 16);
+
+ /* Final transform: */
+ SHA512_Transform(sha, (sha2_word64*)sha->buffer);
+
+#if BYTE_ORDER == LITTLE_ENDIAN
+ {
+ /* Convert TO host byte order */
+ sha2_word64* d = (sha2_word64*)sha->digest;
+ int j;
+ for (j = 0; j < 8; j++) {
+ REVERSE64(sha->state[j],sha->state[j]);
+ *d++ = sha->state[j];
+ }
+ }
+#else
+ MEMCPY_BCOPY(sha->digest, sha->state, SHA512_DIGEST_LENGTH);
+#endif
+
+ /* accumulate the digests */
+ for (i = 0; i < SHA512_DIGEST_LENGTH; i++)
+ sha->digest_sum[i] ^= sha->digest[i];
+
+ /* Clean up state data: */
+ MEMSET_BZERO(&sha->state, sizeof(*sha) - offsetof(Sha512_t, state));
+ usedspace = 0;
+
+ return 0;
+}
+
+static int
+sha512_print(Sum_t* p, Sfio_t* sp, register int flags, size_t scale)
+{
+ register Sha512_t* sha = (Sha512_t*)p;
+ register sha2_byte* d;
+ register sha2_byte* e;
+
+ d = (flags & SUM_TOTAL) ? sha->digest_sum : sha->digest;
+ e = d + SHA512_DIGEST_LENGTH;
+ while (d < e)
+ sfprintf(sp, "%02x", *d++);
+ return 0;
+}
+
+static int
+sha512_data(Sum_t* p, Sumdata_t* data)
+{
+ register Sha512_t* sha = (Sha512_t*)p;
+
+ data->size = SHA512_DIGEST_LENGTH;
+ data->num = 0;
+ data->buf = sha->digest;
+ return 0;
+}
+
+/*** SHA-384: *********************************************************/
+
+#define sha384_description "FIPS SHA-384 secure hash algorithm."
+#define sha384_options "\
+[+(version)?sha-384 (FIPS) 2000-01-01]\
+[+(author)?Aaron D. Gifford]\
+"
+#define sha384_match "sha384|sha-384|SHA384|SHA-384"
+#define sha384_scale 0
+#define sha384_block sha512_block
+#define sha384_done sha512_done
+
+#define sha384_padding md5_pad
+
+#define Sha384_t Sha512_t
+#define SHA384_CTX Sha384_t
+#define SHA384_DIGEST_LENGTH 48
+
+static int
+sha384_init(Sum_t* p)
+{
+ register Sha384_t* sha = (Sha384_t*)p;
+
+ MEMCPY_BCOPY(sha->state, sha384_initial_hash_value, SHA512_DIGEST_LENGTH);
+ MEMSET_BZERO(sha->buffer, SHA384_BLOCK_LENGTH);
+ sha->bitcount[0] = sha->bitcount[1] = 0;
+
+ return 0;
+}
+
+static Sum_t*
+sha384_open(const Method_t* method, const char* name)
+{
+ Sha384_t* sha;
+
+ if (sha = newof(0, Sha384_t, 1, 0))
+ {
+ sha->method = (Method_t*)method;
+ sha->name = name;
+ sha384_init((Sum_t*)sha);
+ }
+ return (Sum_t*)sha;
+}
+
+static int
+sha384_print(Sum_t* p, Sfio_t* sp, register int flags, size_t scale)
+{
+ register Sha384_t* sha = (Sha384_t*)p;
+ register sha2_byte* d;
+ register sha2_byte* e;
+
+ d = (flags & SUM_TOTAL) ? sha->digest_sum : sha->digest;
+ e = d + SHA384_DIGEST_LENGTH;
+ while (d < e)
+ sfprintf(sp, "%02x", *d++);
+ return 0;
+}
+
+static int
+sha384_data(Sum_t* p, Sumdata_t* data)
+{
+ register Sha384_t* sha = (Sha384_t*)p;
+
+ data->size = SHA384_DIGEST_LENGTH;
+ data->num = 0;
+ data->buf = sha->digest;
+ return 0;
+}
+
+#endif /* _typ_int64_t */
diff --git a/src/lib/libsum/sum.h b/src/lib/libsum/sum.h
new file mode 100644
index 0000000..af8ba60
--- /dev/null
+++ b/src/lib/libsum/sum.h
@@ -0,0 +1,65 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1996-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+/*
+ * Glenn Fowler
+ * AT&T Research
+ *
+ * checksum library interface
+ */
+
+#ifndef _SUM_H
+#define _SUM_H
+
+#include <ast.h>
+
+#define SUM_SIZE (1<<0) /* print size too */
+#define SUM_SCALE (1<<1) /* traditional size scale */
+#define SUM_TOTAL (1<<2) /* print totals since sumopen */
+#define SUM_LEGACY (1<<3) /* legacy field widths */
+
+#define _SUM_PUBLIC_ const char* name;
+
+typedef struct Sumdata_s
+{
+ uint32_t size;
+ uint32_t num;
+ void* buf;
+} Sumdata_t;
+
+typedef struct Sum_s
+{
+ _SUM_PUBLIC_
+#ifdef _SUM_PRIVATE_
+ _SUM_PRIVATE_
+#endif
+} Sum_t;
+
+extern Sum_t* sumopen(const char*);
+extern int suminit(Sum_t*);
+extern int sumblock(Sum_t*, const void*, size_t);
+extern int sumdone(Sum_t*);
+extern int sumdata(Sum_t*, Sumdata_t*);
+extern int sumprint(Sum_t*, Sfio_t*, int, size_t);
+extern int sumusage(Sfio_t*);
+extern int sumclose(Sum_t*);
+
+#endif
diff --git a/src/lib/libsum/sumlib.c b/src/lib/libsum/sumlib.c
new file mode 100644
index 0000000..49c4c19
--- /dev/null
+++ b/src/lib/libsum/sumlib.c
@@ -0,0 +1,376 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1996-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Glenn Fowler
+ * AT&T Research
+ *
+ * man this is sum library
+ */
+
+static const char id[] = "\n@(#)$Id: sumlib (AT&T Research) 2009-09-28 $\0\n";
+
+#define _SUM_PRIVATE_ \
+ struct Method_s* method; \
+ uintmax_t total_count; \
+ uintmax_t total_size; \
+ uintmax_t size;
+
+#include <sum.h>
+#include <ctype.h>
+#include <swap.h>
+#include <hashpart.h>
+
+#define SCALE(n,m) (((n)+(m)-1)/(m))
+
+typedef struct Method_s
+{
+ const char* match;
+ const char* description;
+ const char* options;
+ Sum_t* (*open)(const struct Method_s*, const char*);
+ int (*init)(Sum_t*);
+ int (*block)(Sum_t*, const void*, size_t);
+ int (*data)(Sum_t*, Sumdata_t*);
+ int (*print)(Sum_t*, Sfio_t*, int, size_t);
+ int (*done)(Sum_t*);
+ int scale;
+} Method_t;
+
+typedef struct Map_s
+{
+ const char* match;
+ const char* description;
+ const char* map;
+} Map_t;
+
+/*
+ * 16 and 32 bit common code
+ */
+
+#define _INTEGRAL_PRIVATE_ \
+ uint32_t sum; \
+ uint32_t total_sum;
+
+typedef struct Integral_s
+{
+ _SUM_PUBLIC_
+ _SUM_PRIVATE_
+ _INTEGRAL_PRIVATE_
+} Integral_t;
+
+static Sum_t*
+long_open(const Method_t* method, const char* name)
+{
+ Integral_t* p;
+
+ if (p = newof(0, Integral_t, 1, 0))
+ {
+ p->method = (Method_t*)method;
+ p->name = name;
+ }
+ return (Sum_t*)p;
+}
+
+static int
+long_init(Sum_t* p)
+{
+ ((Integral_t*)p)->sum = 0;
+ return 0;
+}
+
+static int
+long_done(Sum_t* p)
+{
+ register Integral_t* x = (Integral_t*)p;
+
+ x->total_sum ^= (x->sum &= 0xffffffff);
+ return 0;
+}
+
+static int
+short_done(Sum_t* p)
+{
+ register Integral_t* x = (Integral_t*)p;
+
+ x->total_sum ^= (x->sum &= 0xffff);
+ return 0;
+}
+
+static int
+long_print(Sum_t* p, Sfio_t* sp, register int flags, size_t scale)
+{
+ register Integral_t* x = (Integral_t*)p;
+ register uint32_t c;
+ register uintmax_t z;
+ register size_t n;
+
+ c = (flags & SUM_TOTAL) ? x->total_sum : x->sum;
+ sfprintf(sp, "%.*I*u", (flags & SUM_LEGACY) ? 5 : 1, sizeof(c), c);
+ if (flags & SUM_SIZE)
+ {
+ z = (flags & SUM_TOTAL) ? x->total_size : x->size;
+ if ((flags & SUM_SCALE) && ((n = scale) || (n = x->method->scale)))
+ z = SCALE(z, n);
+ sfprintf(sp, " %*I*u", (flags & SUM_LEGACY) ? 6 : 0, sizeof(z), z);
+ }
+ if (flags & SUM_TOTAL)
+ sfprintf(sp, " %*I*u", (flags & SUM_LEGACY) ? 6 : 0, sizeof(x->total_count), x->total_count);
+ return 0;
+}
+
+static int
+long_data(Sum_t* p, Sumdata_t* data)
+{
+ register Integral_t* x = (Integral_t*)p;
+
+ data->size = sizeof(data->num);
+ data->num = x->sum;
+ data->buf = 0;
+ return 0;
+}
+
+#include "FEATURE/sum"
+
+#include "sum-att.c"
+#include "sum-ast4.c"
+#include "sum-bsd.c"
+#include "sum-crc.c"
+#include "sum-prng.c"
+
+#if _LIB_md && _lib_MD5Init && _hdr_md5 && _lib_SHA2Init && _hdr_sha2
+
+#include "sum-lmd.c"
+
+#else
+
+#include "sum-md5.c"
+#include "sum-sha1.c"
+#include "sum-sha2.c"
+
+#endif
+
+/*
+ * now the library interface
+ */
+
+#undef METHOD /* solaris <sys/localedef.h>! */
+#define METHOD(x) x##_match,x##_description,x##_options,x##_open,x##_init,x##_block,x##_data,x##_print,x##_done,x##_scale
+
+static const Method_t methods[] =
+{
+ METHOD(att),
+ METHOD(ast4),
+ METHOD(bsd),
+ METHOD(crc),
+ METHOD(prng),
+#ifdef md4_description
+ METHOD(md4),
+#endif
+#ifdef md5_description
+ METHOD(md5),
+#endif
+#ifdef sha1_description
+ METHOD(sha1),
+#endif
+#ifdef sha256_description
+ METHOD(sha256),
+#endif
+#ifdef sha384_description
+ METHOD(sha384),
+#endif
+#ifdef sha512_description
+ METHOD(sha512),
+#endif
+};
+
+static const Map_t maps[] =
+{
+ {
+ "posix|cksum|std|standard",
+ "The posix 1003.2-1992 32 bit crc checksum. This is the"
+ " default \bcksum\b(1) method.",
+ "crc-0x04c11db7-rotate-done-size"
+ },
+ {
+ "zip",
+ "The \bzip\b(1) crc.",
+ "crc-0xedb88320-init-done"
+ },
+ {
+ "fddi",
+ "The FDDI crc.",
+ "crc-0xedb88320-size=0xcc55cc55"
+ },
+ {
+ "fnv|fnv1",
+ "The Fowler-Noll-Vo 32 bit PRNG hash with non-zero"
+ " initializer (FNV-1).",
+ "prng-0x01000193-init=0x811c9dc5"
+ },
+ {
+ "ast|strsum",
+ "The \bast\b \bstrsum\b(3) PRNG hash.",
+ "prng-0x63c63cd9-add=0x9c39c33d"
+ },
+};
+
+/*
+ * simple alternation prefix match
+ */
+
+static int
+match(register const char* s, register const char* p)
+{
+ register const char* b = s;
+
+ for (;;)
+ {
+ do
+ {
+ if (*p == '|' || *p == 0)
+ return 1;
+ } while (*s++ == *p++);
+ for (;;)
+ {
+ switch (*p++)
+ {
+ case 0:
+ return 0;
+ case '|':
+ break;
+ default:
+ continue;
+ }
+ break;
+ }
+ s = b;
+ }
+ return 0;
+}
+
+/*
+ * open sum method name
+ */
+
+Sum_t*
+sumopen(register const char* name)
+{
+ register int n;
+
+ if (!name || !name[0] || name[0] == '-' && !name[1])
+ name = "default";
+ for (n = 0; n < elementsof(maps); n++)
+ if (match(name, maps[n].match))
+ {
+ name = maps[n].map;
+ break;
+ }
+ for (n = 0; n < elementsof(methods); n++)
+ if (match(name, methods[n].match))
+ return (*methods[n].open)(&methods[n], name);
+ return 0;
+}
+
+/*
+ * initialize for a new run of blocks
+ */
+
+int
+suminit(Sum_t* p)
+{
+ p->size = 0;
+ return (*p->method->init)(p);
+}
+
+/*
+ * compute the running sum on buf
+ */
+
+int
+sumblock(Sum_t* p, const void* buf, size_t siz)
+{
+ p->size += siz;
+ return (*p->method->block)(p, buf, siz);
+}
+
+/*
+ * done with this run of blocks
+ */
+
+int
+sumdone(Sum_t* p)
+{
+ p->total_count++;
+ p->total_size += p->size;
+ return (*p->method->done)(p);
+}
+
+/*
+ * print the sum [size] on sp
+ */
+
+int
+sumprint(Sum_t* p, Sfio_t* sp, int flags, size_t scale)
+{
+ return (*p->method->print)(p, sp, flags, scale);
+}
+
+/*
+ * return the current sum (internal) data
+ */
+
+int
+sumdata(Sum_t* p, Sumdata_t* d)
+{
+ return (*p->method->data)(p, d);
+}
+
+/*
+ * close an open sum handle
+ */
+
+int
+sumclose(Sum_t* p)
+{
+ free(p);
+ return 0;
+}
+
+/*
+ * print the checksum method optget(3) usage on sp and return the length
+ */
+
+int
+sumusage(Sfio_t* sp)
+{
+ register int i;
+ register int n;
+
+ for (i = n = 0; i < elementsof(methods); i++)
+ {
+ n += sfprintf(sp, "[+%s?%s]", methods[i].match, methods[i].description);
+ if (methods[i].options)
+ n += sfprintf(sp, "{\n%s\n}", methods[i].options);
+ }
+ for (i = 0; i < elementsof(maps); i++)
+ n += sfprintf(sp, "[+%s?%s Shorthand for \b%s\b.]", maps[i].match, maps[i].description, maps[i].map);
+ return n;
+}