Hi Todd, thank you for your comments!
We have included all the necessary changes in the patch attached. Best regards, Daniel, Stefan and Alexander Index: bin/md5/Makefile =================================================================== RCS file: /cvs/src/bin/md5/Makefile,v retrieving revision 1.15 diff -u -p -u -p -r1.15 Makefile --- bin/md5/Makefile 30 Mar 2016 06:38:40 -0000 1.15 +++ bin/md5/Makefile 10 Jan 2018 13:43:55 -0000 @@ -3,9 +3,16 @@ PROG= md5 SRCS= crc.c md5.c MAN= cksum.1 md5.1 + LINKS= ${BINDIR}/md5 ${BINDIR}/sha1 \ + ${BINDIR}/md5 ${BINDIR}/sha224 \ ${BINDIR}/md5 ${BINDIR}/sha256 \ + ${BINDIR}/md5 ${BINDIR}/sha384 \ ${BINDIR}/md5 ${BINDIR}/sha512 \ + ${BINDIR}/md5 ${BINDIR}/sha3-224 \ + ${BINDIR}/md5 ${BINDIR}/sha3-256 \ + ${BINDIR}/md5 ${BINDIR}/sha3-384 \ + ${BINDIR}/md5 ${BINDIR}/sha3-512 \ ${BINDIR}/md5 ${BINDIR}/cksum CPPFLAGS+= -I${.CURDIR} Index: bin/md5/md5.1 =================================================================== RCS file: /cvs/src/bin/md5/md5.1,v retrieving revision 1.47 diff -u -p -u -p -r1.47 md5.1 --- bin/md5/md5.1 23 Feb 2017 20:46:08 -0000 1.47 +++ bin/md5/md5.1 10 Jan 2018 13:43:55 -0000 @@ -18,14 +18,18 @@ .\" Agency (DARPA) and Air Force Research Laboratory, Air Force .\" Materiel Command, USAF, under agreement number F39502-99-1-0512. .\" -.Dd $Mdocdate: February 23 2017 $ +.Dd $Mdocdate: January 9 2018 $ .Dt MD5 1 .Os .Sh NAME .Nm md5 , .Nm sha1 , .Nm sha256 , -.Nm sha512 +.Nm sha512 , +.Nm sha3-224 , +.Nm sha3-256 , +.Nm sha3-384 , +.Nm sha3-512 .Nd calculate a message digest (checksum) for a file .Sh SYNOPSIS .Nm md5 @@ -52,6 +56,30 @@ .Op Fl h Ar hashfile .Op Fl s Ar string .Op Ar +.Nm sha3-224 +.Op Fl bcpqrtx +.Op Fl C Ar checklist +.Op Fl h Ar hashfile +.Op Fl s Ar string +.Op Ar +.Nm sha3-256 +.Op Fl bcpqrtx +.Op Fl C Ar checklist +.Op Fl h Ar hashfile +.Op Fl s Ar string +.Op Ar +.Nm sha3-384 +.Op Fl bcpqrtx +.Op Fl C Ar checklist +.Op Fl h Ar hashfile +.Op Fl s Ar string +.Op Ar +.Nm sha3-512 +.Op Fl bcpqrtx +.Op Fl C Ar checklist +.Op Fl h Ar hashfile +.Op Fl s Ar string +.Op Ar .Sh DESCRIPTION These utilities take as input a message of arbitrary length and produce as output a message digest (checksum) of the input. @@ -136,7 +164,13 @@ and \*(Gt0 if an error occurs. .%R RFC 3174 .%T US Secure Hash Algorithm 1 (SHA1) .Re +.Pp .Rs .%T Secure Hash Standard .%O FIPS PUB 180-2 +.Re +.Pp +.Rs +.%T SHA-3 Standard: Permutation-Based Hash and Extendable-Output Functions +.%O FIPS PUB 202 .Re Index: bin/md5/md5.c =================================================================== RCS file: /cvs/src/bin/md5/md5.c,v retrieving revision 1.92 diff -u -p -u -p -r1.92 md5.c --- bin/md5/md5.c 11 Sep 2017 16:35:38 -0000 1.92 +++ bin/md5/md5.c 10 Jan 2018 13:43:55 -0000 @@ -42,6 +42,7 @@ #include <rmd160.h> #include <sha1.h> #include <sha2.h> +#include <sha3.h> #include <crc.h> #define STYLE_MD5 0 @@ -61,6 +62,7 @@ union ANY_CTX { SHA1_CTX sha1; #endif /* !defined(SHA2_ONLY) */ SHA2_CTX sha2; + SHA3_CTX sha3; }; struct hash_function { @@ -177,6 +179,50 @@ struct hash_function { (void (*)(void *, const unsigned char *, size_t))SHA512Update, (void (*)(unsigned char *, void *))SHA512Final, (char *(*)(void *, char *))SHA512End + }, + { + "SHA3-224", + SHA3_224_DIGEST_LENGTH, + STYLE_MD5, + 0, + NULL, + (void (*)(void *))SHA3_224Init, + (void (*)(void *, const unsigned char *, size_t))SHA3_Update, + (void (*)(unsigned char *, void *))SHA3_Final, + (char *(*)(void *, char *))SHA3_224End + }, + { + "SHA3-256", + SHA3_256_DIGEST_LENGTH, + STYLE_MD5, + 0, + NULL, + (void (*)(void *))SHA3_256Init, + (void (*)(void *, const unsigned char *, size_t))SHA3_Update, + (void (*)(unsigned char *, void *))SHA3_Final, + (char *(*)(void *, char *))SHA3_256End + }, + { + "SHA3-384", + SHA3_384_DIGEST_LENGTH, + STYLE_MD5, + 0, + NULL, + (void (*)(void *))SHA3_384Init, + (void (*)(void *, const unsigned char *, size_t))SHA3_Update, + (void (*)(unsigned char *, void *))SHA3_Final, + (char *(*)(void *, char *))SHA3_384End + }, + { + "SHA3-512", + SHA3_512_DIGEST_LENGTH, + STYLE_MD5, + 0, + NULL, + (void (*)(void *))SHA3_512Init, + (void (*)(void *, const unsigned char *, size_t))SHA3_Update, + (void (*)(unsigned char *, void *))SHA3_Final, + (char *(*)(void *, char *))SHA3_512End }, { NULL, Index: include/Makefile =================================================================== RCS file: /cvs/src/include/Makefile,v retrieving revision 1.222 diff -u -p -u -p -r1.222 Makefile --- include/Makefile 17 Oct 2017 09:34:52 -0000 1.222 +++ include/Makefile 10 Jan 2018 13:44:01 -0000 @@ -23,7 +23,7 @@ FILES= a.out.h ar.h asr.h assert.h \ ndbm.h netdb.h netgroup.h nlist.h nl_types.h \ paths.h poll.h pthread.h pthread_np.h pwd.h \ ranlib.h readpassphrase.h regex.h resolv.h rmd160.h \ - sched.h search.h setjmp.h semaphore.h sha1.h sha2.h \ + sched.h search.h setjmp.h semaphore.h sha1.h sha2.h sha3.h \ signal.h siphash.h sndio.h spawn.h stdbool.h stddef.h \ stdio.h stdlib.h string.h strings.h sysexits.h \ tar.h tgmath.h tib.h time.h ttyent.h \ Index: include/sha3.h =================================================================== RCS file: include/sha3.h diff -N include/sha3.h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ include/sha3.h 10 Jan 2018 13:44:01 -0000 @@ -0,0 +1,78 @@ +#ifndef _SHA3_H +#define _SHA3_H + +#define SHA3_224_DIGEST_LENGTH 28 +#define SHA3_224_DIGEST_STRING_LENGTH (SHA3_224_DIGEST_LENGTH * 2 + 1) + +#define SHA3_256_DIGEST_LENGTH 32 +#define SHA3_256_DIGEST_STRING_LENGTH (SHA3_256_DIGEST_LENGTH * 2 + 1) + +#define SHA3_384_DIGEST_LENGTH 48 +#define SHA3_384_DIGEST_STRING_LENGTH (SHA3_384_DIGEST_LENGTH * 2 + 1) + +#define SHA3_512_DIGEST_LENGTH 64 +#define SHA3_512_DIGEST_STRING_LENGTH (SHA3_512_DIGEST_LENGTH * 2 + 1) + +#define SHA3_STATE_SIZE (1600 / 8) + + +typedef struct _SHA3_CTX { + unsigned char state[SHA3_STATE_SIZE]; + unsigned int rate; + unsigned int byteIOIndex; + unsigned int fixedOutputLength; +} SHA3_CTX; + + +__BEGIN_DECLS +void SHA3_224Init(SHA3_CTX *); +char *SHA3_224End(SHA3_CTX *, char *) + __attribute__((__bounded__(__minbytes__,2,SHA3_224_DIGEST_STRING_LENGTH))); +char *SHA3_224File(const char *, char *) + __attribute__((__bounded__(__minbytes__,2,SHA3_224_DIGEST_STRING_LENGTH))); +char *SHA3_224FileChunk(const char *, char *, off_t, off_t) + __attribute__((__bounded__(__minbytes__,2,SHA3_224_DIGEST_STRING_LENGTH))); +char *SHA3_224Data(const u_int8_t *, size_t, char *) + __attribute__((__bounded__(__string__,1,2))) + __attribute__((__bounded__(__minbytes__,3,SHA3_224_DIGEST_STRING_LENGTH))); + +void SHA3_256Init(SHA3_CTX *); +char *SHA3_256End(SHA3_CTX *, char *) + __attribute__((__bounded__(__minbytes__,2,SHA3_256_DIGEST_STRING_LENGTH))); +char *SHA3_256File(const char *, char *) + __attribute__((__bounded__(__minbytes__,2,SHA3_256_DIGEST_STRING_LENGTH))); +char *SHA3_256FileChunk(const char *, char *, off_t, off_t) + __attribute__((__bounded__(__minbytes__,2,SHA3_256_DIGEST_STRING_LENGTH))); +char *SHA3_256Data(const u_int8_t *, size_t, char *) + __attribute__((__bounded__(__string__,1,2))) + __attribute__((__bounded__(__minbytes__,3,SHA3_256_DIGEST_STRING_LENGTH))); + +void SHA3_384Init(SHA3_CTX *); +char *SHA3_384End(SHA3_CTX *, char *) + __attribute__((__bounded__(__minbytes__,2,SHA3_384_DIGEST_STRING_LENGTH))); +char *SHA3_384File(const char *, char *) + __attribute__((__bounded__(__minbytes__,2,SHA3_384_DIGEST_STRING_LENGTH))); +char *SHA3_384FileChunk(const char *, char *, off_t, off_t) + __attribute__((__bounded__(__minbytes__,2,SHA3_384_DIGEST_STRING_LENGTH))); +char *SHA3_384Data(const u_int8_t *, size_t, char *) + __attribute__((__bounded__(__string__,1,2))) + __attribute__((__bounded__(__minbytes__,3,SHA3_384_DIGEST_STRING_LENGTH))); + +void SHA3_512Init(SHA3_CTX *); +char *SHA3_512End(SHA3_CTX *, char *) + __attribute__((__bounded__(__minbytes__,2,SHA3_512_DIGEST_STRING_LENGTH))); +char *SHA3_512File(const char *, char *) + __attribute__((__bounded__(__minbytes__,2,SHA3_512_DIGEST_STRING_LENGTH))); +char *SHA3_512FileChunk(const char *, char *, off_t, off_t) + __attribute__((__bounded__(__minbytes__,2,SHA3_512_DIGEST_STRING_LENGTH))); +char *SHA3_512Data(const u_int8_t *, size_t, char *) + __attribute__((__bounded__(__string__,1,2))) + __attribute__((__bounded__(__minbytes__,3,SHA3_512_DIGEST_STRING_LENGTH))); + +void SHA3_Update(SHA3_CTX *, const u_int8_t *, size_t) + __attribute__((__bounded__(__string__,2,3))); +void SHA3_Final(u_int8_t [SHA3_224_DIGEST_LENGTH], SHA3_CTX *) + __attribute__((__bounded__(__minbytes__,1,SHA3_224_DIGEST_LENGTH))); +__END_DECLS + +#endif /* _SHA3_H */ Index: lib/libc/shlib_version =================================================================== RCS file: /cvs/src/lib/libc/shlib_version,v retrieving revision 1.197 diff -u -p -u -p -r1.197 shlib_version --- lib/libc/shlib_version 26 Dec 2017 15:11:17 -0000 1.197 +++ lib/libc/shlib_version 10 Jan 2018 13:44:01 -0000 @@ -1,4 +1,4 @@ major=92 -minor=2 +minor=3 # note: If changes were made to include/thread_private.h or if system # calls were added/changed then librthread/shlib_version also be updated. Index: lib/libc/hash/Makefile.inc =================================================================== RCS file: /cvs/src/lib/libc/hash/Makefile.inc,v retrieving revision 1.24 diff -u -p -u -p -r1.24 Makefile.inc --- lib/libc/hash/Makefile.inc 3 Sep 2016 16:25:03 -0000 1.24 +++ lib/libc/hash/Makefile.inc 10 Jan 2018 13:44:01 -0000 @@ -3,9 +3,9 @@ # hash functions .PATH: ${LIBCSRCDIR}/hash -HELPER= md5hl.c rmd160hl.c sha1hl.c sha224hl.c sha256hl.c sha384hl.c sha512hl.c sha512_256hl.c -SRCS+= md5.c rmd160.c sha1.c sha2.c ${HELPER} siphash.c -MAN+= md5.3 rmd160.3 sha1.3 sha2.3 SipHash24.3 +HELPER= md5hl.c rmd160hl.c sha1hl.c sha224hl.c sha256hl.c sha384hl.c sha512hl.c sha512_256hl.c sha3-224hl.c sha3-256hl.c sha3-384hl.c sha3-512hl.c +SRCS+= md5.c rmd160.c sha1.c sha2.c sha3.c ${HELPER} siphash.c +MAN+= md5.3 rmd160.3 sha1.3 sha2.3 sha3.3 SipHash24.3 CLEANFILES+= ${HELPER} @@ -43,4 +43,32 @@ sha512_256hl.c: helper.c -e 's/HASH/SHA512_256/g' \ -e 's/SHA512_256_CTX/SHA2_CTX/g' $> > $@ -beforedepend: md5hl.c rmd160hl.c sha1hl.c sha256hl.c sha384hl.c sha512hl.c sha512_256hl.c +sha3-224hl.c: helper.c + sed -e 's/hashinc/sha3.h/g' \ + -e 's/HASH/SHA3_224/g' \ + -e 's/SHA3_[0-9][0-9][0-9]Update/SHA3_Update/g' \ + -e 's/SHA3_[0-9][0-9][0-9]Final/SHA3_Final/g' \ + -e 's/SHA3_[0-9][0-9][0-9]_CTX/SHA3_CTX/g' $> > $@ + +sha3-256hl.c: helper.c + sed -e 's/hashinc/sha3.h/g' \ + -e 's/HASH/SHA3_256/g' \ + -e 's/SHA3_[0-9][0-9][0-9]Update/SHA3_Update/g' \ + -e 's/SHA3_[0-9][0-9][0-9]Final/SHA3_Final/g' \ + -e 's/SHA3_[0-9][0-9][0-9]_CTX/SHA3_CTX/g' $> > $@ + +sha3-384hl.c: helper.c + sed -e 's/hashinc/sha3.h/g' \ + -e 's/HASH/SHA3_384/g' \ + -e 's/SHA3_[0-9][0-9][0-9]Update/SHA3_Update/g' \ + -e 's/SHA3_[0-9][0-9][0-9]Final/SHA3_Final/g' \ + -e 's/SHA3_[0-9][0-9][0-9]_CTX/SHA3_CTX/g' $> > $@ + +sha3-512hl.c: helper.c + sed -e 's/hashinc/sha3.h/g' \ + -e 's/HASH/SHA3_512/g' \ + -e 's/SHA3_[0-9][0-9][0-9]Update/SHA3_Update/g' \ + -e 's/SHA3_[0-9][0-9][0-9]Final/SHA3_Final/g' \ + -e 's/SHA3_[0-9][0-9][0-9]_CTX/SHA3_CTX/g' $> > $@ + +beforedepend: md5hl.c rmd160hl.c sha1hl.c sha256hl.c sha384hl.c sha512hl.c sha512_256hl.c sha3-224hl.c sha3-256hl.c sha3-384hl.c sha3-512hl.c Index: lib/libc/hash/sha3.3 =================================================================== RCS file: lib/libc/hash/sha3.3 diff -N lib/libc/hash/sha3.3 --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ lib/libc/hash/sha3.3 10 Jan 2018 13:44:01 -0000 @@ -0,0 +1,292 @@ +.\" $OpenBSD: sha2.3,v 1.26 2016/09/04 09:28:12 tedu Exp $ +.\" +.\" Copyright (c) 2003, 2004 Todd C. Miller <todd.mil...@courtesan.com> +.\" +.\" 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: January 9 2018 $ +.Dt SHA3INIT 3 +.Os +.Sh NAME +.Nm SHA3_224Init , +.Nm SHA3_224Update , +.Nm SHA3_224Final , +.Nm SHA3_224End , +.Nm SHA3_224File , +.Nm SHA3_224FileChunk , +.Nm SHA3_224Data , +.Nm SHA3_256Init , +.Nm SHA3_256Update , +.Nm SHA3_256Final , +.Nm SHA3_256End , +.Nm SHA3_256File , +.Nm SHA3_256FileChunk , +.Nm SHA3_256Data , +.Nm SHA3_384Init , +.Nm SHA3_384Update , +.Nm SHA3_384Final , +.Nm SHA3_384End , +.Nm SHA3_384File , +.Nm SHA3_384FileChunk , +.Nm SHA3_384Data , +.Nm SHA3_512Init , +.Nm SHA3_512Update , +.Nm SHA3_512Final , +.Nm SHA3_512End , +.Nm SHA3_512File , +.Nm SHA3_512FileChunk , +.Nm SHA3_512Data , +.Nm SHA3_512_256Init , +.Nm SHA3_512_256Update , +.Nm SHA3_512_256Final , +.Nm SHA3_512_256End , +.Nm SHA3_512_256File , +.Nm SHA3_512_256FileChunk , +.Nm SHA3_512_256Data +.Nd calculate the NIST Secure Hash Standard (version 3) +.Sh SYNOPSIS +.In sys/types.h +.In sha3.h +.Ft void +.Fn SHA3_224Init "SHA3_CTX *context" +.Ft void +.Fn SHA3_224Update "SHA3_CTX *context" "const u_int8_t *data" "size_t len" +.Ft void +.Fn SHA3_224Final "u_int8_t digest[SHA3_224_DIGEST_LENGTH]" "SHA3_CTX *context" +.Ft "char *" +.Fn SHA3_224End "SHA3_CTX *context" "char *buf" +.Ft "char *" +.Fn SHA3_224File "const char *filename" "char *buf" +.Ft "char *" +.Fn SHA3_224FileChunk "const char *filename" "char *buf" "off_t offset" "off_t length" +.Ft "char *" +.Fn SHA3_224Data "const u_int8_t *data" "size_t len" "char *buf" +.Ft void +.Fn SHA3_256Init "SHA3_CTX *context" +.Ft void +.Fn SHA3_256Update "SHA3_CTX *context" "const u_int8_t *data" "size_t len" +.Ft void +.Fn SHA3_256Final "u_int8_t digest[SHA3_256_DIGEST_LENGTH]" "SHA3_CTX *context" +.Ft "char *" +.Fn SHA3_256End "SHA3_CTX *context" "char *buf" +.Ft "char *" +.Fn SHA3_256File "const char *filename" "char *buf" +.Ft "char *" +.Fn SHA3_256FileChunk "const char *filename" "char *buf" "off_t offset" "off_t length" +.Ft "char *" +.Fn SHA3_256Data "const u_int8_t *data" "size_t len" "char *buf" +.Ft void +.Fn SHA3_384Init "SHA3_CTX *context" +.Ft void +.Fn SHA3_384Update "SHA3_CTX *context" "const u_int8_t *data" "size_t len" +.Ft void +.Fn SHA3_384Final "u_int8_t digest[SHA3_384_DIGEST_LENGTH]" "SHA3_CTX *context" +.Ft "char *" +.Fn SHA3_384End "SHA3_CTX *context" "char *buf" +.Ft "char *" +.Fn SHA3_384File "const char *filename" "char *buf" +.Ft "char *" +.Fn SHA3_384FileChunk "const char *filename" "char *buf" "off_t offset" "off_t length" +.Ft "char *" +.Fn SHA3_384Data "const u_int8_t *data" "size_t len" "char *buf" +.Ft void +.Fn SHA3_512Init "SHA3_CTX *context" +.Ft void +.Fn SHA3_512Update "SHA3_CTX *context" "const u_int8_t *data" "size_t len" +.Ft void +.Fn SHA3_512Final "u_int8_t digest[SHA3_512_DIGEST_LENGTH]" "SHA3_CTX *context" +.Ft "char *" +.Fn SHA3_512End "SHA3_CTX *context" "char *buf" +.Ft "char *" +.Fn SHA3_512File "const char *filename" "char *buf" +.Ft "char *" +.Fn SHA3_512FileChunk "const char *filename" "char *buf" "off_t offset" "off_t length" +.Ft "char *" +.Fn SHA3_512Data "const u_int8_t *data" "size_t len" "char *buf" +.Ft void +.Fn SHA3_512_256Init "SHA3_CTX *context" +.Ft void +.Fn SHA3_512_256Update "SHA3_CTX *context" "const u_int8_t *data" "size_t len" +.Ft void +.Fn SHA3_512_256Final "u_int8_t digest[SHA3_512_256_DIGEST_LENGTH]" "SHA3_CTX *context" +.Ft "char *" +.Fn SHA3_512_256End "SHA3_CTX *context" "char *buf" +.Ft "char *" +.Fn SHA3_512_256File "const char *filename" "char *buf" +.Ft "char *" +.Fn SHA3_512_256FileChunk "const char *filename" "char *buf" "off_t offset" "off_t length" +.Ft "char *" +.Fn SHA3_512_256Data "const u_int8_t *data" "size_t len" "char *buf" +.Sh DESCRIPTION +The SHA-3 functions implement the NIST Secure Hash Standard, +FIPS PUB 202. +The SHA-3 functions are used to generate a condensed representation of a +message called a message digest, suitable for use as a digital signature. +There are four families of functions, with names corresponding to +the number of bits in the resulting message digest. +The functions can process a message of arbitrary length as input. +.Pp +The SHA-3 functions are considered to be more secure than the +.Xr sha1 3 +functions with which they share a similar interface. They are an +alternative to the +.Xr sha2 3 +functions. +The 224, 256, 384, and 512-bit versions of SHA-3 share the same interface. +For brevity, only the 256-bit variants are described below. +.Pp +The +.Fn SHA3_256Init +function initializes a SHA3_CTX +.Fa context +for use with +.Fn SHA3_256Update +and +.Fn SHA3_256Final . +The +.Fn SHA3_256Update +function adds +.Fa data +of length +.Fa len +to the SHA3_CTX specified by +.Fa context . +.Fn SHA3_256Final +is called when all data has been added via +.Fn SHA3_256Update +and stores a message digest in the +.Fa digest +parameter. +.Pp +The +.Fn SHA3_256End +function is a front end for +.Fn SHA3_256Final +which converts the digest into an +.Tn ASCII +representation of the digest in hexadecimal. +.Pp +The +.Fn SHA3_256File +function calculates the digest for a file and returns the result via +.Fn SHA3_256End . +If +.Fn SHA3_256File +is unable to open the file, a +.Dv NULL +pointer is returned. +.Pp +.Fn SHA3_256FileChunk +behaves like +.Fn SHA3_256File +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 SHA3_256Data +function +calculates the digest of an arbitrary string and returns the result via +.Fn SHA3_256End . +.Pp +For each of the +.Fn SHA3_256End , +.Fn SHA3_256File , +.Fn SHA3_256FileChunk , +and +.Fn SHA3_256Data +functions the +.Fa buf +parameter should either be a string large enough to hold the resulting digest +(e.g.\& +.Dv SHA3_224_DIGEST_STRING_LENGTH , +.Dv SHA3_256_DIGEST_STRING_LENGTH , +.Dv SHA3_384_DIGEST_STRING_LENGTH , +.Dv SHA3_512_DIGEST_STRING_LENGTH , +or +.Dv SHA3_512_256_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 SHA3-256 digest for the string +.Qq abc , +which is +.Dq 0x3a985da74fe225b2045c172d6bd390bd855f086e3e9d525b46bfe24511431532 . +.Bd -literal -offset indent +SHA3_CTX ctx; +u_int8_t results[SHA3_256_DIGEST_LENGTH]; +char *buf; +int n; + +buf = "abc"; +n = strlen(buf); +SHA3_256Init(&ctx); +SHA3_256Update(&ctx, (u_int8_t *)buf, n); +SHA3_256Final(results, &ctx); + +/* Print the digest as one long hex value */ +printf("0x"); +for (n = 0; n \*(Lt SHA3_256_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 +u_int8_t output[SHA3_256_DIGEST_STRING_LENGTH]; +char *buf = "abc"; + +printf("0x%s\en", SHA3_256Data(buf, strlen(buf), output)); +.Ed +.Sh SEE ALSO +.Xr cksum 1 , +.Xr md5 3 , +.Xr rmd160 3 , +.Xr sha1 3 , +.Xr sha2 3 +.Rs +.%T SHA-3 Standard: Permutation-Based Hash and Extendable-Output Functions +.%O FIPS PUB 202 +.Re +.Pp +The +.Fn SHA3_256End , +.Fn SHA3_256File , +.Fn SHA3_256FileChunk , +and +.Fn SHA3_256Data +helper functions are derived from code written by +.An Poul-Henning Kamp . Index: lib/libc/hash/sha3.c =================================================================== RCS file: lib/libc/hash/sha3.c diff -N lib/libc/hash/sha3.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ lib/libc/hash/sha3.c 10 Jan 2018 13:44:01 -0000 @@ -0,0 +1,761 @@ +/* + * Implementation by the Keccak, Keyak and Ketje Teams, namely, Guido Bertoni, + * Joan Daemen, Michaƫl Peeters, Gilles Van Assche and Ronny Van Keer, hereby + * denoted as "the implementer". + * + * For more information, feedback or questions, please refer to our websites: + * http://keccak.noekeon.org/ + * http://keyak.noekeon.org/ + * http://ketje.noekeon.org/ + * + * Adaptation to OpenBSD in 2017/18 by + * Stefan-Lukas Gazdag, Alexander von Gernler and Daniel Loebenberger + * https://www.genua.de/ + * also denoted as "the implementer" + * + * To the extent possible under law, the implementer has waived all copyright + * and related or neighboring rights to the source code in this file. + * http://creativecommons.org/publicdomain/zero/1.0/ + */ + +#include <assert.h> +#include <sys/types.h> +#include <string.h> +#include <strings.h> +#include <sha3.h> + +typedef unsigned long long tKeccakLane; + +#define SHA3_NRROUNDS 24 +#define SHA3_NRLANES 25 +#define SHA3_DELIMITER 0x06 + +#define index(x, y) (((x)%5)+5*((y)%5)) + +const tKeccakLane KeccakRoundConstants[SHA3_NRROUNDS] = +{ + 0x0000000000000001, + 0x0000000000008082, + 0x800000000000808a, + 0x8000000080008000, + 0x000000000000808b, + 0x0000000080000001, + 0x8000000080008081, + 0x8000000000008009, + 0x000000000000008a, + 0x0000000000000088, + 0x0000000080008009, + 0x000000008000000a, + 0x000000008000808b, + 0x800000000000008b, + 0x8000000000008089, + 0x8000000000008003, + 0x8000000000008002, + 0x8000000000000080, + 0x000000000000800a, + 0x800000008000000a, + 0x8000000080008081, + 0x8000000000008080, + 0x0000000080000001, + 0x8000000080008008, +}; + +const unsigned int KeccakRhoOffsets[SHA3_NRLANES] = +{ + 0, 1, 62, 28, 27, 36, 44, 6, 55, 20, 3, 10, 43, + 25, 39, 41, 45, 15, 21, 8, 18, 2, 61, 56, 14 +}; + +/* + * unused, but these constance denote the one implementation out of the + * Keccak Code Package that was taken here + */ +#define KeccakP1600_implementation "64-bit reference implementation" +#define KeccakP1600_stateSizeInBytes 200 +#define KeccakP1600_stateAlignment 8 + +/* prototypes for local functions */ +static void KeccakP1600_AddByte(void *state, unsigned char data, + unsigned int offset); +static void KeccakP1600_AddBytes(void *state, const unsigned char *data, + unsigned int offset, unsigned int length); +static void KeccakP1600_Permute_24rounds(void *state); +static void KeccakP1600_ExtractBytes(const void *state, unsigned char *data, + unsigned int offset, unsigned int length); +static void Keccak_HashInitialize(SHA3_CTX *, unsigned int, unsigned int); + + +/* + * interface functions external use + * (rate + capacity) = 1600, + * thus the rate specifies the capacity + */ +void +SHA3_224Init(SHA3_CTX *context) +{ + /* rate = 1152, output width 224 bit */ + Keccak_HashInitialize(context, 1152, 224); +} +DEF_WEAK(SHA3_224Init); + +void +SHA3_256Init(SHA3_CTX *context) +{ + /* rate = 1088, output width 256 bit */ + Keccak_HashInitialize(context, 1088, 256); +} +DEF_WEAK(SHA3_256Init); + +void +SHA3_384Init(SHA3_CTX *context) +{ + /* rate = 832, output width 384 bit */ + Keccak_HashInitialize(context, 832, 384); +} +DEF_WEAK(SHA3_384Init); + +void +SHA3_512Init(SHA3_CTX *context) +{ + /* rate = 576, output width 512 bit */ + Keccak_HashInitialize(context, 576, 512); +} +DEF_WEAK(SHA3_512Init); + + +void +SHA3_Update(SHA3_CTX *context, const u_int8_t *data, size_t len) +{ + size_t i, j; + unsigned int partialBlock; + const unsigned char *curData; + unsigned int rateInBytes; + rateInBytes = context->rate/8; + + i = 0; + curData = data; + while(i < len) { + if ((context->byteIOIndex == 0) && (len >= (i + rateInBytes))) { +#ifdef SnP_FastLoop_Absorb + /* processing full blocks first */ + if ((rateInBytes % (KeccakP1600_width/200)) == 0) { + /* fast lane: whole lane rate */ + j = KeccakP1600_FastLoop_Absorb(context->state, + rateInBytes/(KeccakP1600_width/200), curData, len - i); + i += j; + curData += j; + } + else { +#endif + for(j=len-i; j>=rateInBytes; j-=rateInBytes) { +#ifdef KeccakReference + displayBytes(1, "Block to be absorbed", curData, rateInBytes); +#endif + KeccakP1600_AddBytes(context->state, curData, 0, rateInBytes); + KeccakP1600_Permute_24rounds(context->state); + curData+=rateInBytes; + } + i = len - j; +#ifdef SnP_FastLoop_Absorb + } +#endif + } + else { + /* normal lane: using the message queue */ + partialBlock = (unsigned int)(len - i); + if (partialBlock+context->byteIOIndex > rateInBytes) + partialBlock = rateInBytes-context->byteIOIndex; +#ifdef KeccakReference + displayBytes(1, "Block to be absorbed (part)", curData, partialBlock); +#endif + i += partialBlock; + + KeccakP1600_AddBytes(context->state, curData, context->byteIOIndex, partialBlock); + curData += partialBlock; + context->byteIOIndex += partialBlock; + if (context->byteIOIndex == rateInBytes) { + KeccakP1600_Permute_24rounds(context->state); + context->byteIOIndex = 0; + } + } + } +} +DEF_WEAK(SHA3_Update); + +void +SHA3_Final(u_int8_t* digest, SHA3_CTX *context) +{ + size_t i, j; + unsigned int partialBlock; + unsigned char *curData; + unsigned int rateInBytes; + size_t dataByteLen; + + rateInBytes = context->rate/8; + dataByteLen = context->fixedOutputLength/8; + + /* Last few bits, whose delimiter coincides with first bit of padding */ + KeccakP1600_AddByte(context->state, SHA3_DELIMITER, context->byteIOIndex); + + /* + * If the first bit of padding is at position rate-1, we need a whole + * new block for the second bit of padding + */ + /* Second bit of padding */ + KeccakP1600_AddByte(context->state, 0x80, rateInBytes-1); + + KeccakP1600_Permute_24rounds(context->state); + context->byteIOIndex = 0; + + /* SQUEEZE */ + i = 0; + curData = digest; + while(i < dataByteLen) { + if ((context->byteIOIndex == rateInBytes) && (dataByteLen >= (i + rateInBytes))) { + for(j=dataByteLen-i; j>=rateInBytes; j-=rateInBytes) { + KeccakP1600_Permute_24rounds(context->state); + KeccakP1600_ExtractBytes(context->state, curData, 0, rateInBytes); + curData+=rateInBytes; + } + i = dataByteLen - j; + } + else { + /* normal lane: using the message queue */ + if (context->byteIOIndex == rateInBytes) { + KeccakP1600_Permute_24rounds(context->state); + context->byteIOIndex = 0; + } + partialBlock = (unsigned int)(dataByteLen - i); + if (partialBlock+context->byteIOIndex > rateInBytes) + partialBlock = rateInBytes-context->byteIOIndex; + i += partialBlock; + + KeccakP1600_ExtractBytes(context->state, curData, context->byteIOIndex, partialBlock); + curData += partialBlock; + context->byteIOIndex += partialBlock; + } + } +} +DEF_WEAK(SHA3_Final); + +/* + * internal functions + */ +static void +Keccak_HashInitialize(SHA3_CTX *context, unsigned int rate, + unsigned int hashbitlen) +{ + bzero(context->state, SHA3_STATE_SIZE); + context->rate = rate; + context->byteIOIndex = 0; + context->fixedOutputLength = hashbitlen; +} + +static void +KeccakP1600_AddByte(void *state, unsigned char byte, unsigned int offset) +{ + assert(offset < 200); + ((unsigned char *)state)[offset] ^= byte; +} + +static void +KeccakP1600_AddBytes(void *state, const unsigned char *data, unsigned int offset, unsigned int length) +{ + unsigned int i; + + assert(offset < 200); + assert(offset+length <= 200); + for(i=0; i<length; i++) + ((unsigned char *)state)[offset+i] ^= data[i]; +} + +#if BYTE_ORDER == BIG_ENDIAN +static void fromBytesToWords(tKeccakLane *stateAsWords, const unsigned char *state); +static void fromWordsToBytes(unsigned char *state, const tKeccakLane *stateAsWords); +#endif +static void KeccakP1600OnWords(tKeccakLane *state); +#if BYTE_ORDER == LITTLE_ENDIAN +static void KeccakP1600QuadRound(tKeccakLane *state, unsigned int indexRound); +#else +static void KeccakP1600RoundSlow(tKeccakLane *state, unsigned int indexRound); +static void theta(tKeccakLane *A); +static void rho(tKeccakLane *A); +static void pi(tKeccakLane *A); +static void chi(tKeccakLane *A); +static void iota(tKeccakLane *A, unsigned int indexRound); +#endif + +static void +KeccakP1600_Permute_24rounds(void *state) +{ +#if BYTE_ORDER == LITTLE_ENDIAN + KeccakP1600OnWords((tKeccakLane*)state); +#else + tKeccakLane stateAsWords[1600/64]; + + fromBytesToWords(stateAsWords, (const unsigned char *)state); + KeccakP1600OnWords(stateAsWords); + fromWordsToBytes((unsigned char *)state, stateAsWords); +#endif +} + +#if BYTE_ORDER == BIG_ENDIAN +static void +fromBytesToWords(tKeccakLane *stateAsWords, const unsigned char *state) +{ + unsigned int i, j; + + for(i=0; i<SHA3_NRLANES; i++) { + stateAsWords[i] = 0; + for(j=0; j<(64/8); j++) + stateAsWords[i] |= (tKeccakLane)(state[i*(64/8)+j]) << (8*j); + } +} + +static void +fromWordsToBytes(unsigned char *state, const tKeccakLane *stateAsWords) +{ + unsigned int i, j; + + for(i=0; i<SHA3_NRLANES; i++) + for(j=0; j<(64/8); j++) + state[i*(64/8)+j] = (unsigned char)((stateAsWords[i] >> (8*j)) & 0xFF); +} +#endif + +static void +KeccakP1600OnWords(tKeccakLane *state) +{ + unsigned int i; + + +#if BYTE_ORDER == BIG_ENDIAN + /* + * Use the unoptimized reference implementation when + * on big endian machines + */ + for(i=0; i<SHA3_NRROUNDS; i++) + KeccakP1600RoundSlow(state, i); +#else + /* + * Use the inplace version from the Keccak optimized reference + * code of KeccakP1600 on little endian machines + * Note that this routine does four rounds in one call. + * */ + for(i=0; i<SHA3_NRROUNDS; i+=4) + KeccakP1600QuadRound(state, i); +#endif +} + +#define ROL64(a, offset) ((offset != 0) ? ((((tKeccakLane)a) << offset) ^ (((tKeccakLane)a) >> (64-offset))) : a) + +#if BYTE_ORDER == LITTLE_ENDIAN +static void +KeccakP1600QuadRound(tKeccakLane *state, unsigned int indexRound) +{ + /* + * Inplace implementation by Ronny Van Keer and the designers + * of Keccak from the optimized Keccak reference code + */ + + tKeccakLane Ba, Be, Bi, Bo, Bu; + tKeccakLane Ca, Ce, Ci, Co, Cu; + tKeccakLane Da, De, Di, Do, Du; + +#define Aba state[ 0] +#define Abe state[ 1] +#define Abi state[ 2] +#define Abo state[ 3] +#define Abu state[ 4] +#define Aga state[ 5] +#define Age state[ 6] +#define Agi state[ 7] +#define Ago state[ 8] +#define Agu state[ 9] +#define Aka state[10] +#define Ake state[11] +#define Aki state[12] +#define Ako state[13] +#define Aku state[14] +#define Ama state[15] +#define Ame state[16] +#define Ami state[17] +#define Amo state[18] +#define Amu state[19] +#define Asa state[20] +#define Ase state[21] +#define Asi state[22] +#define Aso state[23] +#define Asu state[24] + + Ca = Aba^Aga^Aka^Ama^Asa; + Ce = Abe^Age^Ake^Ame^Ase; + Ci = Abi^Agi^Aki^Ami^Asi; + Co = Abo^Ago^Ako^Amo^Aso; + Cu = Abu^Agu^Aku^Amu^Asu; + Da = Cu^ROL64(Ce, 1); + De = Ca^ROL64(Ci, 1); + Di = Ce^ROL64(Co, 1); + Do = Ci^ROL64(Cu, 1); + Du = Co^ROL64(Ca, 1); + + Ba = (Aba^Da); + Be = ROL64((Age^De), 44); + Bi = ROL64((Aki^Di), 43); + Bo = ROL64((Amo^Do), 21); + Bu = ROL64((Asu^Du), 14); + Aba = Ba ^((~Be)& Bi ); + Aba ^= KeccakRoundConstants[indexRound]; + Age = Be ^((~Bi)& Bo ); + Aki = Bi ^((~Bo)& Bu ); + Amo = Bo ^((~Bu)& Ba ); + Asu = Bu ^((~Ba)& Be ); + + Bi = ROL64((Aka^Da), 3); + Bo = ROL64((Ame^De), 45); + Bu = ROL64((Asi^Di), 61); + Ba = ROL64((Abo^Do), 28); + Be = ROL64((Agu^Du), 20); + Aka = Ba ^((~Be)& Bi ); + Ame = Be ^((~Bi)& Bo ); + Asi = Bi ^((~Bo)& Bu ); + Abo = Bo ^((~Bu)& Ba ); + Agu = Bu ^((~Ba)& Be ); + + Bu = ROL64((Asa^Da), 18); + Ba = ROL64((Abe^De), 1); + Be = ROL64((Agi^Di), 6); + Bi = ROL64((Ako^Do), 25); + Bo = ROL64((Amu^Du), 8); + Asa = Ba ^((~Be)& Bi ); + Abe = Be ^((~Bi)& Bo ); + Agi = Bi ^((~Bo)& Bu ); + Ako = Bo ^((~Bu)& Ba ); + Amu = Bu ^((~Ba)& Be ); + + Be = ROL64((Aga^Da), 36); + Bi = ROL64((Ake^De), 10); + Bo = ROL64((Ami^Di), 15); + Bu = ROL64((Aso^Do), 56); + Ba = ROL64((Abu^Du), 27); + Aga = Ba ^((~Be)& Bi ); + Ake = Be ^((~Bi)& Bo ); + Ami = Bi ^((~Bo)& Bu ); + Aso = Bo ^((~Bu)& Ba ); + Abu = Bu ^((~Ba)& Be ); + + Bo = ROL64((Ama^Da), 41); + Bu = ROL64((Ase^De), 2); + Ba = ROL64((Abi^Di), 62); + Be = ROL64((Ago^Do), 55); + Bi = ROL64((Aku^Du), 39); + Ama = Ba ^((~Be)& Bi ); + Ase = Be ^((~Bi)& Bo ); + Abi = Bi ^((~Bo)& Bu ); + Ago = Bo ^((~Bu)& Ba ); + Aku = Bu ^((~Ba)& Be ); + + Ca = Aba^Aka^Asa^Aga^Ama; + Ce = Age^Ame^Abe^Ake^Ase; + Ci = Aki^Asi^Agi^Ami^Abi; + Co = Amo^Abo^Ako^Aso^Ago; + Cu = Asu^Agu^Amu^Abu^Aku; + Da = Cu^ROL64(Ce, 1); + De = Ca^ROL64(Ci, 1); + Di = Ce^ROL64(Co, 1); + Do = Ci^ROL64(Cu, 1); + Du = Co^ROL64(Ca, 1); + + Ba = (Aba^Da); + Be = ROL64((Ame^De), 44); + Bi = ROL64((Agi^Di), 43); + Bo = ROL64((Aso^Do), 21); + Bu = ROL64((Aku^Du), 14); + Aba = Ba ^((~Be)& Bi ); + Aba ^= KeccakRoundConstants[indexRound+1]; + Ame = Be ^((~Bi)& Bo ); + Agi = Bi ^((~Bo)& Bu ); + Aso = Bo ^((~Bu)& Ba ); + Aku = Bu ^((~Ba)& Be ); + + Bi = ROL64((Asa^Da), 3); + Bo = ROL64((Ake^De), 45); + Bu = ROL64((Abi^Di), 61); + Ba = ROL64((Amo^Do), 28); + Be = ROL64((Agu^Du), 20); + Asa = Ba ^((~Be)& Bi ); + Ake = Be ^((~Bi)& Bo ); + Abi = Bi ^((~Bo)& Bu ); + Amo = Bo ^((~Bu)& Ba ); + Agu = Bu ^((~Ba)& Be ); + + Bu = ROL64((Ama^Da), 18); + Ba = ROL64((Age^De), 1); + Be = ROL64((Asi^Di), 6); + Bi = ROL64((Ako^Do), 25); + Bo = ROL64((Abu^Du), 8); + Ama = Ba ^((~Be)& Bi ); + Age = Be ^((~Bi)& Bo ); + Asi = Bi ^((~Bo)& Bu ); + Ako = Bo ^((~Bu)& Ba ); + Abu = Bu ^((~Ba)& Be ); + + Be = ROL64((Aka^Da), 36); + Bi = ROL64((Abe^De), 10); + Bo = ROL64((Ami^Di), 15); + Bu = ROL64((Ago^Do), 56); + Ba = ROL64((Asu^Du), 27); + Aka = Ba ^((~Be)& Bi ); + Abe = Be ^((~Bi)& Bo ); + Ami = Bi ^((~Bo)& Bu ); + Ago = Bo ^((~Bu)& Ba ); + Asu = Bu ^((~Ba)& Be ); + + Bo = ROL64((Aga^Da), 41); + Bu = ROL64((Ase^De), 2); + Ba = ROL64((Aki^Di), 62); + Be = ROL64((Abo^Do), 55); + Bi = ROL64((Amu^Du), 39); + Aga = Ba ^((~Be)& Bi ); + Ase = Be ^((~Bi)& Bo ); + Aki = Bi ^((~Bo)& Bu ); + Abo = Bo ^((~Bu)& Ba ); + Amu = Bu ^((~Ba)& Be ); + + Ca = Aba^Asa^Ama^Aka^Aga; + Ce = Ame^Ake^Age^Abe^Ase; + Ci = Agi^Abi^Asi^Ami^Aki; + Co = Aso^Amo^Ako^Ago^Abo; + Cu = Aku^Agu^Abu^Asu^Amu; + Da = Cu^ROL64(Ce, 1); + De = Ca^ROL64(Ci, 1); + Di = Ce^ROL64(Co, 1); + Do = Ci^ROL64(Cu, 1); + Du = Co^ROL64(Ca, 1); + + Ba = (Aba^Da); + Be = ROL64((Ake^De), 44); + Bi = ROL64((Asi^Di), 43); + Bo = ROL64((Ago^Do), 21); + Bu = ROL64((Amu^Du), 14); + Aba = Ba ^((~Be)& Bi ); + Aba ^= KeccakRoundConstants[indexRound+2]; + Ake = Be ^((~Bi)& Bo ); + Asi = Bi ^((~Bo)& Bu ); + Ago = Bo ^((~Bu)& Ba ); + Amu = Bu ^((~Ba)& Be ); + + Bi = ROL64((Ama^Da), 3); + Bo = ROL64((Abe^De), 45); + Bu = ROL64((Aki^Di), 61); + Ba = ROL64((Aso^Do), 28); + Be = ROL64((Agu^Du), 20); + Ama = Ba ^((~Be)& Bi ); + Abe = Be ^((~Bi)& Bo ); + Aki = Bi ^((~Bo)& Bu ); + Aso = Bo ^((~Bu)& Ba ); + Agu = Bu ^((~Ba)& Be ); + + Bu = ROL64((Aga^Da), 18); + Ba = ROL64((Ame^De), 1); + Be = ROL64((Abi^Di), 6); + Bi = ROL64((Ako^Do), 25); + Bo = ROL64((Asu^Du), 8); + Aga = Ba ^((~Be)& Bi ); + Ame = Be ^((~Bi)& Bo ); + Abi = Bi ^((~Bo)& Bu ); + Ako = Bo ^((~Bu)& Ba ); + Asu = Bu ^((~Ba)& Be ); + + Be = ROL64((Asa^Da), 36); + Bi = ROL64((Age^De), 10); + Bo = ROL64((Ami^Di), 15); + Bu = ROL64((Abo^Do), 56); + Ba = ROL64((Aku^Du), 27); + Asa = Ba ^((~Be)& Bi ); + Age = Be ^((~Bi)& Bo ); + Ami = Bi ^((~Bo)& Bu ); + Abo = Bo ^((~Bu)& Ba ); + Aku = Bu ^((~Ba)& Be ); + + Bo = ROL64((Aka^Da), 41); + Bu = ROL64((Ase^De), 2); + Ba = ROL64((Agi^Di), 62); + Be = ROL64((Amo^Do), 55); + Bi = ROL64((Abu^Du), 39); + Aka = Ba ^((~Be)& Bi ); + Ase = Be ^((~Bi)& Bo ); + Agi = Bi ^((~Bo)& Bu ); + Amo = Bo ^((~Bu)& Ba ); + Abu = Bu ^((~Ba)& Be ); + + Ca = Aba^Ama^Aga^Asa^Aka; + Ce = Ake^Abe^Ame^Age^Ase; + Ci = Asi^Aki^Abi^Ami^Agi; + Co = Ago^Aso^Ako^Abo^Amo; + Cu = Amu^Agu^Asu^Aku^Abu; + Da = Cu^ROL64(Ce, 1); + De = Ca^ROL64(Ci, 1); + Di = Ce^ROL64(Co, 1); + Do = Ci^ROL64(Cu, 1); + Du = Co^ROL64(Ca, 1); + + Ba = (Aba^Da); + Be = ROL64((Abe^De), 44); + Bi = ROL64((Abi^Di), 43); + Bo = ROL64((Abo^Do), 21); + Bu = ROL64((Abu^Du), 14); + Aba = Ba ^((~Be)& Bi ); + Aba ^= KeccakRoundConstants[indexRound+3]; + Abe = Be ^((~Bi)& Bo ); + Abi = Bi ^((~Bo)& Bu ); + Abo = Bo ^((~Bu)& Ba ); + Abu = Bu ^((~Ba)& Be ); + + Bi = ROL64((Aga^Da), 3); + Bo = ROL64((Age^De), 45); + Bu = ROL64((Agi^Di), 61); + Ba = ROL64((Ago^Do), 28); + Be = ROL64((Agu^Du), 20); + Aga = Ba ^((~Be)& Bi ); + Age = Be ^((~Bi)& Bo ); + Agi = Bi ^((~Bo)& Bu ); + Ago = Bo ^((~Bu)& Ba ); + Agu = Bu ^((~Ba)& Be ); + + Bu = ROL64((Aka^Da), 18); + Ba = ROL64((Ake^De), 1); + Be = ROL64((Aki^Di), 6); + Bi = ROL64((Ako^Do), 25); + Bo = ROL64((Aku^Du), 8); + Aka = Ba ^((~Be)& Bi ); + Ake = Be ^((~Bi)& Bo ); + Aki = Bi ^((~Bo)& Bu ); + Ako = Bo ^((~Bu)& Ba ); + Aku = Bu ^((~Ba)& Be ); + + Be = ROL64((Ama^Da), 36); + Bi = ROL64((Ame^De), 10); + Bo = ROL64((Ami^Di), 15); + Bu = ROL64((Amo^Do), 56); + Ba = ROL64((Amu^Du), 27); + Ama = Ba ^((~Be)& Bi ); + Ame = Be ^((~Bi)& Bo ); + Ami = Bi ^((~Bo)& Bu ); + Amo = Bo ^((~Bu)& Ba ); + Amu = Bu ^((~Ba)& Be ); + + Bo = ROL64((Asa^Da), 41); + Bu = ROL64((Ase^De), 2); + Ba = ROL64((Asi^Di), 62); + Be = ROL64((Aso^Do), 55); + Bi = ROL64((Asu^Du), 39); + Asa = Ba ^((~Be)& Bi ); + Ase = Be ^((~Bi)& Bo ); + Asi = Bi ^((~Bo)& Bu ); + Aso = Bo ^((~Bu)& Ba ); + Asu = Bu ^((~Ba)& Be ); + +#undef Aba +#undef Abe +#undef Abi +#undef Abo +#undef Abu +#undef Aga +#undef Age +#undef Agi +#undef Ago +#undef Agu +#undef Aka +#undef Ake +#undef Aki +#undef Ako +#undef Aku +#undef Ama +#undef Ame +#undef Ami +#undef Amo +#undef Amu +#undef Asa +#undef Ase +#undef Asi +#undef Aso +#undef Asu +} + +#else /* BYTE_ORDER != BIG_ENDIAN */ +void +KeccakP1600RoundSlow(tKeccakLane *state, unsigned int indexRound) +{ + theta(state); + rho(state); + pi(state); + chi(state); + iota(state, indexRound); +} + +#define ROL64(a, offset) ((offset != 0) ? ((((tKeccakLane)a) << offset) ^ (((tKeccakLane)a) >> (64-offset))) : a) + +static void theta(tKeccakLane *A) +{ + unsigned int x, y; + tKeccakLane C[5], D[5]; + + for(x=0; x<5; x++) { + C[x] = 0; + for(y=0; y<5; y++) + C[x] ^= A[index(x, y)]; + } + for(x=0; x<5; x++) + D[x] = ROL64(C[(x+1)%5], 1) ^ C[(x+4)%5]; + for(x=0; x<5; x++) + for(y=0; y<5; y++) + A[index(x, y)] ^= D[x]; +} + +static void rho(tKeccakLane *A) +{ + unsigned int x, y; + + for(x=0; x<5; x++) for(y=0; y<5; y++) + A[index(x, y)] = ROL64(A[index(x, y)], KeccakRhoOffsets[index(x, y)]); +} + +static void pi(tKeccakLane *A) +{ + unsigned int x, y; + tKeccakLane tempA[25]; + + for(x=0; x<5; x++) for(y=0; y<5; y++) + tempA[index(x, y)] = A[index(x, y)]; + for(x=0; x<5; x++) for(y=0; y<5; y++) + A[index(0*x+1*y, 2*x+3*y)] = tempA[index(x, y)]; +} + +static void chi(tKeccakLane *A) +{ + unsigned int x, y; + tKeccakLane C[5]; + + for(y=0; y<5; y++) { + for(x=0; x<5; x++) + C[x] = A[index(x, y)] ^ ((~A[index(x+1, y)]) & A[index(x+2, y)]); + for(x=0; x<5; x++) + A[index(x, y)] = C[x]; + } +} + +static void iota(tKeccakLane *A, unsigned int indexRound) +{ + A[index(0, 0)] ^= KeccakRoundConstants[indexRound]; +} +#endif /* BYTE_ORDER != BIG_ENDIAN */ + +static void +KeccakP1600_ExtractBytes(const void *state, unsigned char *data, unsigned int offset, unsigned int length) +{ + assert(offset < 200); + assert(offset+length <= 200); + memcpy(data, (unsigned char*)state+offset, length); +} + Index: lib/libc/hidden/sha3.h =================================================================== RCS file: lib/libc/hidden/sha3.h diff -N lib/libc/hidden/sha3.h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ lib/libc/hidden/sha3.h 10 Jan 2018 13:44:01 -0000 @@ -0,0 +1,29 @@ +#ifndef _LIBC_SHA3_H +#define _LIBC_SHA3_H + +#include_next <sha3.h> + +PROTO_NORMAL(SHA3_Update); +PROTO_NORMAL(SHA3_Final); +PROTO_NORMAL(SHA3_224Data); +PROTO_NORMAL(SHA3_224End); +PROTO_NORMAL(SHA3_224File); +PROTO_NORMAL(SHA3_224FileChunk); +PROTO_NORMAL(SHA3_224Init); +PROTO_NORMAL(SHA3_256Data); +PROTO_NORMAL(SHA3_256End); +PROTO_NORMAL(SHA3_256File); +PROTO_NORMAL(SHA3_256FileChunk); +PROTO_NORMAL(SHA3_256Init); +PROTO_NORMAL(SHA3_384Data); +PROTO_NORMAL(SHA3_384End); +PROTO_NORMAL(SHA3_384File); +PROTO_NORMAL(SHA3_384FileChunk); +PROTO_NORMAL(SHA3_384Init); +PROTO_NORMAL(SHA3_512Data); +PROTO_NORMAL(SHA3_512End); +PROTO_NORMAL(SHA3_512File); +PROTO_NORMAL(SHA3_512FileChunk); +PROTO_NORMAL(SHA3_512Init); + +#endif /* _LIBC_SHA3_H */