Pārlūkot izejas kodu

Archive.MTree. Initial Import.

Brucey 3 gadi atpakaļ
vecāks
revīzija
dc0f388f72
55 mainītis faili ar 5508 papildinājumiem un 0 dzēšanām
  1. 188 0
      libmd.mod/config/config.h
  2. 27 0
      libmd.mod/libmd.bmx
  3. 177 0
      libmd.mod/libmd/COPYING
  4. 17 0
      libmd.mod/libmd/Makefile.am
  5. 38 0
      libmd.mod/libmd/README
  6. 4 0
      libmd.mod/libmd/autogen
  7. 111 0
      libmd.mod/libmd/configure.ac
  8. 50 0
      libmd.mod/libmd/get-version
  9. 18 0
      libmd.mod/libmd/include/Makefile.am
  10. 36 0
      libmd.mod/libmd/include/md2.h
  11. 51 0
      libmd.mod/libmd/include/md4.h
  12. 70 0
      libmd.mod/libmd/include/md5.h
  13. 46 0
      libmd.mod/libmd/include/ripemd.h
  14. 61 0
      libmd.mod/libmd/include/rmd160.h
  15. 46 0
      libmd.mod/libmd/include/sha.h
  16. 58 0
      libmd.mod/libmd/include/sha1.h
  17. 104 0
      libmd.mod/libmd/include/sha2.h
  18. 44 0
      libmd.mod/libmd/include/sha256.h
  19. 53 0
      libmd.mod/libmd/include/sha512.h
  20. 2 0
      libmd.mod/libmd/m4/.gitignore
  21. 24 0
      libmd.mod/libmd/m4/libmd-compiler.m4
  22. 22 0
      libmd.mod/libmd/m4/libmd-linker.m4
  23. 3 0
      libmd.mod/libmd/man/.gitignore
  24. 148 0
      libmd.mod/libmd/man/Makefile.am
  25. 227 0
      libmd.mod/libmd/man/mdX.3
  26. 240 0
      libmd.mod/libmd/man/rmd160.3
  27. 237 0
      libmd.mod/libmd/man/sha1.3
  28. 283 0
      libmd.mod/libmd/man/sha2.3
  29. 120 0
      libmd.mod/libmd/src/Makefile.am
  30. 103 0
      libmd.mod/libmd/src/helper.c
  31. 84 0
      libmd.mod/libmd/src/libmd.map
  32. 11 0
      libmd.mod/libmd/src/libmd.pc.in
  33. 60 0
      libmd.mod/libmd/src/local-link.h
  34. 170 0
      libmd.mod/libmd/src/md2.c
  35. 233 0
      libmd.mod/libmd/src/md4.c
  36. 250 0
      libmd.mod/libmd/src/md5.c
  37. 373 0
      libmd.mod/libmd/src/rmd160.c
  38. 236 0
      libmd.mod/libmd/src/sha1.c
  39. 863 0
      libmd.mod/libmd/src/sha2.c
  40. 6 0
      libmd.mod/libmd/test/.gitignore
  41. 23 0
      libmd.mod/libmd/test/Makefile.am
  42. 43 0
      libmd.mod/libmd/test/md2.c
  43. 43 0
      libmd.mod/libmd/test/md4.c
  44. 69 0
      libmd.mod/libmd/test/md5.c
  45. 43 0
      libmd.mod/libmd/test/rmd160.c
  46. 43 0
      libmd.mod/libmd/test/sha1.c
  47. 62 0
      libmd.mod/libmd/test/sha2.c
  48. 77 0
      libmd.mod/libmd/test/test.h
  49. 31 0
      libmd.mod/source.bmx
  50. 31 0
      mtree.mod/common.bmx
  51. 34 0
      mtree.mod/examples/example_01.bmx
  52. 9 0
      mtree.mod/examples/testdata.txt
  53. 9 0
      mtree.mod/examples/테스트_데이터.txt
  54. 66 0
      mtree.mod/mtree.bmx
  55. 31 0
      mtree.mod/source.bmx

+ 188 - 0
libmd.mod/config/config.h

@@ -0,0 +1,188 @@
+/* config.h.  Generated from config.h.in by configure.  */
+/* config.h.in.  Generated from configure.ac by autoheader.  */
+
+/* Define if building universal (internal helper macro) */
+/* #undef AC_APPLE_UNIVERSAL_BUILD */
+
+/* Define to 1 if you have the <dlfcn.h> header file. */
+#define HAVE_DLFCN_H 1
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#define HAVE_INTTYPES_H 1
+
+/* Define to 1 if you have the <minix/config.h> header file. */
+/* #undef HAVE_MINIX_CONFIG_H */
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#define HAVE_STDINT_H 1
+
+/* Define to 1 if you have the <stdio.h> header file. */
+#define HAVE_STDIO_H 1
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#define HAVE_STDLIB_H 1
+
+/* Define to 1 if you have the <strings.h> header file. */
+#define HAVE_STRINGS_H 1
+
+/* Define to 1 if you have the <string.h> header file. */
+#define HAVE_STRING_H 1
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#define HAVE_SYS_STAT_H 1
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#define HAVE_SYS_TYPES_H 1
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#define HAVE_UNISTD_H 1
+
+/* Define to 1 if you have the <wchar.h> header file. */
+#define HAVE_WCHAR_H 1
+
+/* Define to the sub-directory where libtool stores uninstalled libraries. */
+#define LT_OBJDIR ".libs/"
+
+/* Name of package */
+#define PACKAGE "libmd"
+
+/* Define to the address where bug reports for this package should be sent. */
+#define PACKAGE_BUGREPORT "[email protected]"
+
+/* Define to the full name of this package. */
+#define PACKAGE_NAME "libmd"
+
+/* Define to the full name and version of this package. */
+#define PACKAGE_STRING "libmd "
+
+/* Define to the one symbol short name of this package. */
+#define PACKAGE_TARNAME "libmd"
+
+/* Define to the home page for this package. */
+#define PACKAGE_URL ""
+
+/* Define to the version of this package. */
+#define PACKAGE_VERSION ""
+
+/* Define to 1 if all of the C90 standard headers exist (not just the ones
+   required in a freestanding environment). This macro is provided for
+   backward compatibility; new code need not use it. */
+#define STDC_HEADERS 1
+
+/* Enable extensions on AIX 3, Interix.  */
+#ifndef _ALL_SOURCE
+# define _ALL_SOURCE 1
+#endif
+/* Enable general extensions on macOS.  */
+#ifndef _DARWIN_C_SOURCE
+# define _DARWIN_C_SOURCE 1
+#endif
+/* Enable general extensions on Solaris.  */
+#ifndef __EXTENSIONS__
+# define __EXTENSIONS__ 1
+#endif
+/* Enable GNU extensions on systems that have them.  */
+#ifndef _GNU_SOURCE
+# define _GNU_SOURCE 1
+#endif
+/* Enable X/Open compliant socket functions that do not require linking
+   with -lxnet on HP-UX 11.11.  */
+#ifndef _HPUX_ALT_XOPEN_SOCKET_API
+# define _HPUX_ALT_XOPEN_SOCKET_API 1
+#endif
+/* Identify the host operating system as Minix.
+   This macro does not affect the system headers' behavior.
+   A future release of Autoconf may stop defining this macro.  */
+#ifndef _MINIX
+/* # undef _MINIX */
+#endif
+/* Enable general extensions on NetBSD.
+   Enable NetBSD compatibility extensions on Minix.  */
+#ifndef _NETBSD_SOURCE
+# define _NETBSD_SOURCE 1
+#endif
+/* Enable OpenBSD compatibility extensions on NetBSD.
+   Oddly enough, this does nothing on OpenBSD.  */
+#ifndef _OPENBSD_SOURCE
+# define _OPENBSD_SOURCE 1
+#endif
+/* Define to 1 if needed for POSIX-compatible behavior.  */
+#ifndef _POSIX_SOURCE
+/* # undef _POSIX_SOURCE */
+#endif
+/* Define to 2 if needed for POSIX-compatible behavior.  */
+#ifndef _POSIX_1_SOURCE
+/* # undef _POSIX_1_SOURCE */
+#endif
+/* Enable POSIX-compatible threading on Solaris.  */
+#ifndef _POSIX_PTHREAD_SEMANTICS
+# define _POSIX_PTHREAD_SEMANTICS 1
+#endif
+/* Enable extensions specified by ISO/IEC TS 18661-5:2014.  */
+#ifndef __STDC_WANT_IEC_60559_ATTRIBS_EXT__
+# define __STDC_WANT_IEC_60559_ATTRIBS_EXT__ 1
+#endif
+/* Enable extensions specified by ISO/IEC TS 18661-1:2014.  */
+#ifndef __STDC_WANT_IEC_60559_BFP_EXT__
+# define __STDC_WANT_IEC_60559_BFP_EXT__ 1
+#endif
+/* Enable extensions specified by ISO/IEC TS 18661-2:2015.  */
+#ifndef __STDC_WANT_IEC_60559_DFP_EXT__
+# define __STDC_WANT_IEC_60559_DFP_EXT__ 1
+#endif
+/* Enable extensions specified by ISO/IEC TS 18661-4:2015.  */
+#ifndef __STDC_WANT_IEC_60559_FUNCS_EXT__
+# define __STDC_WANT_IEC_60559_FUNCS_EXT__ 1
+#endif
+/* Enable extensions specified by ISO/IEC TS 18661-3:2015.  */
+#ifndef __STDC_WANT_IEC_60559_TYPES_EXT__
+# define __STDC_WANT_IEC_60559_TYPES_EXT__ 1
+#endif
+/* Enable extensions specified by ISO/IEC TR 24731-2:2010.  */
+#ifndef __STDC_WANT_LIB_EXT2__
+# define __STDC_WANT_LIB_EXT2__ 1
+#endif
+/* Enable extensions specified by ISO/IEC 24747:2009.  */
+#ifndef __STDC_WANT_MATH_SPEC_FUNCS__
+# define __STDC_WANT_MATH_SPEC_FUNCS__ 1
+#endif
+/* Enable extensions on HP NonStop.  */
+#ifndef _TANDEM_SOURCE
+# define _TANDEM_SOURCE 1
+#endif
+/* Enable X/Open extensions.  Define to 500 only if necessary
+   to make mbstate_t available.  */
+#ifndef _XOPEN_SOURCE
+/* # undef _XOPEN_SOURCE */
+#endif
+
+
+/* Version number of package */
+#define VERSION ""
+
+/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
+   significant byte first (like Motorola and SPARC, unlike Intel). */
+#if defined AC_APPLE_UNIVERSAL_BUILD
+# if defined __BIG_ENDIAN__
+#  define WORDS_BIGENDIAN 1
+# endif
+#else
+# ifndef WORDS_BIGENDIAN
+/* #  undef WORDS_BIGENDIAN */
+# endif
+#endif
+
+/* Number of bits in a file offset, on hosts where this is settable. */
+/* #undef _FILE_OFFSET_BITS */
+
+/* Define for large files, on AIX-style hosts. */
+/* #undef _LARGE_FILES */
+
+/* Define to `long int' if <sys/types.h> does not define. */
+/* #undef off_t */
+
+/* Define to `unsigned int' if <sys/types.h> does not define. */
+/* #undef size_t */
+
+/* Define to `int' if <sys/types.h> does not define. */
+/* #undef ssize_t */

+ 27 - 0
libmd.mod/libmd.bmx

@@ -0,0 +1,27 @@
+' Copyright (c) 2022 Bruce A Henderson
+' All rights reserved.
+'
+' Redistribution and use in source and binary forms, with or without
+' modification, are permitted provided that the following conditions are met:
+'     * Redistributions of source code must retain the above copyright
+'       notice, this list of conditions and the following disclaimer.
+'     * Redistributions in binary form must reproduce the above copyright
+'       notice, this list of conditions and the following disclaimer in the
+'       documentation and/or other materials provided with the distribution.
+'
+' THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER ``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 COPYRIGHT HOLDER 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.
+'
+SuperStrict
+
+Module Archive.libmd
+
+Import "source.bmx"

+ 177 - 0
libmd.mod/libmd/COPYING

@@ -0,0 +1,177 @@
+Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
+
+Files:
+ *
+Copyright:
+ Copyright © 2009, 2011, 2016 Guillem Jover <[email protected]>
+License: BSD-3-clause
+ 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. The name of the author may not be used to endorse or promote products
+    derived from this software without specific prior written permission.
+ .
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+Files:
+ include/sha2.h
+ src/sha2.c
+Copyright:
+ Copyright © 2000-2001, Aaron D. Gifford
+ All rights reserved.
+License: BSD-3-clause-Aaron-D-Gifford
+ 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.
+
+Files:
+ include/rmd160.h
+ src/rmd160.c
+Copyright:
+ Copyright © 2001 Markus Friedl.  All rights reserved.
+License: BSD-2-clause
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ 1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+ .
+ THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+Files:
+ src/md2.c
+Copyright:
+ Copyright (c) 2001 The NetBSD Foundation, Inc.
+ All rights reserved.
+ .
+ This code is derived from software contributed to The NetBSD Foundation
+ by Andrew Brown.
+License: BSD-2-clause-NetBSD
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ 1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+ .
+ THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ ``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 FOUNDATION OR CONTRIBUTORS
+ 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.
+
+Files:
+ man/rmd160.3
+ man/sha1.3
+ man/sha2.3
+Copyright:
+ Copyright © 1997, 2003, 2004 Todd C. Miller <[email protected]>
+License: ISC
+ Permission to use, copy, modify, and distribute this software for any
+ purpose with or without fee is hereby granted, provided that the above
+ copyright notice and this permission notice appear in all copies.
+ .
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+Files:
+ man/mdX.3
+ src/helper.c
+Copyright:
+ Poul-Henning Kamp <[email protected]>
+License: Beerware
+ "THE BEER-WARE LICENSE" (Revision 42):
+ <[email protected]> wrote this file.  As long as you retain this notice you
+ can do whatever you want with this stuff. If we meet some day, and you think
+ this stuff is worth it, you can buy me a beer in return.   Poul-Henning Kamp
+
+Files:
+ include/md4.h
+ src/md4.c
+Copyright:
+ Colin Plumb
+ Todd C. Miller
+License: public-domain-md4
+ This code implements the MD4 message-digest algorithm.
+ The algorithm is due to Ron Rivest.  This code was
+ written by Colin Plumb in 1993, no copyright is claimed.
+ This code is in the public domain; do with it what you wish.
+ Todd C. Miller modified the MD5 code to do MD4 based on RFC 1186.
+
+Files:
+ include/md5.h
+ src/md5.c
+Copyright:
+ Colin Plumb
+License: public-domain-md5
+ This code implements the MD5 message-digest algorithm.
+ The algorithm is due to Ron Rivest.  This code was
+ written by Colin Plumb in 1993, no copyright is claimed.
+ This code is in the public domain; do with it what you wish.
+
+Files:
+ include/sha1.h
+ src/sha1.c
+Copyright:
+ Steve Reid <[email protected]>
+License: public-domain-sha1
+ 100% Public Domain

+ 17 - 0
libmd.mod/libmd/Makefile.am

@@ -0,0 +1,17 @@
+## Process this file with automake to produce Makefile.in
+
+SUBDIRS = include man src test
+
+ACLOCAL_AMFLAGS = -I m4
+
+EXTRA_DIST = \
+	autogen \
+	get-version \
+	m4/libmd-linker.m4 \
+	$(nil)
+
+dist-hook:
+	echo $(VERSION) >$(distdir)/.dist-version
+	if [ -d .git ]; then \
+	  XDG_CONFIG_HOME= HOME= git log --stat -C >$(distdir)/ChangeLog; \
+	fi

+ 38 - 0
libmd.mod/libmd/README

@@ -0,0 +1,38 @@
+libmd - Message Digest functions from BSD systems
+
+This library provides message digest functions found on BSD systems either
+on their libc or libmd libraries and lacking on others like GNU systems,
+thus making it easier to port projects with strong BSD origins, without
+needing to embed the same code over and over again on each project.
+
+
+Website
+-------
+
+The project website can be found at:
+
+  <https://www.hadrons.org/software/libmd/>
+
+
+Mailing List
+------------
+
+The subscription interface and web archives can be found at:
+
+  <https://lists.freedesktop.org/mailman/listinfo/libbsd>
+
+The mail address is:
+
+  [email protected]
+
+
+Releases
+--------
+
+  <https://archive.hadrons.org/software/libmd/>
+
+
+Source Repository
+-----------------
+
+  <https://git.hadrons.org/cgit/libmd.git>

+ 4 - 0
libmd.mod/libmd/autogen

@@ -0,0 +1,4 @@
+#!/bin/sh
+
+autoreconf -f -i
+rm -rf autom4te.cache

+ 111 - 0
libmd.mod/libmd/configure.ac

@@ -0,0 +1,111 @@
+# Process this file with autoconf to produce a configure script.
+
+AC_PREREQ([2.68])
+AC_INIT([libmd], [m4_esyscmd([./get-version])], [[email protected]])
+AC_CONFIG_SRCDIR([src/sha2.c])
+AC_CONFIG_AUX_DIR([build-aux])
+AC_CONFIG_MACRO_DIR([m4])
+
+AM_INIT_AUTOMAKE([1.8 -Wall foreign nostdinc no-dist-gzip dist-xz])
+
+m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])],
+                            [AC_SUBST([AM_DEFAULT_VERBOSITY], [1])])
+
+LIBMD_ABI_MAJOR=0
+LIBMD_ABI_MINOR=0
+LIBMD_ABI_PATCH=5
+
+LIBMD_ABI="$LIBMD_ABI_MAJOR:$LIBMD_ABI_MINOR:$LIBMD_ABI_PATCH"
+AC_SUBST([LIBMD_ABI])
+
+# Check and store if we got user supplied variables.
+user_CFLAGS=${CFLAGS-unset}
+
+# Checks for operating system services and capabilities.
+AC_USE_SYSTEM_EXTENSIONS
+AC_SYS_LARGEFILE
+
+AM_PROG_AR
+LT_INIT
+LIBMD_LINKER_VERSION_SCRIPT
+
+# Checks for programs.
+AC_PROG_SED
+AC_PROG_CC
+
+# Checks for the build machinery.
+AS_IF([test "$user_CFLAGS" = unset], [
+  LIBMD_CHECK_COMPILER_FLAG([-Wall])
+  LIBMD_CHECK_COMPILER_FLAG([-Wextra])
+
+  LIBMD_CHECK_COMPILER_FLAG([-Wbad-function-cast])
+  LIBMD_CHECK_COMPILER_FLAG([-Wc99-c11-compat])
+  LIBMD_CHECK_COMPILER_FLAG([-Wcast-align])
+  LIBMD_CHECK_COMPILER_FLAG([-Wdeclaration-after-statement])
+  LIBMD_CHECK_COMPILER_FLAG([-Wdocumentation])
+  LIBMD_CHECK_COMPILER_FLAG([-Wduplicated-branches])
+  LIBMD_CHECK_COMPILER_FLAG([-Wduplicated-cond])
+  LIBMD_CHECK_COMPILER_FLAG([-Wformat -Wformat-security])
+  LIBMD_CHECK_COMPILER_FLAG([-Wformat=2])
+  LIBMD_CHECK_COMPILER_FLAG([-Winit-self])
+  LIBMD_CHECK_COMPILER_FLAG([-Wlogical-not-parentheses])
+  LIBMD_CHECK_COMPILER_FLAG([-Wlogical-op])
+  LIBMD_CHECK_COMPILER_FLAG([-Wmissing-declarations])
+  LIBMD_CHECK_COMPILER_FLAG([-Wmissing-format-attribute])
+  LIBMD_CHECK_COMPILER_FLAG([-Wmissing-prototypes])
+  LIBMD_CHECK_COMPILER_FLAG([-Wnested-externs])
+  LIBMD_CHECK_COMPILER_FLAG([-Wno-tautological-constant-out-of-range-compare])
+  LIBMD_CHECK_COMPILER_FLAG([-Wno-unused-parameter])
+  LIBMD_CHECK_COMPILER_FLAG([-Wnull-dereference])
+  LIBMD_CHECK_COMPILER_FLAG([-Wold-style-definition])
+  LIBMD_CHECK_COMPILER_FLAG([-Wpointer-arith])
+  LIBMD_CHECK_COMPILER_FLAG([-Wredundant-decls])
+  LIBMD_CHECK_COMPILER_FLAG([-Wregister])
+  LIBMD_CHECK_COMPILER_FLAG([-Wrestrict])
+  LIBMD_CHECK_COMPILER_FLAG([-Wshadow])
+  LIBMD_CHECK_COMPILER_FLAG([-Wshift-negative-value])
+  LIBMD_CHECK_COMPILER_FLAG([-Wsizeof-array-argument])
+  LIBMD_CHECK_COMPILER_FLAG([-Wstrict-prototypes])
+  LIBMD_CHECK_COMPILER_FLAG([-Wswitch-bool])
+  LIBMD_CHECK_COMPILER_FLAG([-Wvla])
+  LIBMD_CHECK_COMPILER_FLAG([-Wwrite-strings])
+
+  CFLAGS="$LIBMD_COMPILER_FLAGS $CFLAGS"
+
+  AC_ARG_ENABLE([sanitize],
+    [AS_HELP_STRING([--enable-sanitize], [enable compiler sanitizer support])],
+  [
+    LIBMD_COMPILER_FLAGS=''
+
+    LIBMD_CHECK_COMPILER_FLAG([-fsanitize=address])
+    LIBMD_CHECK_COMPILER_FLAG([-fsanitize=leak])
+    LIBMD_CHECK_COMPILER_FLAG([-fsanitize=undefined])
+
+    CFLAGS="$LIBMD_COMPILER_FLAGS $CFLAGS"
+    LDFLAGS="$LIBMD_COMPILER_FLAGS $LDFLAGS"
+  ])
+])
+
+# Checks for libraries.
+
+# Checks for header files.
+AC_CHECK_HEADERS([unistd.h])
+
+# Checks for typedefs, structures, and compiler characteristics.
+AC_C_BIGENDIAN
+AC_TYPE_OFF_T
+AC_TYPE_SIZE_T
+AC_TYPE_SSIZE_T
+
+# Checks for library functions.
+
+AC_CONFIG_FILES([
+	Makefile
+	include/Makefile
+	man/Makefile
+	src/Makefile
+	src/libmd.pc
+	test/Makefile
+])
+AC_CONFIG_HEADERS([config.h])
+AC_OUTPUT

+ 50 - 0
libmd.mod/libmd/get-version

@@ -0,0 +1,50 @@
+#!/bin/sh
+#
+# get-version
+#
+# Copyright © 2009 Guillem Jover <[email protected]>
+#
+# 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. The name of the author may not be used to endorse or promote products
+#    derived from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+# AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+# THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+if [ -f .dist-version ]; then
+  # Get the version from the file distributed in the tarball.
+  version=$(cat .dist-version)
+elif [ -d .git ]; then
+  # Ger the version from the git repository.
+  version=$(git describe --abbrev=4 HEAD 2>/dev/null)
+  if [ -z "$version" ]; then
+    version="initial"
+  fi
+
+  # Check if we are on a dirty checkout.
+  git update-index --refresh -q >/dev/null
+  dirty=$(git diff-index --name-only HEAD 2>/dev/null)
+  if [ -n "$dirty" ]; then
+    version="$version-dirty"
+  fi
+else
+  echo "error: cannot get project version." 1>&2
+  exit 1
+fi
+
+printf "$version"

+ 18 - 0
libmd.mod/libmd/include/Makefile.am

@@ -0,0 +1,18 @@
+## Process this file with automake to produce Makefile.in
+
+include_HEADERS = \
+	md2.h \
+	md4.h \
+	md5.h \
+	rmd160.h \
+	sha1.h \
+	sha2.h \
+	$(nil)
+
+# Compatibility headers
+include_HEADERS += \
+	ripemd.h \
+	sha.h \
+	sha256.h \
+	sha512.h \
+	$(nil)

+ 36 - 0
libmd.mod/libmd/include/md2.h

@@ -0,0 +1,36 @@
+/*	$NetBSD: md2.h,v 1.5 2005/09/25 00:48:21 xtraeme Exp $	*/
+
+#ifndef _MD2_H_
+#define _MD2_H_
+
+#include <sys/types.h>
+
+#include <stdint.h>
+
+#define	MD2_DIGEST_LENGTH		16
+#define	MD2_DIGEST_STRING_LENGTH	33
+
+/* MD2 context. */
+typedef struct MD2Context {
+	uint32_t i;
+	unsigned char C[16];		/* checksum */
+	unsigned char X[48];		/* input buffer */
+} MD2_CTX;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void	MD2Init(MD2_CTX *);
+void	MD2Update(MD2_CTX *, const unsigned char *, unsigned int);
+void	MD2Final(unsigned char[16], MD2_CTX *);
+char	*MD2End(MD2_CTX *, char *);
+char	*MD2File(const char *, char *);
+char	*MD2FileChunk(const char *, char *, off_t, off_t);
+char	*MD2Data(const unsigned char *, size_t, char *);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _MD2_H_ */

+ 51 - 0
libmd.mod/libmd/include/md4.h

@@ -0,0 +1,51 @@
+/*	$OpenBSD: md4.h,v 1.14 2004/05/03 17:30:14 millert Exp $	*/
+
+/*
+ * This code implements the MD4 message-digest algorithm.
+ * The algorithm is due to Ron Rivest.  This code was
+ * written by Colin Plumb in 1993, no copyright is claimed.
+ * This code is in the public domain; do with it what you wish.
+ * Todd C. Miller modified the MD5 code to do MD4 based on RFC 1186.
+ *
+ * Equivalent code is available from RSA Data Security, Inc.
+ * This code has been tested against that, and is equivalent,
+ * except that you don't need to include two pages of legalese
+ * with every copy.
+ */
+
+#ifndef _MD4_H_
+#define _MD4_H_
+
+#include <sys/types.h>
+
+#include <stdint.h>
+
+#define	MD4_BLOCK_LENGTH		64
+#define	MD4_DIGEST_LENGTH		16
+#define	MD4_DIGEST_STRING_LENGTH	(MD4_DIGEST_LENGTH * 2 + 1)
+
+typedef struct MD4Context {
+	uint32_t state[4];			/* state */
+	uint64_t count;				/* number of bits, mod 2^64 */
+	uint8_t buffer[MD4_BLOCK_LENGTH];	/* input buffer */
+} MD4_CTX;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void	 MD4Init(MD4_CTX *);
+void	 MD4Update(MD4_CTX *, const uint8_t *, size_t);
+void	 MD4Pad(MD4_CTX *);
+void	 MD4Final(uint8_t [MD4_DIGEST_LENGTH], MD4_CTX *);
+void	 MD4Transform(uint32_t [4], const uint8_t [MD4_BLOCK_LENGTH]);
+char	*MD4End(MD4_CTX *, char *);
+char	*MD4File(const char *, char *);
+char	*MD4FileChunk(const char *, char *, off_t, off_t);
+char	*MD4Data(const uint8_t *, size_t, char *);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _MD4_H_ */

+ 70 - 0
libmd.mod/libmd/include/md5.h

@@ -0,0 +1,70 @@
+/*	$OpenBSD: md5.h,v 1.15 2004/05/03 17:30:14 millert Exp $	*/
+
+/*
+ * This code implements the MD5 message-digest algorithm.
+ * The algorithm is due to Ron Rivest.  This code was
+ * written by Colin Plumb in 1993, no copyright is claimed.
+ * This code is in the public domain; do with it what you wish.
+ *
+ * Equivalent code is available from RSA Data Security, Inc.
+ * This code has been tested against that, and is equivalent,
+ * except that you don't need to include two pages of legalese
+ * with every copy.
+ */
+
+#ifndef _MD5_H_
+#define _MD5_H_
+
+#include <sys/types.h>
+
+#include <stdint.h>
+
+#define	MD5_BLOCK_LENGTH		64
+#define	MD5_DIGEST_LENGTH		16
+#define	MD5_DIGEST_STRING_LENGTH	(MD5_DIGEST_LENGTH * 2 + 1)
+
+typedef struct MD5Context {
+	uint32_t state[4];			/* state */
+	uint64_t count;				/* number of bits, mod 2^64 */
+	uint8_t buffer[MD5_BLOCK_LENGTH];	/* input buffer */
+} MD5_CTX;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void	 MD5Init(MD5_CTX *);
+void	 MD5Update(MD5_CTX *, const uint8_t *, size_t);
+void	 MD5Pad(MD5_CTX *);
+void	 MD5Final(uint8_t [MD5_DIGEST_LENGTH], MD5_CTX *);
+void	 MD5Transform(uint32_t [4], const uint8_t [MD5_BLOCK_LENGTH]);
+char	*MD5End(MD5_CTX *, char *);
+char	*MD5File(const char *, char *);
+char	*MD5FileChunk(const char *, char *, off_t, off_t);
+char	*MD5Data(const uint8_t *, size_t, char *);
+
+#ifdef __cplusplus
+}
+#endif
+
+/* Avoid polluting the namespace. Even though this makes this usage
+ * implementation-specific, defining it unconditionally should not be
+ * a problem, and better than possibly breaking unexpecting code. */
+#ifdef LIBMD_MD5_ALADDIN
+
+/*
+ * Interface compatibility with Aladdin Enterprises independent
+ * implementation from RFC 1321.
+ */
+
+typedef uint8_t md5_byte_t;
+typedef uint32_t md5_word_t;
+typedef MD5_CTX md5_state_t;
+
+#define md5_init(pms) MD5Init(pms)
+#define md5_append(pms, data, nbytes) MD5Update(pms, data, nbytes)
+#define md5_finish(pms, digest) MD5Final(digest, pms)
+
+#endif /* LIBMD_MD5_ALADDIN */
+
+#endif /* _MD5_H_ */

+ 46 - 0
libmd.mod/libmd/include/ripemd.h

@@ -0,0 +1,46 @@
+/*
+ * Copyright © 2011 Guillem Jover <[email protected]>
+ *
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef LIBMD_RIPEMD_H
+#define LIBMD_RIPEMD_H
+
+#include <rmd160.h>
+
+/* For compatibility with FreeBSD and DragonFlyBSD. */
+
+#define RIPEMD160_DIGEST_LENGTH	20
+
+typedef RMD160_CTX RIPEMD160_CTX;
+
+#define RIPEMD160_Init		RMD160Init
+#define RIPEMD160_Update	RMD160Update
+#define RIPEMD160_Final		RMD160Final
+#define RIPEMD160_End		RMD160End
+#define RIPEMD160_File		RMD160File
+#define RIPEMD160_FileChunk	RMD160FileChunk
+#define RIPEMD160_Data		RMD160Data
+
+#endif

+ 61 - 0
libmd.mod/libmd/include/rmd160.h

@@ -0,0 +1,61 @@
+/*	$OpenBSD: rmd160.h,v 1.15 2004/05/03 17:30:14 millert Exp $	*/
+/*
+ * Copyright (c) 2001 Markus Friedl.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef  _RMD160_H
+#define  _RMD160_H
+
+#include <sys/types.h>
+
+#include <stdint.h>
+
+#define	RMD160_BLOCK_LENGTH		64
+#define	RMD160_DIGEST_LENGTH		20
+#define	RMD160_DIGEST_STRING_LENGTH	(RMD160_DIGEST_LENGTH * 2 + 1)
+
+/* RMD160 context. */
+typedef struct RMD160Context {
+	uint32_t state[5];			/* state */
+	uint64_t count;				/* number of bits, mod 2^64 */
+	uint8_t buffer[RMD160_BLOCK_LENGTH];	/* input buffer */
+} RMD160_CTX;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void	 RMD160Init(RMD160_CTX *);
+void	 RMD160Transform(uint32_t [5], const uint8_t [RMD160_BLOCK_LENGTH]);
+void	 RMD160Update(RMD160_CTX *, const uint8_t *, size_t);
+void	 RMD160Pad(RMD160_CTX *);
+void	 RMD160Final(uint8_t [RMD160_DIGEST_LENGTH], RMD160_CTX *);
+char	*RMD160End(RMD160_CTX *, char *);
+char	*RMD160File(const char *, char *);
+char	*RMD160FileChunk(const char *, char *, off_t, off_t);
+char	*RMD160Data(const uint8_t *, size_t, char *);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif  /* _RMD160_H */

+ 46 - 0
libmd.mod/libmd/include/sha.h

@@ -0,0 +1,46 @@
+/*
+ * Copyright © 2011 Guillem Jover <[email protected]>
+ *
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef LIBMD_SHA_H
+#define LIBMD_SHA_H
+
+/* For compatibility with FreeBSD and DragonFlyBSD. */
+
+#include <sha1.h>
+
+#define SHA_DIGEST_LENGTH	SHA1_DIGEST_LENGTH
+
+typedef SHA1_CTX SHA_CTX;
+
+#define SHA1_Init		SHA1Init
+#define SHA1_Update		SHA1Update
+#define SHA1_Final		SHA1Final
+#define SHA1_End		SHA1End
+#define SHA1_File		SHA1File
+#define SHA1_FileChunk		SHA1FileChunk
+#define SHA1_Data		SHA1Data
+
+#endif

+ 58 - 0
libmd.mod/libmd/include/sha1.h

@@ -0,0 +1,58 @@
+/*	$OpenBSD: sha1.h,v 1.22 2004/05/05 17:09:45 millert Exp $	*/
+
+/*
+ * SHA-1 in C
+ * By Steve Reid <[email protected]>
+ * 100% Public Domain
+ */
+
+#ifndef _SHA1_H
+#define _SHA1_H
+
+#include <sys/types.h>
+
+#include <stdint.h>
+
+#define	SHA1_BLOCK_LENGTH		64
+#define	SHA1_DIGEST_LENGTH		20
+#define	SHA1_DIGEST_STRING_LENGTH	(SHA1_DIGEST_LENGTH * 2 + 1)
+
+typedef struct {
+    uint32_t state[5];
+    uint64_t count;
+    uint8_t buffer[SHA1_BLOCK_LENGTH];
+} SHA1_CTX;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void SHA1Init(SHA1_CTX *);
+void SHA1Pad(SHA1_CTX *);
+void SHA1Transform(uint32_t [5], const uint8_t [SHA1_BLOCK_LENGTH]);
+void SHA1Update(SHA1_CTX *, const uint8_t *, size_t);
+void SHA1Final(uint8_t [SHA1_DIGEST_LENGTH], SHA1_CTX *);
+char *SHA1End(SHA1_CTX *, char *);
+char *SHA1File(const char *, char *);
+char *SHA1FileChunk(const char *, char *, off_t, off_t);
+char *SHA1Data(const uint8_t *, size_t, char *);
+
+#ifdef __cplusplus
+}
+#endif
+
+#define HTONDIGEST(x) do {                                              \
+        x[0] = htonl(x[0]);                                             \
+        x[1] = htonl(x[1]);                                             \
+        x[2] = htonl(x[2]);                                             \
+        x[3] = htonl(x[3]);                                             \
+        x[4] = htonl(x[4]); } while (0)
+
+#define NTOHDIGEST(x) do {                                              \
+        x[0] = ntohl(x[0]);                                             \
+        x[1] = ntohl(x[1]);                                             \
+        x[2] = ntohl(x[2]);                                             \
+        x[3] = ntohl(x[3]);                                             \
+        x[4] = ntohl(x[4]); } while (0)
+
+#endif /* _SHA1_H */

+ 104 - 0
libmd.mod/libmd/include/sha2.h

@@ -0,0 +1,104 @@
+/*	$OpenBSD: sha2.h,v 1.6 2004/06/22 01:57:30 jfb Exp $	*/
+
+/*
+ * FILE:	sha2.h
+ * AUTHOR:	Aaron D. Gifford <[email protected]>
+ * 
+ * Copyright (c) 2000-2001, Aaron D. Gifford
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holder nor the names of contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTOR(S) ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTOR(S) BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $From: sha2.h,v 1.1 2001/11/08 00:02:01 adg Exp adg $
+ */
+
+#ifndef _SHA2_H
+#define _SHA2_H
+
+#include <sys/types.h>
+
+#include <stdint.h>
+
+/*** SHA-256/384/512 Various Length Definitions ***********************/
+#define SHA256_BLOCK_LENGTH		64
+#define SHA256_DIGEST_LENGTH		32
+#define SHA256_DIGEST_STRING_LENGTH	(SHA256_DIGEST_LENGTH * 2 + 1)
+#define SHA384_BLOCK_LENGTH		128
+#define SHA384_DIGEST_LENGTH		48
+#define SHA384_DIGEST_STRING_LENGTH	(SHA384_DIGEST_LENGTH * 2 + 1)
+#define SHA512_BLOCK_LENGTH		128
+#define SHA512_DIGEST_LENGTH		64
+#define SHA512_DIGEST_STRING_LENGTH	(SHA512_DIGEST_LENGTH * 2 + 1)
+
+
+/*** SHA-256/384/512 Context Structure *******************************/
+typedef struct _SHA2_CTX {
+	union {
+		uint32_t	st32[8];
+		uint64_t	st64[8];
+	} state;
+	uint64_t	bitcount[2];
+	uint8_t		buffer[SHA512_BLOCK_LENGTH];
+} SHA2_CTX;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void SHA256Init(SHA2_CTX *);
+void SHA256Transform(uint32_t state[8], const uint8_t [SHA256_BLOCK_LENGTH]);
+void SHA256Update(SHA2_CTX *, const uint8_t *, size_t);
+void SHA256Pad(SHA2_CTX *);
+void SHA256Final(uint8_t [SHA256_DIGEST_LENGTH], SHA2_CTX *);
+char *SHA256End(SHA2_CTX *, char *);
+char *SHA256File(const char *, char *);
+char *SHA256FileChunk(const char *, char *, off_t, off_t);
+char *SHA256Data(const uint8_t *, size_t, char *);
+
+void SHA384Init(SHA2_CTX *);
+void SHA384Transform(uint64_t state[8], const uint8_t [SHA384_BLOCK_LENGTH]);
+void SHA384Update(SHA2_CTX *, const uint8_t *, size_t);
+void SHA384Pad(SHA2_CTX *);
+void SHA384Final(uint8_t [SHA384_DIGEST_LENGTH], SHA2_CTX *);
+char *SHA384End(SHA2_CTX *, char *);
+char *SHA384File(const char *, char *);
+char *SHA384FileChunk(const char *, char *, off_t, off_t);
+char *SHA384Data(const uint8_t *, size_t, char *);
+
+void SHA512Init(SHA2_CTX *);
+void SHA512Transform(uint64_t state[8], const uint8_t [SHA512_BLOCK_LENGTH]);
+void SHA512Update(SHA2_CTX *, const uint8_t *, size_t);
+void SHA512Pad(SHA2_CTX *);
+void SHA512Final(uint8_t [SHA512_DIGEST_LENGTH], SHA2_CTX *);
+char *SHA512End(SHA2_CTX *, char *);
+char *SHA512File(const char *, char *);
+char *SHA512FileChunk(const char *, char *, off_t, off_t);
+char *SHA512Data(const uint8_t *, size_t, char *);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _SHA2_H */

+ 44 - 0
libmd.mod/libmd/include/sha256.h

@@ -0,0 +1,44 @@
+/*
+ * Copyright © 2011 Guillem Jover <[email protected]>
+ *
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef LIBMD_SHA256_H
+#define LIBMD_SHA256_H
+
+/* For compatibility with FreeBSD and DragonFlyBSD. */
+
+#include <sha2.h>
+
+typedef SHA2_CTX SHA256_CTX;
+
+#define SHA256_Init		SHA256Init
+#define SHA256_Update		SHA256Update
+#define SHA256_Final		SHA256Final
+#define SHA256_End		SHA256End
+#define SHA256_File		SHA256File
+#define SHA256_FileChunk	SHA256FileChunk
+#define SHA256_Data		SHA256Data
+
+#endif

+ 53 - 0
libmd.mod/libmd/include/sha512.h

@@ -0,0 +1,53 @@
+/*
+ * Copyright © 2011 Guillem Jover <[email protected]>
+ *
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef LIBMD_SHA512_H
+#define LIBMD_SHA512_H
+
+/* For compatibility with FreeBSD and DragonFlyBSD. */
+
+#include <sha2.h>
+
+typedef SHA2_CTX SHA512_CTX;
+typedef SHA2_CTX SHA384_CTX;
+
+#define SHA384_Init		SHA384Init
+#define SHA384_Update		SHA384Update
+#define SHA384_Final		SHA384Final
+#define SHA384_End		SHA384End
+#define SHA384_Data		SHA384Data
+#define SHA384_File		SHA384File
+#define SHA384_FileChunk	SHA384FileChunk
+
+#define SHA512_Init		SHA512Init
+#define SHA512_Update		SHA512Update
+#define SHA512_Final		SHA512Final
+#define SHA512_End		SHA512End
+#define SHA512_Data		SHA512Data
+#define SHA512_File		SHA512File
+#define SHA512_FileChunk	SHA512FileChunk
+
+#endif

+ 2 - 0
libmd.mod/libmd/m4/.gitignore

@@ -0,0 +1,2 @@
+*.m4
+!libmd*.m4

+ 24 - 0
libmd.mod/libmd/m4/libmd-compiler.m4

@@ -0,0 +1,24 @@
+# Copyright © 2021 Guillem Jover <[email protected]>
+
+# LIBMD_CHECK_COMPILER_FLAG
+# -------------------------
+AC_DEFUN([LIBMD_CHECK_COMPILER_FLAG], [
+  AS_VAR_PUSHDEF([libmd_varname_cache], [libmd_cv_cflags_$1])
+  AC_CACHE_CHECK([whether $CC accepts $1], [libmd_varname_cache], [
+    m4_define([libmd_check_flag], m4_bpatsubst([$1], [^-Wno-], [-W]))
+    AS_VAR_COPY([libmd_save_CFLAGS], [CFLAGS])
+    AS_VAR_SET([CFLAGS], ["-Werror libmd_check_flag"])
+    AC_COMPILE_IFELSE([
+      AC_LANG_SOURCE([[]])
+    ], [
+      AS_VAR_SET([libmd_varname_cache], [yes])
+    ], [
+      AS_VAR_SET([libmd_varname_cache], [no])
+    ])
+    AS_VAR_COPY([CFLAGS], [libmd_save_CFLAGS])
+  ])
+  AS_VAR_IF([libmd_varname_cache], [yes], [
+    AS_VAR_APPEND([LIBMD_COMPILER_FLAGS], [" $1"])
+  ])
+  AS_VAR_POPDEF([libmd_varname_cache])
+])

+ 22 - 0
libmd.mod/libmd/m4/libmd-linker.m4

@@ -0,0 +1,22 @@
+# Copyright © 2014 Guillem Jover <[email protected]>
+
+# LIBMD_LINKER_VERSION_SCRIPT
+# --------------------------
+AC_DEFUN([LIBMD_LINKER_VERSION_SCRIPT], [
+  AC_CACHE_CHECK([for --version-script linker flag], [libmd_cv_version_script], [
+    echo "{ global: symbol; local: *; };" >conftest.map
+    save_LDFLAGS=$LDFLAGS
+    LDFLAGS="$LDFLAGS -Wl,--version-script=conftest.map"
+    AC_LINK_IFELSE([
+      AC_LANG_PROGRAM([], [])
+    ], [
+      libmd_cv_version_script=yes
+    ], [
+      libmd_cv_version_script=no
+    ])
+    LDFLAGS="$save_LDFLAGS"
+    rm -f conftest.map
+  ])
+  AM_CONDITIONAL([HAVE_LINKER_VERSION_SCRIPT],
+    [test "x$libmd_cv_version_script" = "xyes"])
+])

+ 3 - 0
libmd.mod/libmd/man/.gitignore

@@ -0,0 +1,3 @@
+md2.3
+md4.3
+md5.3

+ 148 - 0
libmd.mod/libmd/man/Makefile.am

@@ -0,0 +1,148 @@
+EXTRA_DIST = \
+	mdX.3 \
+	$(nil)
+
+CLEANFILES = \
+	md4.3 \
+	md5.3 \
+	$(nil)
+
+SED_MD2_SUBST = -e 's/mdX/md2/g' -e 's/MDX/MD2/g'
+SED_MD4_SUBST = -e 's/mdX/md4/g' -e 's/MDX/MD4/g'
+SED_MD5_SUBST = -e 's/mdX/md5/g' -e 's/MDX/MD5/g'
+
+md2.3: $(srcdir)/mdX.3
+	$(AM_V_GEN) $(SED) $(SED_MD2_SUBST) $(srcdir)/mdX.3 >$@
+
+md4.3: $(srcdir)/mdX.3
+	$(AM_V_GEN) $(SED) $(SED_MD4_SUBST) $(srcdir)/mdX.3 >$@
+
+md5.3: $(srcdir)/mdX.3
+	$(AM_V_GEN) $(SED) $(SED_MD5_SUBST) $(srcdir)/mdX.3 >$@
+
+dist_man_MANS = \
+	md2.3 \
+	md4.3 \
+	md5.3 \
+	rmd160.3 \
+	sha1.3 \
+	sha2.3 \
+	$(nil)
+
+md2_FUNCS = \
+	MD2Transform \
+	MD2Init \
+	MD2Final \
+	MD2Update \
+	MD2End \
+	MD2File \
+	MD2FileChunk \
+	MD2Data \
+	$(nil)
+
+$(md2_FUNCS): md2.3
+	$(LN_S) -f md2.3 $(DESTDIR)$(man3dir)/[email protected]
+
+md4_FUNCS = \
+	MD4Transform \
+	MD4Init \
+	MD4Final \
+	MD4Update \
+	MD4End \
+	MD4File \
+	MD4FileChunk \
+	MD4Pad \
+	MD4Data \
+	$(nil)
+
+$(md4_FUNCS): md4.3
+	$(LN_S) -f md4.3 $(DESTDIR)$(man3dir)/[email protected]
+
+md5_FUNCS = \
+	MD5Transform \
+	MD5Init \
+	MD5Final \
+	MD5Update \
+	MD5End \
+	MD5File \
+	MD5FileChunk \
+	MD5Pad \
+	MD5Data \
+	$(nil)
+
+$(md5_FUNCS): md5.3
+	$(LN_S) -f md5.3 $(DESTDIR)$(man3dir)/[email protected]
+
+rmd160_FUNCS = \
+	RMD160Transform \
+	RMD160Init \
+	RMD160Final \
+	RMD160Update \
+	RMD160End \
+	RMD160File \
+	RMD160FileChunk \
+	RMD160Pad \
+	RMD160Data \
+	$(nil)
+
+$(rmd160_FUNCS): rmd160.3
+	$(LN_S) -f rmd160.3 $(DESTDIR)$(man3dir)/[email protected]
+
+sha1_FUNCS = \
+	SHA1Transform \
+	SHA1Init \
+	SHA1Final \
+	SHA1Update \
+	SHA1End \
+	SHA1File \
+	SHA1FileChunk \
+	SHA1Pad \
+	SHA1Data \
+	$(nil)
+
+$(sha1_FUNCS): sha1.3
+	$(LN_S) -f sha1.3 $(DESTDIR)$(man3dir)/[email protected]
+
+sha2_FUNCS = \
+	SHA256Init \
+	SHA256Update \
+	SHA256Pad \
+	SHA256Final \
+	SHA256Transform \
+	SHA256End \
+	SHA256File \
+	SHA256FileChunk \
+	SHA256Data \
+	SHA384Init \
+	SHA384Update \
+	SHA384Pad \
+	SHA384Final \
+	SHA384Transform \
+	SHA384End \
+	SHA384File \
+	SHA384FileChunk \
+	SHA384Data \
+	SHA512Init \
+	SHA512Update \
+	SHA512Pad \
+	SHA512Final \
+	SHA512Transform \
+	SHA512End \
+	SHA512File \
+	SHA512FileChunk \
+	SHA512Data \
+	$(nil)
+
+$(sha2_FUNCS): sha2.3
+	$(LN_S) -f sha2.3 $(DESTDIR)$(man3dir)/[email protected]
+
+digest_FUNCS = \
+	$(md2_FUNCS) \
+	$(md4_FUNCS) \
+	$(md5_FUNCS) \
+	$(rmd160_FUNCS) \
+	$(sha1_FUNCS) \
+	$(sha2_FUNCS) \
+	$(nil)
+
+install-data-hook: $(digest_FUNCS)

+ 227 - 0
libmd.mod/libmd/man/mdX.3

@@ -0,0 +1,227 @@
+.\"
+.\" ----------------------------------------------------------------------------
+.\" "THE BEER-WARE LICENSE" (Revision 42):
+.\" <[email protected]> wrote this file.  As long as you retain this notice you
+.\" can do whatever you want with this stuff. If we meet some day, and you think
+.\" this stuff is worth it, you can buy me a beer in return.   Poul-Henning Kamp
+.\" ----------------------------------------------------------------------------
+.\"
+.\" 	$OpenBSD: mdX.3,v 1.11 2010/07/13 22:34:45 tedu Exp $
+.\"
+.Dd $Mdocdate: July 13 2010 $
+.Dt MDX 3
+.Os
+.Sh NAME
+.Nm MDXInit ,
+.Nm MDXUpdate ,
+.Nm MDXPad ,
+.Nm MDXFinal ,
+.Nm MDXTransform ,
+.Nm MDXEnd ,
+.Nm MDXFile ,
+.Nm MDXFileChunk ,
+.Nm MDXData
+.Nd calculate the RSA Data Security, Inc.,
+.Dq MDX
+message digest
+.Sh LIBRARY
+.Lb libmd
+.Sh SYNOPSIS
+.In sys/types.h
+.In mdX.h
+.Ft void
+.Fn MDXInit "MDX_CTX *context"
+.Ft void
+.Fn MDXUpdate "MDX_CTX *context" "const uint8_t *data" "size_t len"
+.Ft void
+.Fn MDXPad "MDX_CTX *context"
+.Ft void
+.Fn MDXFinal "uint8_t digest[MDX_DIGEST_LENGTH]" "MDX_CTX *context"
+.Ft void
+.Fn MDXTransform "uint32_t state[4]" "uint8_t block[MDX_BLOCK_LENGTH]"
+.Ft "char *"
+.Fn MDXEnd "MDX_CTX *context" "char *buf"
+.Ft "char *"
+.Fn MDXFile "const char *filename" "char *buf"
+.Ft "char *"
+.Fn MDXFileChunk "const char *filename" "char *buf" "off_t offset" "off_t length"
+.Ft "char *"
+.Fn MDXData "const uint8_t *data" "size_t len" "char *buf"
+.Sh DESCRIPTION
+The MDX functions calculate a 128-bit cryptographic checksum (digest)
+for any number of input bytes.
+A cryptographic checksum is a one-way
+hash-function, that is, you cannot find (except by exhaustive search)
+the input corresponding to a particular output.
+This net result is a
+.Dq fingerprint
+of the input-data, which doesn't disclose the actual input.
+.Pp
+MD2 is the slowest, MD4 is the fastest and MD5 is somewhere in the middle.
+MD2 can only be used for Privacy-Enhanced Mail.
+MD4 has been criticized for being too weak, so MD5 was developed in
+response as ``MD4 with safety-belts''.
+MD4 and MD5 have been broken; they should only be used where necessary for
+backward compatibility.
+The attacks on both MD4 and MD5
+are both in the nature of finding
+.Dq collisions
+\- that is, multiple
+inputs which hash to the same value; it is still unlikely for an attacker
+to be able to determine the exact original input given a hash value.
+.Pp
+The
+.Fn MDXInit ,
+.Fn MDXUpdate ,
+and
+.Fn MDXFinal
+functions are the core functions.
+Allocate an MDX_CTX, initialize it with
+.Fn MDXInit ,
+run over the data with
+.Fn MDXUpdate ,
+and finally extract the result using
+.Fn MDXFinal .
+.Pp
+The
+.Fn MDXPad
+function can be used to apply padding to the message digest as in
+.Fn MDXFinal ,
+but the current context can still be used with
+.Fn MDXUpdate .
+.Pp
+The
+.Fn MDXTransform
+function is used by
+.Fn MDXUpdate
+to hash 512-bit blocks and forms the core of the algorithm.
+Most programs should use the interface provided by
+.Fn MDXInit ,
+.Fn MDXUpdate
+and
+.Fn MDXFinal
+instead of calling
+.Fn MDXTransform
+directly.
+.Pp
+.Fn MDXEnd
+is a wrapper for
+.Fn MDXFinal
+which converts the return value to an MDX_DIGEST_STRING_LENGTH-character
+(including the terminating '\e0')
+.Tn ASCII
+string which represents the 128 bits in hexadecimal.
+.Pp
+.Fn MDXFile
+calculates the digest of a file, and uses
+.Fn MDXEnd
+to return the result.
+If the file cannot be opened, a null pointer is returned.
+.Pp
+.Fn MDXFileChunk
+behaves like
+.Fn MDXFile
+but calculates the digest only for that portion of the file starting at
+.Fa offset
+and continuing for
+.Fa length
+bytes or until end of file is reached, whichever comes first.
+A zero
+.Fa length
+can be specified to read until end of file.
+A negative
+.Fa length
+or
+.Fa offset
+will be ignored.
+.Fn MDXData
+calculates the digest of a chunk of data in memory, and uses
+.Fn MDXEnd
+to return the result.
+.Pp
+When using
+.Fn MDXEnd ,
+.Fn MDXFile ,
+.Fn MDXFileChunk ,
+or
+.Fn MDXData ,
+the
+.Ar buf
+argument can be a null pointer, in which case the returned string
+is allocated with
+.Xr malloc 3
+and subsequently must be explicitly deallocated using
+.Xr free 3
+after use.
+If the
+.Ar buf
+argument is non-null it must point to at least MDX_DIGEST_STRING_LENGTH
+characters of buffer space.
+.Sh SEE ALSO
+.Xr md2 3 ,
+.Xr md4 3 ,
+.Xr md5 3 ,
+.Xr rmd160 3 ,
+.Xr sha1 3 ,
+.Xr sha2 3
+.Rs
+.%A B. Kaliski
+.%T The MD2 Message-Digest Algorithm
+.%O RFC 1319
+.Re
+.Rs
+.%A R. Rivest
+.%T The MD4 Message-Digest Algorithm
+.%O RFC 1186
+.Re
+.Rs
+.%A R. Rivest
+.%T The MD5 Message-Digest Algorithm
+.%O RFC 1321
+.Re
+.Rs
+.%A RSA Laboratories
+.%T Frequently Asked Questions About today's Cryptography
+.%O \&<http://www.rsa.com/rsalabs/faq/>
+.Re
+.Rs
+.%A H. Dobbertin
+.%T Alf Swindles Ann
+.%J CryptoBytes
+.%N 1(3):5
+.%D 1995
+.Re
+.Rs
+.%A MJ. B. Robshaw
+.%T On Recent Results for MD4 and MD5
+.%J RSA Laboratories Bulletin
+.%N 4
+.%D November 12, 1996
+.Re
+.Rs
+.%A Hans Dobbertin
+.%T Cryptanalysis of MD5 Compress
+.Re
+.Sh HISTORY
+These functions appeared in
+.Ox 2.0
+and
+.Nx 1.3 .
+.Sh AUTHORS
+The original MDX routines were developed by
+.Tn RSA
+Data Security, Inc., and published in the above references.
+This code is derived from a public domain implementation written by Colin Plumb.
+.Pp
+The
+.Fn MDXEnd ,
+.Fn MDXFile ,
+.Fn MDXFileChunk ,
+and
+.Fn MDXData
+helper functions are derived from code written by Poul-Henning Kamp.
+.Sh BUGS
+Collisions have been found for the full versions of both MD4 and MD5.
+The use of
+.Xr sha2 3
+is recommended instead.

+ 240 - 0
libmd.mod/libmd/man/rmd160.3

@@ -0,0 +1,240 @@
+.\"	$OpenBSD: rmd160.3,v 1.30 2010/07/13 07:01:23 jmc Exp $
+.\"
+.\" Copyright (c) 1997, 2004 Todd C. Miller <[email protected]>
+.\"
+.\" Permission to use, copy, modify, and distribute this software for any
+.\" purpose with or without fee is hereby granted, provided that the above
+.\" copyright notice and this permission notice appear in all copies.
+.\"
+.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+.\"
+.\" See http://www.esat.kuleuven.ac.be/~bosselae/ripemd160.html
+.\"	for detailed information about RIPEMD-160.
+.\"
+.Dd $Mdocdate: July 13 2010 $
+.Dt RMD160 3
+.Os
+.Sh NAME
+.Nm RMD160Init ,
+.Nm RMD160Update ,
+.Nm RMD160Pad ,
+.Nm RMD160Final ,
+.Nm RMD160Transform ,
+.Nm RMD160End ,
+.Nm RMD160File ,
+.Nm RMD160FileChunk ,
+.Nm RMD160Data
+.Nd calculate the ``RIPEMD-160'' message digest
+.Sh LIBRARY
+.Lb libmd
+.Sh SYNOPSIS
+.Fd #include <sys/types.h>
+.Fd #include <rmd160.h>
+.Ft void
+.Fn RMD160Init "RMD160_CTX *context"
+.Ft void
+.Fn RMD160Update "RMD160_CTX *context" "const uint8_t *data" "uint32_t nbytes"
+.Ft void
+.Fn RMD160Pad "RMD160_CTX *context"
+.Ft void
+.Fn RMD160Final "uint8_t digest[RMD160_DIGEST_LENGTH]" "RMD160_CTX *context"
+.Ft void
+.Fn RMD160Transform "uint32_t state[5]" "const uint8_t block[RMD160_BLOCK_LENGTH]"
+.Ft "char *"
+.Fn RMD160End "RMD160_CTX *context" "char *buf"
+.Ft "char *"
+.Fn RMD160File "const char *filename" "char *buf"
+.Ft "char *"
+.Fn RMD160FileChunk "const char *filename" "char *buf" "off_t offset" "off_t length"
+.Ft "char *"
+.Fn RMD160Data "const uint8_t *data" "size_t len" "char *buf"
+.Sh DESCRIPTION
+The RMD160 functions implement the 160-bit RIPE message digest hash algorithm
+(RMD-160).
+RMD-160 is used to generate a condensed representation
+of a message called a message digest.
+The algorithm takes a
+message less than 2^64 bits as input and produces a 160-bit digest
+suitable for use as a digital signature.
+.Pp
+The RMD160 functions are considered to be more secure than the
+.Xr md4 3 ,
+.Xr md5 3
+and
+.Xr sha1 3
+functions.
+All share a similar interface.
+.Pp
+The
+.Fn RMD160Init
+function initializes a RMD160_CTX
+.Ar context
+for use with
+.Fn RMD160Update ,
+and
+.Fn RMD160Final .
+The
+.Fn RMD160Update
+function adds
+.Ar data
+of length
+.Ar nbytes
+to the RMD160_CTX specified by
+.Ar context .
+.Fn RMD160Final
+is called when all data has been added via
+.Fn RMD160Update
+and stores a message digest in the
+.Ar digest
+parameter.
+.Pp
+The
+.Fn RMD160Pad
+function can be used to apply padding to the message digest as in
+.Fn RMD160Final ,
+but the current context can still be used with
+.Fn RMD160Update .
+.Pp
+The
+.Fn RMD160Transform
+function is used by
+.Fn RMD160Update
+to hash 512-bit blocks and forms the core of the algorithm.
+Most programs should use the interface provided by
+.Fn RMD160Init ,
+.Fn RMD160Update
+and
+.Fn RMD160Final
+instead of calling
+.Fn RMD160Transform
+directly.
+.Pp
+The
+.Fn RMD160End
+function is a front end for
+.Fn RMD160Final
+which converts the digest into an
+.Tn ASCII
+representation of the 160 bit digest in hexadecimal.
+.Pp
+The
+.Fn RMD160File
+function calculates the digest for a file and returns the result via
+.Fn RMD160End .
+If
+.Fn RMD160File
+is unable to open the file a NULL pointer is returned.
+.Pp
+.Fn RMD160FileChunk
+behaves like
+.Fn RMD160File
+but calculates the digest only for that portion of the file starting at
+.Fa offset
+and continuing for
+.Fa length
+bytes or until end of file is reached, whichever comes first.
+A zero
+.Fa length
+can be specified to read until end of file.
+A negative
+.Fa length
+or
+.Fa offset
+will be ignored.
+.Pp
+The
+.Fn RMD160Data
+function
+calculates the digest of an arbitrary string and returns the result via
+.Fn RMD160End .
+.Pp
+For each of the
+.Fn RMD160End ,
+.Fn RMD160File ,
+and
+.Fn RMD160Data
+functions the
+.Ar buf
+parameter should either be a string of at least 41 characters in
+size or a NULL pointer.
+In the latter case, space will be dynamically allocated via
+.Xr malloc 3
+and should be freed using
+.Xr free 3
+when it is no longer needed.
+.Sh EXAMPLES
+The follow code fragment will calculate the digest for
+the string "abc" which is ``0x8eb208f7e05d987a9b044a8e98c6b087f15a0bfc''.
+.Bd -literal -offset indent
+RMD160_CTX rmd;
+uint8_t results[RMD160_DIGEST_LENGTH];
+char *buf;
+int n;
+
+buf = "abc";
+n = strlen(buf);
+RMD160Init(&rmd);
+RMD160Update(&rmd, (uint8_t *)buf, n);
+RMD160Final(results, &rmd);
+
+/* Print the digest as one long hex value */
+printf("0x");
+for (n = 0; n < RMD160_DIGEST_LENGTH; n++)
+	printf("%02x", results[n]);
+putchar('\en');
+.Ed
+.Pp
+Alternately, the helper functions could be used in the following way:
+.Bd -literal -offset indent
+RMD160_CTX rmd;
+uint8_t output[RMD160_DIGEST_STRING_LENGTH];
+char *buf = "abc";
+
+printf("0x%s\en", RMD160Data(buf, strlen(buf), output));
+.Ed
+.Sh SEE ALSO
+.Xr cksum 1 ,
+.Xr md4 3 ,
+.Xr md5 3 ,
+.Xr sha1 3 ,
+.Xr sha2 3
+.Rs
+.%A H. Dobbertin, A. Bosselaers, B. Preneel
+.%T RIPEMD-160, a strengthened version of RIPEMD
+.Re
+.Rs
+.%T Information technology - Security techniques - Hash-functions - Part 3: Dedicated hash-functions
+.%O ISO/IEC 10118-3
+.Re
+.Rs
+.%A H. Dobbertin, A. Bosselaers, B. Preneel
+.%T The RIPEMD-160 cryptographic hash function
+.%J Dr. Dobb's Journal
+.%V Vol. 22, No. 1
+.%D January 1997
+.%P pp. 24-28
+.Re
+.Sh HISTORY
+The RMD-160 functions appeared in
+.Ox 2.1 .
+.Sh AUTHORS
+This implementation of RMD-160 was written by Markus Friedl.
+.Pp
+The
+.Fn RMD160End ,
+.Fn RMD160File ,
+.Fn RMD160FileChunk ,
+and
+.Fn RMD160Data
+helper functions are derived from code written by Poul-Henning Kamp.
+.Sh CAVEATS
+If a message digest is to be copied to a multi-byte type (ie:
+an array of five 32-bit integers) it will be necessary to
+perform byte swapping on little endian machines such as the i386, alpha,
+and vax.

+ 237 - 0
libmd.mod/libmd/man/sha1.3

@@ -0,0 +1,237 @@
+.\"	$OpenBSD: sha1.3,v 1.36 2007/05/31 19:19:29 jmc Exp $
+.\"
+.\" Copyright (c) 1997, 2004 Todd C. Miller <[email protected]>
+.\"
+.\" Permission to use, copy, modify, and distribute this software for any
+.\" purpose with or without fee is hereby granted, provided that the above
+.\" copyright notice and this permission notice appear in all copies.
+.\"
+.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+.\"
+.\" See http://csrc.nist.gov/publications/fips/fips180-1/fip180-1.txt
+.\" for the detailed standard
+.\"
+.Dd $Mdocdate: February 13 2008 $
+.Dt SHA1 3
+.Os
+.Sh NAME
+.Nm SHA1Init ,
+.Nm SHA1Update ,
+.Nm SHA1Pad ,
+.Nm SHA1Final ,
+.Nm SHA1Transform ,
+.Nm SHA1End ,
+.Nm SHA1File ,
+.Nm SHA1FileChunk ,
+.Nm SHA1Data
+.Nd calculate the NIST Secure Hash Algorithm
+.Sh LIBRARY
+.Lb libmd
+.Sh SYNOPSIS
+.Fd #include <sys/types.h>
+.Fd #include <sha1.h>
+.Ft void
+.Fn SHA1Init "SHA1_CTX *context"
+.Ft void
+.Fn SHA1Update "SHA1_CTX *context" "const uint8_t *data" "size_t len"
+.Ft void
+.Fn SHA1Pad "SHA1_CTX *context"
+.Ft void
+.Fn SHA1Final "uint8_t digest[SHA1_DIGEST_LENGTH]" "SHA1_CTX *context"
+.Ft void
+.Fn SHA1Transform "uint32_t state[5]" "const uint8_t buffer[SHA1_BLOCK_LENGTH]"
+.Ft "char *"
+.Fn SHA1End "SHA1_CTX *context" "char *buf"
+.Ft "char *"
+.Fn SHA1File "const char *filename" "char *buf"
+.Ft "char *"
+.Fn SHA1FileChunk "const char *filename" "char *buf" "off_t offset" "off_t length"
+.Ft "char *"
+.Fn SHA1Data "const uint8_t *data" "size_t len" "char *buf"
+.Sh DESCRIPTION
+The SHA1 functions implement the NIST Secure Hash Algorithm (SHA-1),
+FIPS PUB 180-1.
+SHA-1 is used to generate a condensed representation
+of a message called a message digest.
+The algorithm takes a
+message less than 2^64 bits as input and produces a 160-bit digest
+suitable for use as a digital signature.
+.Pp
+While the SHA1 functions are considered to be more secure than the
+.Xr md4 3
+and
+.Xr md5 3
+functions with which they share a similar interface, they are considered
+insecure as of 2005, and as of 2020 chosen-prefix attacks have become
+practical, thus these must not be used in cryptographic contexts.
+.Pp
+The
+.Fn SHA1Init
+function initializes a SHA1_CTX
+.Ar context
+for use with
+.Fn SHA1Update ,
+and
+.Fn SHA1Final .
+The
+.Fn SHA1Update
+function adds
+.Ar data
+of length
+.Ar len
+to the SHA1_CTX specified by
+.Ar context .
+.Fn SHA1Final
+is called when all data has been added via
+.Fn SHA1Update
+and stores a message digest in the
+.Ar digest
+parameter.
+.Pp
+The
+.Fn SHA1Pad
+function can be used to apply padding to the message digest as in
+.Fn SHA1Final ,
+but the current context can still be used with
+.Fn SHA1Update .
+.Pp
+The
+.Fn SHA1Transform
+function is used by
+.Fn SHA1Update
+to hash 512-bit blocks and forms the core of the algorithm.
+Most programs should use the interface provided by
+.Fn SHA1Init ,
+.Fn SHA1Update
+and
+.Fn SHA1Final
+instead of calling
+.Fn SHA1Transform
+directly.
+.Pp
+The
+.Fn SHA1End
+function is a front end for
+.Fn SHA1Final
+which converts the digest into an
+.Tn ASCII
+representation of the 160 bit digest in hexadecimal.
+.Pp
+The
+.Fn SHA1File
+function calculates the digest for a file and returns the result via
+.Fn SHA1End .
+If
+.Fn SHA1File
+is unable to open the file a NULL pointer is returned.
+.Pp
+.Fn SHA1FileChunk
+behaves like
+.Fn SHA1File
+but calculates the digest only for that portion of the file starting at
+.Fa offset
+and continuing for
+.Fa length
+bytes or until end of file is reached, whichever comes first.
+A zero
+.Fa length
+can be specified to read until end of file.
+A negative
+.Fa length
+or
+.Fa offset
+will be ignored.
+.Pp
+The
+.Fn SHA1Data
+function
+calculates the digest of an arbitrary string and returns the result via
+.Fn SHA1End .
+.Pp
+For each of the
+.Fn SHA1End ,
+.Fn SHA1File ,
+and
+.Fn SHA1Data
+functions the
+.Ar buf
+parameter should either be a string of at least 41 characters in
+size or a NULL pointer.
+In the latter case, space will be dynamically allocated via
+.Xr malloc 3
+and should be freed using
+.Xr free 3
+when it is no longer needed.
+.Sh EXAMPLES
+The follow code fragment will calculate the digest for
+the string "abc" which is ``0xa9993e364706816aba3e25717850c26c9cd0d89d''.
+.Bd -literal -offset indent
+SHA1_CTX sha;
+uint8_t results[SHA1_DIGEST_LENGTH];
+char *buf;
+int n;
+
+buf = "abc";
+n = strlen(buf);
+SHA1Init(&sha);
+SHA1Update(&sha, (uint8_t *)buf, n);
+SHA1Final(results, &sha);
+
+/* Print the digest as one long hex value */
+printf("0x");
+for (n = 0; n < SHA1_DIGEST_LENGTH; n++)
+	printf("%02x", results[n]);
+putchar('\en');
+.Ed
+.Pp
+Alternately, the helper functions could be used in the following way:
+.Bd -literal -offset indent
+uint8_t output[SHA1_DIGEST_STRING_LENGTH];
+char *buf = "abc";
+
+printf("0x%s\en", SHA1Data(buf, strlen(buf), output));
+.Ed
+.Sh SEE ALSO
+.Xr cksum 1 ,
+.Xr sha1 1 ,
+.Xr md4 3 ,
+.Xr md5 3 ,
+.Xr rmd160 3 ,
+.Xr sha2 3
+.Rs
+.%A J. Burrows
+.%T The Secure Hash Standard
+.%O FIPS PUB 180-1
+.Re
+.Rs
+.%A D. Eastlake and P. Jones
+.%T US Secure Hash Algorithm 1
+.%O RFC 3174
+.Re
+.Sh HISTORY
+The SHA-1 functions appeared in
+.Ox 2.0 .
+.Sh AUTHORS
+This implementation of SHA-1 was written by Steve Reid.
+.Pp
+The
+.Fn SHA1End ,
+.Fn SHA1File ,
+.Fn SHA1FileChunk ,
+and
+.Fn SHA1Data
+helper functions are derived from code written by Poul-Henning Kamp.
+.Sh CAVEATS
+This implementation of SHA-1 has not been validated by NIST
+and as such is not in official compliance with the standard.
+.Pp
+If a message digest is to be copied to a multi-byte type (ie:
+an array of five 32-bit integers) it will be necessary to
+perform byte swapping on little endian machines such as the i386, alpha,
+and vax.

+ 283 - 0
libmd.mod/libmd/man/sha2.3

@@ -0,0 +1,283 @@
+.\"	$OpenBSD: sha2.3,v 1.15 2008/09/06 12:00:19 djm Exp $
+.\"
+.\" Copyright (c) 2003, 2004 Todd C. Miller <[email protected]>
+.\"
+.\" Permission to use, copy, modify, and distribute this software for any
+.\" purpose with or without fee is hereby granted, provided that the above
+.\" copyright notice and this permission notice appear in all copies.
+.\"
+.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+.\"
+.\" Sponsored in part by the Defense Advanced Research Projects
+.\" Agency (DARPA) and Air Force Research Laboratory, Air Force
+.\" Materiel Command, USAF, under agreement number F39502-99-1-0512.
+.\"
+.\" See http://www.nist.gov/sha/ for the detailed standard
+.\"
+.Dd $Mdocdate: September 12 2008 $
+.Dt SHA2 3
+.Os
+.Sh NAME
+.Nm SHA256Init ,
+.Nm SHA256Update ,
+.Nm SHA256Pad ,
+.Nm SHA256Final ,
+.Nm SHA256Transform ,
+.Nm SHA256End ,
+.Nm SHA256File ,
+.Nm SHA256FileChunk ,
+.Nm SHA256Data
+.Nd calculate the NIST Secure Hash Standard (version 2)
+.Sh LIBRARY
+.Lb libmd
+.Sh SYNOPSIS
+.Fd #include <sys/types.h>
+.Fd #include <sha2.h>
+.Ft void
+.Fn SHA256Init "SHA2_CTX *context"
+.Ft void
+.Fn SHA256Update "SHA2_CTX *context" "const uint8_t *data" "size_t len"
+.Ft void
+.Fn SHA256Pad "SHA2_CTX *context"
+.Ft void
+.Fn SHA256Final "uint8_t digest[SHA256_DIGEST_LENGTH]" "SHA2_CTX *context"
+.Ft void
+.Fn SHA256Transform "uint32_t state[8]" "const uint8_t buffer[SHA256_BLOCK_LENGTH]"
+.Ft "char *"
+.Fn SHA256End "SHA2_CTX *context" "char *buf"
+.Ft "char *"
+.Fn SHA256File "const char *filename" "char *buf"
+.Ft "char *"
+.Fn SHA256FileChunk "const char *filename" "char *buf" "off_t offset" "off_t length"
+.Ft "char *"
+.Fn SHA256Data "uint8_t *data" "size_t len" "char *buf"
+.Ft void
+.Fn SHA384Init "SHA2_CTX *context"
+.Ft void
+.Fn SHA384Update "SHA2_CTX *context" "const uint8_t *data" "size_t len"
+.Ft void
+.Fn SHA384Pad "SHA2_CTX *context"
+.Ft void
+.Fn SHA384Final "uint8_t digest[SHA384_DIGEST_LENGTH]" "SHA2_CTX *context"
+.Ft void
+.Fn SHA384Transform "uint64_t state[8]" "const uint8_t buffer[SHA384_BLOCK_LENGTH]"
+.Ft "char *"
+.Fn SHA384End "SHA2_CTX *context" "char *buf"
+.Ft "char *"
+.Fn SHA384File "char *filename" "char *buf"
+.Ft "char *"
+.Fn SHA384FileChunk "char *filename" "char *buf" "off_t offset" "off_t length"
+.Ft "char *"
+.Fn SHA384Data "uint8_t *data" "size_t len" "char *buf"
+.Ft void
+.Fn SHA512Init "SHA2_CTX *context"
+.Ft void
+.Fn SHA512Update "SHA2_CTX *context" "const uint8_t *data" "size_t len"
+.Ft void
+.Fn SHA512Pad "SHA2_CTX *context"
+.Ft void
+.Fn SHA512Final "uint8_t digest[SHA512_DIGEST_LENGTH]" "SHA2_CTX *context"
+.Ft void
+.Fn SHA512Transform "uint64_t state[8]" "const uint8_t buffer[SHA512_BLOCK_LENGTH]"
+.Ft "char *"
+.Fn SHA512End "SHA2_CTX *context" "char *buf"
+.Ft "char *"
+.Fn SHA512File "char *filename" "char *buf"
+.Ft "char *"
+.Fn SHA512FileChunk "char *filename" "char *buf" "off_t offset" "off_t length"
+.Ft "char *"
+.Fn SHA512Data "uint8_t *data" "size_t len" "char *buf"
+.Sh DESCRIPTION
+The SHA2 functions implement the NIST Secure Hash Standard,
+FIPS PUB 180-2.
+The SHA2 functions are used to generate a condensed representation of a
+message called a message digest, suitable for use as a digital signature.
+There are three families of functions, with names corresponding to
+the number of bits in the resulting message digest.
+The SHA-256 functions are limited to processing a message of less
+than 2^64 bits as input.
+The SHA-384 and SHA-512 functions can process a message of at most 2^128 - 1
+bits as input.
+.Pp
+The SHA2 functions are considered to be more secure than the
+.Xr sha1 3
+functions with which they share a similar interface.
+The 256, 384, and 512-bit versions of SHA2 share the same interface.
+For brevity, only the 256-bit variants are described below.
+.Pp
+The
+.Fn SHA256Init
+function initializes a SHA2_CTX
+.Ar context
+for use with
+.Fn SHA256Update
+and
+.Fn SHA256Final .
+The
+.Fn SHA256Update
+function adds
+.Ar data
+of length
+.Ar len
+to the SHA2_CTX specified by
+.Ar context .
+.Fn SHA256Final
+is called when all data has been added via
+.Fn SHA256Update
+and stores a message digest in the
+.Ar digest
+parameter.
+.Pp
+The
+.Fn SHA256Pad
+function can be used to apply padding to the message digest as in
+.Fn SHA256Final ,
+but the current context can still be used with
+.Fn SHA256Update .
+.Pp
+The
+.Fn SHA256Transform
+function is used by
+.Fn SHA256Update
+to hash 512-bit blocks and forms the core of the algorithm.
+Most programs should use the interface provided by
+.Fn SHA256Init ,
+.Fn SHA256Update ,
+and
+.Fn SHA256Final
+instead of calling
+.Fn SHA256Transform
+directly.
+.Pp
+The
+.Fn SHA256End
+function is a front end for
+.Fn SHA256Final
+which converts the digest into an
+.Tn ASCII
+representation of the digest in hexadecimal.
+.Pp
+The
+.Fn SHA256File
+function calculates the digest for a file and returns the result via
+.Fn SHA256End .
+If
+.Fn SHA256File
+is unable to open the file, a
+.Dv NULL
+pointer is returned.
+.Pp
+.Fn SHA256FileChunk
+behaves like
+.Fn SHA256File
+but calculates the digest only for that portion of the file starting at
+.Fa offset
+and continuing for
+.Fa length
+bytes or until end of file is reached, whichever comes first.
+A zero
+.Fa length
+can be specified to read until end of file.
+A negative
+.Fa length
+or
+.Fa offset
+will be ignored.
+.Pp
+The
+.Fn SHA256Data
+function
+calculates the digest of an arbitrary string and returns the result via
+.Fn SHA256End .
+.Pp
+For each of the
+.Fn SHA256End ,
+.Fn SHA256File ,
+.Fn SHA256FileChunk ,
+and
+.Fn SHA256Data
+functions the
+.Ar buf
+parameter should either be a string large enough to hold the resulting digest
+(e.g.\&
+.Ev SHA256_DIGEST_STRING_LENGTH ,
+.Ev SHA384_DIGEST_STRING_LENGTH ,
+or
+.Ev SHA512_DIGEST_STRING_LENGTH ,
+depending on the function being used)
+or a
+.Dv NULL
+pointer.
+In the latter case, space will be dynamically allocated via
+.Xr malloc 3
+and should be freed using
+.Xr free 3
+when it is no longer needed.
+.Sh EXAMPLES
+The following code fragment will calculate the SHA-256 digest for the string
+.Qq abc ,
+which is
+.Dq 0xba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad .
+.Bd -literal -offset indent
+SHA2_CTX ctx;
+uint8_t results[SHA256_DIGEST_LENGTH];
+char *buf;
+int n;
+
+buf = "abc";
+n = strlen(buf);
+SHA256Init(&ctx);
+SHA256Update(&ctx, (uint8_t *)buf, n);
+SHA256Final(results, &ctx);
+
+/* Print the digest as one long hex value */
+printf("0x");
+for (n = 0; n \*(Lt SHA256_DIGEST_LENGTH; n++)
+	printf("%02x", results[n]);
+putchar('\en');
+.Ed
+.Pp
+Alternately, the helper functions could be used in the following way:
+.Bd -literal -offset indent
+uint8_t output[SHA256_DIGEST_STRING_LENGTH];
+char *buf = "abc";
+
+printf("0x%s\en", SHA256Data(buf, strlen(buf), output));
+.Ed
+.Sh SEE ALSO
+.Xr cksum 1 ,
+.Xr md4 3 ,
+.Xr md5 3 ,
+.Xr rmd160 3 ,
+.Xr sha1 3
+.Rs
+.%T Secure Hash Standard
+.%O FIPS PUB 180-2
+.Re
+.Sh HISTORY
+The SHA2 functions appeared in
+.Ox 3.4 .
+.Sh AUTHORS
+This implementation of the SHA functions was written by Aaron D. Gifford.
+.Pp
+The
+.Fn SHA256End ,
+.Fn SHA256File ,
+.Fn SHA256FileChunk ,
+and
+.Fn SHA256Data
+helper functions are derived from code written by Poul-Henning Kamp.
+.Sh CAVEATS
+This implementation of the Secure Hash Standard has not been validated by
+NIST and as such is not in official compliance with the standard.
+.Pp
+If a message digest is to be copied to a multi-byte type (i.e.\&
+an array of 32-bit integers) it will be necessary to
+perform byte swapping on little endian machines such as the i386, alpha,
+and vax.

+ 120 - 0
libmd.mod/libmd/src/Makefile.am

@@ -0,0 +1,120 @@
+## Process this file with automake to produce Makefile.in
+
+AM_CPPFLAGS = \
+	-I$(top_builddir) \
+	-I$(srcdir) \
+	-I$(top_srcdir)/include \
+	$(nil)
+
+pkgconfigdir = $(libdir)/pkgconfig
+pkgconfig_DATA = \
+	libmd.pc \
+	$(nil)
+
+lib_LTLIBRARIES = libmd.la
+
+libmd_la_helper_sources = \
+	md2hl.c \
+	md4hl.c \
+	md5hl.c \
+	rmd160hl.c \
+	sha1hl.c \
+	sha256hl.c \
+	sha384hl.c \
+	sha512hl.c \
+	$(nil)
+
+EXTRA_libmd_la_DEPENDENCIES = \
+	libmd.map
+
+libmd_la_LDFLAGS = \
+	-no-undefined \
+	-version-number $(LIBMD_ABI)
+if HAVE_LINKER_VERSION_SCRIPT
+libmd_la_LDFLAGS += \
+	-Wl,--version-script=$(srcdir)/libmd.map
+else
+libmd_la_LDFLAGS += \
+	-export-symbols libmd.sym
+EXTRA_libmd_la_DEPENDENCIES += \
+	libmd.sym
+endif
+EXTRA_libmd_la_DEPENDENCIES += \
+	helper.c \
+	$(nil)
+libmd_la_SOURCES = \
+	local-link.h \
+	md2.c \
+	md4.c \
+	md5.c \
+	rmd160.c \
+	sha1.c \
+	sha2.c \
+	$(libmd_la_helper_sources) \
+	$(nil)
+
+BUILT_SOURCES = \
+	$(libmd_la_helper_sources) \
+	$(nil)
+
+EXTRA_DIST = \
+	libmd.map \
+	libmd.pc.in \
+	helper.c \
+	$(nil)
+
+CLEANFILES = \
+	$(libmd_la_helper_sources) \
+	$(nil)
+
+DISTCLEANFILES = \
+	libmd.sym \
+	$(nil)
+
+# Generate a simple libtool symbol export list to be used as a fallback if
+# there is no version script support.
+libmd.sym: libmd.map
+	$(AM_V_GEN) $(SED) -ne 's/^[[:space:]]\{1,\}\([A-Za-z0-9]\{1,\}\);/\1/p' libmd.map > $@
+
+md2hl.c: helper.c
+	$(AM_V_GEN) $(SED) -e 's/hashinc/md2.h/g' -e 's/HASH/MD2/g' helper.c > $@
+
+md4hl.c: helper.c
+	$(AM_V_GEN) $(SED) -e 's/hashinc/md4.h/g' -e 's/HASH/MD4/g' helper.c > $@
+
+md5hl.c: helper.c
+	$(AM_V_GEN) $(SED) -e 's/hashinc/md5.h/g' -e 's/HASH/MD5/g' helper.c > $@
+
+rmd160hl.c: helper.c
+	$(AM_V_GEN) $(SED) -e 's/hashinc/rmd160.h/g' -e 's/HASH/RMD160/g' helper.c > $@
+
+sha1hl.c: helper.c
+	$(AM_V_GEN) $(SED) -e 's/hashinc/sha1.h/g' -e 's/HASH/SHA1/g' helper.c > $@
+
+sha256hl.c: helper.c
+	$(AM_V_GEN) $(SED) -e 's/hashinc/sha2.h/g' -e 's/HASH/SHA256/g' \
+	                -e 's/SHA[0-9][0-9][0-9]_CTX/SHA2_CTX/g' helper.c > $@
+
+sha384hl.c: helper.c
+	$(AM_V_GEN) $(SED) -e 's/hashinc/sha2.h/g' -e 's/HASH/SHA384/g' \
+	                -e 's/SHA[0-9][0-9][0-9]_CTX/SHA2_CTX/g' helper.c > $@
+
+sha512hl.c: helper.c
+	$(AM_V_GEN) $(SED) -e 's/hashinc/sha2.h/g' -e 's/HASH/SHA512/g' \
+	                -e 's/SHA[0-9][0-9][0-9]_CTX/SHA2_CTX/g' helper.c > $@
+
+runtimelibdir = $(libdir)
+
+install-exec-hook:
+	if [ "$(libdir)" != "$(runtimelibdir)" ]; then \
+		$(MKDIR_P) $(DESTDIR)$(runtimelibdir); \
+		mv $(DESTDIR)$(libdir)/libmd*.so.* \
+		   $(DESTDIR)$(runtimelibdir)/; \
+		soname=`readlink $(DESTDIR)$(libdir)/libmd.so`; \
+		sorelprefix=`echo $(libdir) | $(SED) -r -e 's:(^/)?[^/]+:..:g'`; \
+		ln -sf $$sorelprefix$(runtimelibdir)/$$soname \
+		       $(DESTDIR)$(libdir)/libmd.so; \
+	fi
+
+uninstall-hook:
+	rm -f $(DESTDIR)$(runtimelibdir)/libmd*.so*

+ 103 - 0
libmd.mod/libmd/src/helper.c

@@ -0,0 +1,103 @@
+/*	$OpenBSD: helper.c,v 1.9 2010/01/08 13:30:21 oga Exp $	*/
+
+/*
+ * ----------------------------------------------------------------------------
+ * "THE BEER-WARE LICENSE" (Revision 42):
+ * <[email protected]> wrote this file.  As long as you retain this notice you
+ * can do whatever you want with this stuff. If we meet some day, and you think
+ * this stuff is worth it, you can buy me a beer in return.   Poul-Henning Kamp
+ * ----------------------------------------------------------------------------
+ */
+
+#include <config.h>
+
+#include <sys/stat.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#include <hashinc>
+
+#ifndef MIN
+# define MIN(x, y) (((x) < (y)) ? (x) : (y))
+#endif
+
+/* ARGSUSED */
+char *
+HASHEnd(HASH_CTX *ctx, char *buf)
+{
+	int i;
+	uint8_t digest[HASH_DIGEST_LENGTH];
+	static const char hex[] = "0123456789abcdef";
+
+	if (buf == NULL && (buf = malloc(HASH_DIGEST_STRING_LENGTH)) == NULL)
+		return (NULL);
+
+	HASHFinal(digest, ctx);
+	for (i = 0; i < HASH_DIGEST_LENGTH; i++) {
+		buf[i + i] = hex[digest[i] >> 4];
+		buf[i + i + 1] = hex[digest[i] & 0x0f];
+	}
+	buf[i + i] = '\0';
+	memset(digest, 0, sizeof(digest));
+	return (buf);
+}
+
+char *
+HASHFileChunk(const char *filename, char *buf, off_t off, off_t len)
+{
+	struct stat sb;
+	uint8_t buffer[BUFSIZ];
+	HASH_CTX ctx;
+	int fd, save_errno;
+	ssize_t nr;
+
+	HASHInit(&ctx);
+
+	if ((fd = open(filename, O_RDONLY)) < 0)
+		return (NULL);
+	if (len == 0) {
+		if (fstat(fd, &sb) == -1) {
+			close(fd);
+			return (NULL);
+		}
+		len = sb.st_size;
+	}
+	if (off > 0 && lseek(fd, off, SEEK_SET) < 0) {
+		close(fd);
+		return (NULL);
+	}
+
+	while ((nr = read(fd, buffer, MIN((off_t)sizeof(buffer), len))) > 0) {
+		HASHUpdate(&ctx, buffer, (size_t)nr);
+		if (len > 0 && (len -= nr) == 0)
+			break;
+	}
+
+	save_errno = errno;
+	close(fd);
+	errno = save_errno;
+	return (nr < 0 ? NULL : HASHEnd(&ctx, buf));
+}
+
+char *
+HASHFile(const char *filename, char *buf)
+{
+	return (HASHFileChunk(filename, buf, (off_t)0, (off_t)0));
+}
+
+char *
+HASHData(const uint8_t *data, size_t len, char *buf)
+{
+	HASH_CTX ctx;
+
+	HASHInit(&ctx);
+	HASHUpdate(&ctx, data, len);
+	return (HASHEnd(&ctx, buf));
+}

+ 84 - 0
libmd.mod/libmd/src/libmd.map

@@ -0,0 +1,84 @@
+LIBMD_0.0 {
+global:
+	MD2Data;
+	MD2End;
+	MD2File;
+	MD2FileChunk;
+	MD2Final;
+	MD2Init;
+	MD2Update;
+	MD2Transform;
+
+	MD4Data;
+	MD4End;
+	MD4File;
+	MD4FileChunk;
+	MD4Final;
+	MD4Init;
+	MD4Pad;
+	MD4Transform;
+	MD4Update;
+
+	MD5Data;
+	MD5End;
+	MD5File;
+	MD5FileChunk;
+	MD5Final;
+	MD5Init;
+	MD5Pad;
+	MD5Transform;
+	MD5Update;
+
+	RMD160Data;
+	RMD160End;
+	RMD160File;
+	RMD160FileChunk;
+	RMD160Final;
+	RMD160Init;
+	RMD160Pad;
+	RMD160Transform;
+	RMD160Update;
+
+	SHA1Data;
+	SHA1End;
+	SHA1File;
+	SHA1FileChunk;
+	SHA1Final;
+	SHA1Init;
+	SHA1Pad;
+	SHA1Transform;
+	SHA1Update;
+
+	SHA256Data;
+	SHA256End;
+	SHA256File;
+	SHA256FileChunk;
+	SHA256Final;
+	SHA256Init;
+	SHA256Pad;
+	SHA256Transform;
+	SHA256Update;
+
+	SHA384Data;
+	SHA384End;
+	SHA384File;
+	SHA384FileChunk;
+	SHA384Final;
+	SHA384Init;
+	SHA384Pad;
+	SHA384Transform;
+	SHA384Update;
+
+	SHA512Data;
+	SHA512End;
+	SHA512File;
+	SHA512FileChunk;
+	SHA512Final;
+	SHA512Init;
+	SHA512Pad;
+	SHA512Transform;
+	SHA512Update;
+
+local:
+	*;
+};

+ 11 - 0
libmd.mod/libmd/src/libmd.pc.in

@@ -0,0 +1,11 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: libmd
+Description: Message Digest functions from BSD systems
+Version: @VERSION@
+URL: https://www.hadrons.org/software/libmd/
+Libs: -L${libdir} -lmd
+Cflags: -I${includedir}

+ 60 - 0
libmd.mod/libmd/src/local-link.h

@@ -0,0 +1,60 @@
+/*
+ * Copyright © 2015, 2019 Guillem Jover <[email protected]>
+ *
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef LIBMD_LOCAL_LINK_H
+#define LIBMD_LOCAL_LINK_H
+
+#define libmd_link_warning(symbol, msg) \
+	static const char libmd_emit_link_warning_##symbol[] \
+		__attribute__((__used__,__section__(".gnu.warning." #symbol))) = msg;
+
+/*
+ * On Windows we cannot use proper aliases, and using the /EXPORT linker flag
+ * is too cumbersome, as it does not work when static linking, and when
+ * dynamic linking it does not make the aliases visible within the DLL itself.
+ *
+ * Instead we use normal function wrapper in those cases, which are way more
+ * maintainable.
+ */
+#if !defined(_MSC_VER) && !defined(__APPLE__)
+#define libmd_alias(alias, symbol) \
+	extern __typeof(symbol) alias __attribute__((__alias__(#symbol)))
+#endif
+
+#ifdef __ELF__
+#define libmd_symver_default(alias, symbol, version) \
+	__asm__(".symver " #symbol "," #alias "@@" #version)
+
+#define libmd_symver_variant(alias, symbol, version) \
+	__asm__(".symver " #symbol "," #alias "@" #version)
+#else
+#define libmd_symver_default(alias, symbol, version) \
+	extern __typeof(symbol) alias __attribute__((__alias__(#symbol)))
+
+#define libmd_symver_variant(alias, symbol, version)
+#endif
+
+#endif

+ 170 - 0
libmd.mod/libmd/src/md2.c

@@ -0,0 +1,170 @@
+/*	$NetBSD: md2.c,v 1.7 2012/06/25 22:32:44 abs Exp $	*/
+
+/*
+ * Copyright (c) 2001 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Andrew Brown.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``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 FOUNDATION OR CONTRIBUTORS
+ * 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.
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+
+#include <assert.h>
+#include <md2.h>
+#include <string.h>
+
+#define _DIAGASSERT(x)
+
+#if !HAVE_MD2_H
+
+/* cut-n-pasted from rfc1319 */
+static unsigned char S[256] = {
+	41, 46, 67, 201, 162, 216, 124, 1, 61, 54, 84, 161, 236, 240, 6,
+	19, 98, 167, 5, 243, 192, 199, 115, 140, 152, 147, 43, 217, 188,
+	76, 130, 202, 30, 155, 87, 60, 253, 212, 224, 22, 103, 66, 111, 24,
+	138, 23, 229, 18, 190, 78, 196, 214, 218, 158, 222, 73, 160, 251,
+	245, 142, 187, 47, 238, 122, 169, 104, 121, 145, 21, 178, 7, 63,
+	148, 194, 16, 137, 11, 34, 95, 33, 128, 127, 93, 154, 90, 144, 50,
+	39, 53, 62, 204, 231, 191, 247, 151, 3, 255, 25, 48, 179, 72, 165,
+	181, 209, 215, 94, 146, 42, 172, 86, 170, 198, 79, 184, 56, 210,
+	150, 164, 125, 182, 118, 252, 107, 226, 156, 116, 4, 241, 69, 157,
+	112, 89, 100, 113, 135, 32, 134, 91, 207, 101, 230, 45, 168, 2, 27,
+	96, 37, 173, 174, 176, 185, 246, 28, 70, 97, 105, 52, 64, 126, 15,
+	85, 71, 163, 35, 221, 81, 175, 58, 195, 92, 249, 206, 186, 197,
+	234, 38, 44, 83, 13, 110, 133, 40, 132, 9, 211, 223, 205, 244, 65,
+	129, 77, 82, 106, 220, 55, 200, 108, 193, 171, 250, 36, 225, 123,
+	8, 12, 189, 177, 74, 120, 136, 149, 139, 227, 99, 232, 109, 233,
+	203, 213, 254, 59, 0, 29, 57, 242, 239, 183, 14, 102, 88, 208, 228,
+	166, 119, 114, 248, 235, 117, 75, 10, 49, 68, 80, 180, 143, 237,
+	31, 26, 219, 153, 141, 51, 159, 17, 131, 20
+};
+
+/* cut-n-pasted from rfc1319 */
+static const unsigned char *pad[] = {
+	(const unsigned char *)"",
+	(const unsigned char *)"\001",
+	(const unsigned char *)"\002\002",
+	(const unsigned char *)"\003\003\003",
+	(const unsigned char *)"\004\004\004\004",
+	(const unsigned char *)"\005\005\005\005\005",
+	(const unsigned char *)"\006\006\006\006\006\006",
+	(const unsigned char *)"\007\007\007\007\007\007\007",
+	(const unsigned char *)"\010\010\010\010\010\010\010\010",
+	(const unsigned char *)"\011\011\011\011\011\011\011\011\011",
+	(const unsigned char *)"\012\012\012\012\012\012\012\012\012\012",
+	(const unsigned char *)"\013\013\013\013\013\013\013\013\013\013\013",
+	(const unsigned char *)
+	"\014\014\014\014\014\014\014\014\014\014\014\014",
+	(const unsigned char *)
+	"\015\015\015\015\015\015\015\015\015\015\015\015\015",
+	(const unsigned char *)
+	"\016\016\016\016\016\016\016\016\016\016\016\016\016\016",
+	(const unsigned char *)
+	"\017\017\017\017\017\017\017\017\017\017\017\017\017\017\017",
+	(const unsigned char *)
+	"\020\020\020\020\020\020\020\020\020\020\020\020\020\020\020\020"
+};
+
+/*
+ * XXX This should not be visible, but due to an accident, it is
+ * XXX so it must remain so.
+ */
+/*static*/ void MD2Transform(MD2_CTX *);
+
+void
+MD2Init(MD2_CTX *context)
+{
+	_DIAGASSERT(context != 0);
+
+	context->i = 16;
+	memset(&context->C[0], 0, sizeof(context->C));
+	memset(&context->X[0], 0, sizeof(context->X));
+}
+
+void
+MD2Update(MD2_CTX *context, const unsigned char *input, unsigned int inputLen)
+{
+	unsigned int idx, piece;
+
+	_DIAGASSERT(context != 0);
+	_DIAGASSERT(input != 0);
+
+	for (idx = 0; idx < inputLen; idx += piece) {
+		piece = 32 - context->i;
+		if ((inputLen - idx) < piece)
+			piece = inputLen - idx;
+		memcpy(&context->X[context->i], &input[idx], (size_t)piece);
+		if ((context->i += piece) == 32)
+			MD2Transform(context); /* resets i */
+	}
+}
+
+void
+MD2Final(unsigned char digest[16], MD2_CTX *context)
+{
+	unsigned int padlen;
+
+	_DIAGASSERT(digest != 0);
+	_DIAGASSERT(context != 0);
+
+	/* padlen should be 1..16 */
+	padlen = 32 - context->i;
+
+	/* add padding */
+	MD2Update(context, pad[padlen], padlen);
+
+	/* add checksum */
+	MD2Update(context, &context->C[0], (unsigned int) sizeof(context->C));
+
+	/* copy out final digest */
+	memcpy(digest, &context->X[0], (size_t)16);
+
+	/* reset the context */
+	MD2Init(context);
+}
+
+/*static*/ void
+MD2Transform(MD2_CTX *context)
+{
+	uint32_t l, j, k, t;
+
+	/* set block "3" and update "checksum" */
+	for (l = context->C[15], j = 0; j < 16; j++) {
+		context->X[32 + j] = context->X[j] ^ context->X[16 + j];
+		l = context->C[j] ^= S[context->X[16 + j] ^ l];
+	}
+
+	/* mangle input block */
+	for (t = j = 0; j < 18; t = (t + j) % 256, j++)
+		for (k = 0; k < 48; k++)
+			t = context->X[k] = (context->X[k] ^ S[t]);
+
+	/* reset input pointer */
+	context->i = 16;
+}
+
+#endif /* !HAVE_MD2_H */

+ 233 - 0
libmd.mod/libmd/src/md4.c

@@ -0,0 +1,233 @@
+/*	$OpenBSD: md4.c,v 1.6 2004/05/28 15:10:27 millert Exp $	*/
+
+/*
+ * This code implements the MD4 message-digest algorithm.
+ * The algorithm is due to Ron Rivest.	This code was
+ * written by Colin Plumb in 1993, no copyright is claimed.
+ * This code is in the public domain; do with it what you wish.
+ * Todd C. Miller modified the MD5 code to do MD4 based on RFC 1186.
+ *
+ * Equivalent code is available from RSA Data Security, Inc.
+ * This code has been tested against that, and is equivalent,
+ * except that you don't need to include two pages of legalese
+ * with every copy.
+ *
+ * To compute the message digest of a chunk of bytes, declare an
+ * MD4Context structure, pass it to MD4Init, call MD4Update as
+ * needed on buffers full of bytes, and then call MD4Final, which
+ * will fill a supplied 16-byte array with the digest.
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <string.h>
+#include <md4.h>
+
+#define PUT_64BIT_LE(cp, value) do {					\
+	(cp)[7] = (value) >> 56;					\
+	(cp)[6] = (value) >> 48;					\
+	(cp)[5] = (value) >> 40;					\
+	(cp)[4] = (value) >> 32;					\
+	(cp)[3] = (value) >> 24;					\
+	(cp)[2] = (value) >> 16;					\
+	(cp)[1] = (value) >> 8;						\
+	(cp)[0] = (value); } while (0)
+
+#define PUT_32BIT_LE(cp, value) do {					\
+	(cp)[3] = (value) >> 24;					\
+	(cp)[2] = (value) >> 16;					\
+	(cp)[1] = (value) >> 8;						\
+	(cp)[0] = (value); } while (0)
+
+static uint8_t PADDING[MD4_BLOCK_LENGTH] = {
+	0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+/*
+ * Start MD4 accumulation.
+ * Set bit count to 0 and buffer to mysterious initialization constants.
+ */
+void
+MD4Init(MD4_CTX *ctx)
+{
+	ctx->count = 0;
+	ctx->state[0] = 0x67452301;
+	ctx->state[1] = 0xefcdab89;
+	ctx->state[2] = 0x98badcfe;
+	ctx->state[3] = 0x10325476;
+}
+
+/*
+ * Update context to reflect the concatenation of another buffer full
+ * of bytes.
+ */
+void
+MD4Update(MD4_CTX *ctx, const unsigned char *input, size_t len)
+{
+	size_t have, need;
+
+	/* Check how many bytes we already have and how many more we need. */
+	have = (size_t)((ctx->count >> 3) & (MD4_BLOCK_LENGTH - 1));
+	need = MD4_BLOCK_LENGTH - have;
+
+	/* Update bitcount */
+	ctx->count += (uint64_t)len << 3;
+
+	if (len >= need) {
+		if (have != 0) {
+			memcpy(ctx->buffer + have, input, need);
+			MD4Transform(ctx->state, ctx->buffer);
+			input += need;
+			len -= need;
+			have = 0;
+		}
+
+		/* Process data in MD4_BLOCK_LENGTH-byte chunks. */
+		while (len >= MD4_BLOCK_LENGTH) {
+			MD4Transform(ctx->state, input);
+			input += MD4_BLOCK_LENGTH;
+			len -= MD4_BLOCK_LENGTH;
+		}
+	}
+
+	/* Handle any remaining bytes of data. */
+	if (len != 0)
+		memcpy(ctx->buffer + have, input, len);
+}
+
+/*
+ * Pad pad to 64-byte boundary with the bit pattern
+ * 1 0* (64-bit count of bits processed, MSB-first)
+ */
+void
+MD4Pad(MD4_CTX *ctx)
+{
+	uint8_t count[8];
+	size_t padlen;
+
+	/* Convert count to 8 bytes in little endian order. */
+	PUT_64BIT_LE(count, ctx->count);
+
+	/* Pad out to 56 mod 64. */
+	padlen = MD4_BLOCK_LENGTH -
+	    ((ctx->count >> 3) & (MD4_BLOCK_LENGTH - 1));
+	if (padlen < 1 + 8)
+		padlen += MD4_BLOCK_LENGTH;
+	MD4Update(ctx, PADDING, padlen - 8);		/* padlen - 8 <= 64 */
+	MD4Update(ctx, count, 8);
+}
+
+/*
+ * Final wrapup--call MD4Pad, fill in digest and zero out ctx.
+ */
+void
+MD4Final(unsigned char digest[MD4_DIGEST_LENGTH], MD4_CTX *ctx)
+{
+	int i;
+
+	MD4Pad(ctx);
+	if (digest != NULL) {
+		for (i = 0; i < 4; i++)
+			PUT_32BIT_LE(digest + i * 4, ctx->state[i]);
+		memset(ctx, 0, sizeof(*ctx));
+	}
+}
+
+
+/* The three core functions - F1 is optimized somewhat */
+
+/* #define F1(x, y, z) (x & y | ~x & z) */
+#define F1(x, y, z) (z ^ (x & (y ^ z)))
+#define F2(x, y, z) ((x & y) | (x & z) | (y & z))
+#define F3(x, y, z) (x ^ y ^ z)
+
+/* This is the central step in the MD4 algorithm. */
+#define MD4STEP(f, w, x, y, z, data, s) \
+	( w += f(x, y, z) + data,  w = w<<s | w>>(32-s) )
+
+/*
+ * The core of the MD4 algorithm, this alters an existing MD4 hash to
+ * reflect the addition of 16 longwords of new data.  MD4Update blocks
+ * the data and converts bytes into longwords for this routine.
+ */
+void
+MD4Transform(uint32_t state[4], const uint8_t block[MD4_BLOCK_LENGTH])
+{
+	uint32_t a, b, c, d, in[MD4_BLOCK_LENGTH / 4];
+
+#ifndef WORDS_BIGENDIAN
+	memcpy(in, block, sizeof(in));
+#else
+	for (a = 0; a < MD4_BLOCK_LENGTH / 4; a++) {
+		in[a] = (uint32_t)(
+		    (uint32_t)(block[a * 4 + 0]) |
+		    (uint32_t)(block[a * 4 + 1]) <<  8 |
+		    (uint32_t)(block[a * 4 + 2]) << 16 |
+		    (uint32_t)(block[a * 4 + 3]) << 24);
+	}
+#endif
+
+	a = state[0];
+	b = state[1];
+	c = state[2];
+	d = state[3];
+
+	MD4STEP(F1, a, b, c, d, in[ 0],  3);
+	MD4STEP(F1, d, a, b, c, in[ 1],  7);
+	MD4STEP(F1, c, d, a, b, in[ 2], 11);
+	MD4STEP(F1, b, c, d, a, in[ 3], 19);
+	MD4STEP(F1, a, b, c, d, in[ 4],  3);
+	MD4STEP(F1, d, a, b, c, in[ 5],  7);
+	MD4STEP(F1, c, d, a, b, in[ 6], 11);
+	MD4STEP(F1, b, c, d, a, in[ 7], 19);
+	MD4STEP(F1, a, b, c, d, in[ 8],  3);
+	MD4STEP(F1, d, a, b, c, in[ 9],  7);
+	MD4STEP(F1, c, d, a, b, in[10], 11);
+	MD4STEP(F1, b, c, d, a, in[11], 19);
+	MD4STEP(F1, a, b, c, d, in[12],  3);
+	MD4STEP(F1, d, a, b, c, in[13],  7);
+	MD4STEP(F1, c, d, a, b, in[14], 11);
+	MD4STEP(F1, b, c, d, a, in[15], 19);
+
+	MD4STEP(F2, a, b, c, d, in[ 0] + 0x5a827999,  3);
+	MD4STEP(F2, d, a, b, c, in[ 4] + 0x5a827999,  5);
+	MD4STEP(F2, c, d, a, b, in[ 8] + 0x5a827999,  9);
+	MD4STEP(F2, b, c, d, a, in[12] + 0x5a827999, 13);
+	MD4STEP(F2, a, b, c, d, in[ 1] + 0x5a827999,  3);
+	MD4STEP(F2, d, a, b, c, in[ 5] + 0x5a827999,  5);
+	MD4STEP(F2, c, d, a, b, in[ 9] + 0x5a827999,  9);
+	MD4STEP(F2, b, c, d, a, in[13] + 0x5a827999, 13);
+	MD4STEP(F2, a, b, c, d, in[ 2] + 0x5a827999,  3);
+	MD4STEP(F2, d, a, b, c, in[ 6] + 0x5a827999,  5);
+	MD4STEP(F2, c, d, a, b, in[10] + 0x5a827999,  9);
+	MD4STEP(F2, b, c, d, a, in[14] + 0x5a827999, 13);
+	MD4STEP(F2, a, b, c, d, in[ 3] + 0x5a827999,  3);
+	MD4STEP(F2, d, a, b, c, in[ 7] + 0x5a827999,  5);
+	MD4STEP(F2, c, d, a, b, in[11] + 0x5a827999,  9);
+	MD4STEP(F2, b, c, d, a, in[15] + 0x5a827999, 13);
+
+	MD4STEP(F3, a, b, c, d, in[ 0] + 0x6ed9eba1,  3);
+	MD4STEP(F3, d, a, b, c, in[ 8] + 0x6ed9eba1,  9);
+	MD4STEP(F3, c, d, a, b, in[ 4] + 0x6ed9eba1, 11);
+	MD4STEP(F3, b, c, d, a, in[12] + 0x6ed9eba1, 15);
+	MD4STEP(F3, a, b, c, d, in[ 2] + 0x6ed9eba1,  3);
+	MD4STEP(F3, d, a, b, c, in[10] + 0x6ed9eba1,  9);
+	MD4STEP(F3, c, d, a, b, in[ 6] + 0x6ed9eba1, 11);
+	MD4STEP(F3, b, c, d, a, in[14] + 0x6ed9eba1, 15);
+	MD4STEP(F3, a, b, c, d, in[ 1] + 0x6ed9eba1,  3);
+	MD4STEP(F3, d, a, b, c, in[ 9] + 0x6ed9eba1,  9);
+	MD4STEP(F3, c, d, a, b, in[ 5] + 0x6ed9eba1, 11);
+	MD4STEP(F3, b, c, d, a, in[13] + 0x6ed9eba1, 15);
+	MD4STEP(F3, a, b, c, d, in[ 3] + 0x6ed9eba1,  3);
+	MD4STEP(F3, d, a, b, c, in[11] + 0x6ed9eba1,  9);
+	MD4STEP(F3, c, d, a, b, in[ 7] + 0x6ed9eba1, 11);
+	MD4STEP(F3, b, c, d, a, in[15] + 0x6ed9eba1, 15);
+
+	state[0] += a;
+	state[1] += b;
+	state[2] += c;
+	state[3] += d;
+}

+ 250 - 0
libmd.mod/libmd/src/md5.c

@@ -0,0 +1,250 @@
+/*	$OpenBSD: md5.c,v 1.7 2004/05/28 15:10:27 millert Exp $	*/
+
+/*
+ * This code implements the MD5 message-digest algorithm.
+ * The algorithm is due to Ron Rivest.	This code was
+ * written by Colin Plumb in 1993, no copyright is claimed.
+ * This code is in the public domain; do with it what you wish.
+ *
+ * Equivalent code is available from RSA Data Security, Inc.
+ * This code has been tested against that, and is equivalent,
+ * except that you don't need to include two pages of legalese
+ * with every copy.
+ *
+ * To compute the message digest of a chunk of bytes, declare an
+ * MD5Context structure, pass it to MD5Init, call MD5Update as
+ * needed on buffers full of bytes, and then call MD5Final, which
+ * will fill a supplied 16-byte array with the digest.
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <string.h>
+#include <md5.h>
+
+#define PUT_64BIT_LE(cp, value) do {					\
+	(cp)[7] = (value) >> 56;					\
+	(cp)[6] = (value) >> 48;					\
+	(cp)[5] = (value) >> 40;					\
+	(cp)[4] = (value) >> 32;					\
+	(cp)[3] = (value) >> 24;					\
+	(cp)[2] = (value) >> 16;					\
+	(cp)[1] = (value) >> 8;						\
+	(cp)[0] = (value); } while (0)
+
+#define PUT_32BIT_LE(cp, value) do {					\
+	(cp)[3] = (value) >> 24;					\
+	(cp)[2] = (value) >> 16;					\
+	(cp)[1] = (value) >> 8;						\
+	(cp)[0] = (value); } while (0)
+
+static uint8_t PADDING[MD5_BLOCK_LENGTH] = {
+	0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+/*
+ * Start MD5 accumulation.  Set bit count to 0 and buffer to mysterious
+ * initialization constants.
+ */
+void
+MD5Init(MD5_CTX *ctx)
+{
+	ctx->count = 0;
+	ctx->state[0] = 0x67452301;
+	ctx->state[1] = 0xefcdab89;
+	ctx->state[2] = 0x98badcfe;
+	ctx->state[3] = 0x10325476;
+}
+
+/*
+ * Update context to reflect the concatenation of another buffer full
+ * of bytes.
+ */
+void
+MD5Update(MD5_CTX *ctx, const unsigned char *input, size_t len)
+{
+	size_t have, need;
+
+	/* Check how many bytes we already have and how many more we need. */
+	have = (size_t)((ctx->count >> 3) & (MD5_BLOCK_LENGTH - 1));
+	need = MD5_BLOCK_LENGTH - have;
+
+	/* Update bitcount */
+	ctx->count += (uint64_t)len << 3;
+
+	if (len >= need) {
+		if (have != 0) {
+			memcpy(ctx->buffer + have, input, need);
+			MD5Transform(ctx->state, ctx->buffer);
+			input += need;
+			len -= need;
+			have = 0;
+		}
+
+		/* Process data in MD5_BLOCK_LENGTH-byte chunks. */
+		while (len >= MD5_BLOCK_LENGTH) {
+			MD5Transform(ctx->state, input);
+			input += MD5_BLOCK_LENGTH;
+			len -= MD5_BLOCK_LENGTH;
+		}
+	}
+
+	/* Handle any remaining bytes of data. */
+	if (len != 0)
+		memcpy(ctx->buffer + have, input, len);
+}
+
+/*
+ * Pad pad to 64-byte boundary with the bit pattern
+ * 1 0* (64-bit count of bits processed, MSB-first)
+ */
+void
+MD5Pad(MD5_CTX *ctx)
+{
+	uint8_t count[8];
+	size_t padlen;
+
+	/* Convert count to 8 bytes in little endian order. */
+	PUT_64BIT_LE(count, ctx->count);
+
+	/* Pad out to 56 mod 64. */
+	padlen = MD5_BLOCK_LENGTH -
+	    ((ctx->count >> 3) & (MD5_BLOCK_LENGTH - 1));
+	if (padlen < 1 + 8)
+		padlen += MD5_BLOCK_LENGTH;
+	MD5Update(ctx, PADDING, padlen - 8);		/* padlen - 8 <= 64 */
+	MD5Update(ctx, count, 8);
+}
+
+/*
+ * Final wrapup--call MD5Pad, fill in digest and zero out ctx.
+ */
+void
+MD5Final(unsigned char digest[MD5_DIGEST_LENGTH], MD5_CTX *ctx)
+{
+	int i;
+
+	MD5Pad(ctx);
+	if (digest != NULL) {
+		for (i = 0; i < 4; i++)
+			PUT_32BIT_LE(digest + i * 4, ctx->state[i]);
+		memset(ctx, 0, sizeof(*ctx));
+	}
+}
+
+
+/* The four core functions - F1 is optimized somewhat */
+
+/* #define F1(x, y, z) (x & y | ~x & z) */
+#define F1(x, y, z) (z ^ (x & (y ^ z)))
+#define F2(x, y, z) F1(z, x, y)
+#define F3(x, y, z) (x ^ y ^ z)
+#define F4(x, y, z) (y ^ (x | ~z))
+
+/* This is the central step in the MD5 algorithm. */
+#define MD5STEP(f, w, x, y, z, data, s) \
+	( w += f(x, y, z) + data,  w = w<<s | w>>(32-s),  w += x )
+
+/*
+ * The core of the MD5 algorithm, this alters an existing MD5 hash to
+ * reflect the addition of 16 longwords of new data.  MD5Update blocks
+ * the data and converts bytes into longwords for this routine.
+ */
+void
+MD5Transform(uint32_t state[4], const uint8_t block[MD5_BLOCK_LENGTH])
+{
+	uint32_t a, b, c, d, in[MD5_BLOCK_LENGTH / 4];
+
+#ifndef WORDS_BIGENDIAN
+	memcpy(in, block, sizeof(in));
+#else
+	for (a = 0; a < MD5_BLOCK_LENGTH / 4; a++) {
+		in[a] = (uint32_t)(
+		    (uint32_t)(block[a * 4 + 0]) |
+		    (uint32_t)(block[a * 4 + 1]) <<  8 |
+		    (uint32_t)(block[a * 4 + 2]) << 16 |
+		    (uint32_t)(block[a * 4 + 3]) << 24);
+	}
+#endif
+
+	a = state[0];
+	b = state[1];
+	c = state[2];
+	d = state[3];
+
+	MD5STEP(F1, a, b, c, d, in[ 0] + 0xd76aa478,  7);
+	MD5STEP(F1, d, a, b, c, in[ 1] + 0xe8c7b756, 12);
+	MD5STEP(F1, c, d, a, b, in[ 2] + 0x242070db, 17);
+	MD5STEP(F1, b, c, d, a, in[ 3] + 0xc1bdceee, 22);
+	MD5STEP(F1, a, b, c, d, in[ 4] + 0xf57c0faf,  7);
+	MD5STEP(F1, d, a, b, c, in[ 5] + 0x4787c62a, 12);
+	MD5STEP(F1, c, d, a, b, in[ 6] + 0xa8304613, 17);
+	MD5STEP(F1, b, c, d, a, in[ 7] + 0xfd469501, 22);
+	MD5STEP(F1, a, b, c, d, in[ 8] + 0x698098d8,  7);
+	MD5STEP(F1, d, a, b, c, in[ 9] + 0x8b44f7af, 12);
+	MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17);
+	MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22);
+	MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122,  7);
+	MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12);
+	MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17);
+	MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22);
+
+	MD5STEP(F2, a, b, c, d, in[ 1] + 0xf61e2562,  5);
+	MD5STEP(F2, d, a, b, c, in[ 6] + 0xc040b340,  9);
+	MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14);
+	MD5STEP(F2, b, c, d, a, in[ 0] + 0xe9b6c7aa, 20);
+	MD5STEP(F2, a, b, c, d, in[ 5] + 0xd62f105d,  5);
+	MD5STEP(F2, d, a, b, c, in[10] + 0x02441453,  9);
+	MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14);
+	MD5STEP(F2, b, c, d, a, in[ 4] + 0xe7d3fbc8, 20);
+	MD5STEP(F2, a, b, c, d, in[ 9] + 0x21e1cde6,  5);
+	MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6,  9);
+	MD5STEP(F2, c, d, a, b, in[ 3] + 0xf4d50d87, 14);
+	MD5STEP(F2, b, c, d, a, in[ 8] + 0x455a14ed, 20);
+	MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905,  5);
+	MD5STEP(F2, d, a, b, c, in[ 2] + 0xfcefa3f8,  9);
+	MD5STEP(F2, c, d, a, b, in[ 7] + 0x676f02d9, 14);
+	MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20);
+
+	MD5STEP(F3, a, b, c, d, in[ 5] + 0xfffa3942,  4);
+	MD5STEP(F3, d, a, b, c, in[ 8] + 0x8771f681, 11);
+	MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16);
+	MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23);
+	MD5STEP(F3, a, b, c, d, in[ 1] + 0xa4beea44,  4);
+	MD5STEP(F3, d, a, b, c, in[ 4] + 0x4bdecfa9, 11);
+	MD5STEP(F3, c, d, a, b, in[ 7] + 0xf6bb4b60, 16);
+	MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23);
+	MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6,  4);
+	MD5STEP(F3, d, a, b, c, in[ 0] + 0xeaa127fa, 11);
+	MD5STEP(F3, c, d, a, b, in[ 3] + 0xd4ef3085, 16);
+	MD5STEP(F3, b, c, d, a, in[ 6] + 0x04881d05, 23);
+	MD5STEP(F3, a, b, c, d, in[ 9] + 0xd9d4d039,  4);
+	MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11);
+	MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16);
+	MD5STEP(F3, b, c, d, a, in[2 ] + 0xc4ac5665, 23);
+
+	MD5STEP(F4, a, b, c, d, in[ 0] + 0xf4292244,  6);
+	MD5STEP(F4, d, a, b, c, in[7 ] + 0x432aff97, 10);
+	MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15);
+	MD5STEP(F4, b, c, d, a, in[5 ] + 0xfc93a039, 21);
+	MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3,  6);
+	MD5STEP(F4, d, a, b, c, in[3 ] + 0x8f0ccc92, 10);
+	MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15);
+	MD5STEP(F4, b, c, d, a, in[1 ] + 0x85845dd1, 21);
+	MD5STEP(F4, a, b, c, d, in[8 ] + 0x6fa87e4f,  6);
+	MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10);
+	MD5STEP(F4, c, d, a, b, in[6 ] + 0xa3014314, 15);
+	MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21);
+	MD5STEP(F4, a, b, c, d, in[4 ] + 0xf7537e82,  6);
+	MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10);
+	MD5STEP(F4, c, d, a, b, in[2 ] + 0x2ad7d2bb, 15);
+	MD5STEP(F4, b, c, d, a, in[9 ] + 0xeb86d391, 21);
+
+	state[0] += a;
+	state[1] += b;
+	state[2] += c;
+	state[3] += d;
+}

+ 373 - 0
libmd.mod/libmd/src/rmd160.c

@@ -0,0 +1,373 @@
+/*
+ * Copyright (c) 2001 Markus Friedl.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+/*
+ * Preneel, Bosselaers, Dobbertin, "The Cryptographic Hash Function RIPEMD-160",
+ * RSA Laboratories, CryptoBytes, Volume 3, Number 2, Autumn 1997,
+ * ftp://ftp.rsasecurity.com/pub/cryptobytes/crypto3n2.pdf
+ */
+
+#include <config.h>
+
+#include <string.h>
+#include <sys/types.h>
+#include <rmd160.h>
+
+#define PUT_64BIT_LE(cp, value) do {                                    \
+	(cp)[7] = (value) >> 56;                                        \
+	(cp)[6] = (value) >> 48;                                        \
+	(cp)[5] = (value) >> 40;                                        \
+	(cp)[4] = (value) >> 32;                                        \
+	(cp)[3] = (value) >> 24;                                        \
+	(cp)[2] = (value) >> 16;                                        \
+	(cp)[1] = (value) >> 8;                                         \
+	(cp)[0] = (value); } while (0)
+
+#define PUT_32BIT_LE(cp, value) do {                                    \
+	(cp)[3] = (value) >> 24;                                        \
+	(cp)[2] = (value) >> 16;                                        \
+	(cp)[1] = (value) >> 8;                                         \
+	(cp)[0] = (value); } while (0)
+
+#define	H0	0x67452301U
+#define	H1	0xEFCDAB89U
+#define	H2	0x98BADCFEU
+#define	H3	0x10325476U
+#define	H4	0xC3D2E1F0U
+
+#define	K0	0x00000000U
+#define	K1	0x5A827999U
+#define	K2	0x6ED9EBA1U
+#define	K3	0x8F1BBCDCU
+#define	K4	0xA953FD4EU
+
+#define	KK0	0x50A28BE6U
+#define	KK1	0x5C4DD124U
+#define	KK2	0x6D703EF3U
+#define	KK3	0x7A6D76E9U
+#define	KK4	0x00000000U
+
+/* rotate x left n bits.  */
+#define ROL(n, x) (((x) << (n)) | ((x) >> (32-(n))))
+
+#define F0(x, y, z) ((x) ^ (y) ^ (z))
+#define F1(x, y, z) (((x) & (y)) | ((~x) & (z)))
+#define F2(x, y, z) (((x) | (~y)) ^ (z))
+#define F3(x, y, z) (((x) & (z)) | ((y) & (~z)))
+#define F4(x, y, z) ((x) ^ ((y) | (~z)))
+
+#define R(a, b, c, d, e, Fj, Kj, sj, rj)                                \
+	do {                                                            \
+		a = ROL(sj, a + Fj(b,c,d) + X(rj) + Kj) + e;            \
+		c = ROL(10, c);                                         \
+	} while(0)
+
+#define X(i)	x[i]
+
+static uint8_t PADDING[RMD160_BLOCK_LENGTH] = {
+	0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+void
+RMD160Init(RMD160_CTX *ctx)
+{
+	ctx->count = 0;
+	ctx->state[0] = H0;
+	ctx->state[1] = H1;
+	ctx->state[2] = H2;
+	ctx->state[3] = H3;
+	ctx->state[4] = H4;
+}
+
+void
+RMD160Update(RMD160_CTX *ctx, const uint8_t *input, size_t len)
+{
+	size_t have, off, need;
+
+	have = (ctx->count / 8) % RMD160_BLOCK_LENGTH;
+	need = RMD160_BLOCK_LENGTH - have;
+	ctx->count += 8 * len;
+	off = 0;
+
+	if (len >= need) {
+		if (have) {
+			memcpy(ctx->buffer + have, input, need);
+			RMD160Transform(ctx->state, ctx->buffer);
+			off = need;
+			have = 0;
+		}
+		/* now the buffer is empty */
+		while (off + RMD160_BLOCK_LENGTH <= len) {
+			RMD160Transform(ctx->state, input+off);
+			off += RMD160_BLOCK_LENGTH;
+		}
+	}
+	if (off < len)
+		memcpy(ctx->buffer + have, input+off, len-off);
+}
+
+void
+RMD160Pad(RMD160_CTX *ctx)
+{
+	uint8_t size[8];
+	size_t padlen;
+
+	PUT_64BIT_LE(size, ctx->count);
+
+	/*
+	 * pad to RMD160_BLOCK_LENGTH byte blocks, at least one byte from
+	 * PADDING plus 8 bytes for the size
+	 */
+	padlen = RMD160_BLOCK_LENGTH - ((ctx->count / 8) % RMD160_BLOCK_LENGTH);
+	if (padlen < 1 + 8)
+		padlen += RMD160_BLOCK_LENGTH;
+	RMD160Update(ctx, PADDING, padlen - 8);		/* padlen - 8 <= 64 */
+	RMD160Update(ctx, size, 8);
+}
+
+void
+RMD160Final(uint8_t digest[RMD160_DIGEST_LENGTH], RMD160_CTX *ctx)
+{
+	int i;
+
+	RMD160Pad(ctx);
+	if (digest != NULL) {
+		for (i = 0; i < 5; i++)
+			PUT_32BIT_LE(digest + i*4, ctx->state[i]);
+		memset(ctx, 0, sizeof (*ctx));
+	}
+}
+
+void
+RMD160Transform(uint32_t state[5], const uint8_t block[RMD160_BLOCK_LENGTH])
+{
+	uint32_t a, b, c, d, e, aa, bb, cc, dd, ee, t, x[16];
+
+#ifndef WORDS_BIGENDIAN
+	memcpy(x, block, RMD160_BLOCK_LENGTH);
+#else
+	int i;
+
+	for (i = 0; i < 16; i++)
+		x[i] = (uint32_t)(
+		    (uint32_t)(block[i*4 + 0]) |
+		    (uint32_t)(block[i*4 + 1]) <<  8 |
+		    (uint32_t)(block[i*4 + 2]) << 16 |
+		    (uint32_t)(block[i*4 + 3]) << 24);
+#endif
+
+	a = state[0];
+	b = state[1];
+	c = state[2];
+	d = state[3];
+	e = state[4];
+
+	/* Round 1 */
+	R(a, b, c, d, e, F0, K0, 11,  0);
+	R(e, a, b, c, d, F0, K0, 14,  1);
+	R(d, e, a, b, c, F0, K0, 15,  2);
+	R(c, d, e, a, b, F0, K0, 12,  3);
+	R(b, c, d, e, a, F0, K0,  5,  4);
+	R(a, b, c, d, e, F0, K0,  8,  5);
+	R(e, a, b, c, d, F0, K0,  7,  6);
+	R(d, e, a, b, c, F0, K0,  9,  7);
+	R(c, d, e, a, b, F0, K0, 11,  8);
+	R(b, c, d, e, a, F0, K0, 13,  9);
+	R(a, b, c, d, e, F0, K0, 14, 10);
+	R(e, a, b, c, d, F0, K0, 15, 11);
+	R(d, e, a, b, c, F0, K0,  6, 12);
+	R(c, d, e, a, b, F0, K0,  7, 13);
+	R(b, c, d, e, a, F0, K0,  9, 14);
+	R(a, b, c, d, e, F0, K0,  8, 15); /* #15 */
+	/* Round 2 */
+	R(e, a, b, c, d, F1, K1,  7,  7);
+	R(d, e, a, b, c, F1, K1,  6,  4);
+	R(c, d, e, a, b, F1, K1,  8, 13);
+	R(b, c, d, e, a, F1, K1, 13,  1);
+	R(a, b, c, d, e, F1, K1, 11, 10);
+	R(e, a, b, c, d, F1, K1,  9,  6);
+	R(d, e, a, b, c, F1, K1,  7, 15);
+	R(c, d, e, a, b, F1, K1, 15,  3);
+	R(b, c, d, e, a, F1, K1,  7, 12);
+	R(a, b, c, d, e, F1, K1, 12,  0);
+	R(e, a, b, c, d, F1, K1, 15,  9);
+	R(d, e, a, b, c, F1, K1,  9,  5);
+	R(c, d, e, a, b, F1, K1, 11,  2);
+	R(b, c, d, e, a, F1, K1,  7, 14);
+	R(a, b, c, d, e, F1, K1, 13, 11);
+	R(e, a, b, c, d, F1, K1, 12,  8); /* #31 */
+	/* Round 3 */
+	R(d, e, a, b, c, F2, K2, 11,  3);
+	R(c, d, e, a, b, F2, K2, 13, 10);
+	R(b, c, d, e, a, F2, K2,  6, 14);
+	R(a, b, c, d, e, F2, K2,  7,  4);
+	R(e, a, b, c, d, F2, K2, 14,  9);
+	R(d, e, a, b, c, F2, K2,  9, 15);
+	R(c, d, e, a, b, F2, K2, 13,  8);
+	R(b, c, d, e, a, F2, K2, 15,  1);
+	R(a, b, c, d, e, F2, K2, 14,  2);
+	R(e, a, b, c, d, F2, K2,  8,  7);
+	R(d, e, a, b, c, F2, K2, 13,  0);
+	R(c, d, e, a, b, F2, K2,  6,  6);
+	R(b, c, d, e, a, F2, K2,  5, 13);
+	R(a, b, c, d, e, F2, K2, 12, 11);
+	R(e, a, b, c, d, F2, K2,  7,  5);
+	R(d, e, a, b, c, F2, K2,  5, 12); /* #47 */
+	/* Round 4 */
+	R(c, d, e, a, b, F3, K3, 11,  1);
+	R(b, c, d, e, a, F3, K3, 12,  9);
+	R(a, b, c, d, e, F3, K3, 14, 11);
+	R(e, a, b, c, d, F3, K3, 15, 10);
+	R(d, e, a, b, c, F3, K3, 14,  0);
+	R(c, d, e, a, b, F3, K3, 15,  8);
+	R(b, c, d, e, a, F3, K3,  9, 12);
+	R(a, b, c, d, e, F3, K3,  8,  4);
+	R(e, a, b, c, d, F3, K3,  9, 13);
+	R(d, e, a, b, c, F3, K3, 14,  3);
+	R(c, d, e, a, b, F3, K3,  5,  7);
+	R(b, c, d, e, a, F3, K3,  6, 15);
+	R(a, b, c, d, e, F3, K3,  8, 14);
+	R(e, a, b, c, d, F3, K3,  6,  5);
+	R(d, e, a, b, c, F3, K3,  5,  6);
+	R(c, d, e, a, b, F3, K3, 12,  2); /* #63 */
+	/* Round 5 */
+	R(b, c, d, e, a, F4, K4,  9,  4);
+	R(a, b, c, d, e, F4, K4, 15,  0);
+	R(e, a, b, c, d, F4, K4,  5,  5);
+	R(d, e, a, b, c, F4, K4, 11,  9);
+	R(c, d, e, a, b, F4, K4,  6,  7);
+	R(b, c, d, e, a, F4, K4,  8, 12);
+	R(a, b, c, d, e, F4, K4, 13,  2);
+	R(e, a, b, c, d, F4, K4, 12, 10);
+	R(d, e, a, b, c, F4, K4,  5, 14);
+	R(c, d, e, a, b, F4, K4, 12,  1);
+	R(b, c, d, e, a, F4, K4, 13,  3);
+	R(a, b, c, d, e, F4, K4, 14,  8);
+	R(e, a, b, c, d, F4, K4, 11, 11);
+	R(d, e, a, b, c, F4, K4,  8,  6);
+	R(c, d, e, a, b, F4, K4,  5, 15);
+	R(b, c, d, e, a, F4, K4,  6, 13); /* #79 */
+
+	aa = a ; bb = b; cc = c; dd = d; ee = e;
+
+	a = state[0];
+	b = state[1];
+	c = state[2];
+	d = state[3];
+	e = state[4];
+
+	/* Parallel round 1 */
+	R(a, b, c, d, e, F4, KK0,  8,  5);
+	R(e, a, b, c, d, F4, KK0,  9, 14);
+	R(d, e, a, b, c, F4, KK0,  9,  7);
+	R(c, d, e, a, b, F4, KK0, 11,  0);
+	R(b, c, d, e, a, F4, KK0, 13,  9);
+	R(a, b, c, d, e, F4, KK0, 15,  2);
+	R(e, a, b, c, d, F4, KK0, 15, 11);
+	R(d, e, a, b, c, F4, KK0,  5,  4);
+	R(c, d, e, a, b, F4, KK0,  7, 13);
+	R(b, c, d, e, a, F4, KK0,  7,  6);
+	R(a, b, c, d, e, F4, KK0,  8, 15);
+	R(e, a, b, c, d, F4, KK0, 11,  8);
+	R(d, e, a, b, c, F4, KK0, 14,  1);
+	R(c, d, e, a, b, F4, KK0, 14, 10);
+	R(b, c, d, e, a, F4, KK0, 12,  3);
+	R(a, b, c, d, e, F4, KK0,  6, 12); /* #15 */
+	/* Parallel round 2 */
+	R(e, a, b, c, d, F3, KK1,  9,  6);
+	R(d, e, a, b, c, F3, KK1, 13, 11);
+	R(c, d, e, a, b, F3, KK1, 15,  3);
+	R(b, c, d, e, a, F3, KK1,  7,  7);
+	R(a, b, c, d, e, F3, KK1, 12,  0);
+	R(e, a, b, c, d, F3, KK1,  8, 13);
+	R(d, e, a, b, c, F3, KK1,  9,  5);
+	R(c, d, e, a, b, F3, KK1, 11, 10);
+	R(b, c, d, e, a, F3, KK1,  7, 14);
+	R(a, b, c, d, e, F3, KK1,  7, 15);
+	R(e, a, b, c, d, F3, KK1, 12,  8);
+	R(d, e, a, b, c, F3, KK1,  7, 12);
+	R(c, d, e, a, b, F3, KK1,  6,  4);
+	R(b, c, d, e, a, F3, KK1, 15,  9);
+	R(a, b, c, d, e, F3, KK1, 13,  1);
+	R(e, a, b, c, d, F3, KK1, 11,  2); /* #31 */
+	/* Parallel round 3 */
+	R(d, e, a, b, c, F2, KK2,  9, 15);
+	R(c, d, e, a, b, F2, KK2,  7,  5);
+	R(b, c, d, e, a, F2, KK2, 15,  1);
+	R(a, b, c, d, e, F2, KK2, 11,  3);
+	R(e, a, b, c, d, F2, KK2,  8,  7);
+	R(d, e, a, b, c, F2, KK2,  6, 14);
+	R(c, d, e, a, b, F2, KK2,  6,  6);
+	R(b, c, d, e, a, F2, KK2, 14,  9);
+	R(a, b, c, d, e, F2, KK2, 12, 11);
+	R(e, a, b, c, d, F2, KK2, 13,  8);
+	R(d, e, a, b, c, F2, KK2,  5, 12);
+	R(c, d, e, a, b, F2, KK2, 14,  2);
+	R(b, c, d, e, a, F2, KK2, 13, 10);
+	R(a, b, c, d, e, F2, KK2, 13,  0);
+	R(e, a, b, c, d, F2, KK2,  7,  4);
+	R(d, e, a, b, c, F2, KK2,  5, 13); /* #47 */
+	/* Parallel round 4 */
+	R(c, d, e, a, b, F1, KK3, 15,  8);
+	R(b, c, d, e, a, F1, KK3,  5,  6);
+	R(a, b, c, d, e, F1, KK3,  8,  4);
+	R(e, a, b, c, d, F1, KK3, 11,  1);
+	R(d, e, a, b, c, F1, KK3, 14,  3);
+	R(c, d, e, a, b, F1, KK3, 14, 11);
+	R(b, c, d, e, a, F1, KK3,  6, 15);
+	R(a, b, c, d, e, F1, KK3, 14,  0);
+	R(e, a, b, c, d, F1, KK3,  6,  5);
+	R(d, e, a, b, c, F1, KK3,  9, 12);
+	R(c, d, e, a, b, F1, KK3, 12,  2);
+	R(b, c, d, e, a, F1, KK3,  9, 13);
+	R(a, b, c, d, e, F1, KK3, 12,  9);
+	R(e, a, b, c, d, F1, KK3,  5,  7);
+	R(d, e, a, b, c, F1, KK3, 15, 10);
+	R(c, d, e, a, b, F1, KK3,  8, 14); /* #63 */
+	/* Parallel round 5 */
+	R(b, c, d, e, a, F0, KK4,  8, 12);
+	R(a, b, c, d, e, F0, KK4,  5, 15);
+	R(e, a, b, c, d, F0, KK4, 12, 10);
+	R(d, e, a, b, c, F0, KK4,  9,  4);
+	R(c, d, e, a, b, F0, KK4, 12,  1);
+	R(b, c, d, e, a, F0, KK4,  5,  5);
+	R(a, b, c, d, e, F0, KK4, 14,  8);
+	R(e, a, b, c, d, F0, KK4,  6,  7);
+	R(d, e, a, b, c, F0, KK4,  8,  6);
+	R(c, d, e, a, b, F0, KK4, 13,  2);
+	R(b, c, d, e, a, F0, KK4,  6, 13);
+	R(a, b, c, d, e, F0, KK4,  5, 14);
+	R(e, a, b, c, d, F0, KK4, 15,  0);
+	R(d, e, a, b, c, F0, KK4, 13,  3);
+	R(c, d, e, a, b, F0, KK4, 11,  9);
+	R(b, c, d, e, a, F0, KK4, 11, 11); /* #79 */
+
+	t =        state[1] + cc + d;
+	state[1] = state[2] + dd + e;
+	state[2] = state[3] + ee + a;
+	state[3] = state[4] + aa + b;
+	state[4] = state[0] + bb + c;
+	state[0] = t;
+}

+ 236 - 0
libmd.mod/libmd/src/sha1.c

@@ -0,0 +1,236 @@
+/*	$OpenBSD: sha1.c,v 1.20 2005/08/08 08:05:35 espie Exp $	*/
+
+/*
+ * SHA-1 in C
+ * By Steve Reid <[email protected]>
+ * 100% Public Domain
+ *
+ * Test Vectors (from FIPS PUB 180-1)
+ * "abc"
+ *   A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D
+ * "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
+ *   84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1
+ * A million repetitions of "a"
+ *   34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F
+ */
+
+#include <config.h>
+
+#include <string.h>
+#include <sha1.h>
+
+#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))
+
+/*
+ * blk0() and blk() perform the initial expand.
+ * I got the idea of expanding during the round function from SSLeay
+ */
+#ifndef WORDS_BIGENDIAN
+# 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 {
+	uint8_t c[64];
+	uint32_t l[16];
+} CHAR64LONG16;
+
+#ifdef __sh__
+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.
+ */
+void
+SHA1Transform(uint32_t state[5], const uint8_t buffer[SHA1_BLOCK_LENGTH])
+{
+	uint32_t a, b, c, d, e;
+	uint8_t workspace[SHA1_BLOCK_LENGTH];
+	CHAR64LONG16 *block = (CHAR64LONG16 *)workspace;
+
+	(void)memcpy(block, buffer, SHA1_BLOCK_LENGTH);
+
+	/* Copy context->state[] to working vars */
+	a = state[0];
+	b = state[1];
+	c = state[2];
+	d = state[3];
+	e = state[4];
+
+#ifdef __sh__
+	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;
+}
+
+
+/*
+ * SHA1Init - Initialize new context
+ */
+void
+SHA1Init(SHA1_CTX *context)
+{
+
+	/* SHA1 initialization constants */
+	context->count = 0;
+	context->state[0] = 0x67452301;
+	context->state[1] = 0xEFCDAB89;
+	context->state[2] = 0x98BADCFE;
+	context->state[3] = 0x10325476;
+	context->state[4] = 0xC3D2E1F0;
+}
+
+
+/*
+ * Run your data through this.
+ */
+void
+SHA1Update(SHA1_CTX *context, const uint8_t *data, size_t len)
+{
+	size_t i, j;
+
+	j = (size_t)((context->count >> 3) & 63);
+	context->count += (len << 3);
+	if ((j + len) > 63) {
+		(void)memcpy(&context->buffer[j], data, (i = 64-j));
+		SHA1Transform(context->state, context->buffer);
+		for ( ; i + 63 < len; i += 64)
+			SHA1Transform(context->state, (uint8_t *)&data[i]);
+		j = 0;
+	} else {
+		i = 0;
+	}
+	(void)memcpy(&context->buffer[j], &data[i], len - i);
+}
+
+
+/*
+ * Add padding and return the message digest.
+ */
+void
+SHA1Pad(SHA1_CTX *context)
+{
+	uint8_t finalcount[8];
+	unsigned int i;
+
+	for (i = 0; i < 8; i++) {
+		finalcount[i] = (uint8_t)((context->count >>
+		    ((7 - (i & 7)) * 8)) & 255);	/* Endian independent */
+	}
+	SHA1Update(context, (uint8_t *)"\200", 1);
+	while ((context->count & 504) != 448)
+		SHA1Update(context, (uint8_t *)"\0", 1);
+	SHA1Update(context, finalcount, 8); /* Should cause a SHA1Transform() */
+}
+
+void
+SHA1Final(uint8_t digest[SHA1_DIGEST_LENGTH], SHA1_CTX *context)
+{
+	unsigned int i;
+
+	SHA1Pad(context);
+	if (digest) {
+		for (i = 0; i < SHA1_DIGEST_LENGTH; i++) {
+			digest[i] = (uint8_t)
+			   ((context->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255);
+		}
+		memset(context, 0, sizeof(*context));
+	}
+}

+ 863 - 0
libmd.mod/libmd/src/sha2.c

@@ -0,0 +1,863 @@
+/*	$OpenBSD: sha2.c,v 1.12 2008/09/06 12:00:19 djm Exp $	*/
+
+/*
+ * FILE:	sha2.c
+ * AUTHOR:	Aaron D. Gifford <[email protected]>
+ * 
+ * Copyright (c) 2000-2001, Aaron D. Gifford
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holder nor the names of contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTOR(S) ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTOR(S) BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $From: sha2.c,v 1.1 2001/11/08 00:01:51 adg Exp adg $
+ */
+
+#include <config.h>
+#include "local-link.h"
+
+#include <sys/types.h>
+
+#include <string.h>
+#include <sha2.h>
+
+/*
+ * UNROLLED TRANSFORM LOOP NOTE:
+ * You can define SHA2_UNROLL_TRANSFORM to use the unrolled transform
+ * loop version for the hash transform rounds (defined using macros
+ * later in this file).  Either define on the command line, for example:
+ *
+ *   cc -DSHA2_UNROLL_TRANSFORM -o sha2 sha2.c sha2prog.c
+ *
+ * or define below:
+ *
+ *   #define SHA2_UNROLL_TRANSFORM
+ *
+ */
+
+/*** SHA-256/384/512 Various Length Definitions ***********************/
+/* NOTE: Most of these are in sha2.h */
+#define SHA256_SHORT_BLOCK_LENGTH	(SHA256_BLOCK_LENGTH - 8)
+#define SHA384_SHORT_BLOCK_LENGTH	(SHA384_BLOCK_LENGTH - 16)
+#define SHA512_SHORT_BLOCK_LENGTH	(SHA512_BLOCK_LENGTH - 16)
+
+/*** ENDIAN SPECIFIC COPY MACROS **************************************/
+#define BE_8_TO_32(dst, cp) do {					\
+	(dst) = (uint32_t)(cp)[3] | ((uint32_t)(cp)[2] << 8) |		\
+	    ((uint32_t)(cp)[1] << 16) | ((uint32_t)(cp)[0] << 24);	\
+} while(0)
+
+#define BE_8_TO_64(dst, cp) do {					\
+	(dst) = (uint64_t)(cp)[7] | ((uint64_t)(cp)[6] << 8) |		\
+	    ((uint64_t)(cp)[5] << 16) | ((uint64_t)(cp)[4] << 24) |	\
+	    ((uint64_t)(cp)[3] << 32) | ((uint64_t)(cp)[2] << 40) |	\
+	    ((uint64_t)(cp)[1] << 48) | ((uint64_t)(cp)[0] << 56);	\
+} while (0)
+
+#define BE_64_TO_8(cp, src) do {					\
+	(cp)[0] = (src) >> 56;						\
+        (cp)[1] = (src) >> 48;						\
+	(cp)[2] = (src) >> 40;						\
+	(cp)[3] = (src) >> 32;						\
+	(cp)[4] = (src) >> 24;						\
+	(cp)[5] = (src) >> 16;						\
+	(cp)[6] = (src) >> 8;						\
+	(cp)[7] = (src);						\
+} while (0)
+
+#define BE_32_TO_8(cp, src) do {					\
+	(cp)[0] = (src) >> 24;						\
+	(cp)[1] = (src) >> 16;						\
+	(cp)[2] = (src) >> 8;						\
+	(cp)[3] = (src);						\
+} while (0)
+
+/*
+ * Macro for incrementally adding the unsigned 64-bit integer n to the
+ * unsigned 128-bit integer (represented using a two-element array of
+ * 64-bit words):
+ */
+#define ADDINC128(w,n) do {						\
+	(w)[0] += (uint64_t)(n);					\
+	if ((w)[0] < (n)) {						\
+		(w)[1]++;						\
+	}								\
+} while (0)
+
+/*** THE SIX LOGICAL FUNCTIONS ****************************************/
+/*
+ * Bit shifting and rotation (used by the six SHA-XYZ logical functions:
+ *
+ *   NOTE:  The naming of R and S appears backwards here (R is a SHIFT and
+ *   S is a ROTATION) because the SHA-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 uint32_t K256[64] = {
+	0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL,
+	0x3956c25bUL, 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL,
+	0xd807aa98UL, 0x12835b01UL, 0x243185beUL, 0x550c7dc3UL,
+	0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL, 0xc19bf174UL,
+	0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL,
+	0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL,
+	0x983e5152UL, 0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL,
+	0xc6e00bf3UL, 0xd5a79147UL, 0x06ca6351UL, 0x14292967UL,
+	0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL, 0x53380d13UL,
+	0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL,
+	0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL,
+	0xd192e819UL, 0xd6990624UL, 0xf40e3585UL, 0x106aa070UL,
+	0x19a4c116UL, 0x1e376c08UL, 0x2748774cUL, 0x34b0bcb5UL,
+	0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL, 0x682e6ff3UL,
+	0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL,
+	0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL
+};
+
+/* Initial hash value H for SHA-256: */
+static const uint32_t sha256_initial_hash_value[8] = {
+	0x6a09e667UL,
+	0xbb67ae85UL,
+	0x3c6ef372UL,
+	0xa54ff53aUL,
+	0x510e527fUL,
+	0x9b05688cUL,
+	0x1f83d9abUL,
+	0x5be0cd19UL
+};
+
+#ifndef SHA256_ONLY
+/* Hash constant words K for SHA-384 and SHA-512: */
+static const uint64_t K512[80] = {
+	0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL,
+	0xb5c0fbcfec4d3b2fULL, 0xe9b5dba58189dbbcULL,
+	0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL,
+	0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL,
+	0xd807aa98a3030242ULL, 0x12835b0145706fbeULL,
+	0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL,
+	0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL,
+	0x9bdc06a725c71235ULL, 0xc19bf174cf692694ULL,
+	0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL,
+	0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL,
+	0x2de92c6f592b0275ULL, 0x4a7484aa6ea6e483ULL,
+	0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL,
+	0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL,
+	0xb00327c898fb213fULL, 0xbf597fc7beef0ee4ULL,
+	0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL,
+	0x06ca6351e003826fULL, 0x142929670a0e6e70ULL,
+	0x27b70a8546d22ffcULL, 0x2e1b21385c26c926ULL,
+	0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL,
+	0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL,
+	0x81c2c92e47edaee6ULL, 0x92722c851482353bULL,
+	0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL,
+	0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL,
+	0xd192e819d6ef5218ULL, 0xd69906245565a910ULL,
+	0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL,
+	0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL,
+	0x2748774cdf8eeb99ULL, 0x34b0bcb5e19b48a8ULL,
+	0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL,
+	0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL,
+	0x748f82ee5defb2fcULL, 0x78a5636f43172f60ULL,
+	0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL,
+	0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL,
+	0xbef9a3f7b2c67915ULL, 0xc67178f2e372532bULL,
+	0xca273eceea26619cULL, 0xd186b8c721c0c207ULL,
+	0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL,
+	0x06f067aa72176fbaULL, 0x0a637dc5a2c898a6ULL,
+	0x113f9804bef90daeULL, 0x1b710b35131c471bULL,
+	0x28db77f523047d84ULL, 0x32caab7b40c72493ULL,
+	0x3c9ebe0a15c9bebcULL, 0x431d67c49c100d4cULL,
+	0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL,
+	0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL
+};
+
+/* Initial hash value H for SHA-384 */
+static const uint64_t sha384_initial_hash_value[8] = {
+	0xcbbb9d5dc1059ed8ULL,
+	0x629a292a367cd507ULL,
+	0x9159015a3070dd17ULL,
+	0x152fecd8f70e5939ULL,
+	0x67332667ffc00b31ULL,
+	0x8eb44a8768581511ULL,
+	0xdb0c2e0d64f98fa7ULL,
+	0x47b5481dbefa4fa4ULL
+};
+
+/* Initial hash value H for SHA-512 */
+static const uint64_t sha512_initial_hash_value[8] = {
+	0x6a09e667f3bcc908ULL,
+	0xbb67ae8584caa73bULL,
+	0x3c6ef372fe94f82bULL,
+	0xa54ff53a5f1d36f1ULL,
+	0x510e527fade682d1ULL,
+	0x9b05688c2b3e6c1fULL,
+	0x1f83d9abfb41bd6bULL,
+	0x5be0cd19137e2179ULL
+};
+#endif /* SHA256_ONLY */
+
+/*** SHA-256: *********************************************************/
+void
+SHA256Init(SHA2_CTX *context)
+{
+	if (context == NULL)
+		return;
+	memcpy(context->state.st32, sha256_initial_hash_value,
+	    sizeof(sha256_initial_hash_value));
+	memset(context->buffer, 0, sizeof(context->buffer));
+	context->bitcount[0] = 0;
+}
+
+#ifdef SHA2_UNROLL_TRANSFORM
+
+/* Unrolled SHA-256 round macros: */
+
+#define ROUND256_0_TO_15(a,b,c,d,e,f,g,h) do {				    \
+	BE_8_TO_32(W256[j], data);					    \
+	data += 4;							    \
+	T1 = (h) + Sigma1_256((e)) + Ch((e), (f), (g)) + K256[j] + W256[j]; \
+	(d) += T1;							    \
+	(h) = T1 + Sigma0_256((a)) + Maj((a), (b), (c));		    \
+	j++;								    \
+} while(0)
+
+#define ROUND256(a,b,c,d,e,f,g,h) do {					    \
+	s0 = W256[(j+1)&0x0f];						    \
+	s0 = sigma0_256(s0);						    \
+	s1 = W256[(j+14)&0x0f];						    \
+	s1 = sigma1_256(s1);						    \
+	T1 = (h) + Sigma1_256((e)) + Ch((e), (f), (g)) + K256[j] +	    \
+	     (W256[j&0x0f] += s1 + W256[(j+9)&0x0f] + s0);		    \
+	(d) += T1;							    \
+	(h) = T1 + Sigma0_256((a)) + Maj((a), (b), (c));		    \
+	j++;								    \
+} while(0)
+
+void
+SHA256Transform(uint32_t state[8], const uint8_t data[SHA256_BLOCK_LENGTH])
+{
+	uint32_t	a, b, c, d, e, f, g, h, s0, s1;
+	uint32_t	T1, W256[16];
+	int		j;
+
+	/* Initialize registers with the prev. intermediate value */
+	a = state[0];
+	b = state[1];
+	c = state[2];
+	d = state[3];
+	e = state[4];
+	f = state[5];
+	g = state[6];
+	h = state[7];
+
+	j = 0;
+	do {
+		/* Rounds 0 to 15 (unrolled): */
+		ROUND256_0_TO_15(a,b,c,d,e,f,g,h);
+		ROUND256_0_TO_15(h,a,b,c,d,e,f,g);
+		ROUND256_0_TO_15(g,h,a,b,c,d,e,f);
+		ROUND256_0_TO_15(f,g,h,a,b,c,d,e);
+		ROUND256_0_TO_15(e,f,g,h,a,b,c,d);
+		ROUND256_0_TO_15(d,e,f,g,h,a,b,c);
+		ROUND256_0_TO_15(c,d,e,f,g,h,a,b);
+		ROUND256_0_TO_15(b,c,d,e,f,g,h,a);
+	} while (j < 16);
+
+	/* Now for the remaining rounds up to 63: */
+	do {
+		ROUND256(a,b,c,d,e,f,g,h);
+		ROUND256(h,a,b,c,d,e,f,g);
+		ROUND256(g,h,a,b,c,d,e,f);
+		ROUND256(f,g,h,a,b,c,d,e);
+		ROUND256(e,f,g,h,a,b,c,d);
+		ROUND256(d,e,f,g,h,a,b,c);
+		ROUND256(c,d,e,f,g,h,a,b);
+		ROUND256(b,c,d,e,f,g,h,a);
+	} while (j < 64);
+
+	/* Compute the current intermediate hash value */
+	state[0] += a;
+	state[1] += b;
+	state[2] += c;
+	state[3] += d;
+	state[4] += e;
+	state[5] += f;
+	state[6] += g;
+	state[7] += h;
+
+	/* Clean up */
+	a = b = c = d = e = f = g = h = T1 = 0;
+}
+
+#else /* SHA2_UNROLL_TRANSFORM */
+
+void
+SHA256Transform(uint32_t state[8], const uint8_t data[SHA256_BLOCK_LENGTH])
+{
+	uint32_t	a, b, c, d, e, f, g, h, s0, s1;
+	uint32_t	T1, T2, W256[16];
+	int		j;
+
+	/* Initialize registers with the prev. intermediate value */
+	a = state[0];
+	b = state[1];
+	c = state[2];
+	d = state[3];
+	e = state[4];
+	f = state[5];
+	g = state[6];
+	h = state[7];
+
+	j = 0;
+	do {
+		BE_8_TO_32(W256[j], data);
+		data += 4;
+		/* Apply the SHA-256 compression function to update a..h */
+		T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] + W256[j];
+		T2 = Sigma0_256(a) + Maj(a, b, c);
+		h = g;
+		g = f;
+		f = e;
+		e = d + T1;
+		d = c;
+		c = b;
+		b = a;
+		a = T1 + T2;
+
+		j++;
+	} while (j < 16);
+
+	do {
+		/* Part of the message block expansion: */
+		s0 = W256[(j+1)&0x0f];
+		s0 = sigma0_256(s0);
+		s1 = W256[(j+14)&0x0f];	
+		s1 = sigma1_256(s1);
+
+		/* Apply the SHA-256 compression function to update a..h */
+		T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] + 
+		     (W256[j&0x0f] += s1 + W256[(j+9)&0x0f] + s0);
+		T2 = Sigma0_256(a) + Maj(a, b, c);
+		h = g;
+		g = f;
+		f = e;
+		e = d + T1;
+		d = c;
+		c = b;
+		b = a;
+		a = T1 + T2;
+
+		j++;
+	} while (j < 64);
+
+	/* Compute the current intermediate hash value */
+	state[0] += a;
+	state[1] += b;
+	state[2] += c;
+	state[3] += d;
+	state[4] += e;
+	state[5] += f;
+	state[6] += g;
+	state[7] += h;
+
+	/* Clean up */
+	a = b = c = d = e = f = g = h = T1 = T2 = 0;
+}
+
+#endif /* SHA2_UNROLL_TRANSFORM */
+
+void
+SHA256Update(SHA2_CTX *context, const uint8_t *data, size_t len)
+{
+	size_t	freespace, usedspace;
+
+	/* Calling with no data is valid (we do nothing) */
+	if (len == 0)
+		return;
+
+	usedspace = (context->bitcount[0] >> 3) % SHA256_BLOCK_LENGTH;
+	if (usedspace > 0) {
+		/* Calculate how much free space is available in the buffer */
+		freespace = SHA256_BLOCK_LENGTH - usedspace;
+
+		if (len >= freespace) {
+			/* Fill the buffer completely and process it */
+			memcpy(&context->buffer[usedspace], data, freespace);
+			context->bitcount[0] += freespace << 3;
+			len -= freespace;
+			data += freespace;
+			SHA256Transform(context->state.st32, context->buffer);
+		} else {
+			/* The buffer is not yet full */
+			memcpy(&context->buffer[usedspace], data, len);
+			context->bitcount[0] += len << 3;
+			/* Clean up: */
+			usedspace = freespace = 0;
+			return;
+		}
+	}
+	while (len >= SHA256_BLOCK_LENGTH) {
+		/* Process as many complete blocks as we can */
+		SHA256Transform(context->state.st32, data);
+		context->bitcount[0] += SHA256_BLOCK_LENGTH << 3;
+		len -= SHA256_BLOCK_LENGTH;
+		data += SHA256_BLOCK_LENGTH;
+	}
+	if (len > 0) {
+		/* There's left-overs, so save 'em */
+		memcpy(context->buffer, data, len);
+		context->bitcount[0] += len << 3;
+	}
+	/* Clean up: */
+	usedspace = freespace = 0;
+}
+
+void
+SHA256Pad(SHA2_CTX *context)
+{
+	unsigned int	usedspace;
+
+	usedspace = (context->bitcount[0] >> 3) % SHA256_BLOCK_LENGTH;
+	if (usedspace > 0) {
+		/* Begin padding with a 1 bit: */
+		context->buffer[usedspace++] = 0x80;
+
+		if (usedspace <= SHA256_SHORT_BLOCK_LENGTH) {
+			/* Set-up for the last transform: */
+			memset(&context->buffer[usedspace], 0,
+			    SHA256_SHORT_BLOCK_LENGTH - usedspace);
+		} else {
+			if (usedspace < SHA256_BLOCK_LENGTH) {
+				memset(&context->buffer[usedspace], 0,
+				    SHA256_BLOCK_LENGTH - usedspace);
+			}
+			/* Do second-to-last transform: */
+			SHA256Transform(context->state.st32, context->buffer);
+
+			/* Prepare for last transform: */
+			memset(context->buffer, 0, SHA256_SHORT_BLOCK_LENGTH);
+		}
+	} else {
+		/* Set-up for the last transform: */
+		memset(context->buffer, 0, SHA256_SHORT_BLOCK_LENGTH);
+
+		/* Begin padding with a 1 bit: */
+		*context->buffer = 0x80;
+	}
+	/* Store the length of input data (in bits) in big endian format: */
+	BE_64_TO_8(&context->buffer[SHA256_SHORT_BLOCK_LENGTH],
+	    context->bitcount[0]);
+
+	/* Final transform: */
+	SHA256Transform(context->state.st32, context->buffer);
+
+	/* Clean up: */
+	usedspace = 0;
+}
+
+void
+SHA256Final(uint8_t digest[SHA256_DIGEST_LENGTH], SHA2_CTX *context)
+{
+	SHA256Pad(context);
+
+	/* If no digest buffer is passed, we don't bother doing this: */
+	if (digest != NULL) {
+#ifndef WORDS_BIGENDIAN
+		int	i;
+
+		/* Convert TO host byte order */
+		for (i = 0; i < 8; i++)
+			BE_32_TO_8(digest + i * 4, context->state.st32[i]);
+#else
+		memcpy(digest, context->state.st32, SHA256_DIGEST_LENGTH);
+#endif
+		memset(context, 0, sizeof(*context));
+	}
+}
+
+
+#ifndef SHA256_ONLY
+/*** SHA-512: *********************************************************/
+void
+SHA512Init(SHA2_CTX *context)
+{
+	if (context == NULL)
+		return;
+	memcpy(context->state.st64, sha512_initial_hash_value,
+	    sizeof(sha512_initial_hash_value));
+	memset(context->buffer, 0, sizeof(context->buffer));
+	context->bitcount[0] = context->bitcount[1] =  0;
+}
+
+#ifdef SHA2_UNROLL_TRANSFORM
+
+/* Unrolled SHA-512 round macros: */
+
+#define ROUND512_0_TO_15(a,b,c,d,e,f,g,h) do {				    \
+	BE_8_TO_64(W512[j], data);					    \
+	data += 8;							    \
+	T1 = (h) + Sigma1_512((e)) + Ch((e), (f), (g)) + K512[j] + W512[j]; \
+	(d) += T1;							    \
+	(h) = T1 + Sigma0_512((a)) + Maj((a), (b), (c));		    \
+	j++;								    \
+} while(0)
+
+
+#define ROUND512(a,b,c,d,e,f,g,h) do {					    \
+	s0 = W512[(j+1)&0x0f];						    \
+	s0 = sigma0_512(s0);						    \
+	s1 = W512[(j+14)&0x0f];						    \
+	s1 = sigma1_512(s1);						    \
+	T1 = (h) + Sigma1_512((e)) + Ch((e), (f), (g)) + K512[j] +	    \
+             (W512[j&0x0f] += s1 + W512[(j+9)&0x0f] + s0);		    \
+	(d) += T1;							    \
+	(h) = T1 + Sigma0_512((a)) + Maj((a), (b), (c));		    \
+	j++;								    \
+} while(0)
+
+void
+SHA512Transform(uint64_t state[8], const uint8_t data[SHA512_BLOCK_LENGTH])
+{
+	uint64_t	a, b, c, d, e, f, g, h, s0, s1;
+	uint64_t	T1, W512[16];
+	int		j;
+
+	/* Initialize registers with the prev. intermediate value */
+	a = state[0];
+	b = state[1];
+	c = state[2];
+	d = state[3];
+	e = state[4];
+	f = state[5];
+	g = state[6];
+	h = state[7];
+
+	j = 0;
+	do {
+		/* Rounds 0 to 15 (unrolled): */
+		ROUND512_0_TO_15(a,b,c,d,e,f,g,h);
+		ROUND512_0_TO_15(h,a,b,c,d,e,f,g);
+		ROUND512_0_TO_15(g,h,a,b,c,d,e,f);
+		ROUND512_0_TO_15(f,g,h,a,b,c,d,e);
+		ROUND512_0_TO_15(e,f,g,h,a,b,c,d);
+		ROUND512_0_TO_15(d,e,f,g,h,a,b,c);
+		ROUND512_0_TO_15(c,d,e,f,g,h,a,b);
+		ROUND512_0_TO_15(b,c,d,e,f,g,h,a);
+	} while (j < 16);
+
+	/* Now for the remaining rounds up to 79: */
+	do {
+		ROUND512(a,b,c,d,e,f,g,h);
+		ROUND512(h,a,b,c,d,e,f,g);
+		ROUND512(g,h,a,b,c,d,e,f);
+		ROUND512(f,g,h,a,b,c,d,e);
+		ROUND512(e,f,g,h,a,b,c,d);
+		ROUND512(d,e,f,g,h,a,b,c);
+		ROUND512(c,d,e,f,g,h,a,b);
+		ROUND512(b,c,d,e,f,g,h,a);
+	} while (j < 80);
+
+	/* Compute the current intermediate hash value */
+	state[0] += a;
+	state[1] += b;
+	state[2] += c;
+	state[3] += d;
+	state[4] += e;
+	state[5] += f;
+	state[6] += g;
+	state[7] += h;
+
+	/* Clean up */
+	a = b = c = d = e = f = g = h = T1 = 0;
+}
+
+#else /* SHA2_UNROLL_TRANSFORM */
+
+void
+SHA512Transform(uint64_t state[8], const uint8_t data[SHA512_BLOCK_LENGTH])
+{
+	uint64_t	a, b, c, d, e, f, g, h, s0, s1;
+	uint64_t	T1, T2, W512[16];
+	int		j;
+
+	/* Initialize registers with the prev. intermediate value */
+	a = state[0];
+	b = state[1];
+	c = state[2];
+	d = state[3];
+	e = state[4];
+	f = state[5];
+	g = state[6];
+	h = state[7];
+
+	j = 0;
+	do {
+		BE_8_TO_64(W512[j], data);
+		data += 8;
+		/* Apply the SHA-512 compression function to update a..h */
+		T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] + W512[j];
+		T2 = Sigma0_512(a) + Maj(a, b, c);
+		h = g;
+		g = f;
+		f = e;
+		e = d + T1;
+		d = c;
+		c = b;
+		b = a;
+		a = T1 + T2;
+
+		j++;
+	} while (j < 16);
+
+	do {
+		/* Part of the message block expansion: */
+		s0 = W512[(j+1)&0x0f];
+		s0 = sigma0_512(s0);
+		s1 = W512[(j+14)&0x0f];
+		s1 =  sigma1_512(s1);
+
+		/* Apply the SHA-512 compression function to update a..h */
+		T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] +
+		     (W512[j&0x0f] += s1 + W512[(j+9)&0x0f] + s0);
+		T2 = Sigma0_512(a) + Maj(a, b, c);
+		h = g;
+		g = f;
+		f = e;
+		e = d + T1;
+		d = c;
+		c = b;
+		b = a;
+		a = T1 + T2;
+
+		j++;
+	} while (j < 80);
+
+	/* Compute the current intermediate hash value */
+	state[0] += a;
+	state[1] += b;
+	state[2] += c;
+	state[3] += d;
+	state[4] += e;
+	state[5] += f;
+	state[6] += g;
+	state[7] += h;
+
+	/* Clean up */
+	a = b = c = d = e = f = g = h = T1 = T2 = 0;
+}
+
+#endif /* SHA2_UNROLL_TRANSFORM */
+
+void
+SHA512Update(SHA2_CTX *context, const uint8_t *data, size_t len)
+{
+	size_t	freespace, usedspace;
+
+	/* Calling with no data is valid (we do nothing) */
+	if (len == 0)
+		return;
+
+	usedspace = (context->bitcount[0] >> 3) % SHA512_BLOCK_LENGTH;
+	if (usedspace > 0) {
+		/* Calculate how much free space is available in the buffer */
+		freespace = SHA512_BLOCK_LENGTH - usedspace;
+
+		if (len >= freespace) {
+			/* Fill the buffer completely and process it */
+			memcpy(&context->buffer[usedspace], data, freespace);
+			ADDINC128(context->bitcount, freespace << 3);
+			len -= freespace;
+			data += freespace;
+			SHA512Transform(context->state.st64, context->buffer);
+		} else {
+			/* The buffer is not yet full */
+			memcpy(&context->buffer[usedspace], data, len);
+			ADDINC128(context->bitcount, len << 3);
+			/* Clean up: */
+			usedspace = freespace = 0;
+			return;
+		}
+	}
+	while (len >= SHA512_BLOCK_LENGTH) {
+		/* Process as many complete blocks as we can */
+		SHA512Transform(context->state.st64, data);
+		ADDINC128(context->bitcount, SHA512_BLOCK_LENGTH << 3);
+		len -= SHA512_BLOCK_LENGTH;
+		data += SHA512_BLOCK_LENGTH;
+	}
+	if (len > 0) {
+		/* There's left-overs, so save 'em */
+		memcpy(context->buffer, data, len);
+		ADDINC128(context->bitcount, len << 3);
+	}
+	/* Clean up: */
+	usedspace = freespace = 0;
+}
+
+void
+SHA512Pad(SHA2_CTX *context)
+{
+	unsigned int	usedspace;
+
+	usedspace = (context->bitcount[0] >> 3) % SHA512_BLOCK_LENGTH;
+	if (usedspace > 0) {
+		/* Begin padding with a 1 bit: */
+		context->buffer[usedspace++] = 0x80;
+
+		if (usedspace <= SHA512_SHORT_BLOCK_LENGTH) {
+			/* Set-up for the last transform: */
+			memset(&context->buffer[usedspace], 0, SHA512_SHORT_BLOCK_LENGTH - usedspace);
+		} else {
+			if (usedspace < SHA512_BLOCK_LENGTH) {
+				memset(&context->buffer[usedspace], 0, SHA512_BLOCK_LENGTH - usedspace);
+			}
+			/* Do second-to-last transform: */
+			SHA512Transform(context->state.st64, context->buffer);
+
+			/* And set-up for the last transform: */
+			memset(context->buffer, 0, SHA512_BLOCK_LENGTH - 2);
+		}
+	} else {
+		/* Prepare for final transform: */
+		memset(context->buffer, 0, SHA512_SHORT_BLOCK_LENGTH);
+
+		/* Begin padding with a 1 bit: */
+		*context->buffer = 0x80;
+	}
+	/* Store the length of input data (in bits) in big endian format: */
+	BE_64_TO_8(&context->buffer[SHA512_SHORT_BLOCK_LENGTH],
+	    context->bitcount[1]);
+	BE_64_TO_8(&context->buffer[SHA512_SHORT_BLOCK_LENGTH + 8],
+	    context->bitcount[0]);
+
+	/* Final transform: */
+	SHA512Transform(context->state.st64, context->buffer);
+
+	/* Clean up: */
+	usedspace = 0;
+}
+
+void
+SHA512Final(uint8_t digest[SHA512_DIGEST_LENGTH], SHA2_CTX *context)
+{
+	SHA512Pad(context);
+
+	/* If no digest buffer is passed, we don't bother doing this: */
+	if (digest != NULL) {
+#ifndef WORDS_BIGENDIAN
+		int	i;
+
+		/* Convert TO host byte order */
+		for (i = 0; i < 8; i++)
+			BE_64_TO_8(digest + i * 8, context->state.st64[i]);
+#else
+		memcpy(digest, context->state.st64, SHA512_DIGEST_LENGTH);
+#endif
+		memset(context, 0, sizeof(*context));
+	}
+}
+
+
+/*** SHA-384: *********************************************************/
+void
+SHA384Init(SHA2_CTX *context)
+{
+	if (context == NULL)
+		return;
+	memcpy(context->state.st64, sha384_initial_hash_value,
+	    sizeof(sha384_initial_hash_value));
+	memset(context->buffer, 0, sizeof(context->buffer));
+	context->bitcount[0] = context->bitcount[1] = 0;
+}
+
+#ifdef libmd_alias
+libmd_alias(SHA384Transform, SHA512Transform);
+libmd_alias(SHA384Update, SHA512Update);
+libmd_alias(SHA384Pad, SHA512Pad);
+#else
+void
+SHA384Transform(uint64_t state[8], const uint8_t data[SHA512_BLOCK_LENGTH])
+{
+	SHA512Transform(state, data);
+}
+
+void
+SHA384Update(SHA2_CTX *context, const uint8_t *data, size_t len)
+{
+	SHA512Update(context, data, len);
+}
+
+void
+SHA384Pad(SHA2_CTX *context)
+{
+	SHA512Pad(context);
+}
+#endif
+
+void
+SHA384Final(uint8_t digest[SHA384_DIGEST_LENGTH], SHA2_CTX *context)
+{
+	SHA384Pad(context);
+
+	/* If no digest buffer is passed, we don't bother doing this: */
+	if (digest != NULL) {
+#ifndef WORDS_BIGENDIAN
+		int	i;
+
+		/* Convert TO host byte order */
+		for (i = 0; i < 6; i++)
+			BE_64_TO_8(digest + i * 8, context->state.st64[i]);
+#else
+		memcpy(digest, context->state.st64, SHA384_DIGEST_LENGTH);
+#endif
+	}
+
+	/* Zero out state data */
+	memset(context, 0, sizeof(*context));
+}
+#endif /* SHA256_ONLY */

+ 6 - 0
libmd.mod/libmd/test/.gitignore

@@ -0,0 +1,6 @@
+md2
+md4
+md5
+rmd160
+sha1
+sha2

+ 23 - 0
libmd.mod/libmd/test/Makefile.am

@@ -0,0 +1,23 @@
+## Process this file with automake to produce Makefile.in
+
+AM_CPPFLAGS = \
+	-I$(top_builddir) \
+	-I$(top_srcdir)/include \
+	$(nil)
+
+LDADD = $(top_builddir)/src/libmd.la
+
+check_HEADERS = \
+	test.h \
+	$(nil)
+
+check_PROGRAMS = \
+	md2 \
+	md4 \
+	md5 \
+	rmd160 \
+	sha1 \
+	sha2 \
+	$(nil)
+
+TESTS = $(check_PROGRAMS)

+ 43 - 0
libmd.mod/libmd/test/md2.c

@@ -0,0 +1,43 @@
+/*
+ * Copyright © 2016 Guillem Jover <[email protected]>
+ *
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <config.h>
+
+#include <md2.h>
+
+#include "test.h"
+
+DEF_TEST_DIGEST(MD2, MD2)
+
+int
+main(int argc, char *argv[])
+{
+	test_MD2("8350e5a3e24c153df2275c9f80692773", "");
+	test_MD2("da853b0d3f88d99b30283a69e6ded6bb", "abc");
+	test_MD2("2fe3cb9e21922819e79a2781af74e36d", "12345");
+
+	return 0;
+}

+ 43 - 0
libmd.mod/libmd/test/md4.c

@@ -0,0 +1,43 @@
+/*
+ * Copyright © 2016 Guillem Jover <[email protected]>
+ *
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <config.h>
+
+#include <md4.h>
+
+#include "test.h"
+
+DEF_TEST_DIGEST(MD4, MD4)
+
+int
+main(int argc, char *argv[])
+{
+	test_MD4("31d6cfe0d16ae931b73c59d7e0c089c0", "");
+	test_MD4("a448017aaf21d8525fc10ae87aa6729d", "abc");
+	test_MD4("23580e2a459f7ea40f9efa148b63cafb", "12345");
+
+	return 0;
+}

+ 69 - 0
libmd.mod/libmd/test/md5.c

@@ -0,0 +1,69 @@
+/*
+ * Copyright © 2016 Guillem Jover <[email protected]>
+ *
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#define LIBMD_MD5_ALADDIN 1
+
+#include <config.h>
+
+#include <assert.h>
+#include <md5.h>
+#include <string.h>
+
+#include "test.h"
+
+DEF_TEST_DIGEST(MD5, MD5)
+
+static void
+test_MD5_aladdin(const char *hash_str_ref, const char *data)
+{
+	uint8_t hash_bin_ref[MD5_DIGEST_LENGTH];
+	uint8_t hash_bin_got[MD5_DIGEST_LENGTH];
+	md5_state_t pms;
+
+	hex2bin(hash_bin_ref, hash_str_ref, MD5_DIGEST_LENGTH);
+
+	md5_init(&pms);
+	md5_append(&pms, (const uint8_t *)data, strlen(data));
+	md5_finish(&pms, hash_bin_got);
+	assert(memcmp(hash_bin_ref, hash_bin_got, MD5_DIGEST_LENGTH) == 0);
+}
+
+static void
+test_MD5_all(const char *hash_str_ref, const char *data)
+{
+	test_MD5(hash_str_ref, data);
+	test_MD5_aladdin(hash_str_ref, data);
+}
+
+int
+main(int argc, char *argv[])
+{
+	test_MD5_all("d41d8cd98f00b204e9800998ecf8427e", "");
+	test_MD5_all("900150983cd24fb0d6963f7d28e17f72", "abc");
+	test_MD5_all("827ccb0eea8a706c4c34a16891f84e7b", "12345");
+
+	return 0;
+}

+ 43 - 0
libmd.mod/libmd/test/rmd160.c

@@ -0,0 +1,43 @@
+/*
+ * Copyright © 2016 Guillem Jover <[email protected]>
+ *
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <config.h>
+
+#include <rmd160.h>
+
+#include "test.h"
+
+DEF_TEST_DIGEST(RMD160, RMD160)
+
+int
+main(int argc, char *argv[])
+{
+	test_RMD160("9c1185a5c5e9fc54612808977ee8f548b2258d31", "");
+	test_RMD160("8eb208f7e05d987a9b044a8e98c6b087f15a0bfc", "abc");
+	test_RMD160("e9cbd2ea8015a084ce9cf83a3c65b51f8fa10a39", "12345");
+
+	return 0;
+}

+ 43 - 0
libmd.mod/libmd/test/sha1.c

@@ -0,0 +1,43 @@
+/*
+ * Copyright © 2016 Guillem Jover <[email protected]>
+ *
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <config.h>
+
+#include <sha1.h>
+
+#include "test.h"
+
+DEF_TEST_DIGEST(SHA1, SHA1)
+
+int
+main(int argc, char *argv[])
+{
+	test_SHA1("da39a3ee5e6b4b0d3255bfef95601890afd80709", "");
+	test_SHA1("a9993e364706816aba3e25717850c26c9cd0d89d", "abc");
+	test_SHA1("8cb2237d0679ca88db6464eac60da96345513964", "12345");
+
+	return 0;
+}

+ 62 - 0
libmd.mod/libmd/test/sha2.c

@@ -0,0 +1,62 @@
+/*
+ * Copyright © 2016 Guillem Jover <[email protected]>
+ *
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <config.h>
+
+#include <sha2.h>
+
+#include "test.h"
+
+DEF_TEST_DIGEST(SHA256, SHA2)
+DEF_TEST_DIGEST(SHA384, SHA2)
+DEF_TEST_DIGEST(SHA512, SHA2)
+
+int
+main(int argc, char *argv[])
+{
+	test_SHA256("e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
+	            "");
+	test_SHA256("ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad",
+	            "abc");
+	test_SHA256("5994471abb01112afcc18159f6cc74b4f511b99806da59b3caf5a9c173cacfc5",
+	            "12345");
+
+	test_SHA384("38b060a751ac96384cd9327eb1b1e36a21fdb71114be07434c0cc7bf63f6e1da274edebfe76f65fbd51ad2f14898b95b",
+	            "");
+	test_SHA384("cb00753f45a35e8bb5a03d699ac65007272c32ab0eded1631a8b605a43ff5bed8086072ba1e7cc2358baeca134c825a7",
+	            "abc");
+	test_SHA384("0fa76955abfa9dafd83facca8343a92aa09497f98101086611b0bfa95dbc0dcc661d62e9568a5a032ba81960f3e55d4a",
+	            "12345");
+
+	test_SHA512("cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e",
+	            "");
+	test_SHA512("ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f",
+	            "abc");
+	test_SHA512("3627909a29c31381a071ec27f7c9ca97726182aed29a7ddd2e54353322cfb30abb9e3a6df2ac2c20fe23436311d678564d0c8d305930575f60e2d3d048184d79",
+	            "12345");
+
+	return 0;
+}

+ 77 - 0
libmd.mod/libmd/test/test.h

@@ -0,0 +1,77 @@
+/*
+ * Copyright © 2018 Guillem Jover <[email protected]>
+ *
+ * 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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <config.h>
+
+#include <assert.h>
+#include <string.h>
+
+static int
+hexchar2bin(int c)
+{
+	if (c >= '0' && c <= '9')
+		return c - '0';
+	else if (c >= 'a' && c <= 'f')
+		return c - 'a' + 10;
+	else if (c >= 'A' && c <= 'F')
+		return c - 'A' + 10;
+	assert(!"invalid hexadecimal input");
+}
+
+static void
+hex2bin(uint8_t *bin, const char *str, size_t bin_len)
+{
+	size_t i;
+
+	for (i = 0; i < bin_len; i++)
+		bin[i] = hexchar2bin(str[i * 2]) << 4 |
+			 hexchar2bin(str[i * 2 + 1]);
+}
+
+#define DEF_TEST_DIGEST(name, type) \
+static void \
+test_##name(const char *hash_str_ref, const char *data) \
+{ \
+	uint8_t hash_bin_ref[name##_DIGEST_LENGTH]; \
+	uint8_t hash_bin_got[name##_DIGEST_LENGTH]; \
+	char hash_str_got[name##_DIGEST_STRING_LENGTH]; \
+	type##_CTX ctx; \
+\
+	hex2bin(hash_bin_ref, hash_str_ref, name##_DIGEST_LENGTH); \
+\
+	name##Data((const uint8_t *)data, strlen(data), hash_str_got); \
+	assert(strcmp(hash_str_ref, hash_str_got) == 0); \
+\
+	name##Init(&ctx); \
+	name##Update(&ctx, (const uint8_t *)data, strlen(data)); \
+	name##End(&ctx, hash_str_got); \
+	assert(strcmp(hash_str_ref, hash_str_got) == 0); \
+\
+	name##Init(&ctx); \
+	name##Update(&ctx, (const uint8_t *)data, strlen(data)); \
+	name##Final(hash_bin_got, &ctx); \
+	assert(memcmp(hash_bin_ref, hash_bin_got, sizeof(hash_bin_ref)) == 0); \
+}

+ 31 - 0
libmd.mod/source.bmx

@@ -0,0 +1,31 @@
+' Copyright (c) 2022 Bruce A Henderson
+' All rights reserved.
+'
+' Redistribution and use in source and binary forms, with or without
+' modification, are permitted provided that the following conditions are met:
+'     * Redistributions of source code must retain the above copyright
+'       notice, this list of conditions and the following disclaimer.
+'     * Redistributions in binary form must reproduce the above copyright
+'       notice, this list of conditions and the following disclaimer in the
+'       documentation and/or other materials provided with the distribution.
+'
+' THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER ``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 COPYRIGHT HOLDER 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.
+'
+SuperStrict
+
+Import "config/*.h"
+
+Import "libmd/include/*.h"
+Import "libmd/src/*.h"
+Import "libmd/src/md5.c"
+Import "libmd/src/sha1.c"
+Import "libmd/src/sha2.c"

+ 31 - 0
mtree.mod/common.bmx

@@ -0,0 +1,31 @@
+' Copyright (c) 2022 Bruce A Henderson
+' All rights reserved.
+'
+' Redistribution and use in source and binary forms, with or without
+' modification, are permitted provided that the following conditions are met:
+'     * Redistributions of source code must retain the above copyright
+'       notice, this list of conditions and the following disclaimer.
+'     * Redistributions in binary form must reproduce the above copyright
+'       notice, this list of conditions and the following disclaimer in the
+'       documentation and/or other materials provided with the distribution.
+'
+' THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER ``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 COPYRIGHT HOLDER 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.
+'
+SuperStrict
+
+Import Archive.libmd
+Import "source.bmx"
+
+Extern
+	Function archive_read_support_format_mtree:Int(archive:Byte Ptr)
+	Function archive_write_set_format_mtree:Int(archive:Byte Ptr)
+End Extern

+ 34 - 0
mtree.mod/examples/example_01.bmx

@@ -0,0 +1,34 @@
+SuperStrict
+
+Framework Archive.MTree
+Import brl.standardio
+
+Local wa:TWriteArchive = New TWriteArchive
+wa.SetFormat(EArchiveFormat.MTREE)
+
+wa.Open("data.tree")
+
+wa.AddEntry("testdata.txt", "files/testdata.txt")
+wa.AddEntry("테스트_데이터.txt", "files/테스트_데이터.txt")
+wa.AddEntry("", "empty", 0, 0, EArchiveFileType.Dir)
+
+wa.Close()
+
+
+Local entry:TArchiveEntry = New TArchiveEntry
+
+Local ra:TReadArchive = New TReadArchive
+ra.SetFormat(EArchiveFormat.MTREE)
+ra.Open("data.tree")
+
+While ra.ReadNextHeader(entry) = ARCHIVE_OK
+	Print "File : " + entry.Pathname()
+	Print "Size : " + entry.Size()
+	Local s:String = LoadText(ra.DataStream())
+	Print "String size   : " + s.Length
+	Print "First n chars : " + s[0..17]
+	Print
+Wend
+
+ra.Free()
+

+ 9 - 0
mtree.mod/examples/testdata.txt

@@ -0,0 +1,9 @@
+This is some data we want to compress
+
+
+blah 
+
+blah 
+
+
+blah

+ 9 - 0
mtree.mod/examples/테스트_데이터.txt

@@ -0,0 +1,9 @@
+This is some data we want to compress
+
+
+blah 
+
+blah 
+
+
+blah

+ 66 - 0
mtree.mod/mtree.bmx

@@ -0,0 +1,66 @@
+' Copyright (c) 2022 Bruce A Henderson
+' All rights reserved.
+'
+' Redistribution and use in source and binary forms, with or without
+' modification, are permitted provided that the following conditions are met:
+'     * Redistributions of source code must retain the above copyright
+'       notice, this list of conditions and the following disclaimer.
+'     * Redistributions in binary form must reproduce the above copyright
+'       notice, this list of conditions and the following disclaimer in the
+'       documentation and/or other materials provided with the distribution.
+'
+' THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER ``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 COPYRIGHT HOLDER 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.
+'
+SuperStrict
+
+Module Archive.MTree
+
+ModuleInfo "CC_OPTS: -DARCHIVE_CRYPTO_MD5_LIBMD"
+ModuleInfo "CC_OPTS: -DARCHIVE_CRYPTO_SHA1_LIBMD"
+ModuleInfo "CC_OPTS: -DARCHIVE_CRYPTO_SHA256_LIBMD"
+ModuleInfo "CC_OPTS: -DARCHIVE_CRYPTO_SHA512_LIBMD"
+ModuleInfo "CC_OPTS: -DHAVE_CONFIG_H -D_FILE_OFFSET_BITS=64"
+?win32
+ModuleInfo "CC_OPTS: -DLIBARCHIVE_STATIC"
+?
+
+Import Archive.Core
+Import "common.bmx"
+
+Private
+
+Type TMTreeArchiveFormat Extends TArchiveFormat
+
+	Method AddReadFormat:Int(archive:Byte Ptr, format:EArchiveFormat)
+		If format = EArchiveFormat.MTREE Then
+			archive_read_support_format_mtree(archive)
+			Return True
+		End If
+	End Method
+
+	Method AddWriteFormat:Int(archive:Byte Ptr, format:EArchiveFormat)
+		If format = EArchiveFormat.MTREE Then
+			archive_write_set_format_mtree(archive)
+			Return True
+		End If
+	End Method
+
+	Method AddReadFilter:Int(archive:Byte Ptr, filter:EArchiveFilter)
+		Return False
+	End Method
+
+	Method AddWriteFilter:Int(archive:Byte Ptr, filter:EArchiveFilter)
+		Return False
+	End Method
+End Type
+
+New TMTreeArchiveFormat

+ 31 - 0
mtree.mod/source.bmx

@@ -0,0 +1,31 @@
+' Copyright (c) 2022 Bruce A Henderson
+' All rights reserved.
+'
+' Redistribution and use in source and binary forms, with or without
+' modification, are permitted provided that the following conditions are met:
+'     * Redistributions of source code must retain the above copyright
+'       notice, this list of conditions and the following disclaimer.
+'     * Redistributions in binary form must reproduce the above copyright
+'       notice, this list of conditions and the following disclaimer in the
+'       documentation and/or other materials provided with the distribution.
+'
+' THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER ``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 COPYRIGHT HOLDER 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.
+'
+SuperStrict
+
+Import "../libmd.mod/libmd/include/*.h"
+
+Import "../core.mod/include/*.h"
+Import "../core.mod/libarchive/libarchive/*.h"
+Import "../core.mod/libarchive/libarchive/archive_digest.c"
+Import "../core.mod/libarchive/libarchive/archive_read_support_format_mtree.c"
+Import "../core.mod/libarchive/libarchive/archive_write_set_format_mtree.c"