diff options
Diffstat (limited to 'lgl')
64 files changed, 9950 insertions, 3 deletions
diff --git a/lgl/Makefile.am b/lgl/Makefile.am index ee2e596af5..bce9f74cd5 100644 --- a/lgl/Makefile.am +++ b/lgl/Makefile.am @@ -9,7 +9,7 @@ # the same distribution terms as the rest of that program. # # Generated by gnulib-tool. -# Reproduce by: gnulib-tool --import --dir=. --lib=libgnu --source-base=lgl --m4-base=lgl/m4 --doc-base=doc --aux-dir=. --lgpl --libtool --macro-prefix=lgl memmem +# Reproduce by: gnulib-tool --import --dir=. --lib=libgnu --source-base=lgl --m4-base=lgl/m4 --doc-base=doc --aux-dir=. --lgpl --libtool --macro-prefix=lgl gc gc-arcfour gc-arctwo gc-des gc-hmac-md5 gc-md2 gc-md4 gc-md5 gc-pbkdf2-sha1 gc-random gc-rijndael gc-sha1 memmem stdint AUTOMAKE_OPTIONS = 1.5 gnits @@ -31,6 +31,94 @@ MAINTAINERCLEANFILES = AM_CPPFLAGS = +## begin gnulib module gc + +if GL_COND_LIBTOOL +libgnu_la_LDFLAGS += $(LTLIBGCRYPT) +endif + +EXTRA_DIST += gc-gnulib.c gc-libgcrypt.c gc.h + +## end gnulib module gc + +## begin gnulib module gc-arcfour + + +EXTRA_DIST += arcfour.c arcfour.h + +## end gnulib module gc-arcfour + +## begin gnulib module gc-arctwo + + +EXTRA_DIST += arctwo.c arctwo.h + +## end gnulib module gc-arctwo + +## begin gnulib module gc-des + + +EXTRA_DIST += des.c des.h + +## end gnulib module gc-des + +## begin gnulib module gc-hmac-md5 + + +EXTRA_DIST += hmac-md5.c hmac.h md5.c md5.h memxor.c memxor.h + +## end gnulib module gc-hmac-md5 + +## begin gnulib module gc-hmac-sha1 + + +EXTRA_DIST += hmac-sha1.c hmac.h memxor.c memxor.h sha1.c sha1.h + +## end gnulib module gc-hmac-sha1 + +## begin gnulib module gc-md4 + + +EXTRA_DIST += md4.c md4.h + +## end gnulib module gc-md4 + +## begin gnulib module gc-md5 + +libgnu_la_SOURCES += md5.h + +EXTRA_DIST += md5.c + +## end gnulib module gc-md5 + +## begin gnulib module gc-pbkdf2-sha1 + + +EXTRA_DIST += gc-pbkdf2-sha1.c + +## end gnulib module gc-pbkdf2-sha1 + +## begin gnulib module gc-rijndael + + +EXTRA_DIST += rijndael-alg-fst.c rijndael-alg-fst.h rijndael-api-fst.c rijndael-api-fst.h + +## end gnulib module gc-rijndael + +## begin gnulib module gc-sha1 + + +EXTRA_DIST += sha1.c sha1.h + +## end gnulib module gc-sha1 + +## begin gnulib module md2 + + +EXTRA_DIST += md2.c md2.h + +## end gnulib module md2 + ## begin gnulib module memmem @@ -38,6 +126,52 @@ EXTRA_DIST += memmem.c memmem.h ## end gnulib module memmem +## begin gnulib module minmax + +libgnu_la_SOURCES += minmax.h + +## end gnulib module minmax + +## begin gnulib module stdint + +BUILT_SOURCES += $(STDINT_H) + +# We need the following in order to create <stdint.h> when the system +# doesn't have one that works with the given compiler. +stdint.h: stdint_.h + rm -f $@-t $@ + { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \ + sed -e 's/@''HAVE_WCHAR_H''@/$(HAVE_WCHAR_H)/g' \ + -e 's/@''HAVE_STDINT_H''@/$(HAVE_STDINT_H)/g' \ + -e 's|@''ABSOLUTE_STDINT_H''@|$(ABSOLUTE_STDINT_H)|g' \ + -e 's/@''HAVE_SYS_TYPES_H''@/$(HAVE_SYS_TYPES_H)/g' \ + -e 's/@''HAVE_INTTYPES_H''@/$(HAVE_INTTYPES_H)/g' \ + -e 's/@''HAVE_SYS_INTTYPES_H''@/$(HAVE_SYS_INTTYPES_H)/g' \ + -e 's/@''HAVE_SYS_BITYPES_H''@/$(HAVE_SYS_BITYPES_H)/g' \ + -e 's/@''HAVE_LONG_LONG_INT''@/$(HAVE_LONG_LONG_INT)/g' \ + -e 's/@''HAVE_UNSIGNED_LONG_LONG_INT''@/$(HAVE_UNSIGNED_LONG_LONG_INT)/g' \ + -e 's/@''BITSIZEOF_PTRDIFF_T''@/$(BITSIZEOF_PTRDIFF_T)/g' \ + -e 's/@''PTRDIFF_T_SUFFIX''@/$(PTRDIFF_T_SUFFIX)/g' \ + -e 's/@''BITSIZEOF_SIG_ATOMIC_T''@/$(BITSIZEOF_SIG_ATOMIC_T)/g' \ + -e 's/@''HAVE_SIGNED_SIG_ATOMIC_T''@/$(HAVE_SIGNED_SIG_ATOMIC_T)/g' \ + -e 's/@''SIG_ATOMIC_T_SUFFIX''@/$(SIG_ATOMIC_T_SUFFIX)/g' \ + -e 's/@''BITSIZEOF_SIZE_T''@/$(BITSIZEOF_SIZE_T)/g' \ + -e 's/@''SIZE_T_SUFFIX''@/$(SIZE_T_SUFFIX)/g' \ + -e 's/@''BITSIZEOF_WCHAR_T''@/$(BITSIZEOF_WCHAR_T)/g' \ + -e 's/@''HAVE_SIGNED_WCHAR_T''@/$(HAVE_SIGNED_WCHAR_T)/g' \ + -e 's/@''WCHAR_T_SUFFIX''@/$(WCHAR_T_SUFFIX)/g' \ + -e 's/@''BITSIZEOF_WINT_T''@/$(BITSIZEOF_WINT_T)/g' \ + -e 's/@''HAVE_SIGNED_WINT_T''@/$(HAVE_SIGNED_WINT_T)/g' \ + -e 's/@''WINT_T_SUFFIX''@/$(WINT_T_SUFFIX)/g' \ + < $(srcdir)/stdint_.h; \ + } > $@-t + mv $@-t $@ +MOSTLYCLEANFILES += stdint.h stdint.h-t + +EXTRA_DIST += stdint_.h + +## end gnulib module stdint + ## begin gnulib module dummy libgnu_la_SOURCES += dummy.c diff --git a/lgl/arcfour.c b/lgl/arcfour.c new file mode 100644 index 0000000000..89387b0fc7 --- /dev/null +++ b/lgl/arcfour.c @@ -0,0 +1,79 @@ +/* arcfour.c --- The arcfour stream cipher + * Copyright (C) 2000, 2001, 2002, 2003, 2005 Free Software Foundation, Inc. + * + * This file is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation; either version 2.1, or (at your + * option) any later version. + * + * This file is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this file; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + * + */ + +/* Code from Libgcrypt adapted for gnulib by Simon Josefsson. */ + +/* + * For a description of the algorithm, see: + * Bruce Schneier: Applied Cryptography. John Wiley & Sons, 1996. + * ISBN 0-471-11709-9. Pages 397 ff. + */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include "arcfour.h" + +void +arcfour_stream (arcfour_context * context, const char *inbuf, char *outbuf, + size_t length) +{ + uint8_t i = context->idx_i; + uint8_t j = context->idx_j; + char *sbox = context->sbox; + + for (; length > 0; length--) + { + char t; + + i++; + j += sbox[i]; + t = sbox[i]; + sbox[i] = sbox[j]; + sbox[j] = t; + *outbuf++ = (*inbuf++ + ^ sbox[(0U + sbox[i] + sbox[j]) % ARCFOUR_SBOX_SIZE]); + } + + context->idx_i = i; + context->idx_j = j; +} + +void +arcfour_setkey (arcfour_context * context, const char *key, size_t keylen) +{ + size_t i, j, k; + char *sbox = context->sbox; + + context->idx_i = context->idx_j = 0; + for (i = 0; i < ARCFOUR_SBOX_SIZE; i++) + sbox[i] = i; + for (i = j = k = 0; i < ARCFOUR_SBOX_SIZE; i++) + { + char t; + j = (j + sbox[i] + key[k]) % ARCFOUR_SBOX_SIZE; + t = sbox[i]; + sbox[i] = sbox[j]; + sbox[j] = t; + if (++k == keylen) + k = 0; + } +} diff --git a/lgl/arcfour.h b/lgl/arcfour.h new file mode 100644 index 0000000000..dee819021f --- /dev/null +++ b/lgl/arcfour.h @@ -0,0 +1,51 @@ +/* arcfour.h --- The arcfour stream cipher + * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005 + * Free Software Foundation, Inc. + * + * This file is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation; either version 2.1, or (at your + * option) any later version. + * + * This file is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this file; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + * + */ + +/* Code from Libgcrypt adapted for gnulib by Simon Josefsson. */ + +#ifndef ARCFOUR_H +# define ARCFOUR_H + +# include <stddef.h> +# include <stdint.h> + +#define ARCFOUR_SBOX_SIZE 256 + +typedef struct +{ + char sbox[ARCFOUR_SBOX_SIZE]; + uint8_t idx_i, idx_j; +} arcfour_context; + +/* Apply ARCFOUR stream to INBUF placing the result in OUTBUF, both of + LENGTH size. CONTEXT must be initialized with arcfour_setkey + before this function is called. */ +extern void +arcfour_stream (arcfour_context * context, + const char *inbuf, char *outbuf, size_t length); + +/* Initialize CONTEXT using encryption KEY of KEYLEN bytes. KEY + should be 40 bits (5 bytes) or longer. The KEY cannot be zero + length. */ +extern void +arcfour_setkey (arcfour_context * context, const char *key, size_t keylen); + +#endif /* ARCFOUR_H */ diff --git a/lgl/arctwo.c b/lgl/arctwo.c new file mode 100644 index 0000000000..f0051bc6ce --- /dev/null +++ b/lgl/arctwo.c @@ -0,0 +1,231 @@ +/* arctwo.c --- The RC2 cipher as described in RFC 2268. + * Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc. + * + * This file is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation; either version 2.1, or (at your + * option) any later version. + * + * This file is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this file; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + */ + +/* Code from GnuTLS/Libgcrypt adapted for gnulib by Simon Josefsson. */ + +/* This implementation was written by Nikos Mavroyanopoulos for GNUTLS + * as a Libgcrypt module (gnutls/lib/x509/rc2.c) and later adapted for + * direct use by Libgcrypt by Werner Koch. This implementation is + * only useful for pkcs#12 decryption. + * + * The implementation here is based on Peter Gutmann's RRC.2 paper. + */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include "arctwo.h" + +static const uint8_t arctwo_sbox[] = { + 217, 120, 249, 196, 25, 221, 181, 237, + 40, 233, 253, 121, 74, 160, 216, 157, + 198, 126, 55, 131, 43, 118, 83, 142, + 98, 76, 100, 136, 68, 139, 251, 162, + 23, 154, 89, 245, 135, 179, 79, 19, + 97, 69, 109, 141, 9, 129, 125, 50, + 189, 143, 64, 235, 134, 183, 123, 11, + 240, 149, 33, 34, 92, 107, 78, 130, + 84, 214, 101, 147, 206, 96, 178, 28, + 115, 86, 192, 20, 167, 140, 241, 220, + 18, 117, 202, 31, 59, 190, 228, 209, + 66, 61, 212, 48, 163, 60, 182, 38, + 111, 191, 14, 218, 70, 105, 7, 87, + 39, 242, 29, 155, 188, 148, 67, 3, + 248, 17, 199, 246, 144, 239, 62, 231, + 6, 195, 213, 47, 200, 102, 30, 215, + 8, 232, 234, 222, 128, 82, 238, 247, + 132, 170, 114, 172, 53, 77, 106, 42, + 150, 26, 210, 113, 90, 21, 73, 116, + 75, 159, 208, 94, 4, 24, 164, 236, + 194, 224, 65, 110, 15, 81, 203, 204, + 36, 145, 175, 80, 161, 244, 112, 57, + 153, 124, 58, 133, 35, 184, 180, 122, + 252, 2, 54, 91, 37, 85, 151, 49, + 45, 93, 250, 152, 227, 138, 146, 174, + 5, 223, 41, 16, 103, 108, 186, 201, + 211, 0, 230, 207, 225, 158, 168, 44, + 99, 22, 1, 63, 88, 226, 137, 169, + 13, 56, 52, 27, 171, 51, 255, 176, + 187, 72, 12, 95, 185, 177, 205, 46, + 197, 243, 219, 71, 229, 165, 156, 119, + 10, 166, 32, 104, 254, 127, 193, 173 +}; + +#define rotl16(x,n) (((x) << ((uint16_t)(n))) | ((x) >> (16 - (uint16_t)(n)))) +#define rotr16(x,n) (((x) >> ((uint16_t)(n))) | ((x) << (16 - (uint16_t)(n)))) + +/* C89 compliant way to cast 'char' to 'unsigned char'. */ +static inline unsigned char +to_uchar (char ch) +{ + return ch; +} + +void +arctwo_encrypt (arctwo_context *context, const char *inbuf, + char *outbuf, size_t length) +{ + for (; length >= ARCTWO_BLOCK_SIZE; length -= ARCTWO_BLOCK_SIZE, + inbuf += ARCTWO_BLOCK_SIZE, outbuf += ARCTWO_BLOCK_SIZE) + { + size_t i, j; + uint16_t word0 = 0, word1 = 0, word2 = 0, word3 = 0; + + word0 = (word0 << 8) | to_uchar (inbuf[1]); + word0 = (word0 << 8) | to_uchar (inbuf[0]); + word1 = (word1 << 8) | to_uchar (inbuf[3]); + word1 = (word1 << 8) | to_uchar (inbuf[2]); + word2 = (word2 << 8) | to_uchar (inbuf[5]); + word2 = (word2 << 8) | to_uchar (inbuf[4]); + word3 = (word3 << 8) | to_uchar (inbuf[7]); + word3 = (word3 << 8) | to_uchar (inbuf[6]); + + for (i = 0; i < 16; i++) + { + j = i * 4; + /* For some reason I cannot combine those steps. */ + word0 += (word1 & ~word3) + (word2 & word3) + context->S[j]; + word0 = rotl16 (word0, 1); + + word1 += (word2 & ~word0) + (word3 & word0) + context->S[j + 1]; + word1 = rotl16 (word1, 2); + + word2 += (word3 & ~word1) + (word0 & word1) + context->S[j + 2]; + word2 = rotl16 (word2, 3); + + word3 += (word0 & ~word2) + (word1 & word2) + context->S[j + 3]; + word3 = rotl16 (word3, 5); + + if (i == 4 || i == 10) + { + word0 += context->S[word3 & 63]; + word1 += context->S[word0 & 63]; + word2 += context->S[word1 & 63]; + word3 += context->S[word2 & 63]; + } + } + + outbuf[0] = word0 & 255; + outbuf[1] = word0 >> 8; + outbuf[2] = word1 & 255; + outbuf[3] = word1 >> 8; + outbuf[4] = word2 & 255; + outbuf[5] = word2 >> 8; + outbuf[6] = word3 & 255; + outbuf[7] = word3 >> 8; + } +} + +void +arctwo_decrypt (arctwo_context *context, const char *inbuf, + char *outbuf, size_t length) +{ + for (; length >= ARCTWO_BLOCK_SIZE; length -= ARCTWO_BLOCK_SIZE, + inbuf += ARCTWO_BLOCK_SIZE, outbuf += ARCTWO_BLOCK_SIZE) + { + size_t i, j; + uint16_t word0 = 0, word1 = 0, word2 = 0, word3 = 0; + + word0 = (word0 << 8) | to_uchar (inbuf[1]); + word0 = (word0 << 8) | to_uchar (inbuf[0]); + word1 = (word1 << 8) | to_uchar (inbuf[3]); + word1 = (word1 << 8) | to_uchar (inbuf[2]); + word2 = (word2 << 8) | to_uchar (inbuf[5]); + word2 = (word2 << 8) | to_uchar (inbuf[4]); + word3 = (word3 << 8) | to_uchar (inbuf[7]); + word3 = (word3 << 8) | to_uchar (inbuf[6]); + + for (i = 16; i > 0; i--) + { + j = (i - 1) * 4; + + word3 = rotr16 (word3, 5); + word3 -= (word0 & ~word2) + (word1 & word2) + context->S[j + 3]; + + word2 = rotr16 (word2, 3); + word2 -= (word3 & ~word1) + (word0 & word1) + context->S[j + 2]; + + word1 = rotr16 (word1, 2); + word1 -= (word2 & ~word0) + (word3 & word0) + context->S[j + 1]; + + word0 = rotr16 (word0, 1); + word0 -= (word1 & ~word3) + (word2 & word3) + context->S[j]; + + if (i == 6 || i == 12) + { + word3 = word3 - context->S[word2 & 63]; + word2 = word2 - context->S[word1 & 63]; + word1 = word1 - context->S[word0 & 63]; + word0 = word0 - context->S[word3 & 63]; + } + } + + outbuf[0] = word0 & 255; + outbuf[1] = word0 >> 8; + outbuf[2] = word1 & 255; + outbuf[3] = word1 >> 8; + outbuf[4] = word2 & 255; + outbuf[5] = word2 >> 8; + outbuf[6] = word3 & 255; + outbuf[7] = word3 >> 8; + } +} + +void +arctwo_setkey_ekb (arctwo_context *context, + size_t keylen, const char *key, size_t effective_keylen) +{ + size_t i; + uint8_t *S, x; + + if (keylen < 40 / 8 || effective_keylen > 1024) + return; + + S = (uint8_t *) context->S; + + for (i = 0; i < keylen; i++) + S[i] = (uint8_t) key[i]; + + for (i = keylen; i < 128; i++) + S[i] = arctwo_sbox[(S[i - keylen] + S[i - 1]) & 255]; + + S[0] = arctwo_sbox[S[0]]; + + /* Phase 2 - reduce effective key size to "bits". This was not + * discussed in Gutmann's paper. I've copied that from the public + * domain code posted in sci.crypt. */ + if (effective_keylen) + { + size_t len = (effective_keylen + 7) >> 3; + i = 128 - len; + x = arctwo_sbox[S[i] & (255 >> (7 & -effective_keylen))]; + S[i] = x; + + while (i--) + { + x = arctwo_sbox[x ^ S[i + len]]; + S[i] = x; + } + } + + /* Make the expanded key, endian independent. */ + for (i = 0; i < 64; i++) + context->S[i] = ((uint16_t) S[i * 2] | (((uint16_t) S[i * 2 + 1]) << 8)); +} diff --git a/lgl/arctwo.h b/lgl/arctwo.h new file mode 100644 index 0000000000..c7c3e511b3 --- /dev/null +++ b/lgl/arctwo.h @@ -0,0 +1,63 @@ +/* arctwo.h --- The arctwo block cipher + * Copyright (C) 2000, 2001, 2002, 2003, 2005 Free Software Foundation, Inc. + * + * This file is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation; either version 2.1, or (at your + * option) any later version. + * + * This file is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this file; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + * + */ + +/* Code from Libgcrypt adapted for gnulib by Simon Josefsson. */ + +#ifndef ARCTWO_H +# define ARCTWO_H + +# include <stddef.h> +# include <stdint.h> + +typedef struct +{ + uint16_t S[64]; +} arctwo_context; + +#define ARCTWO_BLOCK_SIZE 8 + +/* Initialize CONTEXT using KEY of KEYLEN length. If + EFFECTIVE_KEYLEN, truncate the key (using a special algorithm) to + only be of EFFECTIVE_KEYLEN bits. Normally, you use + EFFECTIVE_KEYLEN of 0, but see RFC 2268 for more information. */ +void +arctwo_setkey_ekb (arctwo_context *context, + size_t keylen, const char *key, size_t effective_keylen); + +#define arctwo_setkey(context,keylen,key) \ + arctwo_setkey_ekb (context, keylen, key, 8 * (keylen)) + +/* Encrypt INBUF of size LENGTH into OUTBUF. LENGTH must be a + multiple of ARCTWO_BLOCK_SIZE. CONTEXT hold the encryption key, + and must have been initialized with arctwo_setkey or + arctwo_setkey_ekb. */ +extern void +arctwo_encrypt (arctwo_context *context, const char *inbuf, + char *outbuf, size_t length); + +/* Decrypt INBUF of size LENGTH into OUTBUF. LENGTH must be a + multiple of ARCTWO_BLOCK_SIZE. CONTEXT hold the decryption key, + and must have been initialized with arctwo_setkey or + arctwo_setkey_ekb. */ +extern void +arctwo_decrypt (arctwo_context *context, const char *inbuf, + char *outbuf, size_t length); + +#endif /* ARCTWO_H */ diff --git a/lgl/des.c b/lgl/des.c new file mode 100644 index 0000000000..e9ac1c6fa8 --- /dev/null +++ b/lgl/des.c @@ -0,0 +1,683 @@ +/* des.c --- DES and Triple-DES encryption/decryption Algorithm + * Copyright (C) 1998, 1999, 2001, 2002, 2003, 2004, 2005, 2006 + * Free Software Foundation, Inc. + * + * This file is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation; either version 2.1, or (at your + * option) any later version. + * + * This file is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this file; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + * + */ + +/* Adapted for gnulib by Simon Josefsson, based on Libgcrypt. */ + +/* + * For a description of triple encryption, see: + * Bruce Schneier: Applied Cryptography. Second Edition. + * John Wiley & Sons, 1996. ISBN 0-471-12845-7. Pages 358 ff. + * This implementation is according to the definition of DES in FIPS + * PUB 46-2 from December 1993. + * + * Written by Michael Roth <mroth@nessie.de>, September 1998 + */ + +/* + * U S A G E + * =========== + * + * For DES or Triple-DES encryption/decryption you must initialize a proper + * encryption context with a key. + * + * A DES key is 64bit wide but only 56bits of the key are used. The remaining + * bits are parity bits and they will _not_ checked in this implementation, but + * simply ignored. + * + * For Triple-DES you could use either two 64bit keys or three 64bit keys. + * The parity bits will _not_ checked, too. + * + * After initializing a context with a key you could use this context to + * encrypt or decrypt data in 64bit blocks in Electronic Codebook Mode. + * + * DES Example + * ----------- + * unsigned char key[8]; + * unsigned char plaintext[8]; + * unsigned char ciphertext[8]; + * unsigned char recoverd[8]; + * des_ctx context; + * + * // Fill 'key' and 'plaintext' with some data + * .... + * + * // Set up the DES encryption context + * des_setkey(&context, key); + * + * // Encrypt the plaintext + * des_ecb_encrypt(&context, plaintext, ciphertext); + * + * // To recover the orginal plaintext from ciphertext use: + * des_ecb_decrypt(&context, ciphertext, recoverd); + * + * + * Triple-DES Example + * ------------------ + * unsigned char key1[8]; + * unsigned char key2[8]; + * unsigned char key3[8]; + * unsigned char plaintext[8]; + * unsigned char ciphertext[8]; + * unsigned char recoverd[8]; + * tripledes_ctx context; + * + * // If you would like to use two 64bit keys, fill 'key1' and'key2' + * // then setup the encryption context: + * tripledes_set2keys(&context, key1, key2); + * + * // To use three 64bit keys with Triple-DES use: + * tripledes_set3keys(&context, key1, key2, key3); + * + * // Encrypting plaintext with Triple-DES + * tripledes_ecb_encrypt(&context, plaintext, ciphertext); + * + * // Decrypting ciphertext to recover the plaintext with Triple-DES + * tripledes_ecb_decrypt(&context, ciphertext, recoverd); + */ + + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include "des.h" + +#include <stdio.h> +#include <string.h> /* memcpy, memcmp */ + +/* + * The s-box values are permuted according to the 'primitive function P' + * and are rotated one bit to the left. + */ +static const uint32_t sbox1[64] = { + 0x01010400, 0x00000000, 0x00010000, 0x01010404, 0x01010004, 0x00010404, + 0x00000004, 0x00010000, 0x00000400, 0x01010400, 0x01010404, 0x00000400, + 0x01000404, 0x01010004, 0x01000000, 0x00000004, 0x00000404, 0x01000400, + 0x01000400, 0x00010400, 0x00010400, 0x01010000, 0x01010000, 0x01000404, + 0x00010004, 0x01000004, 0x01000004, 0x00010004, 0x00000000, 0x00000404, + 0x00010404, 0x01000000, 0x00010000, 0x01010404, 0x00000004, 0x01010000, + 0x01010400, 0x01000000, 0x01000000, 0x00000400, 0x01010004, 0x00010000, + 0x00010400, 0x01000004, 0x00000400, 0x00000004, 0x01000404, 0x00010404, + 0x01010404, 0x00010004, 0x01010000, 0x01000404, 0x01000004, 0x00000404, + 0x00010404, 0x01010400, 0x00000404, 0x01000400, 0x01000400, 0x00000000, + 0x00010004, 0x00010400, 0x00000000, 0x01010004 +}; + +static const uint32_t sbox2[64] = { + 0x80108020, 0x80008000, 0x00008000, 0x00108020, 0x00100000, 0x00000020, + 0x80100020, 0x80008020, 0x80000020, 0x80108020, 0x80108000, 0x80000000, + 0x80008000, 0x00100000, 0x00000020, 0x80100020, 0x00108000, 0x00100020, + 0x80008020, 0x00000000, 0x80000000, 0x00008000, 0x00108020, 0x80100000, + 0x00100020, 0x80000020, 0x00000000, 0x00108000, 0x00008020, 0x80108000, + 0x80100000, 0x00008020, 0x00000000, 0x00108020, 0x80100020, 0x00100000, + 0x80008020, 0x80100000, 0x80108000, 0x00008000, 0x80100000, 0x80008000, + 0x00000020, 0x80108020, 0x00108020, 0x00000020, 0x00008000, 0x80000000, + 0x00008020, 0x80108000, 0x00100000, 0x80000020, 0x00100020, 0x80008020, + 0x80000020, 0x00100020, 0x00108000, 0x00000000, 0x80008000, 0x00008020, + 0x80000000, 0x80100020, 0x80108020, 0x00108000 +}; + +static const uint32_t sbox3[64] = { + 0x00000208, 0x08020200, 0x00000000, 0x08020008, 0x08000200, 0x00000000, + 0x00020208, 0x08000200, 0x00020008, 0x08000008, 0x08000008, 0x00020000, + 0x08020208, 0x00020008, 0x08020000, 0x00000208, 0x08000000, 0x00000008, + 0x08020200, 0x00000200, 0x00020200, 0x08020000, 0x08020008, 0x00020208, + 0x08000208, 0x00020200, 0x00020000, 0x08000208, 0x00000008, 0x08020208, + 0x00000200, 0x08000000, 0x08020200, 0x08000000, 0x00020008, 0x00000208, + 0x00020000, 0x08020200, 0x08000200, 0x00000000, 0x00000200, 0x00020008, + 0x08020208, 0x08000200, 0x08000008, 0x00000200, 0x00000000, 0x08020008, + 0x08000208, 0x00020000, 0x08000000, 0x08020208, 0x00000008, 0x00020208, + 0x00020200, 0x08000008, 0x08020000, 0x08000208, 0x00000208, 0x08020000, + 0x00020208, 0x00000008, 0x08020008, 0x00020200 +}; + +static const uint32_t sbox4[64] = { + 0x00802001, 0x00002081, 0x00002081, 0x00000080, 0x00802080, 0x00800081, + 0x00800001, 0x00002001, 0x00000000, 0x00802000, 0x00802000, 0x00802081, + 0x00000081, 0x00000000, 0x00800080, 0x00800001, 0x00000001, 0x00002000, + 0x00800000, 0x00802001, 0x00000080, 0x00800000, 0x00002001, 0x00002080, + 0x00800081, 0x00000001, 0x00002080, 0x00800080, 0x00002000, 0x00802080, + 0x00802081, 0x00000081, 0x00800080, 0x00800001, 0x00802000, 0x00802081, + 0x00000081, 0x00000000, 0x00000000, 0x00802000, 0x00002080, 0x00800080, + 0x00800081, 0x00000001, 0x00802001, 0x00002081, 0x00002081, 0x00000080, + 0x00802081, 0x00000081, 0x00000001, 0x00002000, 0x00800001, 0x00002001, + 0x00802080, 0x00800081, 0x00002001, 0x00002080, 0x00800000, 0x00802001, + 0x00000080, 0x00800000, 0x00002000, 0x00802080 +}; + +static const uint32_t sbox5[64] = { + 0x00000100, 0x02080100, 0x02080000, 0x42000100, 0x00080000, 0x00000100, + 0x40000000, 0x02080000, 0x40080100, 0x00080000, 0x02000100, 0x40080100, + 0x42000100, 0x42080000, 0x00080100, 0x40000000, 0x02000000, 0x40080000, + 0x40080000, 0x00000000, 0x40000100, 0x42080100, 0x42080100, 0x02000100, + 0x42080000, 0x40000100, 0x00000000, 0x42000000, 0x02080100, 0x02000000, + 0x42000000, 0x00080100, 0x00080000, 0x42000100, 0x00000100, 0x02000000, + 0x40000000, 0x02080000, 0x42000100, 0x40080100, 0x02000100, 0x40000000, + 0x42080000, 0x02080100, 0x40080100, 0x00000100, 0x02000000, 0x42080000, + 0x42080100, 0x00080100, 0x42000000, 0x42080100, 0x02080000, 0x00000000, + 0x40080000, 0x42000000, 0x00080100, 0x02000100, 0x40000100, 0x00080000, + 0x00000000, 0x40080000, 0x02080100, 0x40000100 +}; + +static const uint32_t sbox6[64] = { + 0x20000010, 0x20400000, 0x00004000, 0x20404010, 0x20400000, 0x00000010, + 0x20404010, 0x00400000, 0x20004000, 0x00404010, 0x00400000, 0x20000010, + 0x00400010, 0x20004000, 0x20000000, 0x00004010, 0x00000000, 0x00400010, + 0x20004010, 0x00004000, 0x00404000, 0x20004010, 0x00000010, 0x20400010, + 0x20400010, 0x00000000, 0x00404010, 0x20404000, 0x00004010, 0x00404000, + 0x20404000, 0x20000000, 0x20004000, 0x00000010, 0x20400010, 0x00404000, + 0x20404010, 0x00400000, 0x00004010, 0x20000010, 0x00400000, 0x20004000, + 0x20000000, 0x00004010, 0x20000010, 0x20404010, 0x00404000, 0x20400000, + 0x00404010, 0x20404000, 0x00000000, 0x20400010, 0x00000010, 0x00004000, + 0x20400000, 0x00404010, 0x00004000, 0x00400010, 0x20004010, 0x00000000, + 0x20404000, 0x20000000, 0x00400010, 0x20004010 +}; + +static const uint32_t sbox7[64] = { + 0x00200000, 0x04200002, 0x04000802, 0x00000000, 0x00000800, 0x04000802, + 0x00200802, 0x04200800, 0x04200802, 0x00200000, 0x00000000, 0x04000002, + 0x00000002, 0x04000000, 0x04200002, 0x00000802, 0x04000800, 0x00200802, + 0x00200002, 0x04000800, 0x04000002, 0x04200000, 0x04200800, 0x00200002, + 0x04200000, 0x00000800, 0x00000802, 0x04200802, 0x00200800, 0x00000002, + 0x04000000, 0x00200800, 0x04000000, 0x00200800, 0x00200000, 0x04000802, + 0x04000802, 0x04200002, 0x04200002, 0x00000002, 0x00200002, 0x04000000, + 0x04000800, 0x00200000, 0x04200800, 0x00000802, 0x00200802, 0x04200800, + 0x00000802, 0x04000002, 0x04200802, 0x04200000, 0x00200800, 0x00000000, + 0x00000002, 0x04200802, 0x00000000, 0x00200802, 0x04200000, 0x00000800, + 0x04000002, 0x04000800, 0x00000800, 0x00200002 +}; + +static const uint32_t sbox8[64] = { + 0x10001040, 0x00001000, 0x00040000, 0x10041040, 0x10000000, 0x10001040, + 0x00000040, 0x10000000, 0x00040040, 0x10040000, 0x10041040, 0x00041000, + 0x10041000, 0x00041040, 0x00001000, 0x00000040, 0x10040000, 0x10000040, + 0x10001000, 0x00001040, 0x00041000, 0x00040040, 0x10040040, 0x10041000, + 0x00001040, 0x00000000, 0x00000000, 0x10040040, 0x10000040, 0x10001000, + 0x00041040, 0x00040000, 0x00041040, 0x00040000, 0x10041000, 0x00001000, + 0x00000040, 0x10040040, 0x00001000, 0x00041040, 0x10001000, 0x00000040, + 0x10000040, 0x10040000, 0x10040040, 0x10000000, 0x00040000, 0x10001040, + 0x00000000, 0x10041040, 0x00040040, 0x10000040, 0x10040000, 0x10001000, + 0x10001040, 0x00000000, 0x10041040, 0x00041000, 0x00041000, 0x00001040, + 0x00001040, 0x00040040, 0x10000000, 0x10041000 +}; + +/* + * These two tables are part of the 'permuted choice 1' function. + * In this implementation several speed improvements are done. + */ +static const uint32_t leftkey_swap[16] = { + 0x00000000, 0x00000001, 0x00000100, 0x00000101, + 0x00010000, 0x00010001, 0x00010100, 0x00010101, + 0x01000000, 0x01000001, 0x01000100, 0x01000101, + 0x01010000, 0x01010001, 0x01010100, 0x01010101 +}; + +static const uint32_t rightkey_swap[16] = { + 0x00000000, 0x01000000, 0x00010000, 0x01010000, + 0x00000100, 0x01000100, 0x00010100, 0x01010100, + 0x00000001, 0x01000001, 0x00010001, 0x01010001, + 0x00000101, 0x01000101, 0x00010101, 0x01010101, +}; + +/* + * Numbers of left shifts per round for encryption subkeys. To + * calculate the decryption subkeys we just reverse the ordering of + * the calculated encryption subkeys, so there is no need for a + * decryption rotate tab. + */ +static const unsigned char encrypt_rotate_tab[16] = { + 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1 +}; + +/* + * Table with weak DES keys sorted in ascending order. In DES there + * are 64 known keys which are weak. They are weak because they + * produce only one, two or four different subkeys in the subkey + * scheduling process. The keys in this table have all their parity + * bits cleared. + */ +static const unsigned char weak_keys[64][8] = { + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*w */ + {0x00, 0x00, 0x1e, 0x1e, 0x00, 0x00, 0x0e, 0x0e}, + {0x00, 0x00, 0xe0, 0xe0, 0x00, 0x00, 0xf0, 0xf0}, + {0x00, 0x00, 0xfe, 0xfe, 0x00, 0x00, 0xfe, 0xfe}, + {0x00, 0x1e, 0x00, 0x1e, 0x00, 0x0e, 0x00, 0x0e}, /*sw */ + {0x00, 0x1e, 0x1e, 0x00, 0x00, 0x0e, 0x0e, 0x00}, + {0x00, 0x1e, 0xe0, 0xfe, 0x00, 0x0e, 0xf0, 0xfe}, + {0x00, 0x1e, 0xfe, 0xe0, 0x00, 0x0e, 0xfe, 0xf0}, + {0x00, 0xe0, 0x00, 0xe0, 0x00, 0xf0, 0x00, 0xf0}, /*sw */ + {0x00, 0xe0, 0x1e, 0xfe, 0x00, 0xf0, 0x0e, 0xfe}, + {0x00, 0xe0, 0xe0, 0x00, 0x00, 0xf0, 0xf0, 0x00}, + {0x00, 0xe0, 0xfe, 0x1e, 0x00, 0xf0, 0xfe, 0x0e}, + {0x00, 0xfe, 0x00, 0xfe, 0x00, 0xfe, 0x00, 0xfe}, /*sw */ + {0x00, 0xfe, 0x1e, 0xe0, 0x00, 0xfe, 0x0e, 0xf0}, + {0x00, 0xfe, 0xe0, 0x1e, 0x00, 0xfe, 0xf0, 0x0e}, + {0x00, 0xfe, 0xfe, 0x00, 0x00, 0xfe, 0xfe, 0x00}, + {0x1e, 0x00, 0x00, 0x1e, 0x0e, 0x00, 0x00, 0x0e}, + {0x1e, 0x00, 0x1e, 0x00, 0x0e, 0x00, 0x0e, 0x00}, /*sw */ + {0x1e, 0x00, 0xe0, 0xfe, 0x0e, 0x00, 0xf0, 0xfe}, + {0x1e, 0x00, 0xfe, 0xe0, 0x0e, 0x00, 0xfe, 0xf0}, + {0x1e, 0x1e, 0x00, 0x00, 0x0e, 0x0e, 0x00, 0x00}, + {0x1e, 0x1e, 0x1e, 0x1e, 0x0e, 0x0e, 0x0e, 0x0e}, /*w */ + {0x1e, 0x1e, 0xe0, 0xe0, 0x0e, 0x0e, 0xf0, 0xf0}, + {0x1e, 0x1e, 0xfe, 0xfe, 0x0e, 0x0e, 0xfe, 0xfe}, + {0x1e, 0xe0, 0x00, 0xfe, 0x0e, 0xf0, 0x00, 0xfe}, + {0x1e, 0xe0, 0x1e, 0xe0, 0x0e, 0xf0, 0x0e, 0xf0}, /*sw */ + {0x1e, 0xe0, 0xe0, 0x1e, 0x0e, 0xf0, 0xf0, 0x0e}, + {0x1e, 0xe0, 0xfe, 0x00, 0x0e, 0xf0, 0xfe, 0x00}, + {0x1e, 0xfe, 0x00, 0xe0, 0x0e, 0xfe, 0x00, 0xf0}, + {0x1e, 0xfe, 0x1e, 0xfe, 0x0e, 0xfe, 0x0e, 0xfe}, /*sw */ + {0x1e, 0xfe, 0xe0, 0x00, 0x0e, 0xfe, 0xf0, 0x00}, + {0x1e, 0xfe, 0xfe, 0x1e, 0x0e, 0xfe, 0xfe, 0x0e}, + {0xe0, 0x00, 0x00, 0xe0, 0xf0, 0x00, 0x00, 0xf0}, + {0xe0, 0x00, 0x1e, 0xfe, 0xf0, 0x00, 0x0e, 0xfe}, + {0xe0, 0x00, 0xe0, 0x00, 0xf0, 0x00, 0xf0, 0x00}, /*sw */ + {0xe0, 0x00, 0xfe, 0x1e, 0xf0, 0x00, 0xfe, 0x0e}, + {0xe0, 0x1e, 0x00, 0xfe, 0xf0, 0x0e, 0x00, 0xfe}, + {0xe0, 0x1e, 0x1e, 0xe0, 0xf0, 0x0e, 0x0e, 0xf0}, + {0xe0, 0x1e, 0xe0, 0x1e, 0xf0, 0x0e, 0xf0, 0x0e}, /*sw */ + {0xe0, 0x1e, 0xfe, 0x00, 0xf0, 0x0e, 0xfe, 0x00}, + {0xe0, 0xe0, 0x00, 0x00, 0xf0, 0xf0, 0x00, 0x00}, + {0xe0, 0xe0, 0x1e, 0x1e, 0xf0, 0xf0, 0x0e, 0x0e}, + {0xe0, 0xe0, 0xe0, 0xe0, 0xf0, 0xf0, 0xf0, 0xf0}, /*w */ + {0xe0, 0xe0, 0xfe, 0xfe, 0xf0, 0xf0, 0xfe, 0xfe}, + {0xe0, 0xfe, 0x00, 0x1e, 0xf0, 0xfe, 0x00, 0x0e}, + {0xe0, 0xfe, 0x1e, 0x00, 0xf0, 0xfe, 0x0e, 0x00}, + {0xe0, 0xfe, 0xe0, 0xfe, 0xf0, 0xfe, 0xf0, 0xfe}, /*sw */ + {0xe0, 0xfe, 0xfe, 0xe0, 0xf0, 0xfe, 0xfe, 0xf0}, + {0xfe, 0x00, 0x00, 0xfe, 0xfe, 0x00, 0x00, 0xfe}, + {0xfe, 0x00, 0x1e, 0xe0, 0xfe, 0x00, 0x0e, 0xf0}, + {0xfe, 0x00, 0xe0, 0x1e, 0xfe, 0x00, 0xf0, 0x0e}, + {0xfe, 0x00, 0xfe, 0x00, 0xfe, 0x00, 0xfe, 0x00}, /*sw */ + {0xfe, 0x1e, 0x00, 0xe0, 0xfe, 0x0e, 0x00, 0xf0}, + {0xfe, 0x1e, 0x1e, 0xfe, 0xfe, 0x0e, 0x0e, 0xfe}, + {0xfe, 0x1e, 0xe0, 0x00, 0xfe, 0x0e, 0xf0, 0x00}, + {0xfe, 0x1e, 0xfe, 0x1e, 0xfe, 0x0e, 0xfe, 0x0e}, /*sw */ + {0xfe, 0xe0, 0x00, 0x1e, 0xfe, 0xf0, 0x00, 0x0e}, + {0xfe, 0xe0, 0x1e, 0x00, 0xfe, 0xf0, 0x0e, 0x00}, + {0xfe, 0xe0, 0xe0, 0xfe, 0xfe, 0xf0, 0xf0, 0xfe}, + {0xfe, 0xe0, 0xfe, 0xe0, 0xfe, 0xf0, 0xfe, 0xf0}, /*sw */ + {0xfe, 0xfe, 0x00, 0x00, 0xfe, 0xfe, 0x00, 0x00}, + {0xfe, 0xfe, 0x1e, 0x1e, 0xfe, 0xfe, 0x0e, 0x0e}, + {0xfe, 0xfe, 0xe0, 0xe0, 0xfe, 0xfe, 0xf0, 0xf0}, + {0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe} /*w */ +}; +static const unsigned char weak_keys_chksum[20] = { + 0xD0, 0xCF, 0x07, 0x38, 0x93, 0x70, 0x8A, 0x83, 0x7D, 0xD7, + 0x8A, 0x36, 0x65, 0x29, 0x6C, 0x1F, 0x7C, 0x3F, 0xD3, 0x41 +}; + +bool +des_is_weak_key (const char * key) +{ + char work[8]; + int i, left, right, middle, cmp_result; + + /* clear parity bits */ + for (i = 0; i < 8; ++i) + work[i] = ((unsigned char)key[i]) & 0xfe; + + /* binary search in the weak key table */ + left = 0; + right = 63; + while (left <= right) + { + middle = (left + right) / 2; + + if (!(cmp_result = memcmp (work, weak_keys[middle], 8))) + return -1; + + if (cmp_result > 0) + left = middle + 1; + else + right = middle - 1; + } + + return 0; +} + +/* + * Macro to swap bits across two words. + */ +#define DO_PERMUTATION(a, temp, b, offset, mask) \ + temp = ((a>>offset) ^ b) & mask; \ + b ^= temp; \ + a ^= temp<<offset; + + +/* + * This performs the 'initial permutation' of the data to be encrypted + * or decrypted. Additionally the resulting two words are rotated one bit + * to the left. + */ +#define INITIAL_PERMUTATION(left, temp, right) \ + DO_PERMUTATION(left, temp, right, 4, 0x0f0f0f0f) \ + DO_PERMUTATION(left, temp, right, 16, 0x0000ffff) \ + DO_PERMUTATION(right, temp, left, 2, 0x33333333) \ + DO_PERMUTATION(right, temp, left, 8, 0x00ff00ff) \ + right = (right << 1) | (right >> 31); \ + temp = (left ^ right) & 0xaaaaaaaa; \ + right ^= temp; \ + left ^= temp; \ + left = (left << 1) | (left >> 31); + +/* + * The 'inverse initial permutation'. + */ +#define FINAL_PERMUTATION(left, temp, right) \ + left = (left << 31) | (left >> 1); \ + temp = (left ^ right) & 0xaaaaaaaa; \ + left ^= temp; \ + right ^= temp; \ + right = (right << 31) | (right >> 1); \ + DO_PERMUTATION(right, temp, left, 8, 0x00ff00ff) \ + DO_PERMUTATION(right, temp, left, 2, 0x33333333) \ + DO_PERMUTATION(left, temp, right, 16, 0x0000ffff) \ + DO_PERMUTATION(left, temp, right, 4, 0x0f0f0f0f) + + +/* + * A full DES round including 'expansion function', 'sbox substitution' + * and 'primitive function P' but without swapping the left and right word. + * Please note: The data in 'from' and 'to' is already rotated one bit to + * the left, done in the initial permutation. + */ +#define DES_ROUND(from, to, work, subkey) \ + work = from ^ *subkey++; \ + to ^= sbox8[ work & 0x3f ]; \ + to ^= sbox6[ (work>>8) & 0x3f ]; \ + to ^= sbox4[ (work>>16) & 0x3f ]; \ + to ^= sbox2[ (work>>24) & 0x3f ]; \ + work = ((from << 28) | (from >> 4)) ^ *subkey++; \ + to ^= sbox7[ work & 0x3f ]; \ + to ^= sbox5[ (work>>8) & 0x3f ]; \ + to ^= sbox3[ (work>>16) & 0x3f ]; \ + to ^= sbox1[ (work>>24) & 0x3f ]; + +/* + * Macros to convert 8 bytes from/to 32bit words. + */ +#define READ_64BIT_DATA(data, left, right) \ + left = (data[0] << 24) | (data[1] << 16) | (data[2] << 8) | data[3]; \ + right = (data[4] << 24) | (data[5] << 16) | (data[6] << 8) | data[7]; + +#define WRITE_64BIT_DATA(data, left, right) \ + data[0] = (left >> 24) &0xff; data[1] = (left >> 16) &0xff; \ + data[2] = (left >> 8) &0xff; data[3] = left &0xff; \ + data[4] = (right >> 24) &0xff; data[5] = (right >> 16) &0xff; \ + data[6] = (right >> 8) &0xff; data[7] = right &0xff; + +/* + * Handy macros for encryption and decryption of data + */ +#define des_ecb_encrypt(ctx, from, to) des_ecb_crypt(ctx, from, to, 0) +#define des_ecb_decrypt(ctx, from, to) des_ecb_crypt(ctx, from, to, 1) +#define tripledes_ecb_encrypt(ctx, from, to) tripledes_ecb_crypt(ctx,from,to,0) +#define tripledes_ecb_decrypt(ctx, from, to) tripledes_ecb_crypt(ctx,from,to,1) + +/* + * des_key_schedule(): Calculate 16 subkeys pairs (even/odd) for + * 16 encryption rounds. + * To calculate subkeys for decryption the caller + * have to reorder the generated subkeys. + * + * rawkey: 8 Bytes of key data + * subkey: Array of at least 32 uint32_ts. Will be filled + * with calculated subkeys. + * + */ +static void +des_key_schedule (const char * _rawkey, uint32_t * subkey) +{ + const unsigned char *rawkey = (const unsigned char *) _rawkey; + uint32_t left, right, work; + int round; + + READ_64BIT_DATA (rawkey, left, right) + DO_PERMUTATION (right, work, left, 4, 0x0f0f0f0f) + DO_PERMUTATION (right, work, left, 0, 0x10101010) + left = ((leftkey_swap[(left >> 0) & 0xf] << 3) + | (leftkey_swap[(left >> 8) & 0xf] << 2) + | (leftkey_swap[(left >> 16) & 0xf] << 1) + | (leftkey_swap[(left >> 24) & 0xf]) + | (leftkey_swap[(left >> 5) & 0xf] << 7) + | (leftkey_swap[(left >> 13) & 0xf] << 6) + | (leftkey_swap[(left >> 21) & 0xf] << 5) + | (leftkey_swap[(left >> 29) & 0xf] << 4)); + + left &= 0x0fffffff; + + right = ((rightkey_swap[(right >> 1) & 0xf] << 3) + | (rightkey_swap[(right >> 9) & 0xf] << 2) + | (rightkey_swap[(right >> 17) & 0xf] << 1) + | (rightkey_swap[(right >> 25) & 0xf]) + | (rightkey_swap[(right >> 4) & 0xf] << 7) + | (rightkey_swap[(right >> 12) & 0xf] << 6) + | (rightkey_swap[(right >> 20) & 0xf] << 5) + | (rightkey_swap[(right >> 28) & 0xf] << 4)); + + right &= 0x0fffffff; + + for (round = 0; round < 16; ++round) + { + left = ((left << encrypt_rotate_tab[round]) + | (left >> (28 - encrypt_rotate_tab[round]))) & 0x0fffffff; + right = ((right << encrypt_rotate_tab[round]) + | (right >> (28 - encrypt_rotate_tab[round]))) & 0x0fffffff; + + *subkey++ = (((left << 4) & 0x24000000) + | ((left << 28) & 0x10000000) + | ((left << 14) & 0x08000000) + | ((left << 18) & 0x02080000) + | ((left << 6) & 0x01000000) + | ((left << 9) & 0x00200000) + | ((left >> 1) & 0x00100000) + | ((left << 10) & 0x00040000) + | ((left << 2) & 0x00020000) + | ((left >> 10) & 0x00010000) + | ((right >> 13) & 0x00002000) + | ((right >> 4) & 0x00001000) + | ((right << 6) & 0x00000800) + | ((right >> 1) & 0x00000400) + | ((right >> 14) & 0x00000200) + | (right & 0x00000100) + | ((right >> 5) & 0x00000020) + | ((right >> 10) & 0x00000010) + | ((right >> 3) & 0x00000008) + | ((right >> 18) & 0x00000004) + | ((right >> 26) & 0x00000002) + | ((right >> 24) & 0x00000001)); + + *subkey++ = (((left << 15) & 0x20000000) + | ((left << 17) & 0x10000000) + | ((left << 10) & 0x08000000) + | ((left << 22) & 0x04000000) + | ((left >> 2) & 0x02000000) + | ((left << 1) & 0x01000000) + | ((left << 16) & 0x00200000) + | ((left << 11) & 0x00100000) + | ((left << 3) & 0x00080000) + | ((left >> 6) & 0x00040000) + | ((left << 15) & 0x00020000) + | ((left >> 4) & 0x00010000) + | ((right >> 2) & 0x00002000) + | ((right << 8) & 0x00001000) + | ((right >> 14) & 0x00000808) + | ((right >> 9) & 0x00000400) + | ((right) & 0x00000200) + | ((right << 7) & 0x00000100) + | ((right >> 7) & 0x00000020) + | ((right >> 3) & 0x00000011) + | ((right << 2) & 0x00000004) + | ((right >> 21) & 0x00000002)); + } +} + +void +des_setkey (des_ctx *ctx, const char * key) +{ + int i; + + des_key_schedule (key, ctx->encrypt_subkeys); + + for (i = 0; i < 32; i += 2) + { + ctx->decrypt_subkeys[i] = ctx->encrypt_subkeys[30 - i]; + ctx->decrypt_subkeys[i + 1] = ctx->encrypt_subkeys[31 - i]; + } +} + +bool +des_makekey (des_ctx *ctx, const char * key, size_t keylen) +{ + if (keylen != 8) + return false; + + des_setkey (ctx, key); + + return !des_is_weak_key (key); +} + +void +des_ecb_crypt (des_ctx *ctx, const char * _from, char * _to, int mode) +{ + const unsigned char *from = (const unsigned char *) _from; + unsigned char *to = (unsigned char *) _to; + uint32_t left, right, work; + uint32_t *keys; + + keys = mode ? ctx->decrypt_subkeys : ctx->encrypt_subkeys; + + READ_64BIT_DATA (from, left, right) + INITIAL_PERMUTATION (left, work, right) + DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys) + DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys) + DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys) + DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys) + DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys) + DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys) + DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys) + DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys) + FINAL_PERMUTATION (right, work, left) + WRITE_64BIT_DATA (to, right, left) +} + +void +tripledes_set2keys (tripledes_ctx *ctx, const char * key1, const char * key2) +{ + int i; + + des_key_schedule (key1, ctx->encrypt_subkeys); + des_key_schedule (key2, &(ctx->decrypt_subkeys[32])); + + for (i = 0; i < 32; i += 2) + { + ctx->decrypt_subkeys[i] = ctx->encrypt_subkeys[30 - i]; + ctx->decrypt_subkeys[i + 1] = ctx->encrypt_subkeys[31 - i]; + + ctx->encrypt_subkeys[i + 32] = ctx->decrypt_subkeys[62 - i]; + ctx->encrypt_subkeys[i + 33] = ctx->decrypt_subkeys[63 - i]; + + ctx->encrypt_subkeys[i + 64] = ctx->encrypt_subkeys[i]; + ctx->encrypt_subkeys[i + 65] = ctx->encrypt_subkeys[i + 1]; + + ctx->decrypt_subkeys[i + 64] = ctx->decrypt_subkeys[i]; + ctx->decrypt_subkeys[i + 65] = ctx->decrypt_subkeys[i + 1]; + } +} + +void +tripledes_set3keys (tripledes_ctx *ctx, const char * key1, + const char * key2, const char * key3) +{ + int i; + + des_key_schedule (key1, ctx->encrypt_subkeys); + des_key_schedule (key2, &(ctx->decrypt_subkeys[32])); + des_key_schedule (key3, &(ctx->encrypt_subkeys[64])); + + for (i = 0; i < 32; i += 2) + { + ctx->decrypt_subkeys[i] = ctx->encrypt_subkeys[94 - i]; + ctx->decrypt_subkeys[i + 1] = ctx->encrypt_subkeys[95 - i]; + + ctx->encrypt_subkeys[i + 32] = ctx->decrypt_subkeys[62 - i]; + ctx->encrypt_subkeys[i + 33] = ctx->decrypt_subkeys[63 - i]; + + ctx->decrypt_subkeys[i + 64] = ctx->encrypt_subkeys[30 - i]; + ctx->decrypt_subkeys[i + 65] = ctx->encrypt_subkeys[31 - i]; + } +} + +void +tripledes_ecb_crypt (tripledes_ctx *ctx, + const char * _from, + char * _to, int mode) +{ + const unsigned char *from = (const unsigned char *) _from; + unsigned char *to = (unsigned char *) _to; + uint32_t left, right, work; + uint32_t *keys; + + keys = mode ? ctx->decrypt_subkeys : ctx->encrypt_subkeys; + + READ_64BIT_DATA (from, left, right) + INITIAL_PERMUTATION (left, work, right) + DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys) + DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys) + DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys) + DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys) + DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys) + DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys) + DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys) + DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys) + DES_ROUND (left, right, work, keys) DES_ROUND (right, left, work, keys) + DES_ROUND (left, right, work, keys) DES_ROUND (right, left, work, keys) + DES_ROUND (left, right, work, keys) DES_ROUND (right, left, work, keys) + DES_ROUND (left, right, work, keys) DES_ROUND (right, left, work, keys) + DES_ROUND (left, right, work, keys) DES_ROUND (right, left, work, keys) + DES_ROUND (left, right, work, keys) DES_ROUND (right, left, work, keys) + DES_ROUND (left, right, work, keys) DES_ROUND (right, left, work, keys) + DES_ROUND (left, right, work, keys) DES_ROUND (right, left, work, keys) + DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys) + DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys) + DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys) + DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys) + DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys) + DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys) + DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys) + DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys) + FINAL_PERMUTATION (right, work, left) + WRITE_64BIT_DATA (to, right, left) +} + +bool +tripledes_makekey (tripledes_ctx *ctx, const char * key, size_t keylen) +{ + if (keylen != 24) + return false; + + tripledes_set3keys (ctx, key, key + 8, key + 16); + + return !(des_is_weak_key (key) + || des_is_weak_key (key + 8) + || des_is_weak_key (key + 16)); +} diff --git a/lgl/des.h b/lgl/des.h new file mode 100644 index 0000000000..2b5f71237a --- /dev/null +++ b/lgl/des.h @@ -0,0 +1,114 @@ +/* des.h --- DES cipher implementation. + * Copyright (C) 2005 Free Software Foundation, Inc. + * + * This file is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation; either version 2.1, or (at your + * option) any later version. + * + * This file is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this file; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + * + */ + +/* Adapted for gnulib by Simon Josefsson, based on Libgcrypt. */ + +#ifndef DES_H +# define DES_H + +#include <stddef.h> +#include <stdint.h> +#include <stdbool.h> + +/* + * Encryption/Decryption context of DES + */ +typedef struct +{ + uint32_t encrypt_subkeys[32]; + uint32_t decrypt_subkeys[32]; +} des_ctx; + +/* + * Encryption/Decryption context of Triple-DES + */ +typedef struct +{ + uint32_t encrypt_subkeys[96]; + uint32_t decrypt_subkeys[96]; +} tripledes_ctx; + +/* Check whether the 8 byte key is weak. Does not check the parity + * bits of the key but simple ignore them. */ +extern bool +des_is_weak_key (const char * key); + +/* + * DES + * --- + */ + +/* Fill a DES context CTX with subkeys calculated from 64bit KEY. + * Does not check parity bits, but simply ignore them. Does not check + * for weak keys. */ +extern void +des_setkey (des_ctx *ctx, const char * key); + +/* Fill a DES context CTX with subkeys calculated from 64bit KEY, with + * weak key checking. Does not check parity bits, but simply ignore + * them. */ +extern bool +des_makekey (des_ctx *ctx, const char * key, size_t keylen); + +/* Electronic Codebook Mode DES encryption/decryption of data + * according to 'mode'. */ +extern void +des_ecb_crypt (des_ctx *ctx, const char * from, char * to, int mode); + +#define des_ecb_encrypt(ctx, from, to) des_ecb_crypt(ctx, from, to, 0) +#define des_ecb_decrypt(ctx, from, to) des_ecb_crypt(ctx, from, to, 1) + +/* Triple-DES + * ---------- + */ + +/* Fill a Triple-DES context CTX with subkeys calculated from two + * 64bit keys in KEY1 and KEY2. Does not check the parity bits of the + * keys, but simply ignore them. Does not check for weak keys. */ +extern void +tripledes_set2keys (tripledes_ctx *ctx, const char * key1, const char * key2); + +/* + * Fill a Triple-DES context CTX with subkeys calculated from three + * 64bit keys in KEY1, KEY2 and KEY3. Does not check the parity bits + * of the keys, but simply ignore them. Does not check for weak + * keys. */ +extern void +tripledes_set3keys (tripledes_ctx *ctx, const char * key1, + const char * key2, const char * key3); + +/* Fill a Triple-DES context CTX with subkeys calculated from three + * concatenated 64bit keys in KEY, with weak key checking. Does not + * check the parity bits of the keys, but simply ignore them. */ +extern bool +tripledes_makekey (tripledes_ctx *ctx, const char * key, size_t keylen); + +/* Electronic Codebook Mode Triple-DES encryption/decryption of data + * according to 'mode'. Sometimes this mode is named 'EDE' mode + * (Encryption-Decryption-Encryption). */ +extern void +tripledes_ecb_crypt (tripledes_ctx *ctx, + const char * from, + char * to, int mode); + +#define tripledes_ecb_encrypt(ctx, from, to) tripledes_ecb_crypt(ctx,from,to,0) +#define tripledes_ecb_decrypt(ctx, from, to) tripledes_ecb_crypt(ctx,from,to,1) + +#endif /* DES_H */ diff --git a/lgl/gc-gnulib.c b/lgl/gc-gnulib.c new file mode 100644 index 0000000000..a31d55e4ed --- /dev/null +++ b/lgl/gc-gnulib.c @@ -0,0 +1,860 @@ +/* gc-gnulib.c --- Common gnulib internal crypto interface functions + * Copyright (C) 2002, 2003, 2004, 2005, 2006 Simon Josefsson + * + * This file is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation; either version 2.1, or (at your + * option) any later version. + * + * This file is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this file; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + * + */ + +/* Note: This file is only built if GC uses internal functions. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +/* Get prototype. */ +#include "gc.h" + +#include <stdlib.h> +#include <string.h> + +/* For randomize. */ +#ifdef GC_USE_RANDOM +# include <unistd.h> +# include <sys/types.h> +# include <sys/stat.h> +# include <fcntl.h> +# include <errno.h> +#endif + +/* Hashes. */ +#ifdef GC_USE_MD2 +# include "md2.h" +#endif +#ifdef GC_USE_MD4 +# include "md4.h" +#endif +#ifdef GC_USE_MD5 +# include "md5.h" +#endif +#ifdef GC_USE_SHA1 +# include "sha1.h" +#endif +#if defined(GC_USE_HMAC_MD5) || defined(GC_USE_HMAC_SHA1) +# include "hmac.h" +#endif + +/* Ciphers. */ +#ifdef GC_USE_ARCFOUR +# include "arcfour.h" +#endif +#ifdef GC_USE_ARCTWO +# include "arctwo.h" +#endif +#ifdef GC_USE_DES +# include "des.h" +#endif +#ifdef GC_USE_RIJNDAEL +# include "rijndael-api-fst.h" +#endif + +Gc_rc +gc_init (void) +{ + return GC_OK; +} + +void +gc_done (void) +{ + return; +} + +#ifdef GC_USE_RANDOM + +/* Randomness. */ + +static Gc_rc +randomize (int level, char *data, size_t datalen) +{ + int fd; + const char *device; + size_t len = 0; + int rc; + + switch (level) + { + case 0: + device = NAME_OF_NONCE_DEVICE; + break; + + case 1: + device = NAME_OF_PSEUDO_RANDOM_DEVICE; + break; + + default: + device = NAME_OF_RANDOM_DEVICE; + break; + } + + if (strcmp (device, "no") == 0) + return GC_RANDOM_ERROR; + + fd = open (device, O_RDONLY); + if (fd < 0) + return GC_RANDOM_ERROR; + + do + { + ssize_t tmp; + + tmp = read (fd, data, datalen); + + if (tmp < 0) + { + int save_errno = errno; + close (fd); + errno = save_errno; + return GC_RANDOM_ERROR; + } + + len += tmp; + } + while (len < datalen); + + rc = close (fd); + if (rc < 0) + return GC_RANDOM_ERROR; + + return GC_OK; +} + +Gc_rc +gc_nonce (char *data, size_t datalen) +{ + return randomize (0, data, datalen); +} + +Gc_rc +gc_pseudo_random (char *data, size_t datalen) +{ + return randomize (1, data, datalen); +} + +Gc_rc +gc_random (char *data, size_t datalen) +{ + return randomize (2, data, datalen); +} + +#endif + +/* Memory allocation. */ + +void +gc_set_allocators (gc_malloc_t func_malloc, + gc_malloc_t secure_malloc, + gc_secure_check_t secure_check, + gc_realloc_t func_realloc, gc_free_t func_free) +{ + return; +} +/* Ciphers. */ + +typedef struct _gc_cipher_ctx { + Gc_cipher alg; + Gc_cipher_mode mode; +#ifdef GC_USE_ARCTWO + arctwo_context arctwoContext; + char arctwoIV[ARCTWO_BLOCK_SIZE]; +#endif +#ifdef GC_USE_ARCFOUR + arcfour_context arcfourContext; +#endif +#ifdef GC_USE_DES + des_ctx desContext; +#endif +#ifdef GC_USE_RIJNDAEL + rijndaelKeyInstance aesEncKey; + rijndaelKeyInstance aesDecKey; + rijndaelCipherInstance aesContext; +#endif +} _gc_cipher_ctx; + +Gc_rc +gc_cipher_open (Gc_cipher alg, Gc_cipher_mode mode, + gc_cipher_handle * outhandle) +{ + _gc_cipher_ctx *ctx; + Gc_rc rc = GC_OK; + + ctx = calloc (sizeof (*ctx), 1); + if (!ctx) + return GC_MALLOC_ERROR; + + ctx->alg = alg; + ctx->mode = mode; + + switch (alg) + { +#ifdef GC_USE_ARCTWO + case GC_ARCTWO40: + switch (mode) + { + case GC_ECB: + case GC_CBC: + break; + + default: + rc = GC_INVALID_CIPHER; + } + break; +#endif + +#ifdef GC_USE_ARCFOUR + case GC_ARCFOUR128: + case GC_ARCFOUR40: + switch (mode) + { + case GC_STREAM: + break; + + default: + rc = GC_INVALID_CIPHER; + } + break; +#endif + +#ifdef GC_USE_DES + case GC_DES: + switch (mode) + { + case GC_ECB: + break; + + default: + rc = GC_INVALID_CIPHER; + } + break; +#endif + +#ifdef GC_USE_RIJNDAEL + case GC_AES128: + case GC_AES192: + case GC_AES256: + switch (mode) + { + case GC_ECB: + case GC_CBC: + break; + + default: + rc = GC_INVALID_CIPHER; + } + break; +#endif + + default: + rc = GC_INVALID_CIPHER; + } + + if (rc == GC_OK) + *outhandle = ctx; + else + free (ctx); + + return rc; +} + +Gc_rc +gc_cipher_setkey (gc_cipher_handle handle, size_t keylen, const char *key) +{ + _gc_cipher_ctx *ctx = handle; + + switch (ctx->alg) + { +#ifdef GC_USE_ARCTWO + case GC_ARCTWO40: + arctwo_setkey (&ctx->arctwoContext, keylen, key); + break; +#endif + +#ifdef GC_USE_ARCFOUR + case GC_ARCFOUR128: + case GC_ARCFOUR40: + arcfour_setkey (&ctx->arcfourContext, key, keylen); + break; +#endif + +#ifdef GC_USE_DES + case GC_DES: + if (keylen != 8) + return GC_INVALID_CIPHER; + des_setkey (&ctx->desContext, key); + break; +#endif + +#ifdef GC_USE_RIJNDAEL + case GC_AES128: + case GC_AES192: + case GC_AES256: + { + rijndael_rc rc; + size_t i; + char keyMaterial[RIJNDAEL_MAX_KEY_SIZE + 1]; + + for (i = 0; i < keylen; i++) + sprintf (&keyMaterial[2*i], "%02x", key[i] & 0xFF); + + rc = rijndaelMakeKey (&ctx->aesEncKey, RIJNDAEL_DIR_ENCRYPT, + keylen * 8, keyMaterial); + if (rc < 0) + return GC_INVALID_CIPHER; + + rc = rijndaelMakeKey (&ctx->aesDecKey, RIJNDAEL_DIR_DECRYPT, + keylen * 8, keyMaterial); + if (rc < 0) + return GC_INVALID_CIPHER; + + rc = rijndaelCipherInit (&ctx->aesContext, RIJNDAEL_MODE_ECB, NULL); + if (rc < 0) + return GC_INVALID_CIPHER; + } + break; +#endif + + default: + return GC_INVALID_CIPHER; + } + + return GC_OK; +} + +Gc_rc +gc_cipher_setiv (gc_cipher_handle handle, size_t ivlen, const char *iv) +{ + _gc_cipher_ctx *ctx = handle; + + switch (ctx->alg) + { +#ifdef GC_USE_ARCTWO + case GC_ARCTWO40: + if (ivlen != ARCTWO_BLOCK_SIZE) + return GC_INVALID_CIPHER; + memcpy (ctx->arctwoIV, iv, ivlen); + break; +#endif + +#ifdef GC_USE_RIJNDAEL + case GC_AES128: + case GC_AES192: + case GC_AES256: + switch (ctx->mode) + { + case GC_ECB: + /* Doesn't use IV. */ + break; + + case GC_CBC: + { + rijndael_rc rc; + size_t i; + char ivMaterial[2 * RIJNDAEL_MAX_IV_SIZE + 1]; + + for (i = 0; i < ivlen; i++) + sprintf (&ivMaterial[2*i], "%02x", iv[i] & 0xFF); + + rc = rijndaelCipherInit (&ctx->aesContext, RIJNDAEL_MODE_CBC, + ivMaterial); + if (rc < 0) + return GC_INVALID_CIPHER; + } + break; + + default: + return GC_INVALID_CIPHER; + } + break; +#endif + + default: + return GC_INVALID_CIPHER; + } + + return GC_OK; +} + +Gc_rc +gc_cipher_encrypt_inline (gc_cipher_handle handle, size_t len, char *data) +{ + _gc_cipher_ctx *ctx = handle; + + switch (ctx->alg) + { +#ifdef GC_USE_ARCTWO + case GC_ARCTWO40: + switch (ctx->mode) + { + case GC_ECB: + arctwo_encrypt (&ctx->arctwoContext, data, data, len); + break; + + case GC_CBC: + for (; len >= ARCTWO_BLOCK_SIZE; len -= ARCTWO_BLOCK_SIZE, + data += ARCTWO_BLOCK_SIZE) + { + size_t i; + for (i = 0; i < ARCTWO_BLOCK_SIZE; i++) + data[i] ^= ctx->arctwoIV[i]; + arctwo_encrypt (&ctx->arctwoContext, data, data, + ARCTWO_BLOCK_SIZE); + memcpy (ctx->arctwoIV, data, ARCTWO_BLOCK_SIZE); + } + break; + + default: + return GC_INVALID_CIPHER; + } + break; +#endif + +#ifdef GC_USE_ARCFOUR + case GC_ARCFOUR128: + case GC_ARCFOUR40: + arcfour_stream (&ctx->arcfourContext, data, data, len); + break; +#endif + +#ifdef GC_USE_DES + case GC_DES: + for (; len >= 8; len -= 8, data += 8) + des_ecb_encrypt (&ctx->desContext, data, data); + break; +#endif + +#ifdef GC_USE_RIJNDAEL + case GC_AES128: + case GC_AES192: + case GC_AES256: + { + int nblocks; + + nblocks = rijndaelBlockEncrypt (&ctx->aesContext, &ctx->aesEncKey, + data, 8 * len, data); + if (nblocks < 0) + return GC_INVALID_CIPHER; + } + break; +#endif + + default: + return GC_INVALID_CIPHER; + } + + return GC_OK; +} + +Gc_rc +gc_cipher_decrypt_inline (gc_cipher_handle handle, size_t len, char *data) +{ + _gc_cipher_ctx *ctx = handle; + + switch (ctx->alg) + { +#ifdef GC_USE_ARCTWO + case GC_ARCTWO40: + switch (ctx->mode) + { + case GC_ECB: + arctwo_decrypt (&ctx->arctwoContext, data, data, len); + break; + + case GC_CBC: + for (; len >= ARCTWO_BLOCK_SIZE; len -= ARCTWO_BLOCK_SIZE, + data += ARCTWO_BLOCK_SIZE) + { + char tmpIV[ARCTWO_BLOCK_SIZE]; + size_t i; + memcpy (tmpIV, data, ARCTWO_BLOCK_SIZE); + arctwo_decrypt (&ctx->arctwoContext, data, data, + ARCTWO_BLOCK_SIZE); + for (i = 0; i < ARCTWO_BLOCK_SIZE; i++) + data[i] ^= ctx->arctwoIV[i]; + memcpy (ctx->arctwoIV, tmpIV, ARCTWO_BLOCK_SIZE); + } + break; + + default: + return GC_INVALID_CIPHER; + } + break; +#endif + +#ifdef GC_USE_ARCFOUR + case GC_ARCFOUR128: + case GC_ARCFOUR40: + arcfour_stream (&ctx->arcfourContext, data, data, len); + break; +#endif + +#ifdef GC_USE_DES + case GC_DES: + for (; len >= 8; len -= 8, data += 8) + des_ecb_decrypt (&ctx->desContext, data, data); + break; +#endif + +#ifdef GC_USE_RIJNDAEL + case GC_AES128: + case GC_AES192: + case GC_AES256: + { + int nblocks; + + nblocks = rijndaelBlockDecrypt (&ctx->aesContext, &ctx->aesDecKey, + data, 8 * len, data); + if (nblocks < 0) + return GC_INVALID_CIPHER; + } + break; +#endif + + default: + return GC_INVALID_CIPHER; + } + + return GC_OK; +} + +Gc_rc +gc_cipher_close (gc_cipher_handle handle) +{ + _gc_cipher_ctx *ctx = handle; + + if (ctx) + free (ctx); + + return GC_OK; +} + +/* Hashes. */ + +#define MAX_DIGEST_SIZE 20 + +typedef struct _gc_hash_ctx { + Gc_hash alg; + Gc_hash_mode mode; + char hash[MAX_DIGEST_SIZE]; +#ifdef GC_USE_MD2 + struct md2_ctx md2Context; +#endif +#ifdef GC_USE_MD4 + struct md4_ctx md4Context; +#endif +#ifdef GC_USE_MD5 + struct md5_ctx md5Context; +#endif +#ifdef GC_USE_SHA1 + struct sha1_ctx sha1Context; +#endif +} _gc_hash_ctx; + +Gc_rc +gc_hash_open (Gc_hash hash, Gc_hash_mode mode, gc_hash_handle * outhandle) +{ + _gc_hash_ctx *ctx; + Gc_rc rc = GC_OK; + + ctx = calloc (sizeof (*ctx), 1); + + ctx->alg = hash; + ctx->mode = mode; + + switch (hash) + { +#ifdef GC_USE_MD2 + case GC_MD2: + md2_init_ctx (&ctx->md2Context); + break; +#endif + +#ifdef GC_USE_MD4 + case GC_MD4: + md4_init_ctx (&ctx->md4Context); + break; +#endif + +#ifdef GC_USE_MD5 + case GC_MD5: + md5_init_ctx (&ctx->md5Context); + break; +#endif + +#ifdef GC_USE_SHA1 + case GC_SHA1: + sha1_init_ctx (&ctx->sha1Context); + break; +#endif + + default: + rc = GC_INVALID_HASH; + break; + } + + switch (mode) + { + case 0: + break; + + default: + rc = GC_INVALID_HASH; + break; + } + + if (rc == GC_OK) + *outhandle = ctx; + else + free (ctx); + + return rc; +} + +Gc_rc +gc_hash_clone (gc_hash_handle handle, gc_hash_handle * outhandle) +{ + _gc_hash_ctx *in = handle; + _gc_hash_ctx *out; + + *outhandle = out = calloc (sizeof (*out), 1); + if (!out) + return GC_MALLOC_ERROR; + + memcpy (out, in, sizeof (*out)); + + return GC_OK; +} + +size_t +gc_hash_digest_length (Gc_hash hash) +{ + size_t len; + + switch (hash) + { + case GC_MD2: + len = GC_MD2_DIGEST_SIZE; + break; + + case GC_MD4: + len = GC_MD4_DIGEST_SIZE; + break; + + case GC_MD5: + len = GC_MD5_DIGEST_SIZE; + break; + + case GC_RMD160: + len = GC_RMD160_DIGEST_SIZE; + break; + + case GC_SHA1: + len = GC_SHA1_DIGEST_SIZE; + break; + + default: + return 0; + } + + return len; +} + +void +gc_hash_write (gc_hash_handle handle, size_t len, const char *data) +{ + _gc_hash_ctx *ctx = handle; + + switch (ctx->alg) + { +#ifdef GC_USE_MD2 + case GC_MD2: + md2_process_bytes (data, len, &ctx->md2Context); + break; +#endif + +#ifdef GC_USE_MD4 + case GC_MD4: + md4_process_bytes (data, len, &ctx->md4Context); + break; +#endif + +#ifdef GC_USE_MD5 + case GC_MD5: + md5_process_bytes (data, len, &ctx->md5Context); + break; +#endif + +#ifdef GC_USE_SHA1 + case GC_SHA1: + sha1_process_bytes (data, len, &ctx->sha1Context); + break; +#endif + + default: + break; + } +} + +const char * +gc_hash_read (gc_hash_handle handle) +{ + _gc_hash_ctx *ctx = handle; + const char *ret = NULL; + + switch (ctx->alg) + { +#ifdef GC_USE_MD2 + case GC_MD2: + md2_finish_ctx (&ctx->md2Context, ctx->hash); + ret = ctx->hash; + break; +#endif + +#ifdef GC_USE_MD4 + case GC_MD4: + md4_finish_ctx (&ctx->md4Context, ctx->hash); + ret = ctx->hash; + break; +#endif + +#ifdef GC_USE_MD5 + case GC_MD5: + md5_finish_ctx (&ctx->md5Context, ctx->hash); + ret = ctx->hash; + break; +#endif + +#ifdef GC_USE_SHA1 + case GC_SHA1: + sha1_finish_ctx (&ctx->sha1Context, ctx->hash); + ret = ctx->hash; + break; +#endif + + default: + return NULL; + } + + return ret; +} + +void +gc_hash_close (gc_hash_handle handle) +{ + _gc_hash_ctx *ctx = handle; + + free (ctx); +} + +Gc_rc +gc_hash_buffer (Gc_hash hash, const void *in, size_t inlen, char *resbuf) +{ + switch (hash) + { +#ifdef GC_USE_MD2 + case GC_MD2: + md2_buffer (in, inlen, resbuf); + break; +#endif + +#ifdef GC_USE_MD4 + case GC_MD4: + md4_buffer (in, inlen, resbuf); + break; +#endif + +#ifdef GC_USE_MD5 + case GC_MD5: + md5_buffer (in, inlen, resbuf); + break; +#endif + +#ifdef GC_USE_SHA1 + case GC_SHA1: + sha1_buffer (in, inlen, resbuf); + break; +#endif + + default: + return GC_INVALID_HASH; + } + + return GC_OK; +} + +#ifdef GC_USE_MD2 +Gc_rc +gc_md2 (const void *in, size_t inlen, void *resbuf) +{ + md2_buffer (in, inlen, resbuf); + return GC_OK; +} +#endif + +#ifdef GC_USE_MD4 +Gc_rc +gc_md4 (const void *in, size_t inlen, void *resbuf) +{ + md4_buffer (in, inlen, resbuf); + return GC_OK; +} +#endif + +#ifdef GC_USE_MD5 +Gc_rc +gc_md5 (const void *in, size_t inlen, void *resbuf) +{ + md5_buffer (in, inlen, resbuf); + return GC_OK; +} +#endif + +#ifdef GC_USE_SHA1 +Gc_rc +gc_sha1 (const void *in, size_t inlen, void *resbuf) +{ + sha1_buffer (in, inlen, resbuf); + return GC_OK; +} +#endif + +#ifdef GC_USE_HMAC_MD5 +Gc_rc +gc_hmac_md5 (const void *key, size_t keylen, + const void *in, size_t inlen, char *resbuf) +{ + hmac_md5 (key, keylen, in, inlen, resbuf); + return GC_OK; +} +#endif + +#ifdef GC_USE_HMAC_SHA1 +Gc_rc +gc_hmac_sha1 (const void *key, size_t keylen, + const void *in, size_t inlen, char *resbuf) +{ + hmac_sha1 (key, keylen, in, inlen, resbuf); + return GC_OK; +} +#endif diff --git a/lgl/gc-libgcrypt.c b/lgl/gc-libgcrypt.c new file mode 100644 index 0000000000..53753c3fe0 --- /dev/null +++ b/lgl/gc-libgcrypt.c @@ -0,0 +1,658 @@ +/* gc-libgcrypt.c --- Crypto wrappers around Libgcrypt for GC. + * Copyright (C) 2002, 2003, 2004, 2005, 2006 Simon Josefsson + * + * This file is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation; either version 2.1, or (at your + * option) any later version. + * + * This file is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this file; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + * + */ + +/* Note: This file is only built if GC uses Libgcrypt. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +/* Get prototype. */ +#include "gc.h" + +#include <stdlib.h> +#include <string.h> + +/* Get libgcrypt API. */ +#include <gcrypt.h> +#ifdef GC_USE_MD2 +# include "md2.h" +#endif + +#include <assert.h> + +/* Initialization. */ + +Gc_rc +gc_init (void) +{ + gcry_error_t err; + + err = gcry_control (GCRYCTL_ANY_INITIALIZATION_P); + if (err == GPG_ERR_NO_ERROR) + { + if (gcry_check_version (GCRYPT_VERSION) == NULL) + return GC_INIT_ERROR; + + err = gcry_control (GCRYCTL_INITIALIZATION_FINISHED, NULL, 0); + if (err != GPG_ERR_NO_ERROR) + return GC_INIT_ERROR; + } + + return GC_OK; +} + +void +gc_done (void) +{ + return; +} + +#ifdef GC_USE_RANDOM + +/* Randomness. */ + +Gc_rc +gc_nonce (char *data, size_t datalen) +{ + gcry_create_nonce ((unsigned char *) data, datalen); + return GC_OK; +} + +Gc_rc +gc_pseudo_random (char *data, size_t datalen) +{ + gcry_randomize ((unsigned char *) data, datalen, GCRY_STRONG_RANDOM); + return GC_OK; +} + +Gc_rc +gc_random (char *data, size_t datalen) +{ + gcry_randomize ((unsigned char *) data, datalen, GCRY_VERY_STRONG_RANDOM); + return GC_OK; +} + +#endif + +/* Memory allocation. */ + +void +gc_set_allocators (gc_malloc_t func_malloc, + gc_malloc_t secure_malloc, + gc_secure_check_t secure_check, + gc_realloc_t func_realloc, gc_free_t func_free) +{ + gcry_set_allocation_handler (func_malloc, secure_malloc, secure_check, + func_realloc, func_free); +} + +/* Ciphers. */ + +Gc_rc +gc_cipher_open (Gc_cipher alg, Gc_cipher_mode mode, + gc_cipher_handle * outhandle) +{ + int gcryalg, gcrymode; + gcry_error_t err; + + switch (alg) + { + case GC_AES128: + gcryalg = GCRY_CIPHER_RIJNDAEL; + break; + + case GC_AES192: + gcryalg = GCRY_CIPHER_RIJNDAEL; + break; + + case GC_AES256: + gcryalg = GCRY_CIPHER_RIJNDAEL256; + break; + + case GC_3DES: + gcryalg = GCRY_CIPHER_3DES; + break; + + case GC_DES: + gcryalg = GCRY_CIPHER_DES; + break; + + case GC_ARCFOUR128: + case GC_ARCFOUR40: + gcryalg = GCRY_CIPHER_ARCFOUR; + break; + + case GC_ARCTWO40: + gcryalg = GCRY_CIPHER_RFC2268_40; + break; + + default: + return GC_INVALID_CIPHER; + } + + switch (mode) + { + case GC_ECB: + gcrymode = GCRY_CIPHER_MODE_ECB; + break; + + case GC_CBC: + gcrymode = GCRY_CIPHER_MODE_CBC; + break; + + case GC_STREAM: + gcrymode = GCRY_CIPHER_MODE_STREAM; + break; + + default: + return GC_INVALID_CIPHER; + } + + err = gcry_cipher_open ((gcry_cipher_hd_t *) outhandle, + gcryalg, gcrymode, 0); + if (gcry_err_code (err)) + return GC_INVALID_CIPHER; + + return GC_OK; +} + +Gc_rc +gc_cipher_setkey (gc_cipher_handle handle, size_t keylen, const char *key) +{ + gcry_error_t err; + + err = gcry_cipher_setkey ((gcry_cipher_hd_t) handle, key, keylen); + if (gcry_err_code (err)) + return GC_INVALID_CIPHER; + + return GC_OK; +} + +Gc_rc +gc_cipher_setiv (gc_cipher_handle handle, size_t ivlen, const char *iv) +{ + gcry_error_t err; + + err = gcry_cipher_setiv ((gcry_cipher_hd_t) handle, iv, ivlen); + if (gcry_err_code (err)) + return GC_INVALID_CIPHER; + + return GC_OK; +} + +Gc_rc +gc_cipher_encrypt_inline (gc_cipher_handle handle, size_t len, char *data) +{ + if (gcry_cipher_encrypt ((gcry_cipher_hd_t) handle, + data, len, NULL, len) != 0) + return GC_INVALID_CIPHER; + + return GC_OK; +} + +Gc_rc +gc_cipher_decrypt_inline (gc_cipher_handle handle, size_t len, char *data) +{ + if (gcry_cipher_decrypt ((gcry_cipher_hd_t) handle, + data, len, NULL, len) != 0) + return GC_INVALID_CIPHER; + + return GC_OK; +} + +Gc_rc +gc_cipher_close (gc_cipher_handle handle) +{ + gcry_cipher_close (handle); + + return GC_OK; +} + +/* Hashes. */ + +typedef struct _gc_hash_ctx { + Gc_hash alg; + Gc_hash_mode mode; + gcry_md_hd_t gch; +#ifdef GC_USE_MD2 + char hash[GC_MD2_DIGEST_SIZE]; + struct md2_ctx md2Context; +#endif +} _gc_hash_ctx; + +Gc_rc +gc_hash_open (Gc_hash hash, Gc_hash_mode mode, gc_hash_handle * outhandle) +{ + _gc_hash_ctx *ctx; + int gcryalg, gcrymode; + gcry_error_t err; + Gc_rc rc = GC_OK; + + ctx = calloc (sizeof (*ctx), 1); + if (!ctx) + return GC_MALLOC_ERROR; + + ctx->alg = hash; + ctx->mode = mode; + + switch (hash) + { + case GC_MD2: + gcryalg = GCRY_MD_NONE; + break; + + case GC_MD4: + gcryalg = GCRY_MD_MD4; + break; + + case GC_MD5: + gcryalg = GCRY_MD_MD5; + break; + + case GC_SHA1: + gcryalg = GCRY_MD_SHA1; + break; + + case GC_RMD160: + gcryalg = GCRY_MD_RMD160; + break; + + default: + rc = GC_INVALID_HASH; + } + + switch (mode) + { + case 0: + gcrymode = 0; + break; + + case GC_HMAC: + gcrymode = GCRY_MD_FLAG_HMAC; + break; + + default: + rc = GC_INVALID_HASH; + } + + if (rc == GC_OK && gcryalg != GCRY_MD_NONE) + { + err = gcry_md_open (&ctx->gch, gcryalg, gcrymode); + if (gcry_err_code (err)) + rc = GC_INVALID_HASH; + } + + if (rc == GC_OK) + *outhandle = ctx; + else + free (ctx); + + return rc; +} + +Gc_rc +gc_hash_clone (gc_hash_handle handle, gc_hash_handle * outhandle) +{ + _gc_hash_ctx *in = handle; + _gc_hash_ctx *out; + int err; + + *outhandle = out = calloc (sizeof (*out), 1); + if (!out) + return GC_MALLOC_ERROR; + + memcpy (out, in, sizeof (*out)); + + err = gcry_md_copy (&out->gch, in->gch); + if (err) + { + free (out); + return GC_INVALID_HASH; + } + + return GC_OK; +} + +size_t +gc_hash_digest_length (Gc_hash hash) +{ + size_t len; + + switch (hash) + { + case GC_MD2: + len = GC_MD2_DIGEST_SIZE; + break; + + case GC_MD4: + len = GC_MD4_DIGEST_SIZE; + break; + + case GC_MD5: + len = GC_MD5_DIGEST_SIZE; + break; + + case GC_RMD160: + len = GC_RMD160_DIGEST_SIZE; + break; + + case GC_SHA1: + len = GC_SHA1_DIGEST_SIZE; + break; + + default: + return 0; + } + + return len; +} + +void +gc_hash_hmac_setkey (gc_hash_handle handle, size_t len, const char *key) +{ + _gc_hash_ctx *ctx = handle; +#ifdef GC_USE_MD2 + if (ctx->alg != GC_MD2) +#endif + gcry_md_setkey (ctx->gch, key, len); +} + +void +gc_hash_write (gc_hash_handle handle, size_t len, const char *data) +{ + _gc_hash_ctx *ctx = handle; + +#ifdef GC_USE_MD2 + if (ctx->alg == GC_MD2) + md2_process_bytes (data, len, &ctx->md2Context); + else +#endif + gcry_md_write (ctx->gch, data, len); +} + +const char * +gc_hash_read (gc_hash_handle handle) +{ + _gc_hash_ctx *ctx = handle; + const char *digest; + +#ifdef GC_USE_MD2 + if (ctx->alg == GC_MD2) + { + md2_finish_ctx (&ctx->md2Context, ctx->hash); + digest = ctx->hash; + } + else +#endif + { + gcry_md_final (ctx->gch); + digest = gcry_md_read (ctx->gch, 0); + } + + return digest; +} + +void +gc_hash_close (gc_hash_handle handle) +{ + _gc_hash_ctx *ctx = handle; + +#ifdef GC_USE_MD2 + if (ctx->alg != GC_MD2) +#endif + gcry_md_close (ctx->gch); + + free (ctx); +} + +Gc_rc +gc_hash_buffer (Gc_hash hash, const void *in, size_t inlen, char *resbuf) +{ + int gcryalg; + + switch (hash) + { +#ifdef GC_USE_MD2 + case GC_MD2: + md2_buffer (in, inlen, resbuf); + return GC_OK; + break; +#endif + +#ifdef GC_USE_MD4 + case GC_MD4: + gcryalg = GCRY_MD_MD4; + break; +#endif + +#ifdef GC_USE_MD5 + case GC_MD5: + gcryalg = GCRY_MD_MD5; + break; +#endif + +#ifdef GC_USE_SHA1 + case GC_SHA1: + gcryalg = GCRY_MD_SHA1; + break; +#endif + +#ifdef GC_USE_RMD160 + case GC_RMD160: + gcryalg = GCRY_MD_RMD160; + break; +#endif + + default: + return GC_INVALID_HASH; + } + + gcry_md_hash_buffer (gcryalg, resbuf, in, inlen); + + return GC_OK; +} + +/* One-call interface. */ + +#ifdef GC_USE_MD2 +Gc_rc +gc_md2 (const void *in, size_t inlen, void *resbuf) +{ + md2_buffer (in, inlen, resbuf); + return GC_OK; +} +#endif + +#ifdef GC_USE_MD4 +Gc_rc +gc_md4 (const void *in, size_t inlen, void *resbuf) +{ + size_t outlen = gcry_md_get_algo_dlen (GCRY_MD_MD4); + gcry_md_hd_t hd; + gpg_error_t err; + unsigned char *p; + + assert (outlen == GC_MD4_DIGEST_SIZE); + + err = gcry_md_open (&hd, GCRY_MD_MD4, 0); + if (err != GPG_ERR_NO_ERROR) + return GC_INVALID_HASH; + + gcry_md_write (hd, in, inlen); + + p = gcry_md_read (hd, GCRY_MD_MD4); + if (p == NULL) + { + gcry_md_close (hd); + return GC_INVALID_HASH; + } + + memcpy (resbuf, p, outlen); + + gcry_md_close (hd); + + return GC_OK; +} +#endif + +#ifdef GC_USE_MD5 +Gc_rc +gc_md5 (const void *in, size_t inlen, void *resbuf) +{ + size_t outlen = gcry_md_get_algo_dlen (GCRY_MD_MD5); + gcry_md_hd_t hd; + gpg_error_t err; + unsigned char *p; + + assert (outlen == GC_MD5_DIGEST_SIZE); + + err = gcry_md_open (&hd, GCRY_MD_MD5, 0); + if (err != GPG_ERR_NO_ERROR) + return GC_INVALID_HASH; + + gcry_md_write (hd, in, inlen); + + p = gcry_md_read (hd, GCRY_MD_MD5); + if (p == NULL) + { + gcry_md_close (hd); + return GC_INVALID_HASH; + } + + memcpy (resbuf, p, outlen); + + gcry_md_close (hd); + + return GC_OK; +} +#endif + +#ifdef GC_USE_SHA1 +Gc_rc +gc_sha1 (const void *in, size_t inlen, void *resbuf) +{ + size_t outlen = gcry_md_get_algo_dlen (GCRY_MD_SHA1); + gcry_md_hd_t hd; + gpg_error_t err; + unsigned char *p; + + assert (outlen == GC_SHA1_DIGEST_SIZE); + + err = gcry_md_open (&hd, GCRY_MD_SHA1, 0); + if (err != GPG_ERR_NO_ERROR) + return GC_INVALID_HASH; + + gcry_md_write (hd, in, inlen); + + p = gcry_md_read (hd, GCRY_MD_SHA1); + if (p == NULL) + { + gcry_md_close (hd); + return GC_INVALID_HASH; + } + + memcpy (resbuf, p, outlen); + + gcry_md_close (hd); + + return GC_OK; +} +#endif + +#ifdef GC_USE_HMAC_MD5 +Gc_rc +gc_hmac_md5 (const void *key, size_t keylen, + const void *in, size_t inlen, char *resbuf) +{ + size_t hlen = gcry_md_get_algo_dlen (GCRY_MD_MD5); + gcry_md_hd_t mdh; + unsigned char *hash; + gpg_error_t err; + + assert (hlen == 16); + + err = gcry_md_open (&mdh, GCRY_MD_MD5, GCRY_MD_FLAG_HMAC); + if (err != GPG_ERR_NO_ERROR) + return GC_INVALID_HASH; + + err = gcry_md_setkey (mdh, key, keylen); + if (err != GPG_ERR_NO_ERROR) + { + gcry_md_close (mdh); + return GC_INVALID_HASH; + } + + gcry_md_write (mdh, in, inlen); + + hash = gcry_md_read (mdh, GCRY_MD_MD5); + if (hash == NULL) + { + gcry_md_close (mdh); + return GC_INVALID_HASH; + } + + memcpy (resbuf, hash, hlen); + + gcry_md_close (mdh); + + return GC_OK; +} +#endif + +#ifdef GC_USE_HMAC_SHA1 +Gc_rc +gc_hmac_sha1 (const void *key, size_t keylen, + const void *in, size_t inlen, char *resbuf) +{ + size_t hlen = gcry_md_get_algo_dlen (GCRY_MD_SHA1); + gcry_md_hd_t mdh; + unsigned char *hash; + gpg_error_t err; + + assert (hlen == GC_SHA1_DIGEST_SIZE); + + err = gcry_md_open (&mdh, GCRY_MD_SHA1, GCRY_MD_FLAG_HMAC); + if (err != GPG_ERR_NO_ERROR) + return GC_INVALID_HASH; + + err = gcry_md_setkey (mdh, key, keylen); + if (err != GPG_ERR_NO_ERROR) + { + gcry_md_close (mdh); + return GC_INVALID_HASH; + } + + gcry_md_write (mdh, in, inlen); + + hash = gcry_md_read (mdh, GCRY_MD_SHA1); + if (hash == NULL) + { + gcry_md_close (mdh); + return GC_INVALID_HASH; + } + + memcpy (resbuf, hash, hlen); + + gcry_md_close (mdh); + + return GC_OK; +} +#endif diff --git a/lgl/gc-pbkdf2-sha1.c b/lgl/gc-pbkdf2-sha1.c new file mode 100644 index 0000000000..89a1bfd169 --- /dev/null +++ b/lgl/gc-pbkdf2-sha1.c @@ -0,0 +1,188 @@ +/* gc-pbkdf2-sha1.c --- Password-Based Key Derivation Function a'la PKCS#5 + Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +/* Written by Simon Josefsson. The comments in this file are taken + from RFC 2898. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include "gc.h" + +#include <stdlib.h> +#include <string.h> + +/* + * 5.2 PBKDF2 + * + * PBKDF2 applies a pseudorandom function (see Appendix B.1 for an + * example) to derive keys. The length of the derived key is essentially + * unbounded. (However, the maximum effective search space for the + * derived key may be limited by the structure of the underlying + * pseudorandom function. See Appendix B.1 for further discussion.) + * PBKDF2 is recommended for new applications. + * + * PBKDF2 (P, S, c, dkLen) + * + * Options: PRF underlying pseudorandom function (hLen + * denotes the length in octets of the + * pseudorandom function output) + * + * Input: P password, an octet string (ASCII or UTF-8) + * S salt, an octet string + * c iteration count, a positive integer + * dkLen intended length in octets of the derived + * key, a positive integer, at most + * (2^32 - 1) * hLen + * + * Output: DK derived key, a dkLen-octet string + */ + +Gc_rc +gc_pbkdf2_sha1 (const char *P, size_t Plen, + const char *S, size_t Slen, + unsigned int c, + char *DK, size_t dkLen) +{ + unsigned int hLen = 20; + char U[20]; + char T[20]; + unsigned int u; + unsigned int l; + unsigned int r; + unsigned int i; + unsigned int k; + int rc; + char *tmp; + size_t tmplen = Slen + 4; + + if (c == 0) + return GC_PKCS5_INVALID_ITERATION_COUNT; + + if (dkLen == 0) + return GC_PKCS5_INVALID_DERIVED_KEY_LENGTH; + + /* + * + * Steps: + * + * 1. If dkLen > (2^32 - 1) * hLen, output "derived key too long" and + * stop. + */ + + if (dkLen > 4294967295U) + return GC_PKCS5_DERIVED_KEY_TOO_LONG; + + /* + * 2. Let l be the number of hLen-octet blocks in the derived key, + * rounding up, and let r be the number of octets in the last + * block: + * + * l = CEIL (dkLen / hLen) , + * r = dkLen - (l - 1) * hLen . + * + * Here, CEIL (x) is the "ceiling" function, i.e. the smallest + * integer greater than, or equal to, x. + */ + + l = ((dkLen - 1) / hLen) + 1; + r = dkLen - (l - 1) * hLen; + + /* + * 3. For each block of the derived key apply the function F defined + * below to the password P, the salt S, the iteration count c, and + * the block index to compute the block: + * + * T_1 = F (P, S, c, 1) , + * T_2 = F (P, S, c, 2) , + * ... + * T_l = F (P, S, c, l) , + * + * where the function F is defined as the exclusive-or sum of the + * first c iterates of the underlying pseudorandom function PRF + * applied to the password P and the concatenation of the salt S + * and the block index i: + * + * F (P, S, c, i) = U_1 \xor U_2 \xor ... \xor U_c + * + * where + * + * U_1 = PRF (P, S || INT (i)) , + * U_2 = PRF (P, U_1) , + * ... + * U_c = PRF (P, U_{c-1}) . + * + * Here, INT (i) is a four-octet encoding of the integer i, most + * significant octet first. + * + * 4. Concatenate the blocks and extract the first dkLen octets to + * produce a derived key DK: + * + * DK = T_1 || T_2 || ... || T_l<0..r-1> + * + * 5. Output the derived key DK. + * + * Note. The construction of the function F follows a "belt-and- + * suspenders" approach. The iterates U_i are computed recursively to + * remove a degree of parallelism from an opponent; they are exclusive- + * ored together to reduce concerns about the recursion degenerating + * into a small set of values. + * + */ + + tmp = malloc (tmplen); + if (tmp == NULL) + return GC_MALLOC_ERROR; + + memcpy (tmp, S, Slen); + + for (i = 1; i <= l; i++) + { + memset (T, 0, hLen); + + for (u = 1; u <= c; u++) + { + if (u == 1) + { + tmp[Slen + 0] = (i & 0xff000000) >> 24; + tmp[Slen + 1] = (i & 0x00ff0000) >> 16; + tmp[Slen + 2] = (i & 0x0000ff00) >> 8; + tmp[Slen + 3] = (i & 0x000000ff) >> 0; + + rc = gc_hmac_sha1 (P, Plen, tmp, tmplen, U); + } + else + rc = gc_hmac_sha1 (P, Plen, U, hLen, U); + + if (rc != GC_OK) + { + free (tmp); + return rc; + } + + for (k = 0; k < hLen; k++) + T[k] ^= U[k]; + } + + memcpy (DK + (i - 1) * hLen, T, i == l ? r : hLen); + } + + free (tmp); + + return GC_OK; +} diff --git a/lgl/gc.h b/lgl/gc.h new file mode 100644 index 0000000000..f30bc29209 --- /dev/null +++ b/lgl/gc.h @@ -0,0 +1,307 @@ +/* gc.h --- Header file for implementation agnostic crypto wrapper API. + * Copyright (C) 2002, 2003, 2004, 2005 Simon Josefsson + * + * This file is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation; either version 2.1, or (at your + * option) any later version. + * + * This file is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this file; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + * + */ + +#ifndef GC_H +# define GC_H + +/* Get size_t. */ +# include <stddef.h> + +enum Gc_rc +{ + GC_OK = 0, + GC_MALLOC_ERROR, + GC_INIT_ERROR, + GC_RANDOM_ERROR, + GC_INVALID_CIPHER, + GC_INVALID_HASH, + GC_PKCS5_INVALID_ITERATION_COUNT, + GC_PKCS5_INVALID_DERIVED_KEY_LENGTH, + GC_PKCS5_DERIVED_KEY_TOO_LONG +}; +typedef enum Gc_rc Gc_rc; + +/* Hash types. */ +enum Gc_hash +{ + GC_MD4, + GC_MD5, + GC_SHA1, + GC_MD2, + GC_RMD160 +}; +typedef enum Gc_hash Gc_hash; + +enum Gc_hash_mode +{ + GC_HMAC = 1 +}; +typedef enum Gc_hash_mode Gc_hash_mode; + +typedef void *gc_hash_handle; + +#define GC_MD2_DIGEST_SIZE 16 +#define GC_MD4_DIGEST_SIZE 16 +#define GC_MD5_DIGEST_SIZE 16 +#define GC_RMD160_DIGEST_SIZE 20 +#define GC_SHA1_DIGEST_SIZE 20 + +/* Cipher types. */ +enum Gc_cipher +{ + GC_AES128, + GC_AES192, + GC_AES256, + GC_3DES, + GC_DES, + GC_ARCFOUR128, + GC_ARCFOUR40, + GC_ARCTWO40 +}; +typedef enum Gc_cipher Gc_cipher; + +enum Gc_cipher_mode +{ + GC_ECB, + GC_CBC, + GC_STREAM +}; +typedef enum Gc_cipher_mode Gc_cipher_mode; + +typedef void *gc_cipher_handle; + +/* Call before respectively after any other functions. */ +extern Gc_rc gc_init (void); +extern void gc_done (void); + +/* Memory allocation (avoid). */ +typedef void *(*gc_malloc_t) (size_t n); +typedef int (*gc_secure_check_t) (const void *); +typedef void *(*gc_realloc_t) (void *p, size_t n); +typedef void (*gc_free_t) (void *); +extern void gc_set_allocators (gc_malloc_t func_malloc, + gc_malloc_t secure_malloc, + gc_secure_check_t secure_check, + gc_realloc_t func_realloc, + gc_free_t func_free); + +/* Randomness. */ +extern Gc_rc gc_nonce (char *data, size_t datalen); +extern Gc_rc gc_pseudo_random (char *data, size_t datalen); +extern Gc_rc gc_random (char *data, size_t datalen); + +/* Ciphers. */ +extern Gc_rc gc_cipher_open (Gc_cipher cipher, Gc_cipher_mode mode, + gc_cipher_handle *outhandle); +extern Gc_rc gc_cipher_setkey (gc_cipher_handle handle, + size_t keylen, const char *key); +extern Gc_rc gc_cipher_setiv (gc_cipher_handle handle, + size_t ivlen, const char *iv); +extern Gc_rc gc_cipher_encrypt_inline (gc_cipher_handle handle, + size_t len, char *data); +extern Gc_rc gc_cipher_decrypt_inline (gc_cipher_handle handle, + size_t len, char *data); +extern Gc_rc gc_cipher_close (gc_cipher_handle handle); + +/* Hashes. */ + +extern Gc_rc gc_hash_open (Gc_hash hash, Gc_hash_mode mode, + gc_hash_handle *outhandle); +extern Gc_rc gc_hash_clone (gc_hash_handle handle, gc_hash_handle *outhandle); +extern size_t gc_hash_digest_length (Gc_hash hash); +extern void gc_hash_hmac_setkey (gc_hash_handle handle, + size_t len, const char *key); +extern void gc_hash_write (gc_hash_handle handle, + size_t len, const char *data); +extern const char *gc_hash_read (gc_hash_handle handle); +extern void gc_hash_close (gc_hash_handle handle); + +/* Compute a hash value over buffer IN of INLEN bytes size using the + algorithm HASH, placing the result in the pre-allocated buffer OUT. + The required size of OUT depends on HASH, and is generally + GC_<HASH>_DIGEST_SIZE. For example, for GC_MD5 the output buffer + must be 16 bytes. The return value is 0 (GC_OK) on success, or + another Gc_rc error code. */ +extern Gc_rc +gc_hash_buffer (Gc_hash hash, const void *in, size_t inlen, char *out); + +/* One-call interface. */ +extern Gc_rc gc_md2 (const void *in, size_t inlen, void *resbuf); +extern Gc_rc gc_md4 (const void *in, size_t inlen, void *resbuf); +extern Gc_rc gc_md5 (const void *in, size_t inlen, void *resbuf); +extern Gc_rc gc_sha1 (const void *in, size_t inlen, void *resbuf); +extern Gc_rc gc_hmac_md5 (const void *key, size_t keylen, + const void *in, size_t inlen, char *resbuf); +extern Gc_rc gc_hmac_sha1 (const void *key, size_t keylen, + const void *in, size_t inlen, char *resbuf); + +/* Derive cryptographic keys from a password P of length PLEN, with + salt S of length SLEN, placing the result in pre-allocated buffer + DK of length DKLEN. An iteration count is specified in C, where a + larger value means this function take more time (typical iteration + counts are 1000-20000). This function "stretches" the key to be + exactly dkLen bytes long. GC_OK is returned on success, otherwise + an Gc_rc error code is returned. */ +extern Gc_rc +gc_pbkdf2_sha1 (const char *P, size_t Plen, + const char *S, size_t Slen, + unsigned int c, char *DK, size_t dkLen); + +/* + TODO: + + From: Simon Josefsson <jas@extundo.com> + Subject: Re: generic crypto + Newsgroups: gmane.comp.lib.gnulib.bugs + Cc: bug-gnulib@gnu.org + Date: Fri, 07 Oct 2005 12:50:57 +0200 + Mail-Copies-To: nobody + + Paul Eggert <eggert@CS.UCLA.EDU> writes: + + > Simon Josefsson <jas@extundo.com> writes: + > + >> * Perhaps the /dev/?random reading should be separated into a separate + >> module? It might be useful outside of the gc layer too. + > + > Absolutely. I've been meaning to do that for months (for a "shuffle" + > program I want to add to coreutils), but hadn't gotten around to it. + > It would have to be generalized a bit. I'd like to have the file + > descriptor cached, for example. + + I'll write a separate module for that part. + + I think we should even add a good PRNG that is re-seeded from + /dev/?random frequently. GnuTLS can need a lot of random data on a + big server, more than /dev/random can supply. And /dev/urandom might + not be strong enough. Further, the security of /dev/?random can also + be questionable. + + >> I'm also not sure about the names of those functions, they suggest + >> a more higher-level API than what is really offered (i.e., the + >> names "nonce" and "pseudo_random" and "random" imply certain + >> cryptographic properties). + > + > Could you expand a bit more on that? What is the relationship between + > nonce/pseudorandom/random and the /dev/ values you are using? + + There is none, that is the problem. + + Applications generally need different kind of "random" numbers. + Sometimes they just need some random data and doesn't care whether it + is possible for an attacker to compute the string (aka a "nonce"). + Sometimes they need data that is very difficult to compute (i.e., + computing it require inverting SHA1 or similar). Sometimes they need + data that is not possible to compute, i.e., it wants real entropy + collected over time on the system. Collecting the last kind of random + data is very expensive, so it must not be used too often. The second + kind of random data ("pseudo random") is typically generated by + seeding a good PRNG with a couple of hundred bytes of real entropy + from the "real random" data pool. The "nonce" is usually computed + using the PRNG as well, because PRNGs are usually fast. + + Pseudo-random data is typically used for session keys. Strong random + data is often used to generate long-term keys (e.g., private RSA + keys). + + Of course, there are many subtleties. There are several different + kind of nonce:s. Sometimes a nonce is just an ever-increasing + integer, starting from 0. Sometimes it is assumed to be unlikely to + be the same as previous nonces, but without a requirement that the + nonce is possible to guess. MD5(system clock) would thus suffice, if + it isn't called too often. You can guess what the next value will be, + but it will always be different. + + The problem is that /dev/?random doesn't offer any kind of semantic + guarantees. But applications need an API that make that promise. + + I think we should do this in several steps: + + 1) Write a module that can read from /dev/?random. + + 2) Add a module for a known-good PRNG suitable for random number + generation, that can be continuously re-seeded. + + 3) Add a high-level module that provide various different randomness + functions. One for nonces, perhaps even different kind of nonces, + one for pseudo random data, and one for strong random data. It is + not clear whether we can hope to achieve the last one in a portable + way. + + Further, it would be useful to allow users to provide their own + entropy source as a file, used to seed the PRNG or initialize the + strong randomness pool. This is used on embedded platforms that + doesn't have enough interrupts to hope to generate good random data. + + > For example, why not use OpenBSD's /dev/arandom? + + I don't trust ARC4. For example, recent cryptographic efforts + indicate that you must throw away the first 512 bytes generated from + the PRNG for it to be secure. I don't know whether OpenBSD do this. + Further, I recall some eprint paper on RC4 security that didn't + inspire confidence. + + While I trust the random devices in OpenBSD more than + Solaris/AIX/HPUX/etc, I think that since we need something better on + Solaris/AIX/HPUX we'd might as well use it on OpenBSD or even Linux + too. + + > Here is one thought. The user could specify a desired quality level + > range, and the implementation then would supply random data that is at + > least as good as the lower bound of the range. I.e., ihe + > implementation refuses to produce any random data if it can't generate + > data that is at least as good as the lower end of the range. The + > upper bound of the range is advice from the user not to be any more + > expensive than that, but the implementation can ignore the advice if + > it doesn't have anything cheaper. + + I'm not sure this is a good idea. Users can't really be expected to + understand this. Further, applications need many different kind of + random data. Selecting the randomness level for each by the user will + be too complicated. + + I think it is better if the application decide, from its cryptographic + requirement, what entropy quality it require, and call the proper API. + Meeting the implied semantic properties should be the job for gnulib. + + >> Perhaps gc_dev_random and gc_dev_urandom? + > + > To some extent. I'd rather insulate the user from the details of + > where the random numbers come from. On the other hand we need to + > provide a way for applications to specify a file that contains + > random bits, so that people can override the defaults. + + Agreed. + + This may require some thinking before it is finalized. Is it ok to + install the GC module as-is meanwhile? Then I can continue to add the + stuff that GnuTLS need, and then come back to re-working the + randomness module. That way, we have two different projects that use + the code. GnuTLS includes the same randomness code that was in GNU + SASL and that is in the current gc module. I feel much more + comfortable working in small steps at a time, rather then working on + this for a long time in gnulib and only later integrate the stuff in + GnuTLS. + + Thanks, + Simon + */ + +#endif /* GC_H */ diff --git a/lgl/hmac-md5.c b/lgl/hmac-md5.c new file mode 100644 index 0000000000..2c70a129eb --- /dev/null +++ b/lgl/hmac-md5.c @@ -0,0 +1,83 @@ +/* hmac-md5.c -- hashed message authentication codes + Copyright (C) 2005 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +/* Written by Simon Josefsson. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include "hmac.h" + +#include "memxor.h" +#include "md5.h" + +#include <string.h> + +#define IPAD 0x36 +#define OPAD 0x5c + +int +hmac_md5 (const void *key, size_t keylen, + const void *in, size_t inlen, void *resbuf) +{ + struct md5_ctx inner; + struct md5_ctx outer; + char optkeybuf[16]; + char block[64]; + char innerhash[16]; + + /* Reduce the key's size, so that it becomes <= 64 bytes large. */ + + if (keylen > 64) + { + struct md5_ctx keyhash; + + md5_init_ctx (&keyhash); + md5_process_bytes (key, keylen, &keyhash); + md5_finish_ctx (&keyhash, optkeybuf); + + key = optkeybuf; + keylen = 16; + } + + /* Compute INNERHASH from KEY and IN. */ + + md5_init_ctx (&inner); + + memset (block, IPAD, sizeof (block)); + memxor (block, key, keylen); + + md5_process_block (block, 64, &inner); + md5_process_bytes (in, inlen, &inner); + + md5_finish_ctx (&inner, innerhash); + + /* Compute result from KEY and INNERHASH. */ + + md5_init_ctx (&outer); + + memset (block, OPAD, sizeof (block)); + memxor (block, key, keylen); + + md5_process_block (block, 64, &outer); + md5_process_bytes (innerhash, 16, &outer); + + md5_finish_ctx (&outer, resbuf); + + return 0; +} diff --git a/lgl/hmac-sha1.c b/lgl/hmac-sha1.c new file mode 100644 index 0000000000..7a78868ef0 --- /dev/null +++ b/lgl/hmac-sha1.c @@ -0,0 +1,83 @@ +/* hmac-sha1.c -- hashed message authentication codes + Copyright (C) 2005 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +/* Written by Simon Josefsson. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include "hmac.h" + +#include "memxor.h" +#include "sha1.h" + +#include <string.h> + +#define IPAD 0x36 +#define OPAD 0x5c + +int +hmac_sha1 (const void *key, size_t keylen, + const void *in, size_t inlen, void *resbuf) +{ + struct sha1_ctx inner; + struct sha1_ctx outer; + char optkeybuf[20]; + char block[64]; + char innerhash[20]; + + /* Reduce the key's size, so that it becomes <= 64 bytes large. */ + + if (keylen > 64) + { + struct sha1_ctx keyhash; + + sha1_init_ctx (&keyhash); + sha1_process_bytes (key, keylen, &keyhash); + sha1_finish_ctx (&keyhash, optkeybuf); + + key = optkeybuf; + keylen = 20; + } + + /* Compute INNERHASH from KEY and IN. */ + + sha1_init_ctx (&inner); + + memset (block, IPAD, sizeof (block)); + memxor (block, key, keylen); + + sha1_process_block (block, 64, &inner); + sha1_process_bytes (in, inlen, &inner); + + sha1_finish_ctx (&inner, innerhash); + + /* Compute result from KEY and INNERHASH. */ + + sha1_init_ctx (&outer); + + memset (block, OPAD, sizeof (block)); + memxor (block, key, keylen); + + sha1_process_block (block, 64, &outer); + sha1_process_bytes (innerhash, 20, &outer); + + sha1_finish_ctx (&outer, resbuf); + + return 0; +} diff --git a/lgl/hmac.h b/lgl/hmac.h new file mode 100644 index 0000000000..5965b60326 --- /dev/null +++ b/lgl/hmac.h @@ -0,0 +1,41 @@ +/* hmac.h -- hashed message authentication codes + Copyright (C) 2005 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +/* Written by Simon Josefsson. */ + +#ifndef HMAC_H +# define HMAC_H 1 + +#include <stddef.h> + +/* Compute Hashed Message Authentication Code with MD5, as described + in RFC 2104, over BUFFER data of BUFLEN bytes using the KEY of + KEYLEN bytes, writing the output to pre-allocated 16 byte minimum + RESBUF buffer. Return 0 on success. */ +int +hmac_md5 (const void *key, size_t keylen, + const void *buffer, size_t buflen, void *resbuf); + +/* Compute Hashed Message Authentication Code with SHA-1, over BUFFER + data of BUFLEN bytes using the KEY of KEYLEN bytes, writing the + output to pre-allocated 20 byte minimum RESBUF buffer. Return 0 on + success. */ +int +hmac_sha1 (const void *key, size_t keylen, + const void *in, size_t inlen, void *resbuf); + +#endif /* HMAC_H */ diff --git a/lgl/m4/absolute-header.m4 b/lgl/m4/absolute-header.m4 new file mode 100644 index 0000000000..c649df0840 --- /dev/null +++ b/lgl/m4/absolute-header.m4 @@ -0,0 +1,44 @@ +# absolute-header.m4 serial 6 +dnl Copyright (C) 2006 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +dnl From Derek Price. + +# gl_ABSOLUTE_HEADER(HEADER1 HEADER2 ...) +# --------------------------------------- +# Find the absolute name of a header file, assuming the header exists. +# If the header were sys/inttypes.h, this macro would define +# ABSOLUTE_SYS_INTTYPES_H to the `""' quoted absolute name of sys/inttypes.h +# in config.h +# (e.g. `#define ABSOLUTE_SYS_INTTYPES_H "///usr/include/sys/inttypes.h"'). +# The three "///" are to pacify Sun C 5.8, which otherwise would say +# "warning: #include of /usr/include/... may be non-portable". +# Use `""', not `<>', so that the /// cannot be confused with a C99 comment. +AC_DEFUN([gl_ABSOLUTE_HEADER], +[AC_LANG_PREPROC_REQUIRE()dnl +AC_FOREACH([gl_HEADER_NAME], [$1], + [AS_VAR_PUSHDEF([gl_absolute_header], + [gl_cv_absolute_]m4_quote(m4_defn([gl_HEADER_NAME])))dnl + AC_CACHE_CHECK([absolute name of <]m4_quote(m4_defn([gl_HEADER_NAME]))[>], + m4_quote(m4_defn([gl_absolute_header])), + [AS_VAR_PUSHDEF([ac_header_exists], + [ac_cv_header_]m4_quote(m4_defn([gl_HEADER_NAME])))dnl + AC_CHECK_HEADERS_ONCE(m4_quote(m4_defn([gl_HEADER_NAME])))dnl + if test AS_VAR_GET(ac_header_exists) = yes; then + AC_LANG_CONFTEST([AC_LANG_SOURCE([[#include <]]m4_dquote(m4_defn([gl_HEADER_NAME]))[[>]])]) +dnl eval is necessary to expand ac_cpp. +dnl Ultrix and Pyramid sh refuse to redirect output of eval, so use subshell. + AS_VAR_SET(gl_absolute_header, +[`(eval "$ac_cpp conftest.$ac_ext") 2>&AS_MESSAGE_LOG_FD | +sed -n '\#/]m4_quote(m4_defn([gl_HEADER_NAME]))[#{s#.*"\(.*/]m4_quote(m4_defn([gl_HEADER_NAME]))[\)".*#\1#;s#^/[^/]#//&#;p;q;}'`]) + fi + AS_VAR_POPDEF([ac_header_exists])dnl + ])dnl + AC_DEFINE_UNQUOTED(AS_TR_CPP([ABSOLUTE_]m4_quote(m4_defn([gl_HEADER_NAME]))), + ["AS_VAR_GET(gl_absolute_header)"], + [Define this to an absolute name of <]m4_quote(m4_defn([gl_HEADER_NAME]))[>.]) + AS_VAR_POPDEF([gl_absolute_header])dnl +])dnl +])# gl_ABSOLUTE_HEADER diff --git a/lgl/m4/arcfour.m4 b/lgl/m4/arcfour.m4 new file mode 100644 index 0000000000..905251a777 --- /dev/null +++ b/lgl/m4/arcfour.m4 @@ -0,0 +1,10 @@ +# arcfour.m4 serial 2 +dnl Copyright (C) 2005, 2006 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +AC_DEFUN([gl_ARCFOUR], +[ + AC_LIBOBJ([arcfour]) +]) diff --git a/lgl/m4/arctwo.m4 b/lgl/m4/arctwo.m4 new file mode 100644 index 0000000000..7ea189f899 --- /dev/null +++ b/lgl/m4/arctwo.m4 @@ -0,0 +1,12 @@ +# arctwo.m4 serial 2 +dnl Copyright (C) 2005, 2006 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +AC_DEFUN([gl_ARCTWO], +[ + AC_LIBOBJ([arctwo]) + # Prerequisites of lib/arctwo.c. + AC_REQUIRE([AC_C_INLINE]) +]) diff --git a/lgl/m4/des.m4 b/lgl/m4/des.m4 new file mode 100644 index 0000000000..dc71132e33 --- /dev/null +++ b/lgl/m4/des.m4 @@ -0,0 +1,10 @@ +# des.m4 serial 2 +dnl Copyright (C) 2005, 2006 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +AC_DEFUN([gl_DES], +[ + AC_LIBOBJ([des]) +]) diff --git a/lgl/m4/gc-arcfour.m4 b/lgl/m4/gc-arcfour.m4 new file mode 100644 index 0000000000..c5adf583af --- /dev/null +++ b/lgl/m4/gc-arcfour.m4 @@ -0,0 +1,15 @@ +# gc-arcfour.m4 serial 1 +dnl Copyright (C) 2005 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +AC_DEFUN([gl_GC_ARCFOUR], +[ + AC_REQUIRE([gl_GC]) + AC_DEFINE(GC_USE_ARCFOUR, 1, + [Define if you want to support ARCFOUR through GC.]) + if test "$ac_cv_libgcrypt" != yes; then + gl_ARCFOUR + fi +]) diff --git a/lgl/m4/gc-arctwo.m4 b/lgl/m4/gc-arctwo.m4 new file mode 100644 index 0000000000..173a87a45f --- /dev/null +++ b/lgl/m4/gc-arctwo.m4 @@ -0,0 +1,15 @@ +# gc-arctwo.m4 serial 1 +dnl Copyright (C) 2005 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +AC_DEFUN([gl_GC_ARCTWO], +[ + AC_REQUIRE([gl_GC]) + AC_DEFINE(GC_USE_ARCTWO, 1, + [Define if you want to support ARCTWO through GC.]) + if test "$ac_cv_libgcrypt" != yes; then + gl_ARCTWO + fi +]) diff --git a/lgl/m4/gc-des.m4 b/lgl/m4/gc-des.m4 new file mode 100644 index 0000000000..d4dd971708 --- /dev/null +++ b/lgl/m4/gc-des.m4 @@ -0,0 +1,14 @@ +# gc-des.m4 serial 1 +dnl Copyright (C) 2005 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +AC_DEFUN([gl_GC_DES], +[ + AC_REQUIRE([gl_GC]) + AC_DEFINE(GC_USE_DES, 1, [Define if you want to support DES through GC.]) + if test "$ac_cv_libgcrypt" != yes; then + gl_DES + fi +]) diff --git a/lgl/m4/gc-hmac-md5.m4 b/lgl/m4/gc-hmac-md5.m4 new file mode 100644 index 0000000000..26d79e944f --- /dev/null +++ b/lgl/m4/gc-hmac-md5.m4 @@ -0,0 +1,17 @@ +# gc-hmac-md5.m4 serial 1 +dnl Copyright (C) 2005 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +AC_DEFUN([gl_GC_HMAC_MD5], +[ + AC_REQUIRE([gl_GC]) + AC_DEFINE(GC_USE_HMAC_MD5, 1, + [Define if you want to support HMAC-MD5 through GC.]) + if test "$ac_cv_libgcrypt" != yes; then + gl_MD5 + gl_HMAC_MD5 + gl_MEMXOR + fi +]) diff --git a/lgl/m4/gc-hmac-sha1.m4 b/lgl/m4/gc-hmac-sha1.m4 new file mode 100644 index 0000000000..c18dd21781 --- /dev/null +++ b/lgl/m4/gc-hmac-sha1.m4 @@ -0,0 +1,17 @@ +# gc-hmac-sha1.m4 serial 1 +dnl Copyright (C) 2005 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +AC_DEFUN([gl_GC_HMAC_SHA1], +[ + AC_REQUIRE([gl_GC]) + AC_DEFINE(GC_USE_HMAC_SHA1, 1, + [Define if you want to support HMAC-SHA1 through GC.]) + if test "$ac_cv_libgcrypt" != yes; then + gl_SHA1 + gl_HMAC_SHA1 + gl_MEMXOR + fi +]) diff --git a/lgl/m4/gc-md2.m4 b/lgl/m4/gc-md2.m4 new file mode 100644 index 0000000000..5a5909d9fe --- /dev/null +++ b/lgl/m4/gc-md2.m4 @@ -0,0 +1,10 @@ +# gc-md2.m4 serial 1 +dnl Copyright (C) 2005 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +AC_DEFUN([gl_GC_MD2], +[ + AC_DEFINE(GC_USE_MD2, 1, [Define if you want to support MD2 through GC.]) +]) diff --git a/lgl/m4/gc-md4.m4 b/lgl/m4/gc-md4.m4 new file mode 100644 index 0000000000..e61f27c9fb --- /dev/null +++ b/lgl/m4/gc-md4.m4 @@ -0,0 +1,14 @@ +# gc-md4.m4 serial 1 +dnl Copyright (C) 2005 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +AC_DEFUN([gl_GC_MD4], +[ + AC_REQUIRE([gl_GC]) + AC_DEFINE(GC_USE_MD4, 1, [Define if you want to support MD4 through GC.]) + if test "$ac_cv_libgcrypt" != yes; then + gl_MD4 + fi +]) diff --git a/lgl/m4/gc-md5.m4 b/lgl/m4/gc-md5.m4 new file mode 100644 index 0000000000..dbb0d3bc5d --- /dev/null +++ b/lgl/m4/gc-md5.m4 @@ -0,0 +1,14 @@ +# gc-md5.m4 serial 1 +dnl Copyright (C) 2005 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +AC_DEFUN([gl_GC_MD5], +[ + AC_REQUIRE([gl_GC]) + AC_DEFINE(GC_USE_MD5, 1, [Define if you want to support MD5 through GC.]) + if test "$ac_cv_libgcrypt" != yes; then + gl_MD5 + fi +]) diff --git a/lgl/m4/gc-pbkdf2-sha1.m4 b/lgl/m4/gc-pbkdf2-sha1.m4 new file mode 100644 index 0000000000..05fc881c29 --- /dev/null +++ b/lgl/m4/gc-pbkdf2-sha1.m4 @@ -0,0 +1,10 @@ +# gc-pbkdf2-sha1.m4 serial 2 +dnl Copyright (C) 2005, 2006 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +AC_DEFUN([gl_GC_PBKDF2_SHA1], +[ + AC_LIBOBJ([gc-pbkdf2-sha1]) +]) diff --git a/lgl/m4/gc-random.m4 b/lgl/m4/gc-random.m4 new file mode 100644 index 0000000000..40e047106a --- /dev/null +++ b/lgl/m4/gc-random.m4 @@ -0,0 +1,89 @@ +# gc-random.m4 serial 1 +dnl Copyright (C) 2005, 2006 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +AC_DEFUN([gl_GC_RANDOM], +[ + # Devices with randomness. + # FIXME: Are these the best defaults? + + AC_REQUIRE([AC_CANONICAL_HOST])dnl + + case "$host_os" in + *openbsd*) + NAME_OF_RANDOM_DEVICE="/dev/srandom" + NAME_OF_PSEUDO_RANDOM_DEVICE="/dev/prandom" + NAME_OF_NONCE_DEVICE="/dev/urandom" + ;; + + *netbsd*) + NAME_OF_RANDOM_DEVICE="/dev/srandom" + NAME_OF_PSEUDO_RANDOM_DEVICE="/dev/urandom" + NAME_OF_NONCE_DEVICE="/dev/urandom" + ;; + + *solaris* | *irix* | *dec-osf* ) + NAME_OF_RANDOM_DEVICE="/dev/random" + NAME_OF_PSEUDO_RANDOM_DEVICE="/dev/random" + NAME_OF_NONCE_DEVICE="/dev/random" + ;; + + *) + NAME_OF_RANDOM_DEVICE="/dev/random" + NAME_OF_PSEUDO_RANDOM_DEVICE="/dev/urandom" + NAME_OF_NONCE_DEVICE="/dev/urandom" + ;; + esac + + AC_MSG_CHECKING([device with (strong) random data...]) + AC_ARG_ENABLE(random-device, + AC_HELP_STRING([--enable-random-device], + [device with (strong) randomness (for Nettle)]), + NAME_OF_RANDOM_DEVICE=$enableval) + AC_MSG_RESULT($NAME_OF_RANDOM_DEVICE) + + AC_MSG_CHECKING([device with pseudo random data...]) + AC_ARG_ENABLE(pseudo-random-device, + AC_HELP_STRING([--enable-pseudo-random-device], + [device with pseudo randomness (for Nettle)]), + NAME_OF_PSEUDO_RANDOM_DEVICE=$enableval) + AC_MSG_RESULT($NAME_OF_PSEUDO_RANDOM_DEVICE) + + AC_MSG_CHECKING([device with unpredictable data for nonces...]) + AC_ARG_ENABLE(nonce-device, + AC_HELP_STRING([--enable-nonce-device], + [device with unpredictable nonces (for Nettle)]), + NAME_OF_NONCE_DEVICE=$enableval) + AC_MSG_RESULT($NAME_OF_NONCE_DEVICE) + + if test "$cross_compiling" != yes; then + if test "$NAME_OF_RANDOM_DEVICE" != "no"; then + AC_CHECK_FILE($NAME_OF_RANDOM_DEVICE,, + AC_MSG_WARN([[Device `$NAME_OF_RANDOM_DEVICE' does not exist, consider to use --enable-random-device]])) + fi + if test "$NAME_OF_PSEUDO_RANDOM_DEVICE" != "no"; then + AC_CHECK_FILE($NAME_OF_PSEUDO_RANDOM_DEVICE,, + AC_MSG_WARN([[Device `$NAME_OF_PSEUDO_RANDOM_DEVICE' does not exist, consider to use --enable-pseudo-random-device]])) + fi + if test "$NAME_OF_NONCE_DEVICE" != "no"; then + AC_CHECK_FILE($NAME_OF_NONCE_DEVICE,, + AC_MSG_WARN([[Device `$NAME_OF_NONCE_DEVICE' does not exist, consider to use --enable-nonce-device]])) + fi + else + AC_MSG_NOTICE([[Cross compiling, assuming random devices exists on the target host...]]) + fi + + # FIXME?: Open+read 42 bytes+close twice and compare data. Should differ. + + AC_DEFINE_UNQUOTED(NAME_OF_RANDOM_DEVICE, "$NAME_OF_RANDOM_DEVICE", + [defined to the name of the (strong) random device]) + AC_DEFINE_UNQUOTED(NAME_OF_PSEUDO_RANDOM_DEVICE, + "$NAME_OF_PSEUDO_RANDOM_DEVICE", + [defined to the name of the pseudo random device]) + AC_DEFINE_UNQUOTED(NAME_OF_NONCE_DEVICE, "$NAME_OF_NONCE_DEVICE", + [defined to the name of the unpredictable nonce device]) + + AC_DEFINE(GC_USE_RANDOM, 1, [Define if you want to support RNG through GC.]) +]) diff --git a/lgl/m4/gc-rijndael.m4 b/lgl/m4/gc-rijndael.m4 new file mode 100644 index 0000000000..ab324634bc --- /dev/null +++ b/lgl/m4/gc-rijndael.m4 @@ -0,0 +1,15 @@ +# gc-rijndael.m4 serial 1 +dnl Copyright (C) 2005 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +AC_DEFUN([gl_GC_RIJNDAEL], +[ + AC_REQUIRE([gl_GC]) + AC_DEFINE(GC_USE_RIJNDAEL, 1, + [Define if you want to support RIJNDAEL through GC.]) + if test "$ac_cv_libgcrypt" != yes; then + gl_RIJNDAEL + fi +]) diff --git a/lgl/m4/gc-sha1.m4 b/lgl/m4/gc-sha1.m4 new file mode 100644 index 0000000000..88010e22a4 --- /dev/null +++ b/lgl/m4/gc-sha1.m4 @@ -0,0 +1,15 @@ +# gc-sha1.m4 serial 1 +dnl Copyright (C) 2005 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +AC_DEFUN([gl_GC_SHA1], +[ + AC_REQUIRE([gl_GC]) + AC_DEFINE(GC_USE_SHA1, 1, + [Define if you want to support SHA-1 through GC.]) + if test "$ac_cv_libgcrypt" != yes; then + gl_SHA1 + fi +]) diff --git a/lgl/m4/gc.m4 b/lgl/m4/gc.m4 new file mode 100644 index 0000000000..1d6b37919c --- /dev/null +++ b/lgl/m4/gc.m4 @@ -0,0 +1,27 @@ +# gc.m4 serial 4 +dnl Copyright (C) 2005, 2006 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +AC_DEFUN([gl_GC], +[ + AC_ARG_WITH(libgcrypt, + AS_HELP_STRING([--with-libgcrypt], [use libgcrypt for low-level crypto]), + libgcrypt=$withval, libgcrypt=no) + if test "$libgcrypt" != no; then + AC_LIB_HAVE_LINKFLAGS([gcrypt], [], [#include <gcrypt.h>]) + fi + if test "$ac_cv_libgcrypt" = yes; then + AC_LIBOBJ([gc-libgcrypt]) + else + AC_LIBOBJ([gc-gnulib]) + fi +]) + +# Prerequisites of lib/gc.h +AC_DEFUN([gl_PREREQ_GC], +[ + AC_REQUIRE([AC_C_RESTRICT]) + : +]) diff --git a/lgl/m4/gnulib-cache.m4 b/lgl/m4/gnulib-cache.m4 index 82fd14f6b9..08eaf80426 100644 --- a/lgl/m4/gnulib-cache.m4 +++ b/lgl/m4/gnulib-cache.m4 @@ -15,11 +15,11 @@ # Specification in the form of a command-line invocation: -# gnulib-tool --import --dir=. --lib=libgnu --source-base=lgl --m4-base=lgl/m4 --doc-base=doc --aux-dir=. --lgpl --libtool --macro-prefix=lgl memmem +# gnulib-tool --import --dir=. --lib=libgnu --source-base=lgl --m4-base=lgl/m4 --doc-base=doc --aux-dir=. --lgpl --libtool --macro-prefix=lgl gc gc-arcfour gc-arctwo gc-des gc-hmac-md5 gc-md2 gc-md4 gc-md5 gc-pbkdf2-sha1 gc-random gc-rijndael gc-sha1 memmem stdint # Specification in the form of a few gnulib-tool.m4 macro invocations: gl_LOCAL_DIR([]) -gl_MODULES([memmem]) +gl_MODULES([gc gc-arcfour gc-arctwo gc-des gc-hmac-md5 gc-md2 gc-md4 gc-md5 gc-pbkdf2-sha1 gc-random gc-rijndael gc-sha1 memmem stdint]) gl_AVOID([]) gl_SOURCE_BASE([lgl]) gl_M4_BASE([lgl/m4]) diff --git a/lgl/m4/gnulib-comp.m4 b/lgl/m4/gnulib-comp.m4 index e0049190c3..652dd36826 100644 --- a/lgl/m4/gnulib-comp.m4 +++ b/lgl/m4/gnulib-comp.m4 @@ -37,7 +37,27 @@ AC_DEFUN([lgl_INIT], AM_CONDITIONAL([GL_COND_LIBTOOL], [true]) gl_cond_libtool=true gl_source_base='lgl' + gl_GC + if test $gl_cond_libtool = false; then + gl_ltlibdeps="$gl_ltlibdeps $LTLIBGCRYPT" + gl_libdeps="$gl_libdeps $LIBGCRYPT" + fi + gl_GC_ARCFOUR + gl_GC_ARCTWO + gl_GC_DES + gl_GC_HMAC_MD5 + gl_GC_HMAC_SHA1 + gl_GC_MD2 + gl_GC_MD4 + gl_GC_MD5 + gl_GC_PBKDF2_SHA1 + gl_GC_RANDOM + gl_GC_RIJNDAEL + gl_GC_SHA1 + gl_MD2 gl_FUNC_MEMMEM + gl_MINMAX + gl_STDINT_H m4_popdef([AC_REPLACE_FUNCS]) m4_popdef([AC_LIBOBJ]) AC_CONFIG_COMMANDS_PRE([ @@ -69,8 +89,70 @@ AC_DEFUN([lgl_REPLACE_FUNCS], # This macro records the list of files which have been installed by # gnulib-tool and may be removed by future gnulib-tool invocations. AC_DEFUN([lgl_FILE_LIST], [ + build-aux/config.rpath + lib/arcfour.c + lib/arcfour.h + lib/arctwo.c + lib/arctwo.h + lib/des.c + lib/des.h lib/dummy.c + lib/gc-gnulib.c + lib/gc-libgcrypt.c + lib/gc-pbkdf2-sha1.c + lib/gc.h + lib/hmac-md5.c + lib/hmac-sha1.c + lib/hmac.h + lib/md2.c + lib/md2.h + lib/md4.c + lib/md4.h + lib/md5.c + lib/md5.h lib/memmem.c lib/memmem.h + lib/memxor.c + lib/memxor.h + lib/minmax.h + lib/rijndael-alg-fst.c + lib/rijndael-alg-fst.h + lib/rijndael-api-fst.c + lib/rijndael-api-fst.h + lib/sha1.c + lib/sha1.h + lib/stdint_.h + m4/absolute-header.m4 + m4/arcfour.m4 + m4/arctwo.m4 + m4/des.m4 + m4/gc-arcfour.m4 + m4/gc-arctwo.m4 + m4/gc-des.m4 + m4/gc-hmac-md5.m4 + m4/gc-hmac-sha1.m4 + m4/gc-md2.m4 + m4/gc-md4.m4 + m4/gc-md5.m4 + m4/gc-pbkdf2-sha1.m4 + m4/gc-random.m4 + m4/gc-rijndael.m4 + m4/gc-sha1.m4 + m4/gc.m4 + m4/hmac-md5.m4 + m4/hmac-sha1.m4 + m4/lib-ld.m4 + m4/lib-link.m4 + m4/lib-prefix.m4 + m4/longlong.m4 + m4/md2.m4 + m4/md4.m4 + m4/md5.m4 m4/memmem.m4 + m4/memxor.m4 + m4/minmax.m4 + m4/rijndael.m4 + m4/sha1.m4 + m4/stdint.m4 + m4/ulonglong.m4 ]) diff --git a/lgl/m4/hmac-md5.m4 b/lgl/m4/hmac-md5.m4 new file mode 100644 index 0000000000..729c6bf827 --- /dev/null +++ b/lgl/m4/hmac-md5.m4 @@ -0,0 +1,10 @@ +# hmac-md5.m4 serial 2 +dnl Copyright (C) 2005, 2006 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +AC_DEFUN([gl_HMAC_MD5], +[ + AC_LIBOBJ([hmac-md5]) +]) diff --git a/lgl/m4/hmac-sha1.m4 b/lgl/m4/hmac-sha1.m4 new file mode 100644 index 0000000000..74c936697d --- /dev/null +++ b/lgl/m4/hmac-sha1.m4 @@ -0,0 +1,10 @@ +# hmac-sha1.m4 serial 2 +dnl Copyright (C) 2005, 2006 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +AC_DEFUN([gl_HMAC_SHA1], +[ + AC_LIBOBJ([hmac-sha1]) +]) diff --git a/lgl/m4/lib-ld.m4 b/lgl/m4/lib-ld.m4 new file mode 100644 index 0000000000..96c4e2c339 --- /dev/null +++ b/lgl/m4/lib-ld.m4 @@ -0,0 +1,110 @@ +# lib-ld.m4 serial 3 (gettext-0.13) +dnl Copyright (C) 1996-2003 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +dnl Subroutines of libtool.m4, +dnl with replacements s/AC_/AC_LIB/ and s/lt_cv/acl_cv/ to avoid collision +dnl with libtool.m4. + +dnl From libtool-1.4. Sets the variable with_gnu_ld to yes or no. +AC_DEFUN([AC_LIB_PROG_LD_GNU], +[AC_CACHE_CHECK([if the linker ($LD) is GNU ld], acl_cv_prog_gnu_ld, +[# I'd rather use --version here, but apparently some GNU ld's only accept -v. +case `$LD -v 2>&1 </dev/null` in +*GNU* | *'with BFD'*) + acl_cv_prog_gnu_ld=yes ;; +*) + acl_cv_prog_gnu_ld=no ;; +esac]) +with_gnu_ld=$acl_cv_prog_gnu_ld +]) + +dnl From libtool-1.4. Sets the variable LD. +AC_DEFUN([AC_LIB_PROG_LD], +[AC_ARG_WITH(gnu-ld, +[ --with-gnu-ld assume the C compiler uses GNU ld [default=no]], +test "$withval" = no || with_gnu_ld=yes, with_gnu_ld=no) +AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([AC_CANONICAL_HOST])dnl +# Prepare PATH_SEPARATOR. +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + echo "#! /bin/sh" >conf$$.sh + echo "exit 0" >>conf$$.sh + chmod +x conf$$.sh + if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then + PATH_SEPARATOR=';' + else + PATH_SEPARATOR=: + fi + rm -f conf$$.sh +fi +ac_prog=ld +if test "$GCC" = yes; then + # Check if gcc -print-prog-name=ld gives a path. + AC_MSG_CHECKING([for ld used by GCC]) + case $host in + *-*-mingw*) + # gcc leaves a trailing carriage return which upsets mingw + ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; + *) + ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; + esac + case $ac_prog in + # Accept absolute paths. + [[\\/]* | [A-Za-z]:[\\/]*)] + [re_direlt='/[^/][^/]*/\.\./'] + # Canonicalize the path of ld + ac_prog=`echo $ac_prog| sed 's%\\\\%/%g'` + while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do + ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"` + done + test -z "$LD" && LD="$ac_prog" + ;; + "") + # If it fails, then pretend we aren't using GCC. + ac_prog=ld + ;; + *) + # If it is relative, then search for the first ld in PATH. + with_gnu_ld=unknown + ;; + esac +elif test "$with_gnu_ld" = yes; then + AC_MSG_CHECKING([for GNU ld]) +else + AC_MSG_CHECKING([for non-GNU ld]) +fi +AC_CACHE_VAL(acl_cv_path_LD, +[if test -z "$LD"; then + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR-:}" + for ac_dir in $PATH; do + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then + acl_cv_path_LD="$ac_dir/$ac_prog" + # Check to see if the program is GNU ld. I'd rather use --version, + # but apparently some GNU ld's only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + case `"$acl_cv_path_LD" -v 2>&1 < /dev/null` in + *GNU* | *'with BFD'*) + test "$with_gnu_ld" != no && break ;; + *) + test "$with_gnu_ld" != yes && break ;; + esac + fi + done + IFS="$ac_save_ifs" +else + acl_cv_path_LD="$LD" # Let the user override the test with a path. +fi]) +LD="$acl_cv_path_LD" +if test -n "$LD"; then + AC_MSG_RESULT($LD) +else + AC_MSG_RESULT(no) +fi +test -z "$LD" && AC_MSG_ERROR([no acceptable ld found in \$PATH]) +AC_LIB_PROG_LD_GNU +]) diff --git a/lgl/m4/lib-link.m4 b/lgl/m4/lib-link.m4 new file mode 100644 index 0000000000..a196556c24 --- /dev/null +++ b/lgl/m4/lib-link.m4 @@ -0,0 +1,644 @@ +# lib-link.m4 serial 9 (gettext-0.15.1) +dnl Copyright (C) 2001-2006 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +dnl From Bruno Haible. + +AC_PREREQ(2.50) + +dnl AC_LIB_LINKFLAGS(name [, dependencies]) searches for libname and +dnl the libraries corresponding to explicit and implicit dependencies. +dnl Sets and AC_SUBSTs the LIB${NAME} and LTLIB${NAME} variables and +dnl augments the CPPFLAGS variable. +AC_DEFUN([AC_LIB_LINKFLAGS], +[ + AC_REQUIRE([AC_LIB_PREPARE_PREFIX]) + AC_REQUIRE([AC_LIB_RPATH]) + define([Name],[translit([$1],[./-], [___])]) + define([NAME],[translit([$1],[abcdefghijklmnopqrstuvwxyz./-], + [ABCDEFGHIJKLMNOPQRSTUVWXYZ___])]) + AC_CACHE_CHECK([how to link with lib[]$1], [ac_cv_lib[]Name[]_libs], [ + AC_LIB_LINKFLAGS_BODY([$1], [$2]) + ac_cv_lib[]Name[]_libs="$LIB[]NAME" + ac_cv_lib[]Name[]_ltlibs="$LTLIB[]NAME" + ac_cv_lib[]Name[]_cppflags="$INC[]NAME" + ]) + LIB[]NAME="$ac_cv_lib[]Name[]_libs" + LTLIB[]NAME="$ac_cv_lib[]Name[]_ltlibs" + INC[]NAME="$ac_cv_lib[]Name[]_cppflags" + AC_LIB_APPENDTOVAR([CPPFLAGS], [$INC]NAME) + AC_SUBST([LIB]NAME) + AC_SUBST([LTLIB]NAME) + dnl Also set HAVE_LIB[]NAME so that AC_LIB_HAVE_LINKFLAGS can reuse the + dnl results of this search when this library appears as a dependency. + HAVE_LIB[]NAME=yes + undefine([Name]) + undefine([NAME]) +]) + +dnl AC_LIB_HAVE_LINKFLAGS(name, dependencies, includes, testcode) +dnl searches for libname and the libraries corresponding to explicit and +dnl implicit dependencies, together with the specified include files and +dnl the ability to compile and link the specified testcode. If found, it +dnl sets and AC_SUBSTs HAVE_LIB${NAME}=yes and the LIB${NAME} and +dnl LTLIB${NAME} variables and augments the CPPFLAGS variable, and +dnl #defines HAVE_LIB${NAME} to 1. Otherwise, it sets and AC_SUBSTs +dnl HAVE_LIB${NAME}=no and LIB${NAME} and LTLIB${NAME} to empty. +AC_DEFUN([AC_LIB_HAVE_LINKFLAGS], +[ + AC_REQUIRE([AC_LIB_PREPARE_PREFIX]) + AC_REQUIRE([AC_LIB_RPATH]) + define([Name],[translit([$1],[./-], [___])]) + define([NAME],[translit([$1],[abcdefghijklmnopqrstuvwxyz./-], + [ABCDEFGHIJKLMNOPQRSTUVWXYZ___])]) + + dnl Search for lib[]Name and define LIB[]NAME, LTLIB[]NAME and INC[]NAME + dnl accordingly. + AC_LIB_LINKFLAGS_BODY([$1], [$2]) + + dnl Add $INC[]NAME to CPPFLAGS before performing the following checks, + dnl because if the user has installed lib[]Name and not disabled its use + dnl via --without-lib[]Name-prefix, he wants to use it. + ac_save_CPPFLAGS="$CPPFLAGS" + AC_LIB_APPENDTOVAR([CPPFLAGS], [$INC]NAME) + + AC_CACHE_CHECK([for lib[]$1], [ac_cv_lib[]Name], [ + ac_save_LIBS="$LIBS" + LIBS="$LIBS $LIB[]NAME" + AC_TRY_LINK([$3], [$4], [ac_cv_lib[]Name=yes], [ac_cv_lib[]Name=no]) + LIBS="$ac_save_LIBS" + ]) + if test "$ac_cv_lib[]Name" = yes; then + HAVE_LIB[]NAME=yes + AC_DEFINE([HAVE_LIB]NAME, 1, [Define if you have the $1 library.]) + AC_MSG_CHECKING([how to link with lib[]$1]) + AC_MSG_RESULT([$LIB[]NAME]) + else + HAVE_LIB[]NAME=no + dnl If $LIB[]NAME didn't lead to a usable library, we don't need + dnl $INC[]NAME either. + CPPFLAGS="$ac_save_CPPFLAGS" + LIB[]NAME= + LTLIB[]NAME= + fi + AC_SUBST([HAVE_LIB]NAME) + AC_SUBST([LIB]NAME) + AC_SUBST([LTLIB]NAME) + undefine([Name]) + undefine([NAME]) +]) + +dnl Determine the platform dependent parameters needed to use rpath: +dnl libext, shlibext, hardcode_libdir_flag_spec, hardcode_libdir_separator, +dnl hardcode_direct, hardcode_minus_L. +AC_DEFUN([AC_LIB_RPATH], +[ + dnl Tell automake >= 1.10 to complain if config.rpath is missing. + m4_ifdef([AC_REQUIRE_AUX_FILE], [AC_REQUIRE_AUX_FILE([config.rpath])]) + AC_REQUIRE([AC_PROG_CC]) dnl we use $CC, $GCC, $LDFLAGS + AC_REQUIRE([AC_LIB_PROG_LD]) dnl we use $LD, $with_gnu_ld + AC_REQUIRE([AC_CANONICAL_HOST]) dnl we use $host + AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT]) dnl we use $ac_aux_dir + AC_CACHE_CHECK([for shared library run path origin], acl_cv_rpath, [ + CC="$CC" GCC="$GCC" LDFLAGS="$LDFLAGS" LD="$LD" with_gnu_ld="$with_gnu_ld" \ + ${CONFIG_SHELL-/bin/sh} "$ac_aux_dir/config.rpath" "$host" > conftest.sh + . ./conftest.sh + rm -f ./conftest.sh + acl_cv_rpath=done + ]) + wl="$acl_cv_wl" + libext="$acl_cv_libext" + shlibext="$acl_cv_shlibext" + hardcode_libdir_flag_spec="$acl_cv_hardcode_libdir_flag_spec" + hardcode_libdir_separator="$acl_cv_hardcode_libdir_separator" + hardcode_direct="$acl_cv_hardcode_direct" + hardcode_minus_L="$acl_cv_hardcode_minus_L" + dnl Determine whether the user wants rpath handling at all. + AC_ARG_ENABLE(rpath, + [ --disable-rpath do not hardcode runtime library paths], + :, enable_rpath=yes) +]) + +dnl AC_LIB_LINKFLAGS_BODY(name [, dependencies]) searches for libname and +dnl the libraries corresponding to explicit and implicit dependencies. +dnl Sets the LIB${NAME}, LTLIB${NAME} and INC${NAME} variables. +AC_DEFUN([AC_LIB_LINKFLAGS_BODY], +[ + AC_REQUIRE([AC_LIB_PREPARE_MULTILIB]) + define([NAME],[translit([$1],[abcdefghijklmnopqrstuvwxyz./-], + [ABCDEFGHIJKLMNOPQRSTUVWXYZ___])]) + dnl By default, look in $includedir and $libdir. + use_additional=yes + AC_LIB_WITH_FINAL_PREFIX([ + eval additional_includedir=\"$includedir\" + eval additional_libdir=\"$libdir\" + ]) + AC_LIB_ARG_WITH([lib$1-prefix], +[ --with-lib$1-prefix[=DIR] search for lib$1 in DIR/include and DIR/lib + --without-lib$1-prefix don't search for lib$1 in includedir and libdir], +[ + if test "X$withval" = "Xno"; then + use_additional=no + else + if test "X$withval" = "X"; then + AC_LIB_WITH_FINAL_PREFIX([ + eval additional_includedir=\"$includedir\" + eval additional_libdir=\"$libdir\" + ]) + else + additional_includedir="$withval/include" + additional_libdir="$withval/$acl_libdirstem" + fi + fi +]) + dnl Search the library and its dependencies in $additional_libdir and + dnl $LDFLAGS. Using breadth-first-seach. + LIB[]NAME= + LTLIB[]NAME= + INC[]NAME= + rpathdirs= + ltrpathdirs= + names_already_handled= + names_next_round='$1 $2' + while test -n "$names_next_round"; do + names_this_round="$names_next_round" + names_next_round= + for name in $names_this_round; do + already_handled= + for n in $names_already_handled; do + if test "$n" = "$name"; then + already_handled=yes + break + fi + done + if test -z "$already_handled"; then + names_already_handled="$names_already_handled $name" + dnl See if it was already located by an earlier AC_LIB_LINKFLAGS + dnl or AC_LIB_HAVE_LINKFLAGS call. + uppername=`echo "$name" | sed -e 'y|abcdefghijklmnopqrstuvwxyz./-|ABCDEFGHIJKLMNOPQRSTUVWXYZ___|'` + eval value=\"\$HAVE_LIB$uppername\" + if test -n "$value"; then + if test "$value" = yes; then + eval value=\"\$LIB$uppername\" + test -z "$value" || LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$value" + eval value=\"\$LTLIB$uppername\" + test -z "$value" || LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }$value" + else + dnl An earlier call to AC_LIB_HAVE_LINKFLAGS has determined + dnl that this library doesn't exist. So just drop it. + : + fi + else + dnl Search the library lib$name in $additional_libdir and $LDFLAGS + dnl and the already constructed $LIBNAME/$LTLIBNAME. + found_dir= + found_la= + found_so= + found_a= + if test $use_additional = yes; then + if test -n "$shlibext" \ + && { test -f "$additional_libdir/lib$name.$shlibext" \ + || { test "$shlibext" = dll \ + && test -f "$additional_libdir/lib$name.dll.a"; }; }; then + found_dir="$additional_libdir" + if test -f "$additional_libdir/lib$name.$shlibext"; then + found_so="$additional_libdir/lib$name.$shlibext" + else + found_so="$additional_libdir/lib$name.dll.a" + fi + if test -f "$additional_libdir/lib$name.la"; then + found_la="$additional_libdir/lib$name.la" + fi + else + if test -f "$additional_libdir/lib$name.$libext"; then + found_dir="$additional_libdir" + found_a="$additional_libdir/lib$name.$libext" + if test -f "$additional_libdir/lib$name.la"; then + found_la="$additional_libdir/lib$name.la" + fi + fi + fi + fi + if test "X$found_dir" = "X"; then + for x in $LDFLAGS $LTLIB[]NAME; do + AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) + case "$x" in + -L*) + dir=`echo "X$x" | sed -e 's/^X-L//'` + if test -n "$shlibext" \ + && { test -f "$dir/lib$name.$shlibext" \ + || { test "$shlibext" = dll \ + && test -f "$dir/lib$name.dll.a"; }; }; then + found_dir="$dir" + if test -f "$dir/lib$name.$shlibext"; then + found_so="$dir/lib$name.$shlibext" + else + found_so="$dir/lib$name.dll.a" + fi + if test -f "$dir/lib$name.la"; then + found_la="$dir/lib$name.la" + fi + else + if test -f "$dir/lib$name.$libext"; then + found_dir="$dir" + found_a="$dir/lib$name.$libext" + if test -f "$dir/lib$name.la"; then + found_la="$dir/lib$name.la" + fi + fi + fi + ;; + esac + if test "X$found_dir" != "X"; then + break + fi + done + fi + if test "X$found_dir" != "X"; then + dnl Found the library. + LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-L$found_dir -l$name" + if test "X$found_so" != "X"; then + dnl Linking with a shared library. We attempt to hardcode its + dnl directory into the executable's runpath, unless it's the + dnl standard /usr/lib. + if test "$enable_rpath" = no || test "X$found_dir" = "X/usr/$acl_libdirstem"; then + dnl No hardcoding is needed. + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so" + else + dnl Use an explicit option to hardcode DIR into the resulting + dnl binary. + dnl Potentially add DIR to ltrpathdirs. + dnl The ltrpathdirs will be appended to $LTLIBNAME at the end. + haveit= + for x in $ltrpathdirs; do + if test "X$x" = "X$found_dir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + ltrpathdirs="$ltrpathdirs $found_dir" + fi + dnl The hardcoding into $LIBNAME is system dependent. + if test "$hardcode_direct" = yes; then + dnl Using DIR/libNAME.so during linking hardcodes DIR into the + dnl resulting binary. + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so" + else + if test -n "$hardcode_libdir_flag_spec" && test "$hardcode_minus_L" = no; then + dnl Use an explicit option to hardcode DIR into the resulting + dnl binary. + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so" + dnl Potentially add DIR to rpathdirs. + dnl The rpathdirs will be appended to $LIBNAME at the end. + haveit= + for x in $rpathdirs; do + if test "X$x" = "X$found_dir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + rpathdirs="$rpathdirs $found_dir" + fi + else + dnl Rely on "-L$found_dir". + dnl But don't add it if it's already contained in the LDFLAGS + dnl or the already constructed $LIBNAME + haveit= + for x in $LDFLAGS $LIB[]NAME; do + AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) + if test "X$x" = "X-L$found_dir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-L$found_dir" + fi + if test "$hardcode_minus_L" != no; then + dnl FIXME: Not sure whether we should use + dnl "-L$found_dir -l$name" or "-L$found_dir $found_so" + dnl here. + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so" + else + dnl We cannot use $hardcode_runpath_var and LD_RUN_PATH + dnl here, because this doesn't fit in flags passed to the + dnl compiler. So give up. No hardcoding. This affects only + dnl very old systems. + dnl FIXME: Not sure whether we should use + dnl "-L$found_dir -l$name" or "-L$found_dir $found_so" + dnl here. + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-l$name" + fi + fi + fi + fi + else + if test "X$found_a" != "X"; then + dnl Linking with a static library. + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_a" + else + dnl We shouldn't come here, but anyway it's good to have a + dnl fallback. + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-L$found_dir -l$name" + fi + fi + dnl Assume the include files are nearby. + additional_includedir= + case "$found_dir" in + */$acl_libdirstem | */$acl_libdirstem/) + basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e "s,/$acl_libdirstem/"'*$,,'` + additional_includedir="$basedir/include" + ;; + esac + if test "X$additional_includedir" != "X"; then + dnl Potentially add $additional_includedir to $INCNAME. + dnl But don't add it + dnl 1. if it's the standard /usr/include, + dnl 2. if it's /usr/local/include and we are using GCC on Linux, + dnl 3. if it's already present in $CPPFLAGS or the already + dnl constructed $INCNAME, + dnl 4. if it doesn't exist as a directory. + if test "X$additional_includedir" != "X/usr/include"; then + haveit= + if test "X$additional_includedir" = "X/usr/local/include"; then + if test -n "$GCC"; then + case $host_os in + linux* | gnu* | k*bsd*-gnu) haveit=yes;; + esac + fi + fi + if test -z "$haveit"; then + for x in $CPPFLAGS $INC[]NAME; do + AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) + if test "X$x" = "X-I$additional_includedir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + if test -d "$additional_includedir"; then + dnl Really add $additional_includedir to $INCNAME. + INC[]NAME="${INC[]NAME}${INC[]NAME:+ }-I$additional_includedir" + fi + fi + fi + fi + fi + dnl Look for dependencies. + if test -n "$found_la"; then + dnl Read the .la file. It defines the variables + dnl dlname, library_names, old_library, dependency_libs, current, + dnl age, revision, installed, dlopen, dlpreopen, libdir. + save_libdir="$libdir" + case "$found_la" in + */* | *\\*) . "$found_la" ;; + *) . "./$found_la" ;; + esac + libdir="$save_libdir" + dnl We use only dependency_libs. + for dep in $dependency_libs; do + case "$dep" in + -L*) + additional_libdir=`echo "X$dep" | sed -e 's/^X-L//'` + dnl Potentially add $additional_libdir to $LIBNAME and $LTLIBNAME. + dnl But don't add it + dnl 1. if it's the standard /usr/lib, + dnl 2. if it's /usr/local/lib and we are using GCC on Linux, + dnl 3. if it's already present in $LDFLAGS or the already + dnl constructed $LIBNAME, + dnl 4. if it doesn't exist as a directory. + if test "X$additional_libdir" != "X/usr/$acl_libdirstem"; then + haveit= + if test "X$additional_libdir" = "X/usr/local/$acl_libdirstem"; then + if test -n "$GCC"; then + case $host_os in + linux* | gnu* | k*bsd*-gnu) haveit=yes;; + esac + fi + fi + if test -z "$haveit"; then + haveit= + for x in $LDFLAGS $LIB[]NAME; do + AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) + if test "X$x" = "X-L$additional_libdir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + if test -d "$additional_libdir"; then + dnl Really add $additional_libdir to $LIBNAME. + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-L$additional_libdir" + fi + fi + haveit= + for x in $LDFLAGS $LTLIB[]NAME; do + AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) + if test "X$x" = "X-L$additional_libdir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + if test -d "$additional_libdir"; then + dnl Really add $additional_libdir to $LTLIBNAME. + LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-L$additional_libdir" + fi + fi + fi + fi + ;; + -R*) + dir=`echo "X$dep" | sed -e 's/^X-R//'` + if test "$enable_rpath" != no; then + dnl Potentially add DIR to rpathdirs. + dnl The rpathdirs will be appended to $LIBNAME at the end. + haveit= + for x in $rpathdirs; do + if test "X$x" = "X$dir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + rpathdirs="$rpathdirs $dir" + fi + dnl Potentially add DIR to ltrpathdirs. + dnl The ltrpathdirs will be appended to $LTLIBNAME at the end. + haveit= + for x in $ltrpathdirs; do + if test "X$x" = "X$dir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + ltrpathdirs="$ltrpathdirs $dir" + fi + fi + ;; + -l*) + dnl Handle this in the next round. + names_next_round="$names_next_round "`echo "X$dep" | sed -e 's/^X-l//'` + ;; + *.la) + dnl Handle this in the next round. Throw away the .la's + dnl directory; it is already contained in a preceding -L + dnl option. + names_next_round="$names_next_round "`echo "X$dep" | sed -e 's,^X.*/,,' -e 's,^lib,,' -e 's,\.la$,,'` + ;; + *) + dnl Most likely an immediate library name. + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$dep" + LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }$dep" + ;; + esac + done + fi + else + dnl Didn't find the library; assume it is in the system directories + dnl known to the linker and runtime loader. (All the system + dnl directories known to the linker should also be known to the + dnl runtime loader, otherwise the system is severely misconfigured.) + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-l$name" + LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-l$name" + fi + fi + fi + done + done + if test "X$rpathdirs" != "X"; then + if test -n "$hardcode_libdir_separator"; then + dnl Weird platform: only the last -rpath option counts, the user must + dnl pass all path elements in one option. We can arrange that for a + dnl single library, but not when more than one $LIBNAMEs are used. + alldirs= + for found_dir in $rpathdirs; do + alldirs="${alldirs}${alldirs:+$hardcode_libdir_separator}$found_dir" + done + dnl Note: hardcode_libdir_flag_spec uses $libdir and $wl. + acl_save_libdir="$libdir" + libdir="$alldirs" + eval flag=\"$hardcode_libdir_flag_spec\" + libdir="$acl_save_libdir" + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$flag" + else + dnl The -rpath options are cumulative. + for found_dir in $rpathdirs; do + acl_save_libdir="$libdir" + libdir="$found_dir" + eval flag=\"$hardcode_libdir_flag_spec\" + libdir="$acl_save_libdir" + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$flag" + done + fi + fi + if test "X$ltrpathdirs" != "X"; then + dnl When using libtool, the option that works for both libraries and + dnl executables is -R. The -R options are cumulative. + for found_dir in $ltrpathdirs; do + LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-R$found_dir" + done + fi +]) + +dnl AC_LIB_APPENDTOVAR(VAR, CONTENTS) appends the elements of CONTENTS to VAR, +dnl unless already present in VAR. +dnl Works only for CPPFLAGS, not for LIB* variables because that sometimes +dnl contains two or three consecutive elements that belong together. +AC_DEFUN([AC_LIB_APPENDTOVAR], +[ + for element in [$2]; do + haveit= + for x in $[$1]; do + AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) + if test "X$x" = "X$element"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + [$1]="${[$1]}${[$1]:+ }$element" + fi + done +]) + +dnl For those cases where a variable contains several -L and -l options +dnl referring to unknown libraries and directories, this macro determines the +dnl necessary additional linker options for the runtime path. +dnl AC_LIB_LINKFLAGS_FROM_LIBS([LDADDVAR], [LIBSVALUE], [USE-LIBTOOL]) +dnl sets LDADDVAR to linker options needed together with LIBSVALUE. +dnl If USE-LIBTOOL evaluates to non-empty, linking with libtool is assumed, +dnl otherwise linking without libtool is assumed. +AC_DEFUN([AC_LIB_LINKFLAGS_FROM_LIBS], +[ + AC_REQUIRE([AC_LIB_RPATH]) + AC_REQUIRE([AC_LIB_PREPARE_MULTILIB]) + $1= + if test "$enable_rpath" != no; then + if test -n "$hardcode_libdir_flag_spec" && test "$hardcode_minus_L" = no; then + dnl Use an explicit option to hardcode directories into the resulting + dnl binary. + rpathdirs= + next= + for opt in $2; do + if test -n "$next"; then + dir="$next" + dnl No need to hardcode the standard /usr/lib. + if test "X$dir" != "X/usr/$acl_libdirstem"; then + rpathdirs="$rpathdirs $dir" + fi + next= + else + case $opt in + -L) next=yes ;; + -L*) dir=`echo "X$opt" | sed -e 's,^X-L,,'` + dnl No need to hardcode the standard /usr/lib. + if test "X$dir" != "X/usr/$acl_libdirstem"; then + rpathdirs="$rpathdirs $dir" + fi + next= ;; + *) next= ;; + esac + fi + done + if test "X$rpathdirs" != "X"; then + if test -n ""$3""; then + dnl libtool is used for linking. Use -R options. + for dir in $rpathdirs; do + $1="${$1}${$1:+ }-R$dir" + done + else + dnl The linker is used for linking directly. + if test -n "$hardcode_libdir_separator"; then + dnl Weird platform: only the last -rpath option counts, the user + dnl must pass all path elements in one option. + alldirs= + for dir in $rpathdirs; do + alldirs="${alldirs}${alldirs:+$hardcode_libdir_separator}$dir" + done + acl_save_libdir="$libdir" + libdir="$alldirs" + eval flag=\"$hardcode_libdir_flag_spec\" + libdir="$acl_save_libdir" + $1="$flag" + else + dnl The -rpath options are cumulative. + for dir in $rpathdirs; do + acl_save_libdir="$libdir" + libdir="$dir" + eval flag=\"$hardcode_libdir_flag_spec\" + libdir="$acl_save_libdir" + $1="${$1}${$1:+ }$flag" + done + fi + fi + fi + fi + fi + AC_SUBST([$1]) +]) diff --git a/lgl/m4/lib-prefix.m4 b/lgl/m4/lib-prefix.m4 new file mode 100644 index 0000000000..a8684e17e3 --- /dev/null +++ b/lgl/m4/lib-prefix.m4 @@ -0,0 +1,185 @@ +# lib-prefix.m4 serial 5 (gettext-0.15) +dnl Copyright (C) 2001-2005 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +dnl From Bruno Haible. + +dnl AC_LIB_ARG_WITH is synonymous to AC_ARG_WITH in autoconf-2.13, and +dnl similar to AC_ARG_WITH in autoconf 2.52...2.57 except that is doesn't +dnl require excessive bracketing. +ifdef([AC_HELP_STRING], +[AC_DEFUN([AC_LIB_ARG_WITH], [AC_ARG_WITH([$1],[[$2]],[$3],[$4])])], +[AC_DEFUN([AC_][LIB_ARG_WITH], [AC_ARG_WITH([$1],[$2],[$3],[$4])])]) + +dnl AC_LIB_PREFIX adds to the CPPFLAGS and LDFLAGS the flags that are needed +dnl to access previously installed libraries. The basic assumption is that +dnl a user will want packages to use other packages he previously installed +dnl with the same --prefix option. +dnl This macro is not needed if only AC_LIB_LINKFLAGS is used to locate +dnl libraries, but is otherwise very convenient. +AC_DEFUN([AC_LIB_PREFIX], +[ + AC_BEFORE([$0], [AC_LIB_LINKFLAGS]) + AC_REQUIRE([AC_PROG_CC]) + AC_REQUIRE([AC_CANONICAL_HOST]) + AC_REQUIRE([AC_LIB_PREPARE_MULTILIB]) + AC_REQUIRE([AC_LIB_PREPARE_PREFIX]) + dnl By default, look in $includedir and $libdir. + use_additional=yes + AC_LIB_WITH_FINAL_PREFIX([ + eval additional_includedir=\"$includedir\" + eval additional_libdir=\"$libdir\" + ]) + AC_LIB_ARG_WITH([lib-prefix], +[ --with-lib-prefix[=DIR] search for libraries in DIR/include and DIR/lib + --without-lib-prefix don't search for libraries in includedir and libdir], +[ + if test "X$withval" = "Xno"; then + use_additional=no + else + if test "X$withval" = "X"; then + AC_LIB_WITH_FINAL_PREFIX([ + eval additional_includedir=\"$includedir\" + eval additional_libdir=\"$libdir\" + ]) + else + additional_includedir="$withval/include" + additional_libdir="$withval/$acl_libdirstem" + fi + fi +]) + if test $use_additional = yes; then + dnl Potentially add $additional_includedir to $CPPFLAGS. + dnl But don't add it + dnl 1. if it's the standard /usr/include, + dnl 2. if it's already present in $CPPFLAGS, + dnl 3. if it's /usr/local/include and we are using GCC on Linux, + dnl 4. if it doesn't exist as a directory. + if test "X$additional_includedir" != "X/usr/include"; then + haveit= + for x in $CPPFLAGS; do + AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) + if test "X$x" = "X-I$additional_includedir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + if test "X$additional_includedir" = "X/usr/local/include"; then + if test -n "$GCC"; then + case $host_os in + linux* | gnu* | k*bsd*-gnu) haveit=yes;; + esac + fi + fi + if test -z "$haveit"; then + if test -d "$additional_includedir"; then + dnl Really add $additional_includedir to $CPPFLAGS. + CPPFLAGS="${CPPFLAGS}${CPPFLAGS:+ }-I$additional_includedir" + fi + fi + fi + fi + dnl Potentially add $additional_libdir to $LDFLAGS. + dnl But don't add it + dnl 1. if it's the standard /usr/lib, + dnl 2. if it's already present in $LDFLAGS, + dnl 3. if it's /usr/local/lib and we are using GCC on Linux, + dnl 4. if it doesn't exist as a directory. + if test "X$additional_libdir" != "X/usr/$acl_libdirstem"; then + haveit= + for x in $LDFLAGS; do + AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) + if test "X$x" = "X-L$additional_libdir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + if test "X$additional_libdir" = "X/usr/local/$acl_libdirstem"; then + if test -n "$GCC"; then + case $host_os in + linux*) haveit=yes;; + esac + fi + fi + if test -z "$haveit"; then + if test -d "$additional_libdir"; then + dnl Really add $additional_libdir to $LDFLAGS. + LDFLAGS="${LDFLAGS}${LDFLAGS:+ }-L$additional_libdir" + fi + fi + fi + fi + fi +]) + +dnl AC_LIB_PREPARE_PREFIX creates variables acl_final_prefix, +dnl acl_final_exec_prefix, containing the values to which $prefix and +dnl $exec_prefix will expand at the end of the configure script. +AC_DEFUN([AC_LIB_PREPARE_PREFIX], +[ + dnl Unfortunately, prefix and exec_prefix get only finally determined + dnl at the end of configure. + if test "X$prefix" = "XNONE"; then + acl_final_prefix="$ac_default_prefix" + else + acl_final_prefix="$prefix" + fi + if test "X$exec_prefix" = "XNONE"; then + acl_final_exec_prefix='${prefix}' + else + acl_final_exec_prefix="$exec_prefix" + fi + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + eval acl_final_exec_prefix=\"$acl_final_exec_prefix\" + prefix="$acl_save_prefix" +]) + +dnl AC_LIB_WITH_FINAL_PREFIX([statement]) evaluates statement, with the +dnl variables prefix and exec_prefix bound to the values they will have +dnl at the end of the configure script. +AC_DEFUN([AC_LIB_WITH_FINAL_PREFIX], +[ + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + $1 + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" +]) + +dnl AC_LIB_PREPARE_MULTILIB creates a variable acl_libdirstem, containing +dnl the basename of the libdir, either "lib" or "lib64". +AC_DEFUN([AC_LIB_PREPARE_MULTILIB], +[ + dnl There is no formal standard regarding lib and lib64. The current + dnl practice is that on a system supporting 32-bit and 64-bit instruction + dnl sets or ABIs, 64-bit libraries go under $prefix/lib64 and 32-bit + dnl libraries go under $prefix/lib. We determine the compiler's default + dnl mode by looking at the compiler's library search path. If at least + dnl of its elements ends in /lib64 or points to a directory whose absolute + dnl pathname ends in /lib64, we assume a 64-bit ABI. Otherwise we use the + dnl default, namely "lib". + acl_libdirstem=lib + searchpath=`(LC_ALL=C $CC -print-search-dirs) 2>/dev/null | sed -n -e 's,^libraries: ,,p' | sed -e 's,^=,,'` + if test -n "$searchpath"; then + acl_save_IFS="${IFS= }"; IFS=":" + for searchdir in $searchpath; do + if test -d "$searchdir"; then + case "$searchdir" in + */lib64/ | */lib64 ) acl_libdirstem=lib64 ;; + *) searchdir=`cd "$searchdir" && pwd` + case "$searchdir" in + */lib64 ) acl_libdirstem=lib64 ;; + esac ;; + esac + fi + done + IFS="$acl_save_IFS" + fi +]) diff --git a/lgl/m4/longlong.m4 b/lgl/m4/longlong.m4 new file mode 100644 index 0000000000..3716c09f6c --- /dev/null +++ b/lgl/m4/longlong.m4 @@ -0,0 +1,48 @@ +# longlong.m4 serial 8 +dnl Copyright (C) 1999-2006 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +dnl From Paul Eggert. + +# Define HAVE_LONG_LONG_INT if 'long long int' works. +# This fixes a bug in Autoconf 2.60, but can be removed once we +# assume 2.61 everywhere. + +# Note: If the type 'long long int' exists but is only 32 bits large +# (as on some very old compilers), AC_TYPE_LONG_LONG_INT will not be +# defined. In this case you can treat 'long long int' like 'long int'. + +AC_DEFUN([AC_TYPE_LONG_LONG_INT], +[ + AC_CACHE_CHECK([for long long int], [ac_cv_type_long_long_int], + [AC_LINK_IFELSE( + [AC_LANG_PROGRAM( + [[long long int ll = 9223372036854775807ll; + long long int nll = -9223372036854775807LL; + typedef int a[((-9223372036854775807LL < 0 + && 0 < 9223372036854775807ll) + ? 1 : -1)]; + int i = 63;]], + [[long long int llmax = 9223372036854775807ll; + return ((ll << 63) | (ll >> 63) | (ll < i) | (ll > i) + | (llmax / ll) | (llmax % ll));]])], + [ac_cv_type_long_long_int=yes], + [ac_cv_type_long_long_int=no])]) + if test $ac_cv_type_long_long_int = yes; then + AC_DEFINE([HAVE_LONG_LONG_INT], 1, + [Define to 1 if the system has the type `long long int'.]) + fi +]) + +# This macro is obsolescent and should go away soon. +AC_DEFUN([gl_AC_TYPE_LONG_LONG], +[ + AC_REQUIRE([AC_TYPE_LONG_LONG_INT]) + ac_cv_type_long_long=$ac_cv_type_long_long_int + if test $ac_cv_type_long_long = yes; then + AC_DEFINE(HAVE_LONG_LONG, 1, + [Define if you have the 'long long' type.]) + fi +]) diff --git a/lgl/m4/md2.m4 b/lgl/m4/md2.m4 new file mode 100644 index 0000000000..03e1ea37c9 --- /dev/null +++ b/lgl/m4/md2.m4 @@ -0,0 +1,10 @@ +# md2.m4 serial 2 +dnl Copyright (C) 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +AC_DEFUN([gl_MD2], +[ + AC_LIBOBJ([md2]) +]) diff --git a/lgl/m4/md4.m4 b/lgl/m4/md4.m4 new file mode 100644 index 0000000000..22a7bdee3e --- /dev/null +++ b/lgl/m4/md4.m4 @@ -0,0 +1,13 @@ +# md4.m4 serial 2 +dnl Copyright (C) 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +AC_DEFUN([gl_MD4], +[ + AC_LIBOBJ([md4]) + + dnl Prerequisites of lib/md4.c. + AC_REQUIRE([AC_C_BIGENDIAN]) +]) diff --git a/lgl/m4/md5.m4 b/lgl/m4/md5.m4 new file mode 100644 index 0000000000..5a1f8755a0 --- /dev/null +++ b/lgl/m4/md5.m4 @@ -0,0 +1,14 @@ +# md5.m4 serial 9 +dnl Copyright (C) 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +AC_DEFUN([gl_MD5], +[ + AC_LIBOBJ([md5]) + + dnl Prerequisites of lib/md5.c. + AC_REQUIRE([AC_C_BIGENDIAN]) + : +]) diff --git a/lgl/m4/memxor.m4 b/lgl/m4/memxor.m4 new file mode 100644 index 0000000000..e14ffbb0f1 --- /dev/null +++ b/lgl/m4/memxor.m4 @@ -0,0 +1,11 @@ +# memxor.m4 serial 3 +dnl Copyright (C) 2006 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +AC_DEFUN([gl_MEMXOR], +[ + AC_LIBOBJ([memxor]) + AC_REQUIRE([AC_C_RESTRICT]) +]) diff --git a/lgl/m4/minmax.m4 b/lgl/m4/minmax.m4 new file mode 100644 index 0000000000..bbd1ba0b84 --- /dev/null +++ b/lgl/m4/minmax.m4 @@ -0,0 +1,41 @@ +# minmax.m4 serial 2 +dnl Copyright (C) 2005 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +AC_PREREQ(2.52) + +AC_DEFUN([gl_MINMAX], +[ + AC_REQUIRE([gl_PREREQ_MINMAX]) +]) + +# Prerequisites of lib/minmax.h. +AC_DEFUN([gl_PREREQ_MINMAX], +[ + gl_MINMAX_IN_HEADER([limits.h]) + gl_MINMAX_IN_HEADER([sys/param.h]) +]) + +dnl gl_MINMAX_IN_HEADER(HEADER) +dnl The parameter has to be a literal header name; it cannot be macro, +dnl nor a shell variable. (Because autoheader collects only AC_DEFINE +dnl invocations with a literal macro name.) +AC_DEFUN([gl_MINMAX_IN_HEADER], +[ + m4_pushdef([header], AS_TR_SH([$1])) + m4_pushdef([HEADER], AS_TR_CPP([$1])) + AC_CACHE_CHECK([whether <$1> defines MIN and MAX], + [gl_cv_minmax_in_]header, + [AC_TRY_COMPILE([#include <$1> +int x = MIN (42, 17);], [], + [gl_cv_minmax_in_]header[=yes], + [gl_cv_minmax_in_]header[=no])]) + if test $gl_cv_minmax_in_[]header = yes; then + AC_DEFINE([HAVE_MINMAX_IN_]HEADER, 1, + [Define to 1 if <$1> defines the MIN and MAX macros.]) + fi + m4_popdef([HEADER]) + m4_popdef([header]) +]) diff --git a/lgl/m4/rijndael.m4 b/lgl/m4/rijndael.m4 new file mode 100644 index 0000000000..f7bb8d37d1 --- /dev/null +++ b/lgl/m4/rijndael.m4 @@ -0,0 +1,11 @@ +# rijndael.m4 serial 2 +dnl Copyright (C) 2005, 2006 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +AC_DEFUN([gl_RIJNDAEL], +[ + AC_LIBOBJ([rijndael-alg-fst]) + AC_LIBOBJ([rijndael-api-fst]) +]) diff --git a/lgl/m4/sha1.m4 b/lgl/m4/sha1.m4 new file mode 100644 index 0000000000..c6e6184b2c --- /dev/null +++ b/lgl/m4/sha1.m4 @@ -0,0 +1,14 @@ +# sha1.m4 serial 7 +dnl Copyright (C) 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +AC_DEFUN([gl_SHA1], +[ + AC_LIBOBJ([sha1]) + + dnl Prerequisites of lib/sha1.c. + AC_REQUIRE([AC_C_BIGENDIAN]) + : +]) diff --git a/lgl/m4/stdint.m4 b/lgl/m4/stdint.m4 new file mode 100644 index 0000000000..9261def3bb --- /dev/null +++ b/lgl/m4/stdint.m4 @@ -0,0 +1,368 @@ +# stdint.m4 serial 19 +dnl Copyright (C) 2001-2002, 2004-2006 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +dnl From Paul Eggert and Bruno Haible. +dnl Test whether <stdint.h> is supported or must be substituted. + +AC_DEFUN([gl_STDINT_H], +[ + AC_PREREQ(2.59)dnl + + dnl Check for long long int and unsigned long long int. + AC_REQUIRE([AC_TYPE_LONG_LONG_INT]) + if test $ac_cv_type_long_long_int = yes; then + HAVE_LONG_LONG_INT=1 + else + HAVE_LONG_LONG_INT=0 + fi + AC_SUBST([HAVE_LONG_LONG_INT]) + AC_REQUIRE([AC_TYPE_UNSIGNED_LONG_LONG_INT]) + if test $ac_cv_type_unsigned_long_long_int = yes; then + HAVE_UNSIGNED_LONG_LONG_INT=1 + else + HAVE_UNSIGNED_LONG_LONG_INT=0 + fi + AC_SUBST([HAVE_UNSIGNED_LONG_LONG_INT]) + + dnl Check for <wchar.h>. + AC_CHECK_HEADERS_ONCE([wchar.h]) + if test $ac_cv_header_wchar_h = yes; then + HAVE_WCHAR_H=1 + else + HAVE_WCHAR_H=0 + fi + AC_SUBST([HAVE_WCHAR_H]) + + dnl Check for <inttypes.h>. + dnl AC_INCLUDES_DEFAULT defines $ac_cv_header_inttypes_h. + if test $ac_cv_header_inttypes_h = yes; then + HAVE_INTTYPES_H=1 + else + HAVE_INTTYPES_H=0 + fi + AC_SUBST([HAVE_INTTYPES_H]) + + dnl Check for <sys/types.h>. + dnl AC_INCLUDES_DEFAULT defines $ac_cv_header_sys_types_h. + if test $ac_cv_header_sys_types_h = yes; then + HAVE_SYS_TYPES_H=1 + else + HAVE_SYS_TYPES_H=0 + fi + AC_SUBST([HAVE_SYS_TYPES_H]) + + dnl AC_INCLUDES_DEFAULT defines $ac_cv_header_stdint_h. + if test $ac_cv_header_stdint_h = yes; then + gl_ABSOLUTE_HEADER([stdint.h]) + ABSOLUTE_STDINT_H=\"$gl_cv_absolute_stdint_h\" + HAVE_STDINT_H=1 + else + ABSOLUTE_STDINT_H=\"no/such/file/stdint.h\" + HAVE_STDINT_H=0 + fi + AC_SUBST([ABSOLUTE_STDINT_H]) + AC_SUBST([HAVE_STDINT_H]) + + dnl Now see whether we need a substitute <stdint.h>. Use + dnl ABSOLUTE_STDINT_H, not <stdint.h>, so that it also works during + dnl a "config.status --recheck" if a stdint.h has been + dnl created in the build directory. + if test $ac_cv_header_stdint_h = yes; then + AC_CACHE_CHECK([whether stdint.h conforms to C99], + [gl_cv_header_working_stdint_h], + [gl_cv_header_working_stdint_h=no + AC_COMPILE_IFELSE([ + AC_LANG_PROGRAM([[ +#include <stddef.h> +#define __STDC_LIMIT_MACROS 1 /* to make it work also in C++ mode */ +#define __STDC_CONSTANT_MACROS 1 /* to make it work also in C++ mode */ +#include ABSOLUTE_STDINT_H +#ifdef INT8_MAX +int8_t a1 = INT8_MAX; +int8_t a1min = INT8_MIN; +#endif +#ifdef INT16_MAX +int16_t a2 = INT16_MAX; +int16_t a2min = INT16_MIN; +#endif +#ifdef INT32_MAX +int32_t a3 = INT32_MAX; +int32_t a3min = INT32_MIN; +#endif +#ifdef INT64_MAX +int64_t a4 = INT64_MAX; +int64_t a4min = INT64_MIN; +#endif +#ifdef UINT8_MAX +uint8_t b1 = UINT8_MAX; +#else +typedef int b1[(unsigned char) -1 != 255 ? 1 : -1]; +#endif +#ifdef UINT16_MAX +uint16_t b2 = UINT16_MAX; +#endif +#ifdef UINT32_MAX +uint32_t b3 = UINT32_MAX; +#endif +#ifdef UINT64_MAX +uint64_t b4 = UINT64_MAX; +#endif +int_least8_t c1 = INT8_C (0x7f); +int_least8_t c1max = INT_LEAST8_MAX; +int_least8_t c1min = INT_LEAST8_MIN; +int_least16_t c2 = INT16_C (0x7fff); +int_least16_t c2max = INT_LEAST16_MAX; +int_least16_t c2min = INT_LEAST16_MIN; +int_least32_t c3 = INT32_C (0x7fffffff); +int_least32_t c3max = INT_LEAST32_MAX; +int_least32_t c3min = INT_LEAST32_MIN; +int_least64_t c4 = INT64_C (0x7fffffffffffffff); +int_least64_t c4max = INT_LEAST64_MAX; +int_least64_t c4min = INT_LEAST64_MIN; +uint_least8_t d1 = UINT8_C (0xff); +uint_least8_t d1max = UINT_LEAST8_MAX; +uint_least16_t d2 = UINT16_C (0xffff); +uint_least16_t d2max = UINT_LEAST16_MAX; +uint_least32_t d3 = UINT32_C (0xffffffff); +uint_least32_t d3max = UINT_LEAST32_MAX; +uint_least64_t d4 = UINT64_C (0xffffffffffffffff); +uint_least64_t d4max = UINT_LEAST64_MAX; +int_fast8_t e1 = INT_FAST8_MAX; +int_fast8_t e1min = INT_FAST8_MIN; +int_fast16_t e2 = INT_FAST16_MAX; +int_fast16_t e2min = INT_FAST16_MIN; +int_fast32_t e3 = INT_FAST32_MAX; +int_fast32_t e3min = INT_FAST32_MIN; +int_fast64_t e4 = INT_FAST64_MAX; +int_fast64_t e4min = INT_FAST64_MIN; +uint_fast8_t f1 = UINT_FAST8_MAX; +uint_fast16_t f2 = UINT_FAST16_MAX; +uint_fast32_t f3 = UINT_FAST32_MAX; +uint_fast64_t f4 = UINT_FAST64_MAX; +#ifdef INTPTR_MAX +intptr_t g = INTPTR_MAX; +intptr_t gmin = INTPTR_MIN; +#endif +#ifdef UINTPTR_MAX +uintptr_t h = UINTPTR_MAX; +#endif +intmax_t i = INTMAX_MAX; +uintmax_t j = UINTMAX_MAX; +struct s { + int check_PTRDIFF: PTRDIFF_MIN < 0 && 0 < PTRDIFF_MAX ? 1 : -1; + int check_SIG_ATOMIC: SIG_ATOMIC_MIN <= 0 && 0 < SIG_ATOMIC_MAX ? 1 : -1; + int check_SIZE: 0 < SIZE_MAX ? 1 : -1; + int check_WCHAR: WCHAR_MIN <= 0 && 0 < WCHAR_MAX ? 1 : -1; + int check_WINT: WINT_MIN <= 0 && 0 < WINT_MAX ? 1 : -1; + + /* Detect bugs in glibc 2.4 and Solaris 10 stdint.h, among others. */ + int check_UINT8_C: + (-1 < UINT8_C (0)) == (-1 < (uint_least8_t) 0) ? 1 : -1; + int check_UINT16_C: + (-1 < UINT16_C (0)) == (-1 < (uint_least16_t) 0) ? 1 : -1; + + /* Detect bugs in OpenBSD 3.9 stdint.h. */ +#ifdef UINT8_MAX + int check_uint8: (uint8_t) -1 == UINT8_MAX ? 1 : -1; +#endif +#ifdef UINT16_MAX + int check_uint16: (uint16_t) -1 == UINT16_MAX ? 1 : -1; +#endif +#ifdef UINT32_MAX + int check_uint32: (uint32_t) -1 == UINT32_MAX ? 1 : -1; +#endif +#ifdef UINT64_MAX + int check_uint64: (uint64_t) -1 == UINT64_MAX ? 1 : -1; +#endif + int check_uint_least8: (uint_least8_t) -1 == UINT_LEAST8_MAX ? 1 : -1; + int check_uint_least16: (uint_least16_t) -1 == UINT_LEAST16_MAX ? 1 : -1; + int check_uint_least32: (uint_least32_t) -1 == UINT_LEAST32_MAX ? 1 : -1; + int check_uint_least64: (uint_least64_t) -1 == UINT_LEAST64_MAX ? 1 : -1; + int check_uint_fast8: (uint_fast8_t) -1 == UINT_FAST8_MAX ? 1 : -1; + int check_uint_fast16: (uint_fast16_t) -1 == UINT_FAST16_MAX ? 1 : -1; + int check_uint_fast32: (uint_fast32_t) -1 == UINT_FAST32_MAX ? 1 : -1; + int check_uint_fast64: (uint_fast64_t) -1 == UINT_FAST64_MAX ? 1 : -1; + int check_uintptr: (uintptr_t) -1 == UINTPTR_MAX ? 1 : -1; + int check_uintmax: (uintmax_t) -1 == UINTMAX_MAX ? 1 : -1; + int check_size: (size_t) -1 == SIZE_MAX ? 1 : -1; +}; + ]])], + [gl_cv_header_working_stdint_h=yes])]) + fi + if test "$gl_cv_header_working_stdint_h" != yes; then + + dnl Check for <sys/inttypes.h>, and for + dnl <sys/bitypes.h> (used in Linux libc4 >= 4.6.7 and libc5). + AC_CHECK_HEADERS([sys/inttypes.h sys/bitypes.h]) + if test $ac_cv_header_sys_inttypes_h = yes; then + HAVE_SYS_INTTYPES_H=1 + else + HAVE_SYS_INTTYPES_H=0 + fi + AC_SUBST([HAVE_SYS_INTTYPES_H]) + if test $ac_cv_header_sys_bitypes_h = yes; then + HAVE_SYS_BITYPES_H=1 + else + HAVE_SYS_BITYPES_H=0 + fi + AC_SUBST([HAVE_SYS_BITYPES_H]) + + gl_STDINT_TYPE_PROPERTIES + STDINT_H=stdint.h + fi + AC_SUBST(STDINT_H) +]) + +dnl gl_STDINT_BITSIZEOF(TYPES, INCLUDES) +dnl Determine the size of each of the given types in bits. +AC_DEFUN([gl_STDINT_BITSIZEOF], +[ + dnl Use a shell loop, to avoid bloating configure, and + dnl - extra AH_TEMPLATE calls, so that autoheader knows what to put into + dnl config.h.in, + dnl - extra AC_SUBST calls, so that the right substitutions are made. + AC_FOREACH([gltype], [$1], + [AH_TEMPLATE([BITSIZEOF_]translit(gltype,[abcdefghijklmnopqrstuvwxyz ],[ABCDEFGHIJKLMNOPQRSTUVWXYZ_]), + [Define to the number of bits in type ']gltype['.])]) + for gltype in $1 ; do + AC_CACHE_CHECK([for bit size of $gltype], [gl_cv_bitsizeof_${gltype}], + [_AC_COMPUTE_INT([sizeof ($gltype) * CHAR_BIT], result, + [$2 +#include <limits.h>], [result=unknown]) + eval gl_cv_bitsizeof_${gltype}=\$result + ]) + eval result=\$gl_cv_bitsizeof_${gltype} + if test $result = unknown; then + dnl Use a nonempty default, because some compilers, such as IRIX 5 cc, + dnl do a syntax check even on unused #if conditions and give an error + dnl on valid C code like this: + dnl #if 0 + dnl # if > 32 + dnl # endif + dnl #endif + result=0 + fi + GLTYPE=`echo "$gltype" | tr 'abcdefghijklmnopqrstuvwxyz ' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ_'` + AC_DEFINE_UNQUOTED([BITSIZEOF_${GLTYPE}], [$result]) + eval BITSIZEOF_${GLTYPE}=\$result + done + AC_FOREACH([gltype], [$1], + [AC_SUBST([BITSIZEOF_]translit(gltype,[abcdefghijklmnopqrstuvwxyz ],[ABCDEFGHIJKLMNOPQRSTUVWXYZ_]))]) +]) + +dnl gl_CHECK_TYPES_SIGNED(TYPES, INCLUDES) +dnl Determine the signedness of each of the given types. +dnl Define HAVE_SIGNED_TYPE if type is signed. +AC_DEFUN([gl_CHECK_TYPES_SIGNED], +[ + dnl Use a shell loop, to avoid bloating configure, and + dnl - extra AH_TEMPLATE calls, so that autoheader knows what to put into + dnl config.h.in, + dnl - extra AC_SUBST calls, so that the right substitutions are made. + AC_FOREACH([gltype], [$1], + [AH_TEMPLATE([HAVE_SIGNED_]translit(gltype,[abcdefghijklmnopqrstuvwxyz ],[ABCDEFGHIJKLMNOPQRSTUVWXYZ_]), + [Define to 1 if ']gltype[' is a signed integer type.])]) + for gltype in $1 ; do + AC_CACHE_CHECK([whether $gltype is signed], [gl_cv_type_${gltype}_signed], + [AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM([$2[ + int verify[2 * (($gltype) -1 < ($gltype) 0) - 1];]])], + result=yes, result=no) + eval gl_cv_type_${gltype}_signed=\$result + ]) + eval result=\$gl_cv_type_${gltype}_signed + GLTYPE=`echo $gltype | tr 'abcdefghijklmnopqrstuvwxyz ' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ_'` + if test "$result" = yes; then + AC_DEFINE_UNQUOTED([HAVE_SIGNED_${GLTYPE}], 1) + eval HAVE_SIGNED_${GLTYPE}=1 + else + eval HAVE_SIGNED_${GLTYPE}=0 + fi + done + AC_FOREACH([gltype], [$1], + [AC_SUBST([HAVE_SIGNED_]translit(gltype,[abcdefghijklmnopqrstuvwxyz ],[ABCDEFGHIJKLMNOPQRSTUVWXYZ_]))]) +]) + +dnl gl_INTEGER_TYPE_SUFFIX(TYPES, INCLUDES) +dnl Determine the suffix to use for integer constants of the given types. +dnl Define t_SUFFIX for each such type. +AC_DEFUN([gl_INTEGER_TYPE_SUFFIX], +[ + dnl Use a shell loop, to avoid bloating configure, and + dnl - extra AH_TEMPLATE calls, so that autoheader knows what to put into + dnl config.h.in, + dnl - extra AC_SUBST calls, so that the right substitutions are made. + AC_FOREACH([gltype], [$1], + [AH_TEMPLATE(translit(gltype,[abcdefghijklmnopqrstuvwxyz ],[ABCDEFGHIJKLMNOPQRSTUVWXYZ_])[_SUFFIX], + [Define to l, ll, u, ul, ull, etc., as suitable for + constants of type ']gltype['.])]) + for gltype in $1 ; do + AC_CACHE_CHECK([for $gltype integer literal suffix], + [gl_cv_type_${gltype}_suffix], + [eval gl_cv_type_${gltype}_suffix=no + eval result=\$gl_cv_type_${gltype}_signed + if test "$result" = yes; then + glsufu= + else + glsufu=u + fi + for glsuf in "$glsufu" ${glsufu}l ${glsufu}ll ${glsufu}i64; do + case $glsuf in + '') gltype1='int';; + l) gltype1='long int';; + ll) gltype1='long long int';; + i64) gltype1='__int64';; + u) gltype1='unsigned int';; + ul) gltype1='unsigned long int';; + ull) gltype1='unsigned long long int';; + ui64)gltype1='unsigned __int64';; + esac + AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM([$2 + extern $gltype foo; + extern $gltype1 foo;])], + [eval gl_cv_type_${gltype}_suffix=\$glsuf]) + eval result=\$gl_cv_type_${gltype}_suffix + test "$result" != no && break + done]) + GLTYPE=`echo $gltype | tr 'abcdefghijklmnopqrstuvwxyz ' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ_'` + eval result=\$gl_cv_type_${gltype}_suffix + test "$result" = no && result= + eval ${GLTYPE}_SUFFIX=\$result + AC_DEFINE_UNQUOTED([${GLTYPE}_SUFFIX], $result) + done + AC_FOREACH([gltype], [$1], + [AC_SUBST(translit(gltype,[abcdefghijklmnopqrstuvwxyz ],[ABCDEFGHIJKLMNOPQRSTUVWXYZ_])[_SUFFIX])]) +]) + +dnl gl_STDINT_INCLUDES +AC_DEFUN([gl_STDINT_INCLUDES], +[[ + #include <stddef.h> + #include <signal.h> + #if HAVE_WCHAR_H + /* BSD/OS 4.1 has a bug: <stdio.h> and <time.h> must be included before + <wchar.h>. */ + # include <stdio.h> + # include <time.h> + # include <wchar.h> + #endif +]]) + +dnl gl_STDINT_TYPE_PROPERTIES +dnl Compute HAVE_SIGNED_t, BITSIZEOF_t and t_SUFFIX, for all the types t +dnl of interest to stdint_.h. +AC_DEFUN([gl_STDINT_TYPE_PROPERTIES], +[ + gl_STDINT_BITSIZEOF([ptrdiff_t sig_atomic_t size_t wchar_t wint_t], + [gl_STDINT_INCLUDES]) + gl_CHECK_TYPES_SIGNED([sig_atomic_t wchar_t wint_t], + [gl_STDINT_INCLUDES]) + gl_cv_type_ptrdiff_t_signed=yes + gl_cv_type_size_t_signed=no + gl_INTEGER_TYPE_SUFFIX([ptrdiff_t sig_atomic_t size_t wchar_t wint_t], + [gl_STDINT_INCLUDES]) +]) diff --git a/lgl/m4/ulonglong.m4 b/lgl/m4/ulonglong.m4 new file mode 100644 index 0000000000..9fae98e3a6 --- /dev/null +++ b/lgl/m4/ulonglong.m4 @@ -0,0 +1,48 @@ +# ulonglong.m4 serial 6 +dnl Copyright (C) 1999-2006 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +dnl From Paul Eggert. + +# Define HAVE_UNSIGNED_LONG_LONG_INT if 'unsigned long long int' works. +# This fixes a bug in Autoconf 2.60, but can be removed once we +# assume 2.61 everywhere. + +# Note: If the type 'unsigned long long int' exists but is only 32 bits +# large (as on some very old compilers), AC_TYPE_UNSIGNED_LONG_LONG_INT +# will not be defined. In this case you can treat 'unsigned long long int' +# like 'unsigned long int'. + +AC_DEFUN([AC_TYPE_UNSIGNED_LONG_LONG_INT], +[ + AC_CACHE_CHECK([for unsigned long long int], + [ac_cv_type_unsigned_long_long_int], + [AC_LINK_IFELSE( + [AC_LANG_PROGRAM( + [[unsigned long long int ull = 18446744073709551615ULL; + typedef int a[(18446744073709551615ULL <= (unsigned long long int) -1 + ? 1 : -1)]; + int i = 63;]], + [[unsigned long long int ullmax = 18446744073709551615ull; + return (ull << 63 | ull >> 63 | ull << i | ull >> i + | ullmax / ull | ullmax % ull);]])], + [ac_cv_type_unsigned_long_long_int=yes], + [ac_cv_type_unsigned_long_long_int=no])]) + if test $ac_cv_type_unsigned_long_long_int = yes; then + AC_DEFINE([HAVE_UNSIGNED_LONG_LONG_INT], 1, + [Define to 1 if the system has the type `unsigned long long int'.]) + fi +]) + +# This macro is obsolescent and should go away soon. +AC_DEFUN([gl_AC_TYPE_UNSIGNED_LONG_LONG], +[ + AC_REQUIRE([AC_TYPE_UNSIGNED_LONG_LONG_INT]) + ac_cv_type_unsigned_long_long=$ac_cv_type_unsigned_long_long_int + if test $ac_cv_type_unsigned_long_long = yes; then + AC_DEFINE(HAVE_UNSIGNED_LONG_LONG, 1, + [Define if you have the 'unsigned long long' type.]) + fi +]) diff --git a/lgl/md2.c b/lgl/md2.c new file mode 100644 index 0000000000..b7b607a40e --- /dev/null +++ b/lgl/md2.c @@ -0,0 +1,275 @@ +/* Functions to compute MD2 message digest of files or memory blocks. + according to the definition of MD2 in RFC 1319 from April 1992. + Copyright (C) 1995,1996,1997,1999,2000,2001,2002,2003,2005 + Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by the + Free Software Foundation; either version 2.1, or (at your option) any + later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +/* Adapted by Simon Josefsson from public domain Libtomcrypt 1.06 by + Tom St Denis. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include "md2.h" + +#include <string.h> +#include <sys/types.h> + +#include <minmax.h> + +#if USE_UNLOCKED_IO +# include "unlocked-io.h" +#endif + +#define BLOCKSIZE 4096 +#if BLOCKSIZE % 64 != 0 +# error "invalid BLOCKSIZE" +#endif + +static void md2_update_chksum (struct md2_ctx *md); +static void md2_compress (struct md2_ctx *md); + +/* Initialize structure containing state of computation. + (RFC 1319, 3.3: Step 3) */ +void +md2_init_ctx (struct md2_ctx *ctx) +{ + memset (ctx->X, 0, sizeof (ctx->X)); + memset (ctx->chksum, 0, sizeof (ctx->chksum)); + memset (ctx->buf, 0, sizeof (ctx->buf)); + ctx->curlen = 0; +} + +/* Put result from CTX in first 16 bytes following RESBUF. The result + must be in little endian byte order. + + IMPORTANT: On some systems it is required that RESBUF is correctly + aligned for a 32 bits value. */ +void * +md2_read_ctx (const struct md2_ctx *ctx, void *resbuf) +{ + memcpy (resbuf, ctx->X, 16); + + return resbuf; +} + +/* Process the remaining bytes in the internal buffer and the usual + prolog according to the standard and write the result to RESBUF. + + IMPORTANT: On some systems it is required that RESBUF is correctly + aligned for a 32 bits value. */ +void * +md2_finish_ctx (struct md2_ctx *ctx, void *resbuf) +{ + unsigned long i, k; + + /* pad the message */ + k = 16 - ctx->curlen; + for (i = ctx->curlen; i < 16; i++) + { + ctx->buf[i] = (unsigned char) k; + } + + /* hash and update */ + md2_compress (ctx); + md2_update_chksum (ctx); + + /* hash checksum */ + memcpy (ctx->buf, ctx->chksum, 16); + md2_compress (ctx); + + return md2_read_ctx (ctx, resbuf); +} + +/* Compute MD2 message digest for bytes read from STREAM. The + resulting message digest number will be written into the 16 bytes + beginning at RESBLOCK. */ +int +md2_stream (FILE *stream, void *resblock) +{ + struct md2_ctx ctx; + char buffer[BLOCKSIZE + 72]; + size_t sum; + + /* Initialize the computation context. */ + md2_init_ctx (&ctx); + + /* Iterate over full file contents. */ + while (1) + { + /* We read the file in blocks of BLOCKSIZE bytes. One call of the + computation function processes the whole buffer so that with the + next round of the loop another block can be read. */ + size_t n; + sum = 0; + + /* Read block. Take care for partial reads. */ + while (1) + { + n = fread (buffer + sum, 1, BLOCKSIZE - sum, stream); + + sum += n; + + if (sum == BLOCKSIZE) + break; + + if (n == 0) + { + /* Check for the error flag IFF N == 0, so that we don't + exit the loop after a partial read due to e.g., EAGAIN + or EWOULDBLOCK. */ + if (ferror (stream)) + return 1; + goto process_partial_block; + } + + /* We've read at least one byte, so ignore errors. But always + check for EOF, since feof may be true even though N > 0. + Otherwise, we could end up calling fread after EOF. */ + if (feof (stream)) + goto process_partial_block; + } + + /* Process buffer with BLOCKSIZE bytes. Note that + BLOCKSIZE % 64 == 0 + */ + md2_process_block (buffer, BLOCKSIZE, &ctx); + } + +process_partial_block:; + + /* Process any remaining bytes. */ + if (sum > 0) + md2_process_bytes (buffer, sum, &ctx); + + /* Construct result in desired memory. */ + md2_finish_ctx (&ctx, resblock); + return 0; +} + +/* Compute MD5 message digest for LEN bytes beginning at BUFFER. The + result is always in little endian byte order, so that a byte-wise + output yields to the wanted ASCII representation of the message + digest. */ +void * +md2_buffer (const char *buffer, size_t len, void *resblock) +{ + struct md2_ctx ctx; + + /* Initialize the computation context. */ + md2_init_ctx (&ctx); + + /* Process whole buffer but last len % 64 bytes. */ + md2_process_block (buffer, len, &ctx); + + /* Put result in desired memory area. */ + return md2_finish_ctx (&ctx, resblock); +} + +void +md2_process_bytes (const void *buffer, size_t len, struct md2_ctx *ctx) +{ + const char *in = buffer; + unsigned long n; + + while (len > 0) + { + n = MIN (len, (16 - ctx->curlen)); + memcpy (ctx->buf + ctx->curlen, in, (size_t) n); + ctx->curlen += n; + in += n; + len -= n; + + /* is 16 bytes full? */ + if (ctx->curlen == 16) + { + md2_compress (ctx); + md2_update_chksum (ctx); + ctx->curlen = 0; + } + } +} + +static const unsigned char PI_SUBST[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 +}; + +/* adds 16 bytes to the checksum */ +static void +md2_update_chksum (struct md2_ctx *ctx) +{ + int j; + unsigned char L; + + L = ctx->chksum[15]; + for (j = 0; j < 16; j++) + { + /* caution, the RFC says its "C[j] = S[M[i*16+j] xor L]" but the + reference source code [and test vectors] say otherwise. */ + L = (ctx->chksum[j] ^= PI_SUBST[(int) (ctx->buf[j] ^ L)] & 255); + } +} + +static void +md2_compress (struct md2_ctx *ctx) +{ + size_t j, k; + unsigned char t; + + /* copy block */ + for (j = 0; j < 16; j++) + { + ctx->X[16 + j] = ctx->buf[j]; + ctx->X[32 + j] = ctx->X[j] ^ ctx->X[16 + j]; + } + + t = (unsigned char) 0; + + /* do 18 rounds */ + for (j = 0; j < 18; j++) + { + for (k = 0; k < 48; k++) + { + t = (ctx->X[k] ^= PI_SUBST[(int) (t & 255)]); + } + t = (t + (unsigned char) j) & 255; + } +} + +/* Process LEN bytes of BUFFER, accumulating context into CTX. */ +void +md2_process_block (const void *buffer, size_t len, struct md2_ctx *ctx) +{ + md2_process_bytes (buffer, len, ctx); +} diff --git a/lgl/md2.h b/lgl/md2.h new file mode 100644 index 0000000000..917e05fc26 --- /dev/null +++ b/lgl/md2.h @@ -0,0 +1,82 @@ +/* Declarations of functions and data types used for MD2 sum + library functions. + Copyright (C) 2000, 2001, 2003, 2005 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by the + Free Software Foundation; either version 2.1, or (at your option) any + later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#ifndef MD2_H +# define MD2_H 1 + +# include <stdio.h> +# include <stddef.h> + +# define MD2_DIGEST_SIZE 16 + +/* Structure to save state of computation between the single steps. */ +struct md2_ctx +{ + unsigned char chksum[16], X[48], buf[16]; + size_t curlen; +}; + + +/* Initialize structure containing state of computation. */ +extern void md2_init_ctx (struct md2_ctx *ctx); + +/* Starting with the result of former calls of this function (or the + initialization function update the context for the next LEN bytes + starting at BUFFER. + It is NOT required that LEN is a multiple of 64. */ +extern void md2_process_block (const void *buffer, size_t len, + struct md2_ctx *ctx); + +/* Starting with the result of former calls of this function (or the + initialization function update the context for the next LEN bytes + starting at BUFFER. + It is NOT required that LEN is a multiple of 64. */ +extern void md2_process_bytes (const void *buffer, size_t len, + struct md2_ctx *ctx); + +/* Process the remaining bytes in the buffer and put result from CTX + in first 16 bytes following RESBUF. The result is always in little + endian byte order, so that a byte-wise output yields to the wanted + ASCII representation of the message digest. + + IMPORTANT: On some systems it is required that RESBUF be correctly + aligned for a 32 bits value. */ +extern void *md2_finish_ctx (struct md2_ctx *ctx, void *resbuf); + + +/* Put result from CTX in first 16 bytes following RESBUF. The result is + always in little endian byte order, so that a byte-wise output yields + to the wanted ASCII representation of the message digest. + + IMPORTANT: On some systems it is required that RESBUF is correctly + aligned for a 32 bits value. */ +extern void *md2_read_ctx (const struct md2_ctx *ctx, void *resbuf); + + +/* Compute MD2 message digest for bytes read from STREAM. The + resulting message digest number will be written into the 16 bytes + beginning at RESBLOCK. */ +extern int md2_stream (FILE *stream, void *resblock); + +/* Compute MD2 message digest for LEN bytes beginning at BUFFER. The + result is always in little endian byte order, so that a byte-wise + output yields to the wanted ASCII representation of the message + digest. */ +extern void *md2_buffer (const char *buffer, size_t len, void *resblock); + +#endif diff --git a/lgl/md4.c b/lgl/md4.c new file mode 100644 index 0000000000..74ee419b2c --- /dev/null +++ b/lgl/md4.c @@ -0,0 +1,380 @@ +/* Functions to compute MD4 message digest of files or memory blocks. + according to the definition of MD4 in RFC 1320 from April 1992. + Copyright (C) 1995,1996,1997,1999,2000,2001,2002,2003,2005,2006 + Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by the + Free Software Foundation; either version 2.1, or (at your option) any + later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +/* Adapted by Simon Josefsson from gnulib md5.? and Libgcrypt + cipher/md4.c . */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include "md4.h" + +#include <stddef.h> +#include <stdlib.h> +#include <string.h> +#include <sys/types.h> + +#if USE_UNLOCKED_IO +# include "unlocked-io.h" +#endif + +#ifdef WORDS_BIGENDIAN +# define SWAP(n) \ + (((n) << 24) | (((n) & 0xff00) << 8) | (((n) >> 8) & 0xff00) | ((n) >> 24)) +#else +# define SWAP(n) (n) +#endif + +#define BLOCKSIZE 4096 +#if BLOCKSIZE % 64 != 0 +# error "invalid BLOCKSIZE" +#endif + +/* This array contains the bytes used to pad the buffer to the next + 64-byte boundary. (RFC 1320, 3.1: Step 1) */ +static const unsigned char fillbuf[64] = { 0x80, 0 /* , 0, 0, ... */ }; + + +/* Initialize structure containing state of computation. + (RFC 1320, 3.3: Step 3) */ +void +md4_init_ctx (struct md4_ctx *ctx) +{ + ctx->A = 0x67452301; + ctx->B = 0xefcdab89; + ctx->C = 0x98badcfe; + ctx->D = 0x10325476; + + ctx->total[0] = ctx->total[1] = 0; + ctx->buflen = 0; +} + +/* Put result from CTX in first 16 bytes following RESBUF. The result + must be in little endian byte order. + + IMPORTANT: On some systems it is required that RESBUF is correctly + aligned for a 32 bits value. */ +void * +md4_read_ctx (const struct md4_ctx *ctx, void *resbuf) +{ + ((uint32_t *) resbuf)[0] = SWAP (ctx->A); + ((uint32_t *) resbuf)[1] = SWAP (ctx->B); + ((uint32_t *) resbuf)[2] = SWAP (ctx->C); + ((uint32_t *) resbuf)[3] = SWAP (ctx->D); + + return resbuf; +} + +/* Process the remaining bytes in the internal buffer and the usual + prolog according to the standard and write the result to RESBUF. + + IMPORTANT: On some systems it is required that RESBUF is correctly + aligned for a 32 bits value. */ +void * +md4_finish_ctx (struct md4_ctx *ctx, void *resbuf) +{ + /* Take yet unprocessed bytes into account. */ + uint32_t bytes = ctx->buflen; + size_t pad; + + /* Now count remaining bytes. */ + ctx->total[0] += bytes; + if (ctx->total[0] < bytes) + ++ctx->total[1]; + + pad = bytes >= 56 ? 64 + 56 - bytes : 56 - bytes; + memcpy (&((char*)ctx->buffer)[bytes], fillbuf, pad); + + /* Put the 64-bit file length in *bits* at the end of the buffer. */ + ctx->buffer[(bytes + pad) / 4] = SWAP (ctx->total[0] << 3); + ctx->buffer[(bytes + pad) / 4 + 1] = SWAP ((ctx->total[1] << 3) | + (ctx->total[0] >> 29)); + + /* Process last bytes. */ + md4_process_block (ctx->buffer, bytes + pad + 8, ctx); + + return md4_read_ctx (ctx, resbuf); +} + +/* Compute MD4 message digest for bytes read from STREAM. The + resulting message digest number will be written into the 16 bytes + beginning at RESBLOCK. */ +int +md4_stream (FILE * stream, void *resblock) +{ + struct md4_ctx ctx; + char buffer[BLOCKSIZE + 72]; + size_t sum; + + /* Initialize the computation context. */ + md4_init_ctx (&ctx); + + /* Iterate over full file contents. */ + while (1) + { + /* We read the file in blocks of BLOCKSIZE bytes. One call of the + computation function processes the whole buffer so that with the + next round of the loop another block can be read. */ + size_t n; + sum = 0; + + /* Read block. Take care for partial reads. */ + while (1) + { + n = fread (buffer + sum, 1, BLOCKSIZE - sum, stream); + + sum += n; + + if (sum == BLOCKSIZE) + break; + + if (n == 0) + { + /* Check for the error flag IFF N == 0, so that we don't + exit the loop after a partial read due to e.g., EAGAIN + or EWOULDBLOCK. */ + if (ferror (stream)) + return 1; + goto process_partial_block; + } + + /* We've read at least one byte, so ignore errors. But always + check for EOF, since feof may be true even though N > 0. + Otherwise, we could end up calling fread after EOF. */ + if (feof (stream)) + goto process_partial_block; + } + + /* Process buffer with BLOCKSIZE bytes. Note that + BLOCKSIZE % 64 == 0 + */ + md4_process_block (buffer, BLOCKSIZE, &ctx); + } + +process_partial_block:; + + /* Process any remaining bytes. */ + if (sum > 0) + md4_process_bytes (buffer, sum, &ctx); + + /* Construct result in desired memory. */ + md4_finish_ctx (&ctx, resblock); + return 0; +} + +/* Compute MD4 message digest for LEN bytes beginning at BUFFER. The + result is always in little endian byte order, so that a byte-wise + output yields to the wanted ASCII representation of the message + digest. */ +void * +md4_buffer (const char *buffer, size_t len, void *resblock) +{ + struct md4_ctx ctx; + + /* Initialize the computation context. */ + md4_init_ctx (&ctx); + + /* Process whole buffer but last len % 64 bytes. */ + md4_process_bytes (buffer, len, &ctx); + + /* Put result in desired memory area. */ + return md4_finish_ctx (&ctx, resblock); +} + +void +md4_process_bytes (const void *buffer, size_t len, struct md4_ctx *ctx) +{ + /* When we already have some bits in our internal buffer concatenate + both inputs first. */ + if (ctx->buflen != 0) + { + size_t left_over = ctx->buflen; + size_t add = 128 - left_over > len ? len : 128 - left_over; + + memcpy (&((char*)ctx->buffer)[left_over], buffer, add); + ctx->buflen += add; + + if (ctx->buflen > 64) + { + md4_process_block (ctx->buffer, ctx->buflen & ~63, ctx); + + ctx->buflen &= 63; + /* The regions in the following copy operation cannot overlap. */ + memcpy (ctx->buffer, &((char*)ctx->buffer)[(left_over + add) & ~63], + ctx->buflen); + } + + buffer = (const char *) buffer + add; + len -= add; + } + + /* Process available complete blocks. */ + if (len >= 64) + { +#if !_STRING_ARCH_unaligned + /* To check alignment gcc has an appropriate operator. Other + compilers don't. */ +# if __GNUC__ >= 2 +# define UNALIGNED_P(p) (((uintptr_t) p) % __alignof__ (uint32_t) != 0) +# else +# define alignof(type) offsetof (struct { char c; type x; }, x) +# define UNALIGNED_P(p) (((size_t) p) % alignof (uint32_t) != 0) +# endif + if (UNALIGNED_P (buffer)) + while (len > 64) + { + md4_process_block (memcpy (ctx->buffer, buffer, 64), 64, ctx); + buffer = (const char *) buffer + 64; + len -= 64; + } + else +#endif + { + md4_process_block (buffer, len & ~63, ctx); + buffer = (const char *) buffer + (len & ~63); + len &= 63; + } + } + + /* Move remaining bytes in internal buffer. */ + if (len > 0) + { + size_t left_over = ctx->buflen; + + memcpy (&((char*)ctx->buffer)[left_over], buffer, len); + left_over += len; + if (left_over >= 64) + { + md4_process_block (ctx->buffer, 64, ctx); + left_over -= 64; + memcpy (ctx->buffer, &ctx->buffer[16], left_over); + } + ctx->buflen = left_over; + } +} + +/* --- Code below is the primary difference between md5.c and md4.c --- */ + +/* MD4 round constants */ +#define K1 0x5a827999 +#define K2 0x6ed9eba1 + +/* Round functions. */ +#define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z)))) +#define G(x, y, z) (((x) & (y)) | ((x) & (z)) | ((y) & (z))) +#define H(x, y, z) ((x) ^ (y) ^ (z)) +#define rol(x, n) (((x) << (n)) | ((uint32_t) (x) >> (32 - (n)))) +#define R1(a,b,c,d,k,s) a=rol(a+F(b,c,d)+x[k],s); +#define R2(a,b,c,d,k,s) a=rol(a+G(b,c,d)+x[k]+K1,s); +#define R3(a,b,c,d,k,s) a=rol(a+H(b,c,d)+x[k]+K2,s); + +/* Process LEN bytes of BUFFER, accumulating context into CTX. + It is assumed that LEN % 64 == 0. */ + +void +md4_process_block (const void *buffer, size_t len, struct md4_ctx *ctx) +{ + const uint32_t *words = buffer; + size_t nwords = len / sizeof (uint32_t); + const uint32_t *endp = words + nwords; + uint32_t x[16]; + uint32_t A = ctx->A; + uint32_t B = ctx->B; + uint32_t C = ctx->C; + uint32_t D = ctx->D; + + /* First increment the byte count. RFC 1320 specifies the possible + length of the file up to 2^64 bits. Here we only compute the + number of bytes. Do a double word increment. */ + ctx->total[0] += len; + if (ctx->total[0] < len) + ++ctx->total[1]; + + /* Process all bytes in the buffer with 64 bytes in each round of + the loop. */ + while (words < endp) + { + int t; + for (t = 0; t < 16; t++) + { + x[t] = SWAP (*words); + words++; + } + + /* Round 1. */ + R1 (A, B, C, D, 0, 3); + R1 (D, A, B, C, 1, 7); + R1 (C, D, A, B, 2, 11); + R1 (B, C, D, A, 3, 19); + R1 (A, B, C, D, 4, 3); + R1 (D, A, B, C, 5, 7); + R1 (C, D, A, B, 6, 11); + R1 (B, C, D, A, 7, 19); + R1 (A, B, C, D, 8, 3); + R1 (D, A, B, C, 9, 7); + R1 (C, D, A, B, 10, 11); + R1 (B, C, D, A, 11, 19); + R1 (A, B, C, D, 12, 3); + R1 (D, A, B, C, 13, 7); + R1 (C, D, A, B, 14, 11); + R1 (B, C, D, A, 15, 19); + + /* Round 2. */ + R2 (A, B, C, D, 0, 3); + R2 (D, A, B, C, 4, 5); + R2 (C, D, A, B, 8, 9); + R2 (B, C, D, A, 12, 13); + R2 (A, B, C, D, 1, 3); + R2 (D, A, B, C, 5, 5); + R2 (C, D, A, B, 9, 9); + R2 (B, C, D, A, 13, 13); + R2 (A, B, C, D, 2, 3); + R2 (D, A, B, C, 6, 5); + R2 (C, D, A, B, 10, 9); + R2 (B, C, D, A, 14, 13); + R2 (A, B, C, D, 3, 3); + R2 (D, A, B, C, 7, 5); + R2 (C, D, A, B, 11, 9); + R2 (B, C, D, A, 15, 13); + + /* Round 3. */ + R3 (A, B, C, D, 0, 3); + R3 (D, A, B, C, 8, 9); + R3 (C, D, A, B, 4, 11); + R3 (B, C, D, A, 12, 15); + R3 (A, B, C, D, 2, 3); + R3 (D, A, B, C, 10, 9); + R3 (C, D, A, B, 6, 11); + R3 (B, C, D, A, 14, 15); + R3 (A, B, C, D, 1, 3); + R3 (D, A, B, C, 9, 9); + R3 (C, D, A, B, 5, 11); + R3 (B, C, D, A, 13, 15); + R3 (A, B, C, D, 3, 3); + R3 (D, A, B, C, 11, 9); + R3 (C, D, A, B, 7, 11); + R3 (B, C, D, A, 15, 15); + + A = ctx->A += A; + B = ctx->B += B; + C = ctx->C += C; + D = ctx->D += D; + } +} diff --git a/lgl/md4.h b/lgl/md4.h new file mode 100644 index 0000000000..8450664774 --- /dev/null +++ b/lgl/md4.h @@ -0,0 +1,88 @@ +/* Declarations of functions and data types used for MD4 sum + library functions. + Copyright (C) 2000, 2001, 2003, 2005 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by the + Free Software Foundation; either version 2.1, or (at your option) any + later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#ifndef MD4_H +# define MD4_H 1 + +# include <stdio.h> +# include <stdint.h> + +# define MD4_DIGEST_SIZE 16 + +/* Structure to save state of computation between the single steps. */ +struct md4_ctx +{ + uint32_t A; + uint32_t B; + uint32_t C; + uint32_t D; + + uint32_t total[2]; + uint32_t buflen; + uint32_t buffer[32]; +}; + + +/* Initialize structure containing state of computation. */ +extern void md4_init_ctx (struct md4_ctx *ctx); + +/* Starting with the result of former calls of this function (or the + initialization function update the context for the next LEN bytes + starting at BUFFER. + It is necessary that LEN is a multiple of 64!!! */ +extern void md4_process_block (const void *buffer, size_t len, + struct md4_ctx *ctx); + +/* Starting with the result of former calls of this function (or the + initialization function update the context for the next LEN bytes + starting at BUFFER. + It is NOT required that LEN is a multiple of 64. */ +extern void md4_process_bytes (const void *buffer, size_t len, + struct md4_ctx *ctx); + +/* Process the remaining bytes in the buffer and put result from CTX + in first 16 bytes following RESBUF. The result is always in little + endian byte order, so that a byte-wise output yields to the wanted + ASCII representation of the message digest. + + IMPORTANT: On some systems it is required that RESBUF be correctly + aligned for a 32 bits value. */ +extern void *md4_finish_ctx (struct md4_ctx *ctx, void *resbuf); + + +/* Put result from CTX in first 16 bytes following RESBUF. The result is + always in little endian byte order, so that a byte-wise output yields + to the wanted ASCII representation of the message digest. + + IMPORTANT: On some systems it is required that RESBUF is correctly + aligned for a 32 bits value. */ +extern void *md4_read_ctx (const struct md4_ctx *ctx, void *resbuf); + + +/* Compute MD4 message digest for bytes read from STREAM. The + resulting message digest number will be written into the 16 bytes + beginning at RESBLOCK. */ +extern int md4_stream (FILE * stream, void *resblock); + +/* Compute MD4 message digest for LEN bytes beginning at BUFFER. The + result is always in little endian byte order, so that a byte-wise + output yields to the wanted ASCII representation of the message + digest. */ +extern void *md4_buffer (const char *buffer, size_t len, void *resblock); + +#endif diff --git a/lgl/md5.c b/lgl/md5.c new file mode 100644 index 0000000000..7d7024e8a5 --- /dev/null +++ b/lgl/md5.c @@ -0,0 +1,451 @@ +/* Functions to compute MD5 message digest of files or memory blocks. + according to the definition of MD5 in RFC 1321 from April 1992. + Copyright (C) 1995,1996,1997,1999,2000,2001,2005,2006 + Free Software Foundation, Inc. + This file is part of the GNU C Library. + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by the + Free Software Foundation; either version 2.1, or (at your option) any + later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +/* Written by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995. */ + +#include <config.h> + +#include "md5.h" + +#include <stddef.h> +#include <stdlib.h> +#include <string.h> +#include <sys/types.h> + +#if USE_UNLOCKED_IO +# include "unlocked-io.h" +#endif + +#ifdef _LIBC +# include <endian.h> +# if __BYTE_ORDER == __BIG_ENDIAN +# define WORDS_BIGENDIAN 1 +# endif +/* We need to keep the namespace clean so define the MD5 function + protected using leading __ . */ +# define md5_init_ctx __md5_init_ctx +# define md5_process_block __md5_process_block +# define md5_process_bytes __md5_process_bytes +# define md5_finish_ctx __md5_finish_ctx +# define md5_read_ctx __md5_read_ctx +# define md5_stream __md5_stream +# define md5_buffer __md5_buffer +#endif + +#ifdef WORDS_BIGENDIAN +# define SWAP(n) \ + (((n) << 24) | (((n) & 0xff00) << 8) | (((n) >> 8) & 0xff00) | ((n) >> 24)) +#else +# define SWAP(n) (n) +#endif + +#define BLOCKSIZE 4096 +#if BLOCKSIZE % 64 != 0 +# error "invalid BLOCKSIZE" +#endif + +/* This array contains the bytes used to pad the buffer to the next + 64-byte boundary. (RFC 1321, 3.1: Step 1) */ +static const unsigned char fillbuf[64] = { 0x80, 0 /* , 0, 0, ... */ }; + + +/* Initialize structure containing state of computation. + (RFC 1321, 3.3: Step 3) */ +void +md5_init_ctx (struct md5_ctx *ctx) +{ + ctx->A = 0x67452301; + ctx->B = 0xefcdab89; + ctx->C = 0x98badcfe; + ctx->D = 0x10325476; + + ctx->total[0] = ctx->total[1] = 0; + ctx->buflen = 0; +} + +/* Put result from CTX in first 16 bytes following RESBUF. The result + must be in little endian byte order. + + IMPORTANT: On some systems it is required that RESBUF is correctly + aligned for a 32-bit value. */ +void * +md5_read_ctx (const struct md5_ctx *ctx, void *resbuf) +{ + ((uint32_t *) resbuf)[0] = SWAP (ctx->A); + ((uint32_t *) resbuf)[1] = SWAP (ctx->B); + ((uint32_t *) resbuf)[2] = SWAP (ctx->C); + ((uint32_t *) resbuf)[3] = SWAP (ctx->D); + + return resbuf; +} + +/* Process the remaining bytes in the internal buffer and the usual + prolog according to the standard and write the result to RESBUF. + + IMPORTANT: On some systems it is required that RESBUF is correctly + aligned for a 32-bit value. */ +void * +md5_finish_ctx (struct md5_ctx *ctx, void *resbuf) +{ + /* Take yet unprocessed bytes into account. */ + uint32_t bytes = ctx->buflen; + size_t size = (bytes < 56) ? 64 / 4 : 64 * 2 / 4; + + /* Now count remaining bytes. */ + ctx->total[0] += bytes; + if (ctx->total[0] < bytes) + ++ctx->total[1]; + + /* Put the 64-bit file length in *bits* at the end of the buffer. */ + ctx->buffer[size - 2] = SWAP (ctx->total[0] << 3); + ctx->buffer[size - 1] = SWAP ((ctx->total[1] << 3) | (ctx->total[0] >> 29)); + + memcpy (&((char *) ctx->buffer)[bytes], fillbuf, (size - 2) * 4 - bytes); + + /* Process last bytes. */ + md5_process_block (ctx->buffer, size * 4, ctx); + + return md5_read_ctx (ctx, resbuf); +} + +/* Compute MD5 message digest for bytes read from STREAM. The + resulting message digest number will be written into the 16 bytes + beginning at RESBLOCK. */ +int +md5_stream (FILE *stream, void *resblock) +{ + struct md5_ctx ctx; + char buffer[BLOCKSIZE + 72]; + size_t sum; + + /* Initialize the computation context. */ + md5_init_ctx (&ctx); + + /* Iterate over full file contents. */ + while (1) + { + /* We read the file in blocks of BLOCKSIZE bytes. One call of the + computation function processes the whole buffer so that with the + next round of the loop another block can be read. */ + size_t n; + sum = 0; + + /* Read block. Take care for partial reads. */ + while (1) + { + n = fread (buffer + sum, 1, BLOCKSIZE - sum, stream); + + sum += n; + + if (sum == BLOCKSIZE) + break; + + if (n == 0) + { + /* Check for the error flag IFF N == 0, so that we don't + exit the loop after a partial read due to e.g., EAGAIN + or EWOULDBLOCK. */ + if (ferror (stream)) + return 1; + goto process_partial_block; + } + + /* We've read at least one byte, so ignore errors. But always + check for EOF, since feof may be true even though N > 0. + Otherwise, we could end up calling fread after EOF. */ + if (feof (stream)) + goto process_partial_block; + } + + /* Process buffer with BLOCKSIZE bytes. Note that + BLOCKSIZE % 64 == 0 + */ + md5_process_block (buffer, BLOCKSIZE, &ctx); + } + +process_partial_block: + + /* Process any remaining bytes. */ + if (sum > 0) + md5_process_bytes (buffer, sum, &ctx); + + /* Construct result in desired memory. */ + md5_finish_ctx (&ctx, resblock); + return 0; +} + +/* Compute MD5 message digest for LEN bytes beginning at BUFFER. The + result is always in little endian byte order, so that a byte-wise + output yields to the wanted ASCII representation of the message + digest. */ +void * +md5_buffer (const char *buffer, size_t len, void *resblock) +{ + struct md5_ctx ctx; + + /* Initialize the computation context. */ + md5_init_ctx (&ctx); + + /* Process whole buffer but last len % 64 bytes. */ + md5_process_bytes (buffer, len, &ctx); + + /* Put result in desired memory area. */ + return md5_finish_ctx (&ctx, resblock); +} + + +void +md5_process_bytes (const void *buffer, size_t len, struct md5_ctx *ctx) +{ + /* When we already have some bits in our internal buffer concatenate + both inputs first. */ + if (ctx->buflen != 0) + { + size_t left_over = ctx->buflen; + size_t add = 128 - left_over > len ? len : 128 - left_over; + + memcpy (&((char *) ctx->buffer)[left_over], buffer, add); + ctx->buflen += add; + + if (ctx->buflen > 64) + { + md5_process_block (ctx->buffer, ctx->buflen & ~63, ctx); + + ctx->buflen &= 63; + /* The regions in the following copy operation cannot overlap. */ + memcpy (ctx->buffer, + &((char *) ctx->buffer)[(left_over + add) & ~63], + ctx->buflen); + } + + buffer = (const char *) buffer + add; + len -= add; + } + + /* Process available complete blocks. */ + if (len >= 64) + { +#if !_STRING_ARCH_unaligned +# define alignof(type) offsetof (struct { char c; type x; }, x) +# define UNALIGNED_P(p) (((size_t) p) % alignof (uint32_t) != 0) + if (UNALIGNED_P (buffer)) + while (len > 64) + { + md5_process_block (memcpy (ctx->buffer, buffer, 64), 64, ctx); + buffer = (const char *) buffer + 64; + len -= 64; + } + else +#endif + { + md5_process_block (buffer, len & ~63, ctx); + buffer = (const char *) buffer + (len & ~63); + len &= 63; + } + } + + /* Move remaining bytes in internal buffer. */ + if (len > 0) + { + size_t left_over = ctx->buflen; + + memcpy (&((char *) ctx->buffer)[left_over], buffer, len); + left_over += len; + if (left_over >= 64) + { + md5_process_block (ctx->buffer, 64, ctx); + left_over -= 64; + memcpy (ctx->buffer, &ctx->buffer[16], left_over); + } + ctx->buflen = left_over; + } +} + + +/* These are the four functions used in the four steps of the MD5 algorithm + and defined in the RFC 1321. The first function is a little bit optimized + (as found in Colin Plumbs public domain implementation). */ +/* #define FF(b, c, d) ((b & c) | (~b & d)) */ +#define FF(b, c, d) (d ^ (b & (c ^ d))) +#define FG(b, c, d) FF (d, b, c) +#define FH(b, c, d) (b ^ c ^ d) +#define FI(b, c, d) (c ^ (b | ~d)) + +/* Process LEN bytes of BUFFER, accumulating context into CTX. + It is assumed that LEN % 64 == 0. */ + +void +md5_process_block (const void *buffer, size_t len, struct md5_ctx *ctx) +{ + uint32_t correct_words[16]; + const uint32_t *words = buffer; + size_t nwords = len / sizeof (uint32_t); + const uint32_t *endp = words + nwords; + uint32_t A = ctx->A; + uint32_t B = ctx->B; + uint32_t C = ctx->C; + uint32_t D = ctx->D; + + /* First increment the byte count. RFC 1321 specifies the possible + length of the file up to 2^64 bits. Here we only compute the + number of bytes. Do a double word increment. */ + ctx->total[0] += len; + if (ctx->total[0] < len) + ++ctx->total[1]; + + /* Process all bytes in the buffer with 64 bytes in each round of + the loop. */ + while (words < endp) + { + uint32_t *cwp = correct_words; + uint32_t A_save = A; + uint32_t B_save = B; + uint32_t C_save = C; + uint32_t D_save = D; + + /* First round: using the given function, the context and a constant + the next context is computed. Because the algorithms processing + unit is a 32-bit word and it is determined to work on words in + little endian byte order we perhaps have to change the byte order + before the computation. To reduce the work for the next steps + we store the swapped words in the array CORRECT_WORDS. */ + +#define OP(a, b, c, d, s, T) \ + do \ + { \ + a += FF (b, c, d) + (*cwp++ = SWAP (*words)) + T; \ + ++words; \ + CYCLIC (a, s); \ + a += b; \ + } \ + while (0) + + /* It is unfortunate that C does not provide an operator for + cyclic rotation. Hope the C compiler is smart enough. */ +#define CYCLIC(w, s) (w = (w << s) | (w >> (32 - s))) + + /* Before we start, one word to the strange constants. + They are defined in RFC 1321 as + + T[i] = (int) (4294967296.0 * fabs (sin (i))), i=1..64 + + Here is an equivalent invocation using Perl: + + perl -e 'foreach(1..64){printf "0x%08x\n", int (4294967296 * abs (sin $_))}' + */ + + /* Round 1. */ + OP (A, B, C, D, 7, 0xd76aa478); + OP (D, A, B, C, 12, 0xe8c7b756); + OP (C, D, A, B, 17, 0x242070db); + OP (B, C, D, A, 22, 0xc1bdceee); + OP (A, B, C, D, 7, 0xf57c0faf); + OP (D, A, B, C, 12, 0x4787c62a); + OP (C, D, A, B, 17, 0xa8304613); + OP (B, C, D, A, 22, 0xfd469501); + OP (A, B, C, D, 7, 0x698098d8); + OP (D, A, B, C, 12, 0x8b44f7af); + OP (C, D, A, B, 17, 0xffff5bb1); + OP (B, C, D, A, 22, 0x895cd7be); + OP (A, B, C, D, 7, 0x6b901122); + OP (D, A, B, C, 12, 0xfd987193); + OP (C, D, A, B, 17, 0xa679438e); + OP (B, C, D, A, 22, 0x49b40821); + + /* For the second to fourth round we have the possibly swapped words + in CORRECT_WORDS. Redefine the macro to take an additional first + argument specifying the function to use. */ +#undef OP +#define OP(f, a, b, c, d, k, s, T) \ + do \ + { \ + a += f (b, c, d) + correct_words[k] + T; \ + CYCLIC (a, s); \ + a += b; \ + } \ + while (0) + + /* Round 2. */ + OP (FG, A, B, C, D, 1, 5, 0xf61e2562); + OP (FG, D, A, B, C, 6, 9, 0xc040b340); + OP (FG, C, D, A, B, 11, 14, 0x265e5a51); + OP (FG, B, C, D, A, 0, 20, 0xe9b6c7aa); + OP (FG, A, B, C, D, 5, 5, 0xd62f105d); + OP (FG, D, A, B, C, 10, 9, 0x02441453); + OP (FG, C, D, A, B, 15, 14, 0xd8a1e681); + OP (FG, B, C, D, A, 4, 20, 0xe7d3fbc8); + OP (FG, A, B, C, D, 9, 5, 0x21e1cde6); + OP (FG, D, A, B, C, 14, 9, 0xc33707d6); + OP (FG, C, D, A, B, 3, 14, 0xf4d50d87); + OP (FG, B, C, D, A, 8, 20, 0x455a14ed); + OP (FG, A, B, C, D, 13, 5, 0xa9e3e905); + OP (FG, D, A, B, C, 2, 9, 0xfcefa3f8); + OP (FG, C, D, A, B, 7, 14, 0x676f02d9); + OP (FG, B, C, D, A, 12, 20, 0x8d2a4c8a); + + /* Round 3. */ + OP (FH, A, B, C, D, 5, 4, 0xfffa3942); + OP (FH, D, A, B, C, 8, 11, 0x8771f681); + OP (FH, C, D, A, B, 11, 16, 0x6d9d6122); + OP (FH, B, C, D, A, 14, 23, 0xfde5380c); + OP (FH, A, B, C, D, 1, 4, 0xa4beea44); + OP (FH, D, A, B, C, 4, 11, 0x4bdecfa9); + OP (FH, C, D, A, B, 7, 16, 0xf6bb4b60); + OP (FH, B, C, D, A, 10, 23, 0xbebfbc70); + OP (FH, A, B, C, D, 13, 4, 0x289b7ec6); + OP (FH, D, A, B, C, 0, 11, 0xeaa127fa); + OP (FH, C, D, A, B, 3, 16, 0xd4ef3085); + OP (FH, B, C, D, A, 6, 23, 0x04881d05); + OP (FH, A, B, C, D, 9, 4, 0xd9d4d039); + OP (FH, D, A, B, C, 12, 11, 0xe6db99e5); + OP (FH, C, D, A, B, 15, 16, 0x1fa27cf8); + OP (FH, B, C, D, A, 2, 23, 0xc4ac5665); + + /* Round 4. */ + OP (FI, A, B, C, D, 0, 6, 0xf4292244); + OP (FI, D, A, B, C, 7, 10, 0x432aff97); + OP (FI, C, D, A, B, 14, 15, 0xab9423a7); + OP (FI, B, C, D, A, 5, 21, 0xfc93a039); + OP (FI, A, B, C, D, 12, 6, 0x655b59c3); + OP (FI, D, A, B, C, 3, 10, 0x8f0ccc92); + OP (FI, C, D, A, B, 10, 15, 0xffeff47d); + OP (FI, B, C, D, A, 1, 21, 0x85845dd1); + OP (FI, A, B, C, D, 8, 6, 0x6fa87e4f); + OP (FI, D, A, B, C, 15, 10, 0xfe2ce6e0); + OP (FI, C, D, A, B, 6, 15, 0xa3014314); + OP (FI, B, C, D, A, 13, 21, 0x4e0811a1); + OP (FI, A, B, C, D, 4, 6, 0xf7537e82); + OP (FI, D, A, B, C, 11, 10, 0xbd3af235); + OP (FI, C, D, A, B, 2, 15, 0x2ad7d2bb); + OP (FI, B, C, D, A, 9, 21, 0xeb86d391); + + /* Add the starting values of the context. */ + A += A_save; + B += B_save; + C += C_save; + D += D_save; + } + + /* Put checksum in context given as argument. */ + ctx->A = A; + ctx->B = B; + ctx->C = C; + ctx->D = D; +} diff --git a/lgl/md5.h b/lgl/md5.h new file mode 100644 index 0000000000..6018a6f6d5 --- /dev/null +++ b/lgl/md5.h @@ -0,0 +1,124 @@ +/* Declaration of functions and data types used for MD5 sum computing + library functions. + Copyright (C) 1995-1997,1999,2000,2001,2004,2005,2006 + Free Software Foundation, Inc. + This file is part of the GNU C Library. + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by the + Free Software Foundation; either version 2.1, or (at your option) any + later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#ifndef _MD5_H +#define _MD5_H 1 + +#include <stdio.h> +#include <stdint.h> + +#define MD5_DIGEST_SIZE 16 +#define MD5_BLOCK_SIZE 64 + +#ifndef __GNUC_PREREQ +# if defined __GNUC__ && defined __GNUC_MINOR__ +# define __GNUC_PREREQ(maj, min) \ + ((__GNUC__ << 16) + __GNUC_MINOR__ >= ((maj) << 16) + (min)) +# else +# define __GNUC_PREREQ(maj, min) 0 +# endif +#endif + +#ifndef __THROW +# if defined __cplusplus && __GNUC_PREREQ (2,8) +# define __THROW throw () +# else +# define __THROW +# endif +#endif + +#ifndef _LIBC +# define __md5_buffer md5_buffer +# define __md5_finish_ctx md5_finish_ctx +# define __md5_init_ctx md5_init_ctx +# define __md5_process_block md5_process_block +# define __md5_process_bytes md5_process_bytes +# define __md5_read_ctx md5_read_ctx +# define __md5_stream md5_stream +#endif + +/* Structure to save state of computation between the single steps. */ +struct md5_ctx +{ + uint32_t A; + uint32_t B; + uint32_t C; + uint32_t D; + + uint32_t total[2]; + uint32_t buflen; + uint32_t buffer[32]; +}; + +/* + * The following three functions are build up the low level used in + * the functions `md5_stream' and `md5_buffer'. + */ + +/* Initialize structure containing state of computation. + (RFC 1321, 3.3: Step 3) */ +extern void __md5_init_ctx (struct md5_ctx *ctx) __THROW; + +/* Starting with the result of former calls of this function (or the + initialization function update the context for the next LEN bytes + starting at BUFFER. + It is necessary that LEN is a multiple of 64!!! */ +extern void __md5_process_block (const void *buffer, size_t len, + struct md5_ctx *ctx) __THROW; + +/* Starting with the result of former calls of this function (or the + initialization function update the context for the next LEN bytes + starting at BUFFER. + It is NOT required that LEN is a multiple of 64. */ +extern void __md5_process_bytes (const void *buffer, size_t len, + struct md5_ctx *ctx) __THROW; + +/* Process the remaining bytes in the buffer and put result from CTX + in first 16 bytes following RESBUF. The result is always in little + endian byte order, so that a byte-wise output yields to the wanted + ASCII representation of the message digest. + + IMPORTANT: On some systems, RESBUF must be aligned to a 32-bit + boundary. */ +extern void *__md5_finish_ctx (struct md5_ctx *ctx, void *resbuf) __THROW; + + +/* Put result from CTX in first 16 bytes following RESBUF. The result is + always in little endian byte order, so that a byte-wise output yields + to the wanted ASCII representation of the message digest. + + IMPORTANT: On some systems, RESBUF must be aligned to a 32-bit + boundary. */ +extern void *__md5_read_ctx (const struct md5_ctx *ctx, void *resbuf) __THROW; + + +/* Compute MD5 message digest for bytes read from STREAM. The + resulting message digest number will be written into the 16 bytes + beginning at RESBLOCK. */ +extern int __md5_stream (FILE *stream, void *resblock) __THROW; + +/* Compute MD5 message digest for LEN bytes beginning at BUFFER. The + result is always in little endian byte order, so that a byte-wise + output yields to the wanted ASCII representation of the message + digest. */ +extern void *__md5_buffer (const char *buffer, size_t len, + void *resblock) __THROW; + +#endif /* md5.h */ diff --git a/lgl/memxor.c b/lgl/memxor.c new file mode 100644 index 0000000000..a046844604 --- /dev/null +++ b/lgl/memxor.c @@ -0,0 +1,37 @@ +/* memxor.c -- perform binary exclusive OR operation of two memory blocks. + Copyright (C) 2005 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +/* Written by Simon Josefsson. The interface was inspired by memxor + in Niels Möller's Nettle. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include "memxor.h" + +void * +memxor (void *restrict dest, const void *restrict src, size_t n) +{ + char const *s = src; + char *d = dest; + + for (; n > 0; n--) + *d++ ^= *s++; + + return dest; +} diff --git a/lgl/memxor.h b/lgl/memxor.h new file mode 100644 index 0000000000..4f85f2d7e9 --- /dev/null +++ b/lgl/memxor.h @@ -0,0 +1,31 @@ +/* memxor.h -- perform binary exclusive OR operation on memory blocks. + Copyright (C) 2005 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +/* Written by Simon Josefsson. The interface was inspired by memxor + in Niels Möller's Nettle. */ + +#ifndef MEMXOR_H +# define MEMXOR_H + +#include <stddef.h> + +/* Compute binary exclusive OR of memory areas DEST and SRC, putting + the result in DEST, of length N bytes. Returns a pointer to + DEST. */ +void *memxor (void *restrict dest, const void *restrict src, size_t n); + +#endif /* MEMXOR_H */ diff --git a/lgl/minmax.h b/lgl/minmax.h new file mode 100644 index 0000000000..431e7dd918 --- /dev/null +++ b/lgl/minmax.h @@ -0,0 +1,60 @@ +/* MIN, MAX macros. + Copyright (C) 1995, 1998, 2001, 2003, 2005 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#ifndef _MINMAX_H +#define _MINMAX_H + +/* Note: MIN, MAX are also defined in <sys/param.h> on some systems + (glibc, IRIX, HP-UX, OSF/1). Therefore you might get warnings about + MIN, MAX macro redefinitions on some systems; the workaround is to + #include this file as the last one among the #include list. */ + +/* Before we define the following symbols we get the <limits.h> file + since otherwise we get redefinitions on some systems if <limits.h> is + included after this file. Likewise for <sys/param.h>. + If more than one of these system headers define MIN and MAX, pick just + one of the headers (because the definitions most likely are the same). */ +#if HAVE_MINMAX_IN_LIMITS_H +# include <limits.h> +#elif HAVE_MINMAX_IN_SYS_PARAM_H +# include <sys/param.h> +#endif + +/* Note: MIN and MAX should be used with two arguments of the + same type. They might not return the minimum and maximum of their two + arguments, if the arguments have different types or have unusual + floating-point values. For example, on a typical host with 32-bit 'int', + 64-bit 'long long', and 64-bit IEEE 754 'double' types: + + MAX (-1, 2147483648) returns 4294967295. + MAX (9007199254740992.0, 9007199254740993) returns 9007199254740992.0. + MAX (NaN, 0.0) returns 0.0. + MAX (+0.0, -0.0) returns -0.0. + + and in each case the answer is in some sense bogus. */ + +/* MAX(a,b) returns the maximum of A and B. */ +#ifndef MAX +# define MAX(a,b) ((a) > (b) ? (a) : (b)) +#endif + +/* MIN(a,b) returns the minimum of A and B. */ +#ifndef MIN +# define MIN(a,b) ((a) < (b) ? (a) : (b)) +#endif + +#endif /* _MINMAX_H */ diff --git a/lgl/rijndael-alg-fst.c b/lgl/rijndael-alg-fst.c new file mode 100644 index 0000000000..5bc5e7e072 --- /dev/null +++ b/lgl/rijndael-alg-fst.c @@ -0,0 +1,1085 @@ +/* rijndael-alg-fst.c --- Rijndael cipher implementation. + * Copyright (C) 2005 Free Software Foundation, Inc. + * + * This file is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation; either version 2.1, or (at your + * option) any later version. + * + * This file is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this file; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + * + */ + +/* Adapted for gnulib by Simon Josefsson. + * + * Based on public domain "Optimised C code" retrieved from (SHA1 + * 7c8e4b00d06685d1dbc6724a9e0d502353de339e): + * http://www.iaik.tu-graz.ac.at/research/krypto/AES/old/~rijmen/rijndael/rijndael-fst-3.0.zip + */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +/** + * rijndael-alg-fst.c + * + * @version 3.0 (December 2000) + * + * Optimised ANSI C code for the Rijndael cipher (now AES) + * + * @author Vincent Rijmen <vincent.rijmen@esat.kuleuven.ac.be> + * @author Antoon Bosselaers <antoon.bosselaers@esat.kuleuven.ac.be> + * @author Paulo Barreto <paulo.barreto@terra.com.br> + * + * This code is hereby placed in the public domain. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''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 AUTHORS 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 "rijndael-alg-fst.h" + +/* +Te0[x] = S [x].[02, 01, 01, 03]; +Te1[x] = S [x].[03, 02, 01, 01]; +Te2[x] = S [x].[01, 03, 02, 01]; +Te3[x] = S [x].[01, 01, 03, 02]; +Te4[x] = S [x].[01, 01, 01, 01]; + +Td0[x] = Si[x].[0e, 09, 0d, 0b]; +Td1[x] = Si[x].[0b, 0e, 09, 0d]; +Td2[x] = Si[x].[0d, 0b, 0e, 09]; +Td3[x] = Si[x].[09, 0d, 0b, 0e]; +Td4[x] = Si[x].[01, 01, 01, 01]; +*/ + +static const uint32_t Te0[256] = { + 0xc66363a5, 0xf87c7c84, 0xee777799, 0xf67b7b8d, + 0xfff2f20d, 0xd66b6bbd, 0xde6f6fb1, 0x91c5c554, + 0x60303050, 0x02010103, 0xce6767a9, 0x562b2b7d, + 0xe7fefe19, 0xb5d7d762, 0x4dababe6, 0xec76769a, + 0x8fcaca45, 0x1f82829d, 0x89c9c940, 0xfa7d7d87, + 0xeffafa15, 0xb25959eb, 0x8e4747c9, 0xfbf0f00b, + 0x41adadec, 0xb3d4d467, 0x5fa2a2fd, 0x45afafea, + 0x239c9cbf, 0x53a4a4f7, 0xe4727296, 0x9bc0c05b, + 0x75b7b7c2, 0xe1fdfd1c, 0x3d9393ae, 0x4c26266a, + 0x6c36365a, 0x7e3f3f41, 0xf5f7f702, 0x83cccc4f, + 0x6834345c, 0x51a5a5f4, 0xd1e5e534, 0xf9f1f108, + 0xe2717193, 0xabd8d873, 0x62313153, 0x2a15153f, + 0x0804040c, 0x95c7c752, 0x46232365, 0x9dc3c35e, + 0x30181828, 0x379696a1, 0x0a05050f, 0x2f9a9ab5, + 0x0e070709, 0x24121236, 0x1b80809b, 0xdfe2e23d, + 0xcdebeb26, 0x4e272769, 0x7fb2b2cd, 0xea75759f, + 0x1209091b, 0x1d83839e, 0x582c2c74, 0x341a1a2e, + 0x361b1b2d, 0xdc6e6eb2, 0xb45a5aee, 0x5ba0a0fb, + 0xa45252f6, 0x763b3b4d, 0xb7d6d661, 0x7db3b3ce, + 0x5229297b, 0xdde3e33e, 0x5e2f2f71, 0x13848497, + 0xa65353f5, 0xb9d1d168, 0x00000000, 0xc1eded2c, + 0x40202060, 0xe3fcfc1f, 0x79b1b1c8, 0xb65b5bed, + 0xd46a6abe, 0x8dcbcb46, 0x67bebed9, 0x7239394b, + 0x944a4ade, 0x984c4cd4, 0xb05858e8, 0x85cfcf4a, + 0xbbd0d06b, 0xc5efef2a, 0x4faaaae5, 0xedfbfb16, + 0x864343c5, 0x9a4d4dd7, 0x66333355, 0x11858594, + 0x8a4545cf, 0xe9f9f910, 0x04020206, 0xfe7f7f81, + 0xa05050f0, 0x783c3c44, 0x259f9fba, 0x4ba8a8e3, + 0xa25151f3, 0x5da3a3fe, 0x804040c0, 0x058f8f8a, + 0x3f9292ad, 0x219d9dbc, 0x70383848, 0xf1f5f504, + 0x63bcbcdf, 0x77b6b6c1, 0xafdada75, 0x42212163, + 0x20101030, 0xe5ffff1a, 0xfdf3f30e, 0xbfd2d26d, + 0x81cdcd4c, 0x180c0c14, 0x26131335, 0xc3ecec2f, + 0xbe5f5fe1, 0x359797a2, 0x884444cc, 0x2e171739, + 0x93c4c457, 0x55a7a7f2, 0xfc7e7e82, 0x7a3d3d47, + 0xc86464ac, 0xba5d5de7, 0x3219192b, 0xe6737395, + 0xc06060a0, 0x19818198, 0x9e4f4fd1, 0xa3dcdc7f, + 0x44222266, 0x542a2a7e, 0x3b9090ab, 0x0b888883, + 0x8c4646ca, 0xc7eeee29, 0x6bb8b8d3, 0x2814143c, + 0xa7dede79, 0xbc5e5ee2, 0x160b0b1d, 0xaddbdb76, + 0xdbe0e03b, 0x64323256, 0x743a3a4e, 0x140a0a1e, + 0x924949db, 0x0c06060a, 0x4824246c, 0xb85c5ce4, + 0x9fc2c25d, 0xbdd3d36e, 0x43acacef, 0xc46262a6, + 0x399191a8, 0x319595a4, 0xd3e4e437, 0xf279798b, + 0xd5e7e732, 0x8bc8c843, 0x6e373759, 0xda6d6db7, + 0x018d8d8c, 0xb1d5d564, 0x9c4e4ed2, 0x49a9a9e0, + 0xd86c6cb4, 0xac5656fa, 0xf3f4f407, 0xcfeaea25, + 0xca6565af, 0xf47a7a8e, 0x47aeaee9, 0x10080818, + 0x6fbabad5, 0xf0787888, 0x4a25256f, 0x5c2e2e72, + 0x381c1c24, 0x57a6a6f1, 0x73b4b4c7, 0x97c6c651, + 0xcbe8e823, 0xa1dddd7c, 0xe874749c, 0x3e1f1f21, + 0x964b4bdd, 0x61bdbddc, 0x0d8b8b86, 0x0f8a8a85, + 0xe0707090, 0x7c3e3e42, 0x71b5b5c4, 0xcc6666aa, + 0x904848d8, 0x06030305, 0xf7f6f601, 0x1c0e0e12, + 0xc26161a3, 0x6a35355f, 0xae5757f9, 0x69b9b9d0, + 0x17868691, 0x99c1c158, 0x3a1d1d27, 0x279e9eb9, + 0xd9e1e138, 0xebf8f813, 0x2b9898b3, 0x22111133, + 0xd26969bb, 0xa9d9d970, 0x078e8e89, 0x339494a7, + 0x2d9b9bb6, 0x3c1e1e22, 0x15878792, 0xc9e9e920, + 0x87cece49, 0xaa5555ff, 0x50282878, 0xa5dfdf7a, + 0x038c8c8f, 0x59a1a1f8, 0x09898980, 0x1a0d0d17, + 0x65bfbfda, 0xd7e6e631, 0x844242c6, 0xd06868b8, + 0x824141c3, 0x299999b0, 0x5a2d2d77, 0x1e0f0f11, + 0x7bb0b0cb, 0xa85454fc, 0x6dbbbbd6, 0x2c16163a, +}; +static const uint32_t Te1[256] = { + 0xa5c66363, 0x84f87c7c, 0x99ee7777, 0x8df67b7b, + 0x0dfff2f2, 0xbdd66b6b, 0xb1de6f6f, 0x5491c5c5, + 0x50603030, 0x03020101, 0xa9ce6767, 0x7d562b2b, + 0x19e7fefe, 0x62b5d7d7, 0xe64dabab, 0x9aec7676, + 0x458fcaca, 0x9d1f8282, 0x4089c9c9, 0x87fa7d7d, + 0x15effafa, 0xebb25959, 0xc98e4747, 0x0bfbf0f0, + 0xec41adad, 0x67b3d4d4, 0xfd5fa2a2, 0xea45afaf, + 0xbf239c9c, 0xf753a4a4, 0x96e47272, 0x5b9bc0c0, + 0xc275b7b7, 0x1ce1fdfd, 0xae3d9393, 0x6a4c2626, + 0x5a6c3636, 0x417e3f3f, 0x02f5f7f7, 0x4f83cccc, + 0x5c683434, 0xf451a5a5, 0x34d1e5e5, 0x08f9f1f1, + 0x93e27171, 0x73abd8d8, 0x53623131, 0x3f2a1515, + 0x0c080404, 0x5295c7c7, 0x65462323, 0x5e9dc3c3, + 0x28301818, 0xa1379696, 0x0f0a0505, 0xb52f9a9a, + 0x090e0707, 0x36241212, 0x9b1b8080, 0x3ddfe2e2, + 0x26cdebeb, 0x694e2727, 0xcd7fb2b2, 0x9fea7575, + 0x1b120909, 0x9e1d8383, 0x74582c2c, 0x2e341a1a, + 0x2d361b1b, 0xb2dc6e6e, 0xeeb45a5a, 0xfb5ba0a0, + 0xf6a45252, 0x4d763b3b, 0x61b7d6d6, 0xce7db3b3, + 0x7b522929, 0x3edde3e3, 0x715e2f2f, 0x97138484, + 0xf5a65353, 0x68b9d1d1, 0x00000000, 0x2cc1eded, + 0x60402020, 0x1fe3fcfc, 0xc879b1b1, 0xedb65b5b, + 0xbed46a6a, 0x468dcbcb, 0xd967bebe, 0x4b723939, + 0xde944a4a, 0xd4984c4c, 0xe8b05858, 0x4a85cfcf, + 0x6bbbd0d0, 0x2ac5efef, 0xe54faaaa, 0x16edfbfb, + 0xc5864343, 0xd79a4d4d, 0x55663333, 0x94118585, + 0xcf8a4545, 0x10e9f9f9, 0x06040202, 0x81fe7f7f, + 0xf0a05050, 0x44783c3c, 0xba259f9f, 0xe34ba8a8, + 0xf3a25151, 0xfe5da3a3, 0xc0804040, 0x8a058f8f, + 0xad3f9292, 0xbc219d9d, 0x48703838, 0x04f1f5f5, + 0xdf63bcbc, 0xc177b6b6, 0x75afdada, 0x63422121, + 0x30201010, 0x1ae5ffff, 0x0efdf3f3, 0x6dbfd2d2, + 0x4c81cdcd, 0x14180c0c, 0x35261313, 0x2fc3ecec, + 0xe1be5f5f, 0xa2359797, 0xcc884444, 0x392e1717, + 0x5793c4c4, 0xf255a7a7, 0x82fc7e7e, 0x477a3d3d, + 0xacc86464, 0xe7ba5d5d, 0x2b321919, 0x95e67373, + 0xa0c06060, 0x98198181, 0xd19e4f4f, 0x7fa3dcdc, + 0x66442222, 0x7e542a2a, 0xab3b9090, 0x830b8888, + 0xca8c4646, 0x29c7eeee, 0xd36bb8b8, 0x3c281414, + 0x79a7dede, 0xe2bc5e5e, 0x1d160b0b, 0x76addbdb, + 0x3bdbe0e0, 0x56643232, 0x4e743a3a, 0x1e140a0a, + 0xdb924949, 0x0a0c0606, 0x6c482424, 0xe4b85c5c, + 0x5d9fc2c2, 0x6ebdd3d3, 0xef43acac, 0xa6c46262, + 0xa8399191, 0xa4319595, 0x37d3e4e4, 0x8bf27979, + 0x32d5e7e7, 0x438bc8c8, 0x596e3737, 0xb7da6d6d, + 0x8c018d8d, 0x64b1d5d5, 0xd29c4e4e, 0xe049a9a9, + 0xb4d86c6c, 0xfaac5656, 0x07f3f4f4, 0x25cfeaea, + 0xafca6565, 0x8ef47a7a, 0xe947aeae, 0x18100808, + 0xd56fbaba, 0x88f07878, 0x6f4a2525, 0x725c2e2e, + 0x24381c1c, 0xf157a6a6, 0xc773b4b4, 0x5197c6c6, + 0x23cbe8e8, 0x7ca1dddd, 0x9ce87474, 0x213e1f1f, + 0xdd964b4b, 0xdc61bdbd, 0x860d8b8b, 0x850f8a8a, + 0x90e07070, 0x427c3e3e, 0xc471b5b5, 0xaacc6666, + 0xd8904848, 0x05060303, 0x01f7f6f6, 0x121c0e0e, + 0xa3c26161, 0x5f6a3535, 0xf9ae5757, 0xd069b9b9, + 0x91178686, 0x5899c1c1, 0x273a1d1d, 0xb9279e9e, + 0x38d9e1e1, 0x13ebf8f8, 0xb32b9898, 0x33221111, + 0xbbd26969, 0x70a9d9d9, 0x89078e8e, 0xa7339494, + 0xb62d9b9b, 0x223c1e1e, 0x92158787, 0x20c9e9e9, + 0x4987cece, 0xffaa5555, 0x78502828, 0x7aa5dfdf, + 0x8f038c8c, 0xf859a1a1, 0x80098989, 0x171a0d0d, + 0xda65bfbf, 0x31d7e6e6, 0xc6844242, 0xb8d06868, + 0xc3824141, 0xb0299999, 0x775a2d2d, 0x111e0f0f, + 0xcb7bb0b0, 0xfca85454, 0xd66dbbbb, 0x3a2c1616, +}; +static const uint32_t Te2[256] = { + 0x63a5c663, 0x7c84f87c, 0x7799ee77, 0x7b8df67b, + 0xf20dfff2, 0x6bbdd66b, 0x6fb1de6f, 0xc55491c5, + 0x30506030, 0x01030201, 0x67a9ce67, 0x2b7d562b, + 0xfe19e7fe, 0xd762b5d7, 0xabe64dab, 0x769aec76, + 0xca458fca, 0x829d1f82, 0xc94089c9, 0x7d87fa7d, + 0xfa15effa, 0x59ebb259, 0x47c98e47, 0xf00bfbf0, + 0xadec41ad, 0xd467b3d4, 0xa2fd5fa2, 0xafea45af, + 0x9cbf239c, 0xa4f753a4, 0x7296e472, 0xc05b9bc0, + 0xb7c275b7, 0xfd1ce1fd, 0x93ae3d93, 0x266a4c26, + 0x365a6c36, 0x3f417e3f, 0xf702f5f7, 0xcc4f83cc, + 0x345c6834, 0xa5f451a5, 0xe534d1e5, 0xf108f9f1, + 0x7193e271, 0xd873abd8, 0x31536231, 0x153f2a15, + 0x040c0804, 0xc75295c7, 0x23654623, 0xc35e9dc3, + 0x18283018, 0x96a13796, 0x050f0a05, 0x9ab52f9a, + 0x07090e07, 0x12362412, 0x809b1b80, 0xe23ddfe2, + 0xeb26cdeb, 0x27694e27, 0xb2cd7fb2, 0x759fea75, + 0x091b1209, 0x839e1d83, 0x2c74582c, 0x1a2e341a, + 0x1b2d361b, 0x6eb2dc6e, 0x5aeeb45a, 0xa0fb5ba0, + 0x52f6a452, 0x3b4d763b, 0xd661b7d6, 0xb3ce7db3, + 0x297b5229, 0xe33edde3, 0x2f715e2f, 0x84971384, + 0x53f5a653, 0xd168b9d1, 0x00000000, 0xed2cc1ed, + 0x20604020, 0xfc1fe3fc, 0xb1c879b1, 0x5bedb65b, + 0x6abed46a, 0xcb468dcb, 0xbed967be, 0x394b7239, + 0x4ade944a, 0x4cd4984c, 0x58e8b058, 0xcf4a85cf, + 0xd06bbbd0, 0xef2ac5ef, 0xaae54faa, 0xfb16edfb, + 0x43c58643, 0x4dd79a4d, 0x33556633, 0x85941185, + 0x45cf8a45, 0xf910e9f9, 0x02060402, 0x7f81fe7f, + 0x50f0a050, 0x3c44783c, 0x9fba259f, 0xa8e34ba8, + 0x51f3a251, 0xa3fe5da3, 0x40c08040, 0x8f8a058f, + 0x92ad3f92, 0x9dbc219d, 0x38487038, 0xf504f1f5, + 0xbcdf63bc, 0xb6c177b6, 0xda75afda, 0x21634221, + 0x10302010, 0xff1ae5ff, 0xf30efdf3, 0xd26dbfd2, + 0xcd4c81cd, 0x0c14180c, 0x13352613, 0xec2fc3ec, + 0x5fe1be5f, 0x97a23597, 0x44cc8844, 0x17392e17, + 0xc45793c4, 0xa7f255a7, 0x7e82fc7e, 0x3d477a3d, + 0x64acc864, 0x5de7ba5d, 0x192b3219, 0x7395e673, + 0x60a0c060, 0x81981981, 0x4fd19e4f, 0xdc7fa3dc, + 0x22664422, 0x2a7e542a, 0x90ab3b90, 0x88830b88, + 0x46ca8c46, 0xee29c7ee, 0xb8d36bb8, 0x143c2814, + 0xde79a7de, 0x5ee2bc5e, 0x0b1d160b, 0xdb76addb, + 0xe03bdbe0, 0x32566432, 0x3a4e743a, 0x0a1e140a, + 0x49db9249, 0x060a0c06, 0x246c4824, 0x5ce4b85c, + 0xc25d9fc2, 0xd36ebdd3, 0xacef43ac, 0x62a6c462, + 0x91a83991, 0x95a43195, 0xe437d3e4, 0x798bf279, + 0xe732d5e7, 0xc8438bc8, 0x37596e37, 0x6db7da6d, + 0x8d8c018d, 0xd564b1d5, 0x4ed29c4e, 0xa9e049a9, + 0x6cb4d86c, 0x56faac56, 0xf407f3f4, 0xea25cfea, + 0x65afca65, 0x7a8ef47a, 0xaee947ae, 0x08181008, + 0xbad56fba, 0x7888f078, 0x256f4a25, 0x2e725c2e, + 0x1c24381c, 0xa6f157a6, 0xb4c773b4, 0xc65197c6, + 0xe823cbe8, 0xdd7ca1dd, 0x749ce874, 0x1f213e1f, + 0x4bdd964b, 0xbddc61bd, 0x8b860d8b, 0x8a850f8a, + 0x7090e070, 0x3e427c3e, 0xb5c471b5, 0x66aacc66, + 0x48d89048, 0x03050603, 0xf601f7f6, 0x0e121c0e, + 0x61a3c261, 0x355f6a35, 0x57f9ae57, 0xb9d069b9, + 0x86911786, 0xc15899c1, 0x1d273a1d, 0x9eb9279e, + 0xe138d9e1, 0xf813ebf8, 0x98b32b98, 0x11332211, + 0x69bbd269, 0xd970a9d9, 0x8e89078e, 0x94a73394, + 0x9bb62d9b, 0x1e223c1e, 0x87921587, 0xe920c9e9, + 0xce4987ce, 0x55ffaa55, 0x28785028, 0xdf7aa5df, + 0x8c8f038c, 0xa1f859a1, 0x89800989, 0x0d171a0d, + 0xbfda65bf, 0xe631d7e6, 0x42c68442, 0x68b8d068, + 0x41c38241, 0x99b02999, 0x2d775a2d, 0x0f111e0f, + 0xb0cb7bb0, 0x54fca854, 0xbbd66dbb, 0x163a2c16, +}; +static const uint32_t Te3[256] = { + 0x6363a5c6, 0x7c7c84f8, 0x777799ee, 0x7b7b8df6, + 0xf2f20dff, 0x6b6bbdd6, 0x6f6fb1de, 0xc5c55491, + 0x30305060, 0x01010302, 0x6767a9ce, 0x2b2b7d56, + 0xfefe19e7, 0xd7d762b5, 0xababe64d, 0x76769aec, + 0xcaca458f, 0x82829d1f, 0xc9c94089, 0x7d7d87fa, + 0xfafa15ef, 0x5959ebb2, 0x4747c98e, 0xf0f00bfb, + 0xadadec41, 0xd4d467b3, 0xa2a2fd5f, 0xafafea45, + 0x9c9cbf23, 0xa4a4f753, 0x727296e4, 0xc0c05b9b, + 0xb7b7c275, 0xfdfd1ce1, 0x9393ae3d, 0x26266a4c, + 0x36365a6c, 0x3f3f417e, 0xf7f702f5, 0xcccc4f83, + 0x34345c68, 0xa5a5f451, 0xe5e534d1, 0xf1f108f9, + 0x717193e2, 0xd8d873ab, 0x31315362, 0x15153f2a, + 0x04040c08, 0xc7c75295, 0x23236546, 0xc3c35e9d, + 0x18182830, 0x9696a137, 0x05050f0a, 0x9a9ab52f, + 0x0707090e, 0x12123624, 0x80809b1b, 0xe2e23ddf, + 0xebeb26cd, 0x2727694e, 0xb2b2cd7f, 0x75759fea, + 0x09091b12, 0x83839e1d, 0x2c2c7458, 0x1a1a2e34, + 0x1b1b2d36, 0x6e6eb2dc, 0x5a5aeeb4, 0xa0a0fb5b, + 0x5252f6a4, 0x3b3b4d76, 0xd6d661b7, 0xb3b3ce7d, + 0x29297b52, 0xe3e33edd, 0x2f2f715e, 0x84849713, + 0x5353f5a6, 0xd1d168b9, 0x00000000, 0xeded2cc1, + 0x20206040, 0xfcfc1fe3, 0xb1b1c879, 0x5b5bedb6, + 0x6a6abed4, 0xcbcb468d, 0xbebed967, 0x39394b72, + 0x4a4ade94, 0x4c4cd498, 0x5858e8b0, 0xcfcf4a85, + 0xd0d06bbb, 0xefef2ac5, 0xaaaae54f, 0xfbfb16ed, + 0x4343c586, 0x4d4dd79a, 0x33335566, 0x85859411, + 0x4545cf8a, 0xf9f910e9, 0x02020604, 0x7f7f81fe, + 0x5050f0a0, 0x3c3c4478, 0x9f9fba25, 0xa8a8e34b, + 0x5151f3a2, 0xa3a3fe5d, 0x4040c080, 0x8f8f8a05, + 0x9292ad3f, 0x9d9dbc21, 0x38384870, 0xf5f504f1, + 0xbcbcdf63, 0xb6b6c177, 0xdada75af, 0x21216342, + 0x10103020, 0xffff1ae5, 0xf3f30efd, 0xd2d26dbf, + 0xcdcd4c81, 0x0c0c1418, 0x13133526, 0xecec2fc3, + 0x5f5fe1be, 0x9797a235, 0x4444cc88, 0x1717392e, + 0xc4c45793, 0xa7a7f255, 0x7e7e82fc, 0x3d3d477a, + 0x6464acc8, 0x5d5de7ba, 0x19192b32, 0x737395e6, + 0x6060a0c0, 0x81819819, 0x4f4fd19e, 0xdcdc7fa3, + 0x22226644, 0x2a2a7e54, 0x9090ab3b, 0x8888830b, + 0x4646ca8c, 0xeeee29c7, 0xb8b8d36b, 0x14143c28, + 0xdede79a7, 0x5e5ee2bc, 0x0b0b1d16, 0xdbdb76ad, + 0xe0e03bdb, 0x32325664, 0x3a3a4e74, 0x0a0a1e14, + 0x4949db92, 0x06060a0c, 0x24246c48, 0x5c5ce4b8, + 0xc2c25d9f, 0xd3d36ebd, 0xacacef43, 0x6262a6c4, + 0x9191a839, 0x9595a431, 0xe4e437d3, 0x79798bf2, + 0xe7e732d5, 0xc8c8438b, 0x3737596e, 0x6d6db7da, + 0x8d8d8c01, 0xd5d564b1, 0x4e4ed29c, 0xa9a9e049, + 0x6c6cb4d8, 0x5656faac, 0xf4f407f3, 0xeaea25cf, + 0x6565afca, 0x7a7a8ef4, 0xaeaee947, 0x08081810, + 0xbabad56f, 0x787888f0, 0x25256f4a, 0x2e2e725c, + 0x1c1c2438, 0xa6a6f157, 0xb4b4c773, 0xc6c65197, + 0xe8e823cb, 0xdddd7ca1, 0x74749ce8, 0x1f1f213e, + 0x4b4bdd96, 0xbdbddc61, 0x8b8b860d, 0x8a8a850f, + 0x707090e0, 0x3e3e427c, 0xb5b5c471, 0x6666aacc, + 0x4848d890, 0x03030506, 0xf6f601f7, 0x0e0e121c, + 0x6161a3c2, 0x35355f6a, 0x5757f9ae, 0xb9b9d069, + 0x86869117, 0xc1c15899, 0x1d1d273a, 0x9e9eb927, + 0xe1e138d9, 0xf8f813eb, 0x9898b32b, 0x11113322, + 0x6969bbd2, 0xd9d970a9, 0x8e8e8907, 0x9494a733, + 0x9b9bb62d, 0x1e1e223c, 0x87879215, 0xe9e920c9, + 0xcece4987, 0x5555ffaa, 0x28287850, 0xdfdf7aa5, + 0x8c8c8f03, 0xa1a1f859, 0x89898009, 0x0d0d171a, + 0xbfbfda65, 0xe6e631d7, 0x4242c684, 0x6868b8d0, + 0x4141c382, 0x9999b029, 0x2d2d775a, 0x0f0f111e, + 0xb0b0cb7b, 0x5454fca8, 0xbbbbd66d, 0x16163a2c, +}; +static const uint32_t Te4[256] = { + 0x63636363, 0x7c7c7c7c, 0x77777777, 0x7b7b7b7b, + 0xf2f2f2f2, 0x6b6b6b6b, 0x6f6f6f6f, 0xc5c5c5c5, + 0x30303030, 0x01010101, 0x67676767, 0x2b2b2b2b, + 0xfefefefe, 0xd7d7d7d7, 0xabababab, 0x76767676, + 0xcacacaca, 0x82828282, 0xc9c9c9c9, 0x7d7d7d7d, + 0xfafafafa, 0x59595959, 0x47474747, 0xf0f0f0f0, + 0xadadadad, 0xd4d4d4d4, 0xa2a2a2a2, 0xafafafaf, + 0x9c9c9c9c, 0xa4a4a4a4, 0x72727272, 0xc0c0c0c0, + 0xb7b7b7b7, 0xfdfdfdfd, 0x93939393, 0x26262626, + 0x36363636, 0x3f3f3f3f, 0xf7f7f7f7, 0xcccccccc, + 0x34343434, 0xa5a5a5a5, 0xe5e5e5e5, 0xf1f1f1f1, + 0x71717171, 0xd8d8d8d8, 0x31313131, 0x15151515, + 0x04040404, 0xc7c7c7c7, 0x23232323, 0xc3c3c3c3, + 0x18181818, 0x96969696, 0x05050505, 0x9a9a9a9a, + 0x07070707, 0x12121212, 0x80808080, 0xe2e2e2e2, + 0xebebebeb, 0x27272727, 0xb2b2b2b2, 0x75757575, + 0x09090909, 0x83838383, 0x2c2c2c2c, 0x1a1a1a1a, + 0x1b1b1b1b, 0x6e6e6e6e, 0x5a5a5a5a, 0xa0a0a0a0, + 0x52525252, 0x3b3b3b3b, 0xd6d6d6d6, 0xb3b3b3b3, + 0x29292929, 0xe3e3e3e3, 0x2f2f2f2f, 0x84848484, + 0x53535353, 0xd1d1d1d1, 0x00000000, 0xedededed, + 0x20202020, 0xfcfcfcfc, 0xb1b1b1b1, 0x5b5b5b5b, + 0x6a6a6a6a, 0xcbcbcbcb, 0xbebebebe, 0x39393939, + 0x4a4a4a4a, 0x4c4c4c4c, 0x58585858, 0xcfcfcfcf, + 0xd0d0d0d0, 0xefefefef, 0xaaaaaaaa, 0xfbfbfbfb, + 0x43434343, 0x4d4d4d4d, 0x33333333, 0x85858585, + 0x45454545, 0xf9f9f9f9, 0x02020202, 0x7f7f7f7f, + 0x50505050, 0x3c3c3c3c, 0x9f9f9f9f, 0xa8a8a8a8, + 0x51515151, 0xa3a3a3a3, 0x40404040, 0x8f8f8f8f, + 0x92929292, 0x9d9d9d9d, 0x38383838, 0xf5f5f5f5, + 0xbcbcbcbc, 0xb6b6b6b6, 0xdadadada, 0x21212121, + 0x10101010, 0xffffffff, 0xf3f3f3f3, 0xd2d2d2d2, + 0xcdcdcdcd, 0x0c0c0c0c, 0x13131313, 0xecececec, + 0x5f5f5f5f, 0x97979797, 0x44444444, 0x17171717, + 0xc4c4c4c4, 0xa7a7a7a7, 0x7e7e7e7e, 0x3d3d3d3d, + 0x64646464, 0x5d5d5d5d, 0x19191919, 0x73737373, + 0x60606060, 0x81818181, 0x4f4f4f4f, 0xdcdcdcdc, + 0x22222222, 0x2a2a2a2a, 0x90909090, 0x88888888, + 0x46464646, 0xeeeeeeee, 0xb8b8b8b8, 0x14141414, + 0xdededede, 0x5e5e5e5e, 0x0b0b0b0b, 0xdbdbdbdb, + 0xe0e0e0e0, 0x32323232, 0x3a3a3a3a, 0x0a0a0a0a, + 0x49494949, 0x06060606, 0x24242424, 0x5c5c5c5c, + 0xc2c2c2c2, 0xd3d3d3d3, 0xacacacac, 0x62626262, + 0x91919191, 0x95959595, 0xe4e4e4e4, 0x79797979, + 0xe7e7e7e7, 0xc8c8c8c8, 0x37373737, 0x6d6d6d6d, + 0x8d8d8d8d, 0xd5d5d5d5, 0x4e4e4e4e, 0xa9a9a9a9, + 0x6c6c6c6c, 0x56565656, 0xf4f4f4f4, 0xeaeaeaea, + 0x65656565, 0x7a7a7a7a, 0xaeaeaeae, 0x08080808, + 0xbabababa, 0x78787878, 0x25252525, 0x2e2e2e2e, + 0x1c1c1c1c, 0xa6a6a6a6, 0xb4b4b4b4, 0xc6c6c6c6, + 0xe8e8e8e8, 0xdddddddd, 0x74747474, 0x1f1f1f1f, + 0x4b4b4b4b, 0xbdbdbdbd, 0x8b8b8b8b, 0x8a8a8a8a, + 0x70707070, 0x3e3e3e3e, 0xb5b5b5b5, 0x66666666, + 0x48484848, 0x03030303, 0xf6f6f6f6, 0x0e0e0e0e, + 0x61616161, 0x35353535, 0x57575757, 0xb9b9b9b9, + 0x86868686, 0xc1c1c1c1, 0x1d1d1d1d, 0x9e9e9e9e, + 0xe1e1e1e1, 0xf8f8f8f8, 0x98989898, 0x11111111, + 0x69696969, 0xd9d9d9d9, 0x8e8e8e8e, 0x94949494, + 0x9b9b9b9b, 0x1e1e1e1e, 0x87878787, 0xe9e9e9e9, + 0xcececece, 0x55555555, 0x28282828, 0xdfdfdfdf, + 0x8c8c8c8c, 0xa1a1a1a1, 0x89898989, 0x0d0d0d0d, + 0xbfbfbfbf, 0xe6e6e6e6, 0x42424242, 0x68686868, + 0x41414141, 0x99999999, 0x2d2d2d2d, 0x0f0f0f0f, + 0xb0b0b0b0, 0x54545454, 0xbbbbbbbb, 0x16161616, +}; +static const uint32_t Td0[256] = { + 0x51f4a750, 0x7e416553, 0x1a17a4c3, 0x3a275e96, + 0x3bab6bcb, 0x1f9d45f1, 0xacfa58ab, 0x4be30393, + 0x2030fa55, 0xad766df6, 0x88cc7691, 0xf5024c25, + 0x4fe5d7fc, 0xc52acbd7, 0x26354480, 0xb562a38f, + 0xdeb15a49, 0x25ba1b67, 0x45ea0e98, 0x5dfec0e1, + 0xc32f7502, 0x814cf012, 0x8d4697a3, 0x6bd3f9c6, + 0x038f5fe7, 0x15929c95, 0xbf6d7aeb, 0x955259da, + 0xd4be832d, 0x587421d3, 0x49e06929, 0x8ec9c844, + 0x75c2896a, 0xf48e7978, 0x99583e6b, 0x27b971dd, + 0xbee14fb6, 0xf088ad17, 0xc920ac66, 0x7dce3ab4, + 0x63df4a18, 0xe51a3182, 0x97513360, 0x62537f45, + 0xb16477e0, 0xbb6bae84, 0xfe81a01c, 0xf9082b94, + 0x70486858, 0x8f45fd19, 0x94de6c87, 0x527bf8b7, + 0xab73d323, 0x724b02e2, 0xe31f8f57, 0x6655ab2a, + 0xb2eb2807, 0x2fb5c203, 0x86c57b9a, 0xd33708a5, + 0x302887f2, 0x23bfa5b2, 0x02036aba, 0xed16825c, + 0x8acf1c2b, 0xa779b492, 0xf307f2f0, 0x4e69e2a1, + 0x65daf4cd, 0x0605bed5, 0xd134621f, 0xc4a6fe8a, + 0x342e539d, 0xa2f355a0, 0x058ae132, 0xa4f6eb75, + 0x0b83ec39, 0x4060efaa, 0x5e719f06, 0xbd6e1051, + 0x3e218af9, 0x96dd063d, 0xdd3e05ae, 0x4de6bd46, + 0x91548db5, 0x71c45d05, 0x0406d46f, 0x605015ff, + 0x1998fb24, 0xd6bde997, 0x894043cc, 0x67d99e77, + 0xb0e842bd, 0x07898b88, 0xe7195b38, 0x79c8eedb, + 0xa17c0a47, 0x7c420fe9, 0xf8841ec9, 0x00000000, + 0x09808683, 0x322bed48, 0x1e1170ac, 0x6c5a724e, + 0xfd0efffb, 0x0f853856, 0x3daed51e, 0x362d3927, + 0x0a0fd964, 0x685ca621, 0x9b5b54d1, 0x24362e3a, + 0x0c0a67b1, 0x9357e70f, 0xb4ee96d2, 0x1b9b919e, + 0x80c0c54f, 0x61dc20a2, 0x5a774b69, 0x1c121a16, + 0xe293ba0a, 0xc0a02ae5, 0x3c22e043, 0x121b171d, + 0x0e090d0b, 0xf28bc7ad, 0x2db6a8b9, 0x141ea9c8, + 0x57f11985, 0xaf75074c, 0xee99ddbb, 0xa37f60fd, + 0xf701269f, 0x5c72f5bc, 0x44663bc5, 0x5bfb7e34, + 0x8b432976, 0xcb23c6dc, 0xb6edfc68, 0xb8e4f163, + 0xd731dcca, 0x42638510, 0x13972240, 0x84c61120, + 0x854a247d, 0xd2bb3df8, 0xaef93211, 0xc729a16d, + 0x1d9e2f4b, 0xdcb230f3, 0x0d8652ec, 0x77c1e3d0, + 0x2bb3166c, 0xa970b999, 0x119448fa, 0x47e96422, + 0xa8fc8cc4, 0xa0f03f1a, 0x567d2cd8, 0x223390ef, + 0x87494ec7, 0xd938d1c1, 0x8ccaa2fe, 0x98d40b36, + 0xa6f581cf, 0xa57ade28, 0xdab78e26, 0x3fadbfa4, + 0x2c3a9de4, 0x5078920d, 0x6a5fcc9b, 0x547e4662, + 0xf68d13c2, 0x90d8b8e8, 0x2e39f75e, 0x82c3aff5, + 0x9f5d80be, 0x69d0937c, 0x6fd52da9, 0xcf2512b3, + 0xc8ac993b, 0x10187da7, 0xe89c636e, 0xdb3bbb7b, + 0xcd267809, 0x6e5918f4, 0xec9ab701, 0x834f9aa8, + 0xe6956e65, 0xaaffe67e, 0x21bccf08, 0xef15e8e6, + 0xbae79bd9, 0x4a6f36ce, 0xea9f09d4, 0x29b07cd6, + 0x31a4b2af, 0x2a3f2331, 0xc6a59430, 0x35a266c0, + 0x744ebc37, 0xfc82caa6, 0xe090d0b0, 0x33a7d815, + 0xf104984a, 0x41ecdaf7, 0x7fcd500e, 0x1791f62f, + 0x764dd68d, 0x43efb04d, 0xccaa4d54, 0xe49604df, + 0x9ed1b5e3, 0x4c6a881b, 0xc12c1fb8, 0x4665517f, + 0x9d5eea04, 0x018c355d, 0xfa877473, 0xfb0b412e, + 0xb3671d5a, 0x92dbd252, 0xe9105633, 0x6dd64713, + 0x9ad7618c, 0x37a10c7a, 0x59f8148e, 0xeb133c89, + 0xcea927ee, 0xb761c935, 0xe11ce5ed, 0x7a47b13c, + 0x9cd2df59, 0x55f2733f, 0x1814ce79, 0x73c737bf, + 0x53f7cdea, 0x5ffdaa5b, 0xdf3d6f14, 0x7844db86, + 0xcaaff381, 0xb968c43e, 0x3824342c, 0xc2a3405f, + 0x161dc372, 0xbce2250c, 0x283c498b, 0xff0d9541, + 0x39a80171, 0x080cb3de, 0xd8b4e49c, 0x6456c190, + 0x7bcb8461, 0xd532b670, 0x486c5c74, 0xd0b85742, +}; +static const uint32_t Td1[256] = { + 0x5051f4a7, 0x537e4165, 0xc31a17a4, 0x963a275e, + 0xcb3bab6b, 0xf11f9d45, 0xabacfa58, 0x934be303, + 0x552030fa, 0xf6ad766d, 0x9188cc76, 0x25f5024c, + 0xfc4fe5d7, 0xd7c52acb, 0x80263544, 0x8fb562a3, + 0x49deb15a, 0x6725ba1b, 0x9845ea0e, 0xe15dfec0, + 0x02c32f75, 0x12814cf0, 0xa38d4697, 0xc66bd3f9, + 0xe7038f5f, 0x9515929c, 0xebbf6d7a, 0xda955259, + 0x2dd4be83, 0xd3587421, 0x2949e069, 0x448ec9c8, + 0x6a75c289, 0x78f48e79, 0x6b99583e, 0xdd27b971, + 0xb6bee14f, 0x17f088ad, 0x66c920ac, 0xb47dce3a, + 0x1863df4a, 0x82e51a31, 0x60975133, 0x4562537f, + 0xe0b16477, 0x84bb6bae, 0x1cfe81a0, 0x94f9082b, + 0x58704868, 0x198f45fd, 0x8794de6c, 0xb7527bf8, + 0x23ab73d3, 0xe2724b02, 0x57e31f8f, 0x2a6655ab, + 0x07b2eb28, 0x032fb5c2, 0x9a86c57b, 0xa5d33708, + 0xf2302887, 0xb223bfa5, 0xba02036a, 0x5ced1682, + 0x2b8acf1c, 0x92a779b4, 0xf0f307f2, 0xa14e69e2, + 0xcd65daf4, 0xd50605be, 0x1fd13462, 0x8ac4a6fe, + 0x9d342e53, 0xa0a2f355, 0x32058ae1, 0x75a4f6eb, + 0x390b83ec, 0xaa4060ef, 0x065e719f, 0x51bd6e10, + 0xf93e218a, 0x3d96dd06, 0xaedd3e05, 0x464de6bd, + 0xb591548d, 0x0571c45d, 0x6f0406d4, 0xff605015, + 0x241998fb, 0x97d6bde9, 0xcc894043, 0x7767d99e, + 0xbdb0e842, 0x8807898b, 0x38e7195b, 0xdb79c8ee, + 0x47a17c0a, 0xe97c420f, 0xc9f8841e, 0x00000000, + 0x83098086, 0x48322bed, 0xac1e1170, 0x4e6c5a72, + 0xfbfd0eff, 0x560f8538, 0x1e3daed5, 0x27362d39, + 0x640a0fd9, 0x21685ca6, 0xd19b5b54, 0x3a24362e, + 0xb10c0a67, 0x0f9357e7, 0xd2b4ee96, 0x9e1b9b91, + 0x4f80c0c5, 0xa261dc20, 0x695a774b, 0x161c121a, + 0x0ae293ba, 0xe5c0a02a, 0x433c22e0, 0x1d121b17, + 0x0b0e090d, 0xadf28bc7, 0xb92db6a8, 0xc8141ea9, + 0x8557f119, 0x4caf7507, 0xbbee99dd, 0xfda37f60, + 0x9ff70126, 0xbc5c72f5, 0xc544663b, 0x345bfb7e, + 0x768b4329, 0xdccb23c6, 0x68b6edfc, 0x63b8e4f1, + 0xcad731dc, 0x10426385, 0x40139722, 0x2084c611, + 0x7d854a24, 0xf8d2bb3d, 0x11aef932, 0x6dc729a1, + 0x4b1d9e2f, 0xf3dcb230, 0xec0d8652, 0xd077c1e3, + 0x6c2bb316, 0x99a970b9, 0xfa119448, 0x2247e964, + 0xc4a8fc8c, 0x1aa0f03f, 0xd8567d2c, 0xef223390, + 0xc787494e, 0xc1d938d1, 0xfe8ccaa2, 0x3698d40b, + 0xcfa6f581, 0x28a57ade, 0x26dab78e, 0xa43fadbf, + 0xe42c3a9d, 0x0d507892, 0x9b6a5fcc, 0x62547e46, + 0xc2f68d13, 0xe890d8b8, 0x5e2e39f7, 0xf582c3af, + 0xbe9f5d80, 0x7c69d093, 0xa96fd52d, 0xb3cf2512, + 0x3bc8ac99, 0xa710187d, 0x6ee89c63, 0x7bdb3bbb, + 0x09cd2678, 0xf46e5918, 0x01ec9ab7, 0xa8834f9a, + 0x65e6956e, 0x7eaaffe6, 0x0821bccf, 0xe6ef15e8, + 0xd9bae79b, 0xce4a6f36, 0xd4ea9f09, 0xd629b07c, + 0xaf31a4b2, 0x312a3f23, 0x30c6a594, 0xc035a266, + 0x37744ebc, 0xa6fc82ca, 0xb0e090d0, 0x1533a7d8, + 0x4af10498, 0xf741ecda, 0x0e7fcd50, 0x2f1791f6, + 0x8d764dd6, 0x4d43efb0, 0x54ccaa4d, 0xdfe49604, + 0xe39ed1b5, 0x1b4c6a88, 0xb8c12c1f, 0x7f466551, + 0x049d5eea, 0x5d018c35, 0x73fa8774, 0x2efb0b41, + 0x5ab3671d, 0x5292dbd2, 0x33e91056, 0x136dd647, + 0x8c9ad761, 0x7a37a10c, 0x8e59f814, 0x89eb133c, + 0xeecea927, 0x35b761c9, 0xede11ce5, 0x3c7a47b1, + 0x599cd2df, 0x3f55f273, 0x791814ce, 0xbf73c737, + 0xea53f7cd, 0x5b5ffdaa, 0x14df3d6f, 0x867844db, + 0x81caaff3, 0x3eb968c4, 0x2c382434, 0x5fc2a340, + 0x72161dc3, 0x0cbce225, 0x8b283c49, 0x41ff0d95, + 0x7139a801, 0xde080cb3, 0x9cd8b4e4, 0x906456c1, + 0x617bcb84, 0x70d532b6, 0x74486c5c, 0x42d0b857, +}; +static const uint32_t Td2[256] = { + 0xa75051f4, 0x65537e41, 0xa4c31a17, 0x5e963a27, + 0x6bcb3bab, 0x45f11f9d, 0x58abacfa, 0x03934be3, + 0xfa552030, 0x6df6ad76, 0x769188cc, 0x4c25f502, + 0xd7fc4fe5, 0xcbd7c52a, 0x44802635, 0xa38fb562, + 0x5a49deb1, 0x1b6725ba, 0x0e9845ea, 0xc0e15dfe, + 0x7502c32f, 0xf012814c, 0x97a38d46, 0xf9c66bd3, + 0x5fe7038f, 0x9c951592, 0x7aebbf6d, 0x59da9552, + 0x832dd4be, 0x21d35874, 0x692949e0, 0xc8448ec9, + 0x896a75c2, 0x7978f48e, 0x3e6b9958, 0x71dd27b9, + 0x4fb6bee1, 0xad17f088, 0xac66c920, 0x3ab47dce, + 0x4a1863df, 0x3182e51a, 0x33609751, 0x7f456253, + 0x77e0b164, 0xae84bb6b, 0xa01cfe81, 0x2b94f908, + 0x68587048, 0xfd198f45, 0x6c8794de, 0xf8b7527b, + 0xd323ab73, 0x02e2724b, 0x8f57e31f, 0xab2a6655, + 0x2807b2eb, 0xc2032fb5, 0x7b9a86c5, 0x08a5d337, + 0x87f23028, 0xa5b223bf, 0x6aba0203, 0x825ced16, + 0x1c2b8acf, 0xb492a779, 0xf2f0f307, 0xe2a14e69, + 0xf4cd65da, 0xbed50605, 0x621fd134, 0xfe8ac4a6, + 0x539d342e, 0x55a0a2f3, 0xe132058a, 0xeb75a4f6, + 0xec390b83, 0xefaa4060, 0x9f065e71, 0x1051bd6e, + 0x8af93e21, 0x063d96dd, 0x05aedd3e, 0xbd464de6, + 0x8db59154, 0x5d0571c4, 0xd46f0406, 0x15ff6050, + 0xfb241998, 0xe997d6bd, 0x43cc8940, 0x9e7767d9, + 0x42bdb0e8, 0x8b880789, 0x5b38e719, 0xeedb79c8, + 0x0a47a17c, 0x0fe97c42, 0x1ec9f884, 0x00000000, + 0x86830980, 0xed48322b, 0x70ac1e11, 0x724e6c5a, + 0xfffbfd0e, 0x38560f85, 0xd51e3dae, 0x3927362d, + 0xd9640a0f, 0xa621685c, 0x54d19b5b, 0x2e3a2436, + 0x67b10c0a, 0xe70f9357, 0x96d2b4ee, 0x919e1b9b, + 0xc54f80c0, 0x20a261dc, 0x4b695a77, 0x1a161c12, + 0xba0ae293, 0x2ae5c0a0, 0xe0433c22, 0x171d121b, + 0x0d0b0e09, 0xc7adf28b, 0xa8b92db6, 0xa9c8141e, + 0x198557f1, 0x074caf75, 0xddbbee99, 0x60fda37f, + 0x269ff701, 0xf5bc5c72, 0x3bc54466, 0x7e345bfb, + 0x29768b43, 0xc6dccb23, 0xfc68b6ed, 0xf163b8e4, + 0xdccad731, 0x85104263, 0x22401397, 0x112084c6, + 0x247d854a, 0x3df8d2bb, 0x3211aef9, 0xa16dc729, + 0x2f4b1d9e, 0x30f3dcb2, 0x52ec0d86, 0xe3d077c1, + 0x166c2bb3, 0xb999a970, 0x48fa1194, 0x642247e9, + 0x8cc4a8fc, 0x3f1aa0f0, 0x2cd8567d, 0x90ef2233, + 0x4ec78749, 0xd1c1d938, 0xa2fe8cca, 0x0b3698d4, + 0x81cfa6f5, 0xde28a57a, 0x8e26dab7, 0xbfa43fad, + 0x9de42c3a, 0x920d5078, 0xcc9b6a5f, 0x4662547e, + 0x13c2f68d, 0xb8e890d8, 0xf75e2e39, 0xaff582c3, + 0x80be9f5d, 0x937c69d0, 0x2da96fd5, 0x12b3cf25, + 0x993bc8ac, 0x7da71018, 0x636ee89c, 0xbb7bdb3b, + 0x7809cd26, 0x18f46e59, 0xb701ec9a, 0x9aa8834f, + 0x6e65e695, 0xe67eaaff, 0xcf0821bc, 0xe8e6ef15, + 0x9bd9bae7, 0x36ce4a6f, 0x09d4ea9f, 0x7cd629b0, + 0xb2af31a4, 0x23312a3f, 0x9430c6a5, 0x66c035a2, + 0xbc37744e, 0xcaa6fc82, 0xd0b0e090, 0xd81533a7, + 0x984af104, 0xdaf741ec, 0x500e7fcd, 0xf62f1791, + 0xd68d764d, 0xb04d43ef, 0x4d54ccaa, 0x04dfe496, + 0xb5e39ed1, 0x881b4c6a, 0x1fb8c12c, 0x517f4665, + 0xea049d5e, 0x355d018c, 0x7473fa87, 0x412efb0b, + 0x1d5ab367, 0xd25292db, 0x5633e910, 0x47136dd6, + 0x618c9ad7, 0x0c7a37a1, 0x148e59f8, 0x3c89eb13, + 0x27eecea9, 0xc935b761, 0xe5ede11c, 0xb13c7a47, + 0xdf599cd2, 0x733f55f2, 0xce791814, 0x37bf73c7, + 0xcdea53f7, 0xaa5b5ffd, 0x6f14df3d, 0xdb867844, + 0xf381caaf, 0xc43eb968, 0x342c3824, 0x405fc2a3, + 0xc372161d, 0x250cbce2, 0x498b283c, 0x9541ff0d, + 0x017139a8, 0xb3de080c, 0xe49cd8b4, 0xc1906456, + 0x84617bcb, 0xb670d532, 0x5c74486c, 0x5742d0b8, +}; +static const uint32_t Td3[256] = { + 0xf4a75051, 0x4165537e, 0x17a4c31a, 0x275e963a, + 0xab6bcb3b, 0x9d45f11f, 0xfa58abac, 0xe303934b, + 0x30fa5520, 0x766df6ad, 0xcc769188, 0x024c25f5, + 0xe5d7fc4f, 0x2acbd7c5, 0x35448026, 0x62a38fb5, + 0xb15a49de, 0xba1b6725, 0xea0e9845, 0xfec0e15d, + 0x2f7502c3, 0x4cf01281, 0x4697a38d, 0xd3f9c66b, + 0x8f5fe703, 0x929c9515, 0x6d7aebbf, 0x5259da95, + 0xbe832dd4, 0x7421d358, 0xe0692949, 0xc9c8448e, + 0xc2896a75, 0x8e7978f4, 0x583e6b99, 0xb971dd27, + 0xe14fb6be, 0x88ad17f0, 0x20ac66c9, 0xce3ab47d, + 0xdf4a1863, 0x1a3182e5, 0x51336097, 0x537f4562, + 0x6477e0b1, 0x6bae84bb, 0x81a01cfe, 0x082b94f9, + 0x48685870, 0x45fd198f, 0xde6c8794, 0x7bf8b752, + 0x73d323ab, 0x4b02e272, 0x1f8f57e3, 0x55ab2a66, + 0xeb2807b2, 0xb5c2032f, 0xc57b9a86, 0x3708a5d3, + 0x2887f230, 0xbfa5b223, 0x036aba02, 0x16825ced, + 0xcf1c2b8a, 0x79b492a7, 0x07f2f0f3, 0x69e2a14e, + 0xdaf4cd65, 0x05bed506, 0x34621fd1, 0xa6fe8ac4, + 0x2e539d34, 0xf355a0a2, 0x8ae13205, 0xf6eb75a4, + 0x83ec390b, 0x60efaa40, 0x719f065e, 0x6e1051bd, + 0x218af93e, 0xdd063d96, 0x3e05aedd, 0xe6bd464d, + 0x548db591, 0xc45d0571, 0x06d46f04, 0x5015ff60, + 0x98fb2419, 0xbde997d6, 0x4043cc89, 0xd99e7767, + 0xe842bdb0, 0x898b8807, 0x195b38e7, 0xc8eedb79, + 0x7c0a47a1, 0x420fe97c, 0x841ec9f8, 0x00000000, + 0x80868309, 0x2bed4832, 0x1170ac1e, 0x5a724e6c, + 0x0efffbfd, 0x8538560f, 0xaed51e3d, 0x2d392736, + 0x0fd9640a, 0x5ca62168, 0x5b54d19b, 0x362e3a24, + 0x0a67b10c, 0x57e70f93, 0xee96d2b4, 0x9b919e1b, + 0xc0c54f80, 0xdc20a261, 0x774b695a, 0x121a161c, + 0x93ba0ae2, 0xa02ae5c0, 0x22e0433c, 0x1b171d12, + 0x090d0b0e, 0x8bc7adf2, 0xb6a8b92d, 0x1ea9c814, + 0xf1198557, 0x75074caf, 0x99ddbbee, 0x7f60fda3, + 0x01269ff7, 0x72f5bc5c, 0x663bc544, 0xfb7e345b, + 0x4329768b, 0x23c6dccb, 0xedfc68b6, 0xe4f163b8, + 0x31dccad7, 0x63851042, 0x97224013, 0xc6112084, + 0x4a247d85, 0xbb3df8d2, 0xf93211ae, 0x29a16dc7, + 0x9e2f4b1d, 0xb230f3dc, 0x8652ec0d, 0xc1e3d077, + 0xb3166c2b, 0x70b999a9, 0x9448fa11, 0xe9642247, + 0xfc8cc4a8, 0xf03f1aa0, 0x7d2cd856, 0x3390ef22, + 0x494ec787, 0x38d1c1d9, 0xcaa2fe8c, 0xd40b3698, + 0xf581cfa6, 0x7ade28a5, 0xb78e26da, 0xadbfa43f, + 0x3a9de42c, 0x78920d50, 0x5fcc9b6a, 0x7e466254, + 0x8d13c2f6, 0xd8b8e890, 0x39f75e2e, 0xc3aff582, + 0x5d80be9f, 0xd0937c69, 0xd52da96f, 0x2512b3cf, + 0xac993bc8, 0x187da710, 0x9c636ee8, 0x3bbb7bdb, + 0x267809cd, 0x5918f46e, 0x9ab701ec, 0x4f9aa883, + 0x956e65e6, 0xffe67eaa, 0xbccf0821, 0x15e8e6ef, + 0xe79bd9ba, 0x6f36ce4a, 0x9f09d4ea, 0xb07cd629, + 0xa4b2af31, 0x3f23312a, 0xa59430c6, 0xa266c035, + 0x4ebc3774, 0x82caa6fc, 0x90d0b0e0, 0xa7d81533, + 0x04984af1, 0xecdaf741, 0xcd500e7f, 0x91f62f17, + 0x4dd68d76, 0xefb04d43, 0xaa4d54cc, 0x9604dfe4, + 0xd1b5e39e, 0x6a881b4c, 0x2c1fb8c1, 0x65517f46, + 0x5eea049d, 0x8c355d01, 0x877473fa, 0x0b412efb, + 0x671d5ab3, 0xdbd25292, 0x105633e9, 0xd647136d, + 0xd7618c9a, 0xa10c7a37, 0xf8148e59, 0x133c89eb, + 0xa927eece, 0x61c935b7, 0x1ce5ede1, 0x47b13c7a, + 0xd2df599c, 0xf2733f55, 0x14ce7918, 0xc737bf73, + 0xf7cdea53, 0xfdaa5b5f, 0x3d6f14df, 0x44db8678, + 0xaff381ca, 0x68c43eb9, 0x24342c38, 0xa3405fc2, + 0x1dc37216, 0xe2250cbc, 0x3c498b28, 0x0d9541ff, + 0xa8017139, 0x0cb3de08, 0xb4e49cd8, 0x56c19064, + 0xcb84617b, 0x32b670d5, 0x6c5c7448, 0xb85742d0, +}; +static const uint32_t Td4[256] = { + 0x52525252, 0x09090909, 0x6a6a6a6a, 0xd5d5d5d5, + 0x30303030, 0x36363636, 0xa5a5a5a5, 0x38383838, + 0xbfbfbfbf, 0x40404040, 0xa3a3a3a3, 0x9e9e9e9e, + 0x81818181, 0xf3f3f3f3, 0xd7d7d7d7, 0xfbfbfbfb, + 0x7c7c7c7c, 0xe3e3e3e3, 0x39393939, 0x82828282, + 0x9b9b9b9b, 0x2f2f2f2f, 0xffffffff, 0x87878787, + 0x34343434, 0x8e8e8e8e, 0x43434343, 0x44444444, + 0xc4c4c4c4, 0xdededede, 0xe9e9e9e9, 0xcbcbcbcb, + 0x54545454, 0x7b7b7b7b, 0x94949494, 0x32323232, + 0xa6a6a6a6, 0xc2c2c2c2, 0x23232323, 0x3d3d3d3d, + 0xeeeeeeee, 0x4c4c4c4c, 0x95959595, 0x0b0b0b0b, + 0x42424242, 0xfafafafa, 0xc3c3c3c3, 0x4e4e4e4e, + 0x08080808, 0x2e2e2e2e, 0xa1a1a1a1, 0x66666666, + 0x28282828, 0xd9d9d9d9, 0x24242424, 0xb2b2b2b2, + 0x76767676, 0x5b5b5b5b, 0xa2a2a2a2, 0x49494949, + 0x6d6d6d6d, 0x8b8b8b8b, 0xd1d1d1d1, 0x25252525, + 0x72727272, 0xf8f8f8f8, 0xf6f6f6f6, 0x64646464, + 0x86868686, 0x68686868, 0x98989898, 0x16161616, + 0xd4d4d4d4, 0xa4a4a4a4, 0x5c5c5c5c, 0xcccccccc, + 0x5d5d5d5d, 0x65656565, 0xb6b6b6b6, 0x92929292, + 0x6c6c6c6c, 0x70707070, 0x48484848, 0x50505050, + 0xfdfdfdfd, 0xedededed, 0xb9b9b9b9, 0xdadadada, + 0x5e5e5e5e, 0x15151515, 0x46464646, 0x57575757, + 0xa7a7a7a7, 0x8d8d8d8d, 0x9d9d9d9d, 0x84848484, + 0x90909090, 0xd8d8d8d8, 0xabababab, 0x00000000, + 0x8c8c8c8c, 0xbcbcbcbc, 0xd3d3d3d3, 0x0a0a0a0a, + 0xf7f7f7f7, 0xe4e4e4e4, 0x58585858, 0x05050505, + 0xb8b8b8b8, 0xb3b3b3b3, 0x45454545, 0x06060606, + 0xd0d0d0d0, 0x2c2c2c2c, 0x1e1e1e1e, 0x8f8f8f8f, + 0xcacacaca, 0x3f3f3f3f, 0x0f0f0f0f, 0x02020202, + 0xc1c1c1c1, 0xafafafaf, 0xbdbdbdbd, 0x03030303, + 0x01010101, 0x13131313, 0x8a8a8a8a, 0x6b6b6b6b, + 0x3a3a3a3a, 0x91919191, 0x11111111, 0x41414141, + 0x4f4f4f4f, 0x67676767, 0xdcdcdcdc, 0xeaeaeaea, + 0x97979797, 0xf2f2f2f2, 0xcfcfcfcf, 0xcececece, + 0xf0f0f0f0, 0xb4b4b4b4, 0xe6e6e6e6, 0x73737373, + 0x96969696, 0xacacacac, 0x74747474, 0x22222222, + 0xe7e7e7e7, 0xadadadad, 0x35353535, 0x85858585, + 0xe2e2e2e2, 0xf9f9f9f9, 0x37373737, 0xe8e8e8e8, + 0x1c1c1c1c, 0x75757575, 0xdfdfdfdf, 0x6e6e6e6e, + 0x47474747, 0xf1f1f1f1, 0x1a1a1a1a, 0x71717171, + 0x1d1d1d1d, 0x29292929, 0xc5c5c5c5, 0x89898989, + 0x6f6f6f6f, 0xb7b7b7b7, 0x62626262, 0x0e0e0e0e, + 0xaaaaaaaa, 0x18181818, 0xbebebebe, 0x1b1b1b1b, + 0xfcfcfcfc, 0x56565656, 0x3e3e3e3e, 0x4b4b4b4b, + 0xc6c6c6c6, 0xd2d2d2d2, 0x79797979, 0x20202020, + 0x9a9a9a9a, 0xdbdbdbdb, 0xc0c0c0c0, 0xfefefefe, + 0x78787878, 0xcdcdcdcd, 0x5a5a5a5a, 0xf4f4f4f4, + 0x1f1f1f1f, 0xdddddddd, 0xa8a8a8a8, 0x33333333, + 0x88888888, 0x07070707, 0xc7c7c7c7, 0x31313131, + 0xb1b1b1b1, 0x12121212, 0x10101010, 0x59595959, + 0x27272727, 0x80808080, 0xecececec, 0x5f5f5f5f, + 0x60606060, 0x51515151, 0x7f7f7f7f, 0xa9a9a9a9, + 0x19191919, 0xb5b5b5b5, 0x4a4a4a4a, 0x0d0d0d0d, + 0x2d2d2d2d, 0xe5e5e5e5, 0x7a7a7a7a, 0x9f9f9f9f, + 0x93939393, 0xc9c9c9c9, 0x9c9c9c9c, 0xefefefef, + 0xa0a0a0a0, 0xe0e0e0e0, 0x3b3b3b3b, 0x4d4d4d4d, + 0xaeaeaeae, 0x2a2a2a2a, 0xf5f5f5f5, 0xb0b0b0b0, + 0xc8c8c8c8, 0xebebebeb, 0xbbbbbbbb, 0x3c3c3c3c, + 0x83838383, 0x53535353, 0x99999999, 0x61616161, + 0x17171717, 0x2b2b2b2b, 0x04040404, 0x7e7e7e7e, + 0xbabababa, 0x77777777, 0xd6d6d6d6, 0x26262626, + 0xe1e1e1e1, 0x69696969, 0x14141414, 0x63636363, + 0x55555555, 0x21212121, 0x0c0c0c0c, 0x7d7d7d7d, +}; +static const uint32_t rcon[] = { + 0x01000000, 0x02000000, 0x04000000, 0x08000000, + 0x10000000, 0x20000000, 0x40000000, 0x80000000, + 0x1B000000, 0x36000000 + /* for 128-bit blocks, Rijndael never uses more than 10 rcon values */ +}; + +#define GETU32(pt) (((uint32_t)((pt)[0] & 0xFF) << 24) ^ \ + ((uint32_t)((pt)[1] & 0xFF) << 16) ^ \ + ((uint32_t)((pt)[2] & 0xFF) << 8) ^ \ + ((uint32_t)((pt)[3] & 0xFF))) +#define PUTU32(ct, st) { \ + (ct)[0] = (char)((st) >> 24); \ + (ct)[1] = (char)((st) >> 16); \ + (ct)[2] = (char)((st) >> 8); \ + (ct)[3] = (char)(st); } + +/** + * Expand the cipher key into the encryption key schedule. + * + * @return the number of rounds for the given cipher key size. + */ +int +rijndaelKeySetupEnc (uint32_t rk[ /*4*(Nr + 1) */ ], + const char cipherKey[], size_t keyBits) +{ + size_t i = 0; + uint32_t temp; + + rk[0] = GETU32 (cipherKey); + rk[1] = GETU32 (cipherKey + 4); + rk[2] = GETU32 (cipherKey + 8); + rk[3] = GETU32 (cipherKey + 12); + if (keyBits == 128) + { + for (;;) + { + temp = rk[3]; + rk[4] = rk[0] ^ + (Te4[(temp >> 16) & 0xff] & 0xff000000) ^ + (Te4[(temp >> 8) & 0xff] & 0x00ff0000) ^ + (Te4[(temp) & 0xff] & 0x0000ff00) ^ + (Te4[(temp >> 24)] & 0x000000ff) ^ rcon[i]; + rk[5] = rk[1] ^ rk[4]; + rk[6] = rk[2] ^ rk[5]; + rk[7] = rk[3] ^ rk[6]; + if (++i == 10) + { + return 10; + } + rk += 4; + } + } + rk[4] = GETU32 (cipherKey + 16); + rk[5] = GETU32 (cipherKey + 20); + if (keyBits == 192) + { + for (;;) + { + temp = rk[5]; + rk[6] = rk[0] ^ + (Te4[(temp >> 16) & 0xff] & 0xff000000) ^ + (Te4[(temp >> 8) & 0xff] & 0x00ff0000) ^ + (Te4[(temp) & 0xff] & 0x0000ff00) ^ + (Te4[(temp >> 24)] & 0x000000ff) ^ rcon[i]; + rk[7] = rk[1] ^ rk[6]; + rk[8] = rk[2] ^ rk[7]; + rk[9] = rk[3] ^ rk[8]; + if (++i == 8) + { + return 12; + } + rk[10] = rk[4] ^ rk[9]; + rk[11] = rk[5] ^ rk[10]; + rk += 6; + } + } + rk[6] = GETU32 (cipherKey + 24); + rk[7] = GETU32 (cipherKey + 28); + if (keyBits == 256) + { + for (;;) + { + temp = rk[7]; + rk[8] = rk[0] ^ + (Te4[(temp >> 16) & 0xff] & 0xff000000) ^ + (Te4[(temp >> 8) & 0xff] & 0x00ff0000) ^ + (Te4[(temp) & 0xff] & 0x0000ff00) ^ + (Te4[(temp >> 24)] & 0x000000ff) ^ rcon[i]; + rk[9] = rk[1] ^ rk[8]; + rk[10] = rk[2] ^ rk[9]; + rk[11] = rk[3] ^ rk[10]; + if (++i == 7) + { + return 14; + } + temp = rk[11]; + rk[12] = rk[4] ^ + (Te4[(temp >> 24)] & 0xff000000) ^ + (Te4[(temp >> 16) & 0xff] & 0x00ff0000) ^ + (Te4[(temp >> 8) & 0xff] & 0x0000ff00) ^ + (Te4[(temp) & 0xff] & 0x000000ff); + rk[13] = rk[5] ^ rk[12]; + rk[14] = rk[6] ^ rk[13]; + rk[15] = rk[7] ^ rk[14]; + + rk += 8; + } + } + return 0; +} + +/** + * Expand the cipher key into the decryption key schedule. + * + * @return the number of rounds for the given cipher key size. + */ +int +rijndaelKeySetupDec (uint32_t rk[ /*4*(Nr + 1) */ ], + const char cipherKey[], size_t keyBits) +{ + size_t Nr, i, j; + uint32_t temp; + + /* expand the cipher key: */ + Nr = rijndaelKeySetupEnc (rk, cipherKey, keyBits); + /* invert the order of the round keys: */ + for (i = 0, j = 4 * Nr; i < j; i += 4, j -= 4) + { + temp = rk[i]; + rk[i] = rk[j]; + rk[j] = temp; + temp = rk[i + 1]; + rk[i + 1] = rk[j + 1]; + rk[j + 1] = temp; + temp = rk[i + 2]; + rk[i + 2] = rk[j + 2]; + rk[j + 2] = temp; + temp = rk[i + 3]; + rk[i + 3] = rk[j + 3]; + rk[j + 3] = temp; + } + /* apply the inverse MixColumn transform to all round keys but the + first and the last: */ + for (i = 1; i < Nr; i++) + { + rk += 4; + rk[0] = + Td0[Te4[(rk[0] >> 24)] & 0xff] ^ + Td1[Te4[(rk[0] >> 16) & 0xff] & 0xff] ^ + Td2[Te4[(rk[0] >> 8) & 0xff] & 0xff] ^ + Td3[Te4[(rk[0]) & 0xff] & 0xff]; + rk[1] = + Td0[Te4[(rk[1] >> 24)] & 0xff] ^ + Td1[Te4[(rk[1] >> 16) & 0xff] & 0xff] ^ + Td2[Te4[(rk[1] >> 8) & 0xff] & 0xff] ^ + Td3[Te4[(rk[1]) & 0xff] & 0xff]; + rk[2] = + Td0[Te4[(rk[2] >> 24)] & 0xff] ^ + Td1[Te4[(rk[2] >> 16) & 0xff] & 0xff] ^ + Td2[Te4[(rk[2] >> 8) & 0xff] & 0xff] ^ + Td3[Te4[(rk[2]) & 0xff] & 0xff]; + rk[3] = + Td0[Te4[(rk[3] >> 24)] & 0xff] ^ + Td1[Te4[(rk[3] >> 16) & 0xff] & 0xff] ^ + Td2[Te4[(rk[3] >> 8) & 0xff] & 0xff] ^ + Td3[Te4[(rk[3]) & 0xff] & 0xff]; + } + return Nr; +} + +void +rijndaelEncrypt (const uint32_t rk[ /*4*(Nr + 1) */ ], size_t Nr, + const char pt[16], char ct[16]) +{ + uint32_t s0, s1, s2, s3, t0, t1, t2, t3; + size_t r; + + /* + * map byte array block to cipher state + * and add initial round key: + */ + s0 = GETU32 (pt) ^ rk[0]; + s1 = GETU32 (pt + 4) ^ rk[1]; + s2 = GETU32 (pt + 8) ^ rk[2]; + s3 = GETU32 (pt + 12) ^ rk[3]; + /* + * Nr - 1 full rounds: + */ + r = Nr >> 1; + for (;;) + { + t0 = + Te0[(s0 >> 24)] ^ + Te1[(s1 >> 16) & 0xff] ^ + Te2[(s2 >> 8) & 0xff] ^ Te3[(s3) & 0xff] ^ rk[4]; + t1 = + Te0[(s1 >> 24)] ^ + Te1[(s2 >> 16) & 0xff] ^ + Te2[(s3 >> 8) & 0xff] ^ Te3[(s0) & 0xff] ^ rk[5]; + t2 = + Te0[(s2 >> 24)] ^ + Te1[(s3 >> 16) & 0xff] ^ + Te2[(s0 >> 8) & 0xff] ^ Te3[(s1) & 0xff] ^ rk[6]; + t3 = + Te0[(s3 >> 24)] ^ + Te1[(s0 >> 16) & 0xff] ^ + Te2[(s1 >> 8) & 0xff] ^ Te3[(s2) & 0xff] ^ rk[7]; + + rk += 8; + if (--r == 0) + { + break; + } + + s0 = + Te0[(t0 >> 24)] ^ + Te1[(t1 >> 16) & 0xff] ^ + Te2[(t2 >> 8) & 0xff] ^ Te3[(t3) & 0xff] ^ rk[0]; + s1 = + Te0[(t1 >> 24)] ^ + Te1[(t2 >> 16) & 0xff] ^ + Te2[(t3 >> 8) & 0xff] ^ Te3[(t0) & 0xff] ^ rk[1]; + s2 = + Te0[(t2 >> 24)] ^ + Te1[(t3 >> 16) & 0xff] ^ + Te2[(t0 >> 8) & 0xff] ^ Te3[(t1) & 0xff] ^ rk[2]; + s3 = + Te0[(t3 >> 24)] ^ + Te1[(t0 >> 16) & 0xff] ^ + Te2[(t1 >> 8) & 0xff] ^ Te3[(t2) & 0xff] ^ rk[3]; + } + /* + * apply last round and + * map cipher state to byte array block: + */ + s0 = + (Te4[(t0 >> 24)] & 0xff000000) ^ + (Te4[(t1 >> 16) & 0xff] & 0x00ff0000) ^ + (Te4[(t2 >> 8) & 0xff] & 0x0000ff00) ^ + (Te4[(t3) & 0xff] & 0x000000ff) ^ rk[0]; + PUTU32 (ct, s0); + s1 = + (Te4[(t1 >> 24)] & 0xff000000) ^ + (Te4[(t2 >> 16) & 0xff] & 0x00ff0000) ^ + (Te4[(t3 >> 8) & 0xff] & 0x0000ff00) ^ + (Te4[(t0) & 0xff] & 0x000000ff) ^ rk[1]; + PUTU32 (ct + 4, s1); + s2 = + (Te4[(t2 >> 24)] & 0xff000000) ^ + (Te4[(t3 >> 16) & 0xff] & 0x00ff0000) ^ + (Te4[(t0 >> 8) & 0xff] & 0x0000ff00) ^ + (Te4[(t1) & 0xff] & 0x000000ff) ^ rk[2]; + PUTU32 (ct + 8, s2); + s3 = + (Te4[(t3 >> 24)] & 0xff000000) ^ + (Te4[(t0 >> 16) & 0xff] & 0x00ff0000) ^ + (Te4[(t1 >> 8) & 0xff] & 0x0000ff00) ^ + (Te4[(t2) & 0xff] & 0x000000ff) ^ rk[3]; + PUTU32 (ct + 12, s3); +} + +void +rijndaelDecrypt (const uint32_t rk[ /*4*(Nr + 1) */ ], size_t Nr, + const char ct[16], char pt[16]) +{ + uint32_t s0, s1, s2, s3, t0, t1, t2, t3; + size_t r; + + /* + * map byte array block to cipher state + * and add initial round key: + */ + s0 = GETU32 (ct) ^ rk[0]; + s1 = GETU32 (ct + 4) ^ rk[1]; + s2 = GETU32 (ct + 8) ^ rk[2]; + s3 = GETU32 (ct + 12) ^ rk[3]; + /* + * Nr - 1 full rounds: + */ + r = Nr >> 1; + for (;;) + { + t0 = + Td0[(s0 >> 24)] ^ + Td1[(s3 >> 16) & 0xff] ^ + Td2[(s2 >> 8) & 0xff] ^ Td3[(s1) & 0xff] ^ rk[4]; + t1 = + Td0[(s1 >> 24)] ^ + Td1[(s0 >> 16) & 0xff] ^ + Td2[(s3 >> 8) & 0xff] ^ Td3[(s2) & 0xff] ^ rk[5]; + t2 = + Td0[(s2 >> 24)] ^ + Td1[(s1 >> 16) & 0xff] ^ + Td2[(s0 >> 8) & 0xff] ^ Td3[(s3) & 0xff] ^ rk[6]; + t3 = + Td0[(s3 >> 24)] ^ + Td1[(s2 >> 16) & 0xff] ^ + Td2[(s1 >> 8) & 0xff] ^ Td3[(s0) & 0xff] ^ rk[7]; + + rk += 8; + if (--r == 0) + { + break; + } + + s0 = + Td0[(t0 >> 24)] ^ + Td1[(t3 >> 16) & 0xff] ^ + Td2[(t2 >> 8) & 0xff] ^ Td3[(t1) & 0xff] ^ rk[0]; + s1 = + Td0[(t1 >> 24)] ^ + Td1[(t0 >> 16) & 0xff] ^ + Td2[(t3 >> 8) & 0xff] ^ Td3[(t2) & 0xff] ^ rk[1]; + s2 = + Td0[(t2 >> 24)] ^ + Td1[(t1 >> 16) & 0xff] ^ + Td2[(t0 >> 8) & 0xff] ^ Td3[(t3) & 0xff] ^ rk[2]; + s3 = + Td0[(t3 >> 24)] ^ + Td1[(t2 >> 16) & 0xff] ^ + Td2[(t1 >> 8) & 0xff] ^ Td3[(t0) & 0xff] ^ rk[3]; + } + /* + * apply last round and + * map cipher state to byte array block: + */ + s0 = + (Td4[(t0 >> 24)] & 0xff000000) ^ + (Td4[(t3 >> 16) & 0xff] & 0x00ff0000) ^ + (Td4[(t2 >> 8) & 0xff] & 0x0000ff00) ^ + (Td4[(t1) & 0xff] & 0x000000ff) ^ rk[0]; + PUTU32 (pt, s0); + s1 = + (Td4[(t1 >> 24)] & 0xff000000) ^ + (Td4[(t0 >> 16) & 0xff] & 0x00ff0000) ^ + (Td4[(t3 >> 8) & 0xff] & 0x0000ff00) ^ + (Td4[(t2) & 0xff] & 0x000000ff) ^ rk[1]; + PUTU32 (pt + 4, s1); + s2 = + (Td4[(t2 >> 24)] & 0xff000000) ^ + (Td4[(t1 >> 16) & 0xff] & 0x00ff0000) ^ + (Td4[(t0 >> 8) & 0xff] & 0x0000ff00) ^ + (Td4[(t3) & 0xff] & 0x000000ff) ^ rk[2]; + PUTU32 (pt + 8, s2); + s3 = + (Td4[(t3 >> 24)] & 0xff000000) ^ + (Td4[(t2 >> 16) & 0xff] & 0x00ff0000) ^ + (Td4[(t1 >> 8) & 0xff] & 0x0000ff00) ^ + (Td4[(t0) & 0xff] & 0x000000ff) ^ rk[3]; + PUTU32 (pt + 12, s3); +} diff --git a/lgl/rijndael-alg-fst.h b/lgl/rijndael-alg-fst.h new file mode 100644 index 0000000000..8839102315 --- /dev/null +++ b/lgl/rijndael-alg-fst.h @@ -0,0 +1,67 @@ +/* rijndael-alg-fst.h --- Rijndael cipher implementation. + * Copyright (C) 2005 Free Software Foundation, Inc. + * + * This file is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation; either version 2.1, or (at your + * option) any later version. + * + * This file is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this file; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + * + */ + +/* Adapted for gnulib by Simon Josefsson. */ + +/** + * rijndael-alg-fst.h + * + * @version 3.0 (December 2000) + * + * Optimised ANSI C code for the Rijndael cipher (now AES) + * + * @author Vincent Rijmen <vincent.rijmen@esat.kuleuven.ac.be> + * @author Antoon Bosselaers <antoon.bosselaers@esat.kuleuven.ac.be> + * @author Paulo Barreto <paulo.barreto@terra.com.br> + * + * This code is hereby placed in the public domain. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''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 AUTHORS 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. + */ +#ifndef __RIJNDAEL_ALG_FST_H +#define __RIJNDAEL_ALG_FST_H + +#include <stdint.h> +#include <stddef.h> + +#define RIJNDAEL_MAXKC (256/32) +#define RIJNDAEL_MAXKB (256/8) +#define RIJNDAEL_MAXNR 14 + +int rijndaelKeySetupEnc (uint32_t rk[ /*4*(Nr + 1) */ ], + const char cipherKey[], size_t keyBits); +int rijndaelKeySetupDec (uint32_t rk[ /*4*(Nr + 1) */ ], + const char cipherKey[], size_t keyBits); +void rijndaelEncrypt (const uint32_t rk[ /*4*(Nr + 1) */ ], size_t Nr, + const char pt[16], char ct[16]); +void rijndaelDecrypt (const uint32_t rk[ /*4*(Nr + 1) */ ], size_t Nr, + const char ct[16], char pt[16]); + +#endif /* __RIJNDAEL_ALG_FST_H */ diff --git a/lgl/rijndael-api-fst.c b/lgl/rijndael-api-fst.c new file mode 100644 index 0000000000..85cc480e8f --- /dev/null +++ b/lgl/rijndael-api-fst.c @@ -0,0 +1,523 @@ +/* rijndael-api-fst.c --- Rijndael cipher implementation. + * Copyright (C) 2005, 2006 Free Software Foundation, Inc. + * + * This file is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation; either version 2.1, or (at your + * option) any later version. + * + * This file is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this file; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + * + */ + +/* Adapted for gnulib by Simon Josefsson. + * + * Based on public domain "Optimised C code" retrieved from (SHA1 + * 7c8e4b00d06685d1dbc6724a9e0d502353de339e): + * http://www.iaik.tu-graz.ac.at/research/krypto/AES/old/~rijmen/rijndael/rijndael-fst-3.0.zip + */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +/** + * rijndael-api-fst.c + * + * @version 2.9 (December 2000) + * + * Optimised ANSI C code for the Rijndael cipher (now AES) + * + * @author Vincent Rijmen <vincent.rijmen@esat.kuleuven.ac.be> + * @author Antoon Bosselaers <antoon.bosselaers@esat.kuleuven.ac.be> + * @author Paulo Barreto <paulo.barreto@terra.com.br> + * + * This code is hereby placed in the public domain. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''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 AUTHORS 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. + * + * Acknowledgements: + * + * We are deeply indebted to the following people for their bug reports, + * fixes, and improvement suggestions to this implementation. Though we + * tried to list all contributions, we apologise in advance for any + * missing reference. + * + * Andrew Bales <Andrew.Bales@Honeywell.com> + * Markus Friedl <markus.friedl@informatik.uni-erlangen.de> + * John Skodon <skodonj@webquill.com> + */ + +#include "rijndael-alg-fst.h" +#include "rijndael-api-fst.h" + +#include <assert.h> +#include <stdlib.h> +#include <string.h> + +rijndael_rc +rijndaelMakeKey (rijndaelKeyInstance *key, rijndael_direction direction, + size_t keyLen, const char *keyMaterial) +{ + size_t i; + char *keyMat; + char cipherKey[RIJNDAEL_MAXKB]; + + if (key == NULL) + { + return RIJNDAEL_BAD_KEY_INSTANCE; + } + + if ((direction == RIJNDAEL_DIR_ENCRYPT) + || (direction == RIJNDAEL_DIR_DECRYPT)) + { + key->direction = direction; + } + else + { + return RIJNDAEL_BAD_KEY_DIR; + } + + if ((keyLen == 128) || (keyLen == 192) || (keyLen == 256)) + { + key->keyLen = keyLen; + } + else + { + return RIJNDAEL_BAD_KEY_MAT; + } + + if (keyMaterial != NULL) + { + strncpy (key->keyMaterial, keyMaterial, keyLen / 4); + } + + /* initialize key schedule: */ + keyMat = key->keyMaterial; + for (i = 0; i < key->keyLen / 8; i++) + { + char t, v; + + t = *keyMat++; + if ((t >= '0') && (t <= '9')) + v = (t - '0') << 4; + else if ((t >= 'a') && (t <= 'f')) + v = (t - 'a' + 10) << 4; + else if ((t >= 'A') && (t <= 'F')) + v = (t - 'A' + 10) << 4; + else + return RIJNDAEL_BAD_KEY_MAT; + + t = *keyMat++; + if ((t >= '0') && (t <= '9')) + v ^= (t - '0'); + else if ((t >= 'a') && (t <= 'f')) + v ^= (t - 'a' + 10); + else if ((t >= 'A') && (t <= 'F')) + v ^= (t - 'A' + 10); + else + return RIJNDAEL_BAD_KEY_MAT; + + cipherKey[i] = v; + } + if (direction == RIJNDAEL_DIR_ENCRYPT) + { + key->Nr = rijndaelKeySetupEnc (key->rk, cipherKey, keyLen); + } + else + { + key->Nr = rijndaelKeySetupDec (key->rk, cipherKey, keyLen); + } + rijndaelKeySetupEnc (key->ek, cipherKey, keyLen); + return 0; +} + +rijndael_rc +rijndaelCipherInit (rijndaelCipherInstance *cipher, rijndael_mode mode, + const char *IV) +{ + if ((mode == RIJNDAEL_MODE_ECB) || (mode == RIJNDAEL_MODE_CBC) + || (mode == RIJNDAEL_MODE_CFB1)) + { + cipher->mode = mode; + } + else + { + return RIJNDAEL_BAD_CIPHER_MODE; + } + if (IV != NULL) + { + int i; + for (i = 0; i < RIJNDAEL_MAX_IV_SIZE; i++) + { + int t, j; + + t = IV[2 * i]; + if ((t >= '0') && (t <= '9')) + j = (t - '0') << 4; + else if ((t >= 'a') && (t <= 'f')) + j = (t - 'a' + 10) << 4; + else if ((t >= 'A') && (t <= 'F')) + j = (t - 'A' + 10) << 4; + else + return RIJNDAEL_BAD_CIPHER_INSTANCE; + + t = IV[2 * i + 1]; + if ((t >= '0') && (t <= '9')) + j ^= (t - '0'); + else if ((t >= 'a') && (t <= 'f')) + j ^= (t - 'a' + 10); + else if ((t >= 'A') && (t <= 'F')) + j ^= (t - 'A' + 10); + else + return RIJNDAEL_BAD_CIPHER_INSTANCE; + + cipher->IV[i] = (uint8_t) j; + } + } + else + { + memset (cipher->IV, 0, RIJNDAEL_MAX_IV_SIZE); + } + return 0; +} + +int +rijndaelBlockEncrypt (rijndaelCipherInstance *cipher, + const rijndaelKeyInstance *key, + const char *input, + size_t inputLen, char *outBuffer) +{ + size_t i, k, t, numBlocks; + char block[16], *iv; + + if (cipher == NULL || key == NULL || key->direction == RIJNDAEL_DIR_DECRYPT) + { + return RIJNDAEL_BAD_CIPHER_STATE; + } + if (input == NULL || inputLen <= 0) + { + return 0; /* nothing to do */ + } + + numBlocks = inputLen / 128; + + switch (cipher->mode) + { + case RIJNDAEL_MODE_ECB: + for (i = numBlocks; i > 0; i--) + { + rijndaelEncrypt (key->rk, key->Nr, input, outBuffer); + input += 16; + outBuffer += 16; + } + break; + + case RIJNDAEL_MODE_CBC: + iv = cipher->IV; + for (i = numBlocks; i > 0; i--) + { + ((uint32_t *) block)[0] = ((uint32_t *) input)[0] ^ + ((uint32_t *) iv)[0]; + ((uint32_t *) block)[1] = ((uint32_t *) input)[1] ^ + ((uint32_t *) iv)[1]; + ((uint32_t *) block)[2] = ((uint32_t *) input)[2] ^ + ((uint32_t *) iv)[2]; + ((uint32_t *) block)[3] = ((uint32_t *) input)[3] ^ + ((uint32_t *) iv)[3]; + rijndaelEncrypt (key->rk, key->Nr, block, outBuffer); + memcpy (cipher->IV, outBuffer, 16); + input += 16; + outBuffer += 16; + } + break; + + case RIJNDAEL_MODE_CFB1: + iv = cipher->IV; + for (i = numBlocks; i > 0; i--) + { + memcpy (outBuffer, input, 16); + for (k = 0; k < 128; k++) + { + rijndaelEncrypt (key->ek, key->Nr, iv, block); + outBuffer[k >> 3] ^= (block[0] & 0x80U) >> (k & 7); + for (t = 0; t < 15; t++) + { + iv[t] = (iv[t] << 1) | (iv[t + 1] >> 7); + } + iv[15] = (iv[15] << 1) | + ((outBuffer[k >> 3] >> (7 - (k & 7))) & 1); + } + outBuffer += 16; + input += 16; + } + break; + + default: + return RIJNDAEL_BAD_CIPHER_STATE; + } + + return 128 * numBlocks; +} + +int +rijndaelPadEncrypt (rijndaelCipherInstance *cipher, + const rijndaelKeyInstance *key, + const char *input, + size_t inputOctets, char *outBuffer) +{ + size_t i, numBlocks, padLen; + char block[16], *iv; + + if (cipher == NULL || key == NULL || key->direction == RIJNDAEL_DIR_DECRYPT) + { + return RIJNDAEL_BAD_CIPHER_STATE; + } + if (input == NULL || inputOctets <= 0) + { + return 0; /* nothing to do */ + } + + numBlocks = inputOctets / 16; + + switch (cipher->mode) + { + case RIJNDAEL_MODE_ECB: + for (i = numBlocks; i > 0; i--) + { + rijndaelEncrypt (key->rk, key->Nr, input, outBuffer); + input += 16; + outBuffer += 16; + } + padLen = 16 - (inputOctets - 16 * numBlocks); + assert (padLen > 0 && padLen <= 16); + memcpy (block, input, 16 - padLen); + memset (block + 16 - padLen, padLen, padLen); + rijndaelEncrypt (key->rk, key->Nr, block, outBuffer); + break; + + case RIJNDAEL_MODE_CBC: + iv = cipher->IV; + for (i = numBlocks; i > 0; i--) + { + ((uint32_t *) block)[0] = ((uint32_t *) input)[0] ^ + ((uint32_t *) iv)[0]; + ((uint32_t *) block)[1] = ((uint32_t *) input)[1] ^ + ((uint32_t *) iv)[1]; + ((uint32_t *) block)[2] = ((uint32_t *) input)[2] ^ + ((uint32_t *) iv)[2]; + ((uint32_t *) block)[3] = ((uint32_t *) input)[3] ^ + ((uint32_t *) iv)[3]; + rijndaelEncrypt (key->rk, key->Nr, block, outBuffer); + memcpy (cipher->IV, outBuffer, 16); + input += 16; + outBuffer += 16; + } + padLen = 16 - (inputOctets - 16 * numBlocks); + assert (padLen > 0 && padLen <= 16); + for (i = 0; i < 16 - padLen; i++) + { + block[i] = input[i] ^ iv[i]; + } + for (i = 16 - padLen; i < 16; i++) + { + block[i] = (char) padLen ^ iv[i]; + } + rijndaelEncrypt (key->rk, key->Nr, block, outBuffer); + memcpy (cipher->IV, outBuffer, 16); + break; + + default: + return RIJNDAEL_BAD_CIPHER_STATE; + } + + return 16 * (numBlocks + 1); +} + +int +rijndaelBlockDecrypt (rijndaelCipherInstance *cipher, + const rijndaelKeyInstance *key, + const char *input, + size_t inputLen, char *outBuffer) +{ + size_t i, k, t, numBlocks; + char block[16], *iv; + + if (cipher == NULL + || key == NULL + || (cipher->mode != RIJNDAEL_MODE_CFB1 + && key->direction == RIJNDAEL_DIR_ENCRYPT)) + { + return RIJNDAEL_BAD_CIPHER_STATE; + } + if (input == NULL || inputLen <= 0) + { + return 0; /* nothing to do */ + } + + numBlocks = inputLen / 128; + + switch (cipher->mode) + { + case RIJNDAEL_MODE_ECB: + for (i = numBlocks; i > 0; i--) + { + rijndaelDecrypt (key->rk, key->Nr, input, outBuffer); + input += 16; + outBuffer += 16; + } + break; + + case RIJNDAEL_MODE_CBC: + iv = cipher->IV; + for (i = numBlocks; i > 0; i--) + { + rijndaelDecrypt (key->rk, key->Nr, input, block); + ((uint32_t *) block)[0] ^= ((uint32_t *) iv)[0]; + ((uint32_t *) block)[1] ^= ((uint32_t *) iv)[1]; + ((uint32_t *) block)[2] ^= ((uint32_t *) iv)[2]; + ((uint32_t *) block)[3] ^= ((uint32_t *) iv)[3]; + memcpy (cipher->IV, input, 16); + memcpy (outBuffer, block, 16); + input += 16; + outBuffer += 16; + } + break; + + case RIJNDAEL_MODE_CFB1: + iv = cipher->IV; + for (i = numBlocks; i > 0; i--) + { + memcpy (outBuffer, input, 16); + for (k = 0; k < 128; k++) + { + rijndaelEncrypt (key->ek, key->Nr, iv, block); + for (t = 0; t < 15; t++) + { + iv[t] = (iv[t] << 1) | (iv[t + 1] >> 7); + } + iv[15] = (iv[15] << 1) | ((input[k >> 3] >> (7 - (k & 7))) & 1); + outBuffer[k >> 3] ^= (block[0] & 0x80U) >> (k & 7); + } + outBuffer += 16; + input += 16; + } + break; + + default: + return RIJNDAEL_BAD_CIPHER_STATE; + } + + return 128 * numBlocks; +} + +int +rijndaelPadDecrypt (rijndaelCipherInstance *cipher, + const rijndaelKeyInstance *key, + const char *input, + size_t inputOctets, char *outBuffer) +{ + size_t i, numBlocks, padLen; + char block[16]; + + if (cipher == NULL || key == NULL || key->direction == RIJNDAEL_DIR_ENCRYPT) + { + return RIJNDAEL_BAD_CIPHER_STATE; + } + if (input == NULL || inputOctets <= 0) + { + return 0; /* nothing to do */ + } + if (inputOctets % 16 != 0) + { + return RIJNDAEL_BAD_DATA; + } + + numBlocks = inputOctets / 16; + + switch (cipher->mode) + { + case RIJNDAEL_MODE_ECB: + /* all blocks but last */ + for (i = numBlocks - 1; i > 0; i--) + { + rijndaelDecrypt (key->rk, key->Nr, input, outBuffer); + input += 16; + outBuffer += 16; + } + /* last block */ + rijndaelDecrypt (key->rk, key->Nr, input, block); + padLen = block[15]; + if (padLen >= 16) + { + return RIJNDAEL_BAD_DATA; + } + for (i = 16 - padLen; i < 16; i++) + { + if (block[i] != padLen) + { + return RIJNDAEL_BAD_DATA; + } + } + memcpy (outBuffer, block, 16 - padLen); + break; + + case RIJNDAEL_MODE_CBC: + /* all blocks but last */ + for (i = numBlocks - 1; i > 0; i--) + { + rijndaelDecrypt (key->rk, key->Nr, input, block); + ((uint32_t *) block)[0] ^= ((uint32_t *) cipher->IV)[0]; + ((uint32_t *) block)[1] ^= ((uint32_t *) cipher->IV)[1]; + ((uint32_t *) block)[2] ^= ((uint32_t *) cipher->IV)[2]; + ((uint32_t *) block)[3] ^= ((uint32_t *) cipher->IV)[3]; + memcpy (cipher->IV, input, 16); + memcpy (outBuffer, block, 16); + input += 16; + outBuffer += 16; + } + /* last block */ + rijndaelDecrypt (key->rk, key->Nr, input, block); + ((uint32_t *) block)[0] ^= ((uint32_t *) cipher->IV)[0]; + ((uint32_t *) block)[1] ^= ((uint32_t *) cipher->IV)[1]; + ((uint32_t *) block)[2] ^= ((uint32_t *) cipher->IV)[2]; + ((uint32_t *) block)[3] ^= ((uint32_t *) cipher->IV)[3]; + padLen = block[15]; + if (padLen <= 0 || padLen > 16) + { + return RIJNDAEL_BAD_DATA; + } + for (i = 16 - padLen; i < 16; i++) + { + if (block[i] != padLen) + { + return RIJNDAEL_BAD_DATA; + } + } + memcpy (outBuffer, block, 16 - padLen); + break; + + default: + return RIJNDAEL_BAD_CIPHER_STATE; + } + + return 16 * numBlocks - padLen; +} diff --git a/lgl/rijndael-api-fst.h b/lgl/rijndael-api-fst.h new file mode 100644 index 0000000000..d0ff60ac0a --- /dev/null +++ b/lgl/rijndael-api-fst.h @@ -0,0 +1,207 @@ +/* rijndael-api-fst.h --- Rijndael cipher implementation. + * Copyright (C) 2005 Free Software Foundation, Inc. + * + * This file is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation; either version 2.1, or (at your + * option) any later version. + * + * This file is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this file; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + * + */ + +/* Adapted for gnulib by Simon Josefsson. */ + +/** + * rijndael-api-fst.h + * + * @version 2.9 (December 2000) + * + * Optimised ANSI C code for the Rijndael cipher (now AES) + * + * @author Vincent Rijmen <vincent.rijmen@esat.kuleuven.ac.be> + * @author Antoon Bosselaers <antoon.bosselaers@esat.kuleuven.ac.be> + * @author Paulo Barreto <paulo.barreto@terra.com.br> + * + * This code is hereby placed in the public domain. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''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 AUTHORS 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. + * + * Acknowledgements: + * + * We are deeply indebted to the following people for their bug reports, + * fixes, and improvement suggestions to this implementation. Though we + * tried to list all contributions, we apologise in advance for any + * missing reference. + * + * Andrew Bales <Andrew.Bales@Honeywell.com> + * Markus Friedl <markus.friedl@informatik.uni-erlangen.de> + * John Skodon <skodonj@webquill.com> + */ + +#ifndef __RIJNDAEL_API_FST_H +#define __RIJNDAEL_API_FST_H + +#include "rijndael-alg-fst.h" + +#include <stdio.h> + +/* Default number of bits in a cipher block */ +#define RIJNDAEL_BITSPERBLOCK 128 + +/* Number of ASCII char's needed to represent a key */ +#define RIJNDAEL_MAX_KEY_SIZE 64 + +/* Number bytes needed to represent an IV */ +#define RIJNDAEL_MAX_IV_SIZE 16 + +typedef enum +{ + /* Key direction is invalid, e.g., unknown value */ + RIJNDAEL_BAD_KEY_DIR = -1, + /* Key material not of correct length */ + RIJNDAEL_BAD_KEY_MAT = -2, + /* Key passed is not valid */ + RIJNDAEL_BAD_KEY_INSTANCE = -3, + /* Params struct passed to cipherInit invalid */ + RIJNDAEL_BAD_CIPHER_MODE = -4, + /* Cipher in wrong state (e.g., not initialized) */ + RIJNDAEL_BAD_CIPHER_STATE = -5, + RIJNDAEL_BAD_BLOCK_LENGTH = -6, + RIJNDAEL_BAD_CIPHER_INSTANCE = -7, + /* Data contents are invalid, e.g., invalid padding */ + RIJNDAEL_BAD_DATA = -8, + /* Unknown error */ + RIJNDAEL_BAD_OTHER = -9 +} rijndael_rc; + +typedef enum +{ + RIJNDAEL_DIR_ENCRYPT = 0, /* Are we encrypting? */ + RIJNDAEL_DIR_DECRYPT = 1 /* Are we decrypting? */ +} rijndael_direction; + +typedef enum +{ + RIJNDAEL_MODE_ECB = 1, /* Are we ciphering in ECB mode? */ + RIJNDAEL_MODE_CBC = 2, /* Are we ciphering in CBC mode? */ + RIJNDAEL_MODE_CFB1 = 3 /* Are we ciphering in 1-bit CFB mode? */ +} rijndael_mode; + +/* The structure for key information */ +typedef struct +{ + /* Key used for encrypting or decrypting? */ + rijndael_direction direction; + /* Length of the key */ + size_t keyLen; + /* Raw key data in ASCII, e.g., user input or KAT values */ + char keyMaterial[RIJNDAEL_MAX_KEY_SIZE + 1]; + /* key-length-dependent number of rounds */ + int Nr; + /* key schedule */ + uint32_t rk[4 * (RIJNDAEL_MAXNR + 1)]; + /* CFB1 key schedule (encryption only) */ + uint32_t ek[4 * (RIJNDAEL_MAXNR + 1)]; +} rijndaelKeyInstance; + +/* The structure for cipher information */ +typedef struct +{ /* changed order of the components */ + rijndael_mode mode; /* MODE_ECB, MODE_CBC, or MODE_CFB1 */ + /* A possible Initialization Vector for ciphering */ + char IV[RIJNDAEL_MAX_IV_SIZE]; +} rijndaelCipherInstance; + +/* Function prototypes */ + +/* Create KEY, for encryption or decryption depending on DIRECTION, + from KEYMATERIAL, a hex string, of KEYLEN size. KEYLEN should be + 128, 192 or 256. Returns 0 on success, or an error code. */ +extern rijndael_rc +rijndaelMakeKey (rijndaelKeyInstance *key, rijndael_direction direction, + size_t keyLen, const char *keyMaterial); + +/* Initialize cipher state CIPHER for encryption MODE (e.g., + RIJNDAEL_MODE_CBC) with initialization vector IV, a hex string of + 2*RIJNDAEL_MAX_IV_SIZE length. IV may be NULL for modes that do + not need an IV (i.e., RIJNDAEL_MODE_ECB). */ +extern rijndael_rc +rijndaelCipherInit (rijndaelCipherInstance *cipher, + rijndael_mode mode, const char *IV); + +/* Encrypt data in INPUT, of INPUTLEN/8 bytes length, placing the + output in the pre-allocated OUTBUFFER which must hold at least + INPUTLEN/8 bytes of data. The CIPHER is used as state, and must be + initialized with rijndaelCipherInit before calling this function. + The encryption KEY must be initialized with rijndaelMakeKey before + calling this function. Return the number of bits written, or a + negative rijndael_rc error code. */ +extern int +rijndaelBlockEncrypt (rijndaelCipherInstance *cipher, + const rijndaelKeyInstance *key, + const char *input, size_t inputLen, + char *outBuffer); + +/* Encrypt data in INPUT, of INPUTOCTETS bytes length, placing the + output in the pre-allocated OUTBUFFER which must hold at least + INPUTOCTETS aligned to the next block size boundary. + Ciphertext-Stealing as described in RFC 2040 is used to encrypt + partial blocks. The CIPHER is used as state, and must be + initialized with rijndaelCipherInit before calling this function. + The encryption KEY must be initialized with rijndaelMakeKey before + calling this function. Return the number of bits written, or a + negative rijndael_rc error code. */ +extern int +rijndaelPadEncrypt (rijndaelCipherInstance *cipher, + const rijndaelKeyInstance *key, + const char *input, size_t inputOctets, + char *outBuffer); + +/* Decrypt data in INPUT, of INPUTLEN/8 bytes length, placing the + output in the pre-allocated OUTBUFFER which must hold at least + INPUTLEN/8 bytes of data. The CIPHER is used as state, and must be + initialized with rijndaelCipherInit before calling this function. + The encryption KEY must be initialized with rijndaelMakeKey before + calling this function. Return the number of bits written, or a + negative rijndael_rc error code. */ +extern int +rijndaelBlockDecrypt (rijndaelCipherInstance *cipher, + const rijndaelKeyInstance *key, + const char *input, size_t inputLen, + char *outBuffer); + +/* Decrypt data in INPUT, of INPUTOCTETS bytes length, placing the + output in the pre-allocated OUTBUFFER which must hold at least + INPUTOCTETS aligned to the next block size boundary. + Ciphertext-Stealing as described in RFC 2040 is used to encrypt + partial blocks. The CIPHER is used as state, and must be + initialized with rijndaelCipherInit before calling this function. + The encryption KEY must be initialized with rijndaelMakeKey before + calling this function. Return the number of bits written, or a + negative rijndael_rc error code. */ +extern int +rijndaelPadDecrypt (rijndaelCipherInstance *cipher, + const rijndaelKeyInstance *key, + const char *input, size_t inputOctets, + char *outBuffer); + +#endif /* __RIJNDAEL_API_FST_H */ diff --git a/lgl/sha1.c b/lgl/sha1.c new file mode 100644 index 0000000000..d4f38775c2 --- /dev/null +++ b/lgl/sha1.c @@ -0,0 +1,416 @@ +/* sha1.c - Functions to compute SHA1 message digest of files or + memory blocks according to the NIST specification FIPS-180-1. + + Copyright (C) 2000, 2001, 2003, 2004, 2005, 2006 Free Software + Foundation, Inc. + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by the + Free Software Foundation; either version 2.1, or (at your option) any + later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +/* Written by Scott G. Miller + Credits: + Robert Klep <robert@ilse.nl> -- Expansion function fix +*/ + +#include <config.h> + +#include "sha1.h" + +#include <stddef.h> +#include <string.h> + +#if USE_UNLOCKED_IO +# include "unlocked-io.h" +#endif + +#ifdef WORDS_BIGENDIAN +# define SWAP(n) (n) +#else +# define SWAP(n) \ + (((n) << 24) | (((n) & 0xff00) << 8) | (((n) >> 8) & 0xff00) | ((n) >> 24)) +#endif + +#define BLOCKSIZE 4096 +#if BLOCKSIZE % 64 != 0 +# error "invalid BLOCKSIZE" +#endif + +/* This array contains the bytes used to pad the buffer to the next + 64-byte boundary. (RFC 1321, 3.1: Step 1) */ +static const unsigned char fillbuf[64] = { 0x80, 0 /* , 0, 0, ... */ }; + + +/* Take a pointer to a 160 bit block of data (five 32 bit ints) and + initialize it to the start constants of the SHA1 algorithm. This + must be called before using hash in the call to sha1_hash. */ +void +sha1_init_ctx (struct sha1_ctx *ctx) +{ + ctx->A = 0x67452301; + ctx->B = 0xefcdab89; + ctx->C = 0x98badcfe; + ctx->D = 0x10325476; + ctx->E = 0xc3d2e1f0; + + ctx->total[0] = ctx->total[1] = 0; + ctx->buflen = 0; +} + +/* Put result from CTX in first 20 bytes following RESBUF. The result + must be in little endian byte order. + + IMPORTANT: On some systems it is required that RESBUF is correctly + aligned for a 32-bit value. */ +void * +sha1_read_ctx (const struct sha1_ctx *ctx, void *resbuf) +{ + ((uint32_t *) resbuf)[0] = SWAP (ctx->A); + ((uint32_t *) resbuf)[1] = SWAP (ctx->B); + ((uint32_t *) resbuf)[2] = SWAP (ctx->C); + ((uint32_t *) resbuf)[3] = SWAP (ctx->D); + ((uint32_t *) resbuf)[4] = SWAP (ctx->E); + + return resbuf; +} + +/* Process the remaining bytes in the internal buffer and the usual + prolog according to the standard and write the result to RESBUF. + + IMPORTANT: On some systems it is required that RESBUF is correctly + aligned for a 32-bit value. */ +void * +sha1_finish_ctx (struct sha1_ctx *ctx, void *resbuf) +{ + /* Take yet unprocessed bytes into account. */ + uint32_t bytes = ctx->buflen; + size_t size = (bytes < 56) ? 64 / 4 : 64 * 2 / 4; + + /* Now count remaining bytes. */ + ctx->total[0] += bytes; + if (ctx->total[0] < bytes) + ++ctx->total[1]; + + /* Put the 64-bit file length in *bits* at the end of the buffer. */ + ctx->buffer[size - 2] = SWAP ((ctx->total[1] << 3) | (ctx->total[0] >> 29)); + ctx->buffer[size - 1] = SWAP (ctx->total[0] << 3); + + memcpy (&((char *) ctx->buffer)[bytes], fillbuf, (size - 2) * 4 - bytes); + + /* Process last bytes. */ + sha1_process_block (ctx->buffer, size * 4, ctx); + + return sha1_read_ctx (ctx, resbuf); +} + +/* Compute SHA1 message digest for bytes read from STREAM. The + resulting message digest number will be written into the 16 bytes + beginning at RESBLOCK. */ +int +sha1_stream (FILE *stream, void *resblock) +{ + struct sha1_ctx ctx; + char buffer[BLOCKSIZE + 72]; + size_t sum; + + /* Initialize the computation context. */ + sha1_init_ctx (&ctx); + + /* Iterate over full file contents. */ + while (1) + { + /* We read the file in blocks of BLOCKSIZE bytes. One call of the + computation function processes the whole buffer so that with the + next round of the loop another block can be read. */ + size_t n; + sum = 0; + + /* Read block. Take care for partial reads. */ + while (1) + { + n = fread (buffer + sum, 1, BLOCKSIZE - sum, stream); + + sum += n; + + if (sum == BLOCKSIZE) + break; + + if (n == 0) + { + /* Check for the error flag IFF N == 0, so that we don't + exit the loop after a partial read due to e.g., EAGAIN + or EWOULDBLOCK. */ + if (ferror (stream)) + return 1; + goto process_partial_block; + } + + /* We've read at least one byte, so ignore errors. But always + check for EOF, since feof may be true even though N > 0. + Otherwise, we could end up calling fread after EOF. */ + if (feof (stream)) + goto process_partial_block; + } + + /* Process buffer with BLOCKSIZE bytes. Note that + BLOCKSIZE % 64 == 0 + */ + sha1_process_block (buffer, BLOCKSIZE, &ctx); + } + + process_partial_block:; + + /* Process any remaining bytes. */ + if (sum > 0) + sha1_process_bytes (buffer, sum, &ctx); + + /* Construct result in desired memory. */ + sha1_finish_ctx (&ctx, resblock); + return 0; +} + +/* Compute SHA1 message digest for LEN bytes beginning at BUFFER. The + result is always in little endian byte order, so that a byte-wise + output yields to the wanted ASCII representation of the message + digest. */ +void * +sha1_buffer (const char *buffer, size_t len, void *resblock) +{ + struct sha1_ctx ctx; + + /* Initialize the computation context. */ + sha1_init_ctx (&ctx); + + /* Process whole buffer but last len % 64 bytes. */ + sha1_process_bytes (buffer, len, &ctx); + + /* Put result in desired memory area. */ + return sha1_finish_ctx (&ctx, resblock); +} + +void +sha1_process_bytes (const void *buffer, size_t len, struct sha1_ctx *ctx) +{ + /* When we already have some bits in our internal buffer concatenate + both inputs first. */ + if (ctx->buflen != 0) + { + size_t left_over = ctx->buflen; + size_t add = 128 - left_over > len ? len : 128 - left_over; + + memcpy (&((char *) ctx->buffer)[left_over], buffer, add); + ctx->buflen += add; + + if (ctx->buflen > 64) + { + sha1_process_block (ctx->buffer, ctx->buflen & ~63, ctx); + + ctx->buflen &= 63; + /* The regions in the following copy operation cannot overlap. */ + memcpy (ctx->buffer, + &((char *) ctx->buffer)[(left_over + add) & ~63], + ctx->buflen); + } + + buffer = (const char *) buffer + add; + len -= add; + } + + /* Process available complete blocks. */ + if (len >= 64) + { +#if !_STRING_ARCH_unaligned +# define alignof(type) offsetof (struct { char c; type x; }, x) +# define UNALIGNED_P(p) (((size_t) p) % alignof (uint32_t) != 0) + if (UNALIGNED_P (buffer)) + while (len > 64) + { + sha1_process_block (memcpy (ctx->buffer, buffer, 64), 64, ctx); + buffer = (const char *) buffer + 64; + len -= 64; + } + else +#endif + { + sha1_process_block (buffer, len & ~63, ctx); + buffer = (const char *) buffer + (len & ~63); + len &= 63; + } + } + + /* Move remaining bytes in internal buffer. */ + if (len > 0) + { + size_t left_over = ctx->buflen; + + memcpy (&((char *) ctx->buffer)[left_over], buffer, len); + left_over += len; + if (left_over >= 64) + { + sha1_process_block (ctx->buffer, 64, ctx); + left_over -= 64; + memcpy (ctx->buffer, &ctx->buffer[16], left_over); + } + ctx->buflen = left_over; + } +} + +/* --- Code below is the primary difference between md5.c and sha1.c --- */ + +/* SHA1 round constants */ +#define K1 0x5a827999 +#define K2 0x6ed9eba1 +#define K3 0x8f1bbcdc +#define K4 0xca62c1d6 + +/* Round functions. Note that F2 is the same as F4. */ +#define F1(B,C,D) ( D ^ ( B & ( C ^ D ) ) ) +#define F2(B,C,D) (B ^ C ^ D) +#define F3(B,C,D) ( ( B & C ) | ( D & ( B | C ) ) ) +#define F4(B,C,D) (B ^ C ^ D) + +/* Process LEN bytes of BUFFER, accumulating context into CTX. + It is assumed that LEN % 64 == 0. + Most of this code comes from GnuPG's cipher/sha1.c. */ + +void +sha1_process_block (const void *buffer, size_t len, struct sha1_ctx *ctx) +{ + const uint32_t *words = buffer; + size_t nwords = len / sizeof (uint32_t); + const uint32_t *endp = words + nwords; + uint32_t x[16]; + uint32_t a = ctx->A; + uint32_t b = ctx->B; + uint32_t c = ctx->C; + uint32_t d = ctx->D; + uint32_t e = ctx->E; + + /* First increment the byte count. RFC 1321 specifies the possible + length of the file up to 2^64 bits. Here we only compute the + number of bytes. Do a double word increment. */ + ctx->total[0] += len; + if (ctx->total[0] < len) + ++ctx->total[1]; + +#define rol(x, n) (((x) << (n)) | ((uint32_t) (x) >> (32 - (n)))) + +#define M(I) ( tm = x[I&0x0f] ^ x[(I-14)&0x0f] \ + ^ x[(I-8)&0x0f] ^ x[(I-3)&0x0f] \ + , (x[I&0x0f] = rol(tm, 1)) ) + +#define R(A,B,C,D,E,F,K,M) do { E += rol( A, 5 ) \ + + F( B, C, D ) \ + + K \ + + M; \ + B = rol( B, 30 ); \ + } while(0) + + while (words < endp) + { + uint32_t tm; + int t; + for (t = 0; t < 16; t++) + { + x[t] = SWAP (*words); + words++; + } + + R( a, b, c, d, e, F1, K1, x[ 0] ); + R( e, a, b, c, d, F1, K1, x[ 1] ); + R( d, e, a, b, c, F1, K1, x[ 2] ); + R( c, d, e, a, b, F1, K1, x[ 3] ); + R( b, c, d, e, a, F1, K1, x[ 4] ); + R( a, b, c, d, e, F1, K1, x[ 5] ); + R( e, a, b, c, d, F1, K1, x[ 6] ); + R( d, e, a, b, c, F1, K1, x[ 7] ); + R( c, d, e, a, b, F1, K1, x[ 8] ); + R( b, c, d, e, a, F1, K1, x[ 9] ); + R( a, b, c, d, e, F1, K1, x[10] ); + R( e, a, b, c, d, F1, K1, x[11] ); + R( d, e, a, b, c, F1, K1, x[12] ); + R( c, d, e, a, b, F1, K1, x[13] ); + R( b, c, d, e, a, F1, K1, x[14] ); + R( a, b, c, d, e, F1, K1, x[15] ); + R( e, a, b, c, d, F1, K1, M(16) ); + R( d, e, a, b, c, F1, K1, M(17) ); + R( c, d, e, a, b, F1, K1, M(18) ); + R( b, c, d, e, a, F1, K1, M(19) ); + R( a, b, c, d, e, F2, K2, M(20) ); + R( e, a, b, c, d, F2, K2, M(21) ); + R( d, e, a, b, c, F2, K2, M(22) ); + R( c, d, e, a, b, F2, K2, M(23) ); + R( b, c, d, e, a, F2, K2, M(24) ); + R( a, b, c, d, e, F2, K2, M(25) ); + R( e, a, b, c, d, F2, K2, M(26) ); + R( d, e, a, b, c, F2, K2, M(27) ); + R( c, d, e, a, b, F2, K2, M(28) ); + R( b, c, d, e, a, F2, K2, M(29) ); + R( a, b, c, d, e, F2, K2, M(30) ); + R( e, a, b, c, d, F2, K2, M(31) ); + R( d, e, a, b, c, F2, K2, M(32) ); + R( c, d, e, a, b, F2, K2, M(33) ); + R( b, c, d, e, a, F2, K2, M(34) ); + R( a, b, c, d, e, F2, K2, M(35) ); + R( e, a, b, c, d, F2, K2, M(36) ); + R( d, e, a, b, c, F2, K2, M(37) ); + R( c, d, e, a, b, F2, K2, M(38) ); + R( b, c, d, e, a, F2, K2, M(39) ); + R( a, b, c, d, e, F3, K3, M(40) ); + R( e, a, b, c, d, F3, K3, M(41) ); + R( d, e, a, b, c, F3, K3, M(42) ); + R( c, d, e, a, b, F3, K3, M(43) ); + R( b, c, d, e, a, F3, K3, M(44) ); + R( a, b, c, d, e, F3, K3, M(45) ); + R( e, a, b, c, d, F3, K3, M(46) ); + R( d, e, a, b, c, F3, K3, M(47) ); + R( c, d, e, a, b, F3, K3, M(48) ); + R( b, c, d, e, a, F3, K3, M(49) ); + R( a, b, c, d, e, F3, K3, M(50) ); + R( e, a, b, c, d, F3, K3, M(51) ); + R( d, e, a, b, c, F3, K3, M(52) ); + R( c, d, e, a, b, F3, K3, M(53) ); + R( b, c, d, e, a, F3, K3, M(54) ); + R( a, b, c, d, e, F3, K3, M(55) ); + R( e, a, b, c, d, F3, K3, M(56) ); + R( d, e, a, b, c, F3, K3, M(57) ); + R( c, d, e, a, b, F3, K3, M(58) ); + R( b, c, d, e, a, F3, K3, M(59) ); + R( a, b, c, d, e, F4, K4, M(60) ); + R( e, a, b, c, d, F4, K4, M(61) ); + R( d, e, a, b, c, F4, K4, M(62) ); + R( c, d, e, a, b, F4, K4, M(63) ); + R( b, c, d, e, a, F4, K4, M(64) ); + R( a, b, c, d, e, F4, K4, M(65) ); + R( e, a, b, c, d, F4, K4, M(66) ); + R( d, e, a, b, c, F4, K4, M(67) ); + R( c, d, e, a, b, F4, K4, M(68) ); + R( b, c, d, e, a, F4, K4, M(69) ); + R( a, b, c, d, e, F4, K4, M(70) ); + R( e, a, b, c, d, F4, K4, M(71) ); + R( d, e, a, b, c, F4, K4, M(72) ); + R( c, d, e, a, b, F4, K4, M(73) ); + R( b, c, d, e, a, F4, K4, M(74) ); + R( a, b, c, d, e, F4, K4, M(75) ); + R( e, a, b, c, d, F4, K4, M(76) ); + R( d, e, a, b, c, F4, K4, M(77) ); + R( c, d, e, a, b, F4, K4, M(78) ); + R( b, c, d, e, a, F4, K4, M(79) ); + + a = ctx->A += a; + b = ctx->B += b; + c = ctx->C += c; + d = ctx->D += d; + e = ctx->E += e; + } +} diff --git a/lgl/sha1.h b/lgl/sha1.h new file mode 100644 index 0000000000..ed0de2b4e8 --- /dev/null +++ b/lgl/sha1.h @@ -0,0 +1,87 @@ +/* Declarations of functions and data types used for SHA1 sum + library functions. + Copyright (C) 2000, 2001, 2003, 2005, 2006 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by the + Free Software Foundation; either version 2.1, or (at your option) any + later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#ifndef SHA1_H +# define SHA1_H 1 + +# include <stdio.h> +# include <stdint.h> + +/* Structure to save state of computation between the single steps. */ +struct sha1_ctx +{ + uint32_t A; + uint32_t B; + uint32_t C; + uint32_t D; + uint32_t E; + + uint32_t total[2]; + uint32_t buflen; + uint32_t buffer[32]; +}; + + +/* Initialize structure containing state of computation. */ +extern void sha1_init_ctx (struct sha1_ctx *ctx); + +/* Starting with the result of former calls of this function (or the + initialization function update the context for the next LEN bytes + starting at BUFFER. + It is necessary that LEN is a multiple of 64!!! */ +extern void sha1_process_block (const void *buffer, size_t len, + struct sha1_ctx *ctx); + +/* Starting with the result of former calls of this function (or the + initialization function update the context for the next LEN bytes + starting at BUFFER. + It is NOT required that LEN is a multiple of 64. */ +extern void sha1_process_bytes (const void *buffer, size_t len, + struct sha1_ctx *ctx); + +/* Process the remaining bytes in the buffer and put result from CTX + in first 20 bytes following RESBUF. The result is always in little + endian byte order, so that a byte-wise output yields to the wanted + ASCII representation of the message digest. + + IMPORTANT: On some systems it is required that RESBUF be correctly + aligned for a 32 bits value. */ +extern void *sha1_finish_ctx (struct sha1_ctx *ctx, void *resbuf); + + +/* Put result from CTX in first 20 bytes following RESBUF. The result is + always in little endian byte order, so that a byte-wise output yields + to the wanted ASCII representation of the message digest. + + IMPORTANT: On some systems it is required that RESBUF is correctly + aligned for a 32 bits value. */ +extern void *sha1_read_ctx (const struct sha1_ctx *ctx, void *resbuf); + + +/* Compute SHA1 message digest for bytes read from STREAM. The + resulting message digest number will be written into the 20 bytes + beginning at RESBLOCK. */ +extern int sha1_stream (FILE *stream, void *resblock); + +/* Compute SHA1 message digest for LEN bytes beginning at BUFFER. The + result is always in little endian byte order, so that a byte-wise + output yields to the wanted ASCII representation of the message + digest. */ +extern void *sha1_buffer (const char *buffer, size_t len, void *resblock); + +#endif diff --git a/lgl/stdint_.h b/lgl/stdint_.h new file mode 100644 index 0000000000..7866bf7f6d --- /dev/null +++ b/lgl/stdint_.h @@ -0,0 +1,492 @@ +/* Copyright (C) 2001-2002, 2004-2006 Free Software Foundation, Inc. + Written by Paul Eggert, Bruno Haible, Sam Steingold, Peter Burwood. + This file is part of gnulib. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#ifndef _GL_STDINT_H +#define _GL_STDINT_H + +/* + * ISO C 99 <stdint.h> for platforms that lack it. + * <http://www.opengroup.org/susv3xbd/stdint.h.html> + */ + +/* Get those types that are already defined in other system include + files, so that we can "#define int8_t signed char" below without + worrying about a later system include file containing a "typedef + signed char int8_t;" that will get messed up by our macro. Our + macros should all be consistent with the system versions, except + for the "fast" types and macros, which we recommend against using + in public interfaces due to compiler differences. */ + +#if @HAVE_STDINT_H@ +# if defined __sgi && ! defined __c99 + /* Bypass IRIX's <stdint.h> if in C89 mode, since it merely annoys users + with "This header file is to be used only for c99 mode compilations" + diagnostics. */ +# define __STDINT_H__ +# endif + /* Other systems may have an incomplete or buggy <stdint.h>. + Include it before <inttypes.h>, since any "#include <stdint.h>" + in <inttypes.h> would reinclude us, skipping our contents because + _GL_STDINT_H is defined. */ +# include @ABSOLUTE_STDINT_H@ +#endif + +/* <sys/types.h> defines some of the stdint.h types as well, on glibc, + IRIX 6.5, and OpenBSD 3.8 (via <machine/types.h>). + MacOS X 10.4.6 <sys/types.h> includes <stdint.h> (which is us), but + relies on the system <stdint.h> definitions, so include + <sys/types.h> after @ABSOLUTE_STDINT_H@. */ +#if @HAVE_SYS_TYPES_H@ +# include <sys/types.h> +#endif + +/* Get LONG_MIN, LONG_MAX, ULONG_MAX. */ +#include <limits.h> + +#if @HAVE_INTTYPES_H@ + /* In OpenBSD 3.8, <inttypes.h> includes <machine/types.h>, which defines + int{8,16,32,64}_t, uint{8,16,32,64}_t and __BIT_TYPES_DEFINED__. + <inttypes.h> also defines intptr_t and uintptr_t. */ +# define _GL_JUST_INCLUDE_ABSOLUTE_INTTYPES_H +# include <inttypes.h> +# undef _GL_JUST_INCLUDE_ABSOLUTE_INTTYPES_H +#elif @HAVE_SYS_INTTYPES_H@ + /* Solaris 7 <sys/inttypes.h> has the types except the *_fast*_t types, and + the macros except for *_FAST*_*, INTPTR_MIN, PTRDIFF_MIN, PTRDIFF_MAX. */ +# include <sys/inttypes.h> +#endif + +#if @HAVE_SYS_BITYPES_H@ && ! defined __BIT_TYPES_DEFINED__ + /* Linux libc4 >= 4.6.7 and libc5 have a <sys/bitypes.h> that defines + int{8,16,32,64}_t and __BIT_TYPES_DEFINED__. In libc5 >= 5.2.2 it is + included by <sys/types.h>. */ +# include <sys/bitypes.h> +#endif + +#if ! defined __cplusplus || defined __STDC_CONSTANT_MACROS + +/* Get WCHAR_MIN, WCHAR_MAX. */ +# if @HAVE_WCHAR_H@ && ! (defined WCHAR_MIN && defined WCHAR_MAX) + /* BSD/OS 4.1 has a bug: <stdio.h> and <time.h> must be included before + <wchar.h>. */ +# include <stdio.h> +# include <time.h> +# include <wchar.h> +# endif + +#endif + +/* Minimum and maximum values for a integer type under the usual assumption. + Return an unspecified value if BITS == 0, adding a check to pacify + picky compilers. */ + +#define _STDINT_MIN(signed, bits, zero) \ + ((signed) ? (- ((zero) + 1) << ((bits) ? (bits) - 1 : 0)) : (zero)) + +#define _STDINT_MAX(signed, bits, zero) \ + ((signed) \ + ? ~ _STDINT_MIN (signed, bits, zero) \ + : ((((zero) + 1) << ((bits) ? (bits) - 1 : 0)) - 1) * 2 + 1) + +/* 7.18.1.1. Exact-width integer types */ + +/* Here we assume a standard architecture where the hardware integer + types have 8, 16, 32, optionally 64 bits. */ + +#undef int8_t +#undef uint8_t +#define int8_t signed char +#define uint8_t unsigned char + +#undef int16_t +#undef uint16_t +#define int16_t short int +#define uint16_t unsigned short int + +#undef int32_t +#undef uint32_t +#define int32_t int +#define uint32_t unsigned int + +#undef int64_t +#if LONG_MAX >> 31 >> 31 == 1 +# define int64_t long int +#elif defined _MSC_VER +# define int64_t __int64 +#elif @HAVE_LONG_LONG_INT@ +# define int64_t long long int +#endif + +#undef uint64_t +#if ULONG_MAX >> 31 >> 31 >> 1 == 1 +# define uint64_t unsigned long int +#elif defined _MSC_VER +# define uint64_t unsigned __int64 +#elif @HAVE_UNSIGNED_LONG_LONG_INT@ +# define uint64_t unsigned long long int +#endif + +/* Avoid collision with Solaris 2.5.1 <pthread.h> etc. */ +#define _UINT8_T +#define _UINT32_T +#define _UINT64_T + + +/* 7.18.1.2. Minimum-width integer types */ + +/* Here we assume a standard architecture where the hardware integer + types have 8, 16, 32, optionally 64 bits. Therefore the leastN_t types + are the same as the corresponding N_t types. */ + +#undef int_least8_t +#undef uint_least8_t +#undef int_least16_t +#undef uint_least16_t +#undef int_least32_t +#undef uint_least32_t +#undef int_least64_t +#undef uint_least64_t +#define int_least8_t int8_t +#define uint_least8_t uint8_t +#define int_least16_t int16_t +#define uint_least16_t uint16_t +#define int_least32_t int32_t +#define uint_least32_t uint32_t +#ifdef int64_t +# define int_least64_t int64_t +#endif +#ifdef uint64_t +# define uint_least64_t uint64_t +#endif + +/* 7.18.1.3. Fastest minimum-width integer types */ + +/* Note: Other <stdint.h> substitutes may define these types differently. + It is not recommended to use these types in public header files. */ + +/* Here we assume a standard architecture where the hardware integer + types have 8, 16, 32, optionally 64 bits. Therefore the fastN_t types + are taken from the same list of types. Assume that 'long int' + is fast enough for all narrower integers. */ + +#undef int_fast8_t +#undef uint_fast8_t +#undef int_fast16_t +#undef uint_fast16_t +#undef int_fast32_t +#undef uint_fast32_t +#undef int_fast64_t +#undef uint_fast64_t +#define int_fast8_t long int +#define uint_fast8_t unsigned int_fast8_t +#define int_fast16_t long int +#define uint_fast16_t unsigned int_fast16_t +#define int_fast32_t long int +#define uint_fast32_t unsigned int_fast32_t +#ifdef int64_t +# define int_fast64_t int64_t +#endif +#ifdef uint64_t +# define uint_fast64_t uint64_t +#endif + +/* 7.18.1.4. Integer types capable of holding object pointers */ + +#undef intptr_t +#undef uintptr_t +#define intptr_t long int +#define uintptr_t unsigned long int + +/* 7.18.1.5. Greatest-width integer types */ + +/* Note: These types are compiler dependent. It may be unwise to use them in + public header files. */ + +#undef intmax_t +#if @HAVE_LONG_LONG_INT@ && LONG_MAX >> 30 == 1 +# define intmax_t long long int +#elif defined int64_t +# define intmax_t int64_t +#else +# define intmax_t long int +#endif + +#undef uintmax_t +#if @HAVE_UNSIGNED_LONG_LONG_INT@ && ULONG_MAX >> 31 == 1 +# define uintmax_t unsigned long long int +#elif defined int64_t +# define uintmax_t uint64_t +#else +# define uintmax_t unsigned long int +#endif + +/* 7.18.2. Limits of specified-width integer types */ + +#if ! defined __cplusplus || defined __STDC_LIMIT_MACROS + +/* 7.18.2.1. Limits of exact-width integer types */ + +/* Here we assume a standard architecture where the hardware integer + types have 8, 16, 32, optionally 64 bits. */ + +#undef INT8_MIN +#undef INT8_MAX +#undef UINT8_MAX +#define INT8_MIN (~ INT8_MAX) +#define INT8_MAX 127 +#define UINT8_MAX 255 + +#undef INT16_MIN +#undef INT16_MAX +#undef UINT16_MAX +#define INT16_MIN (~ INT16_MAX) +#define INT16_MAX 32767 +#define UINT16_MAX 65535 + +#undef INT32_MIN +#undef INT32_MAX +#undef UINT32_MAX +#define INT32_MIN (~ INT32_MAX) +#define INT32_MAX 2147483647 +#define UINT32_MAX 4294967295U + +#undef INT64_MIN +#undef INT64_MAX +#ifdef int64_t +# define INT64_MIN (~ INT64_MAX) +# define INT64_MAX INTMAX_C (9223372036854775807) +#endif + +#undef UINT64_MAX +#ifdef uint64_t +# define UINT64_MAX UINTMAX_C (18446744073709551615) +#endif + +/* 7.18.2.2. Limits of minimum-width integer types */ + +/* Here we assume a standard architecture where the hardware integer + types have 8, 16, 32, optionally 64 bits. Therefore the leastN_t types + are the same as the corresponding N_t types. */ + +#undef INT_LEAST8_MIN +#undef INT_LEAST8_MAX +#undef UINT_LEAST8_MAX +#define INT_LEAST8_MIN INT8_MIN +#define INT_LEAST8_MAX INT8_MAX +#define UINT_LEAST8_MAX UINT8_MAX + +#undef INT_LEAST16_MIN +#undef INT_LEAST16_MAX +#undef UINT_LEAST16_MAX +#define INT_LEAST16_MIN INT16_MIN +#define INT_LEAST16_MAX INT16_MAX +#define UINT_LEAST16_MAX UINT16_MAX + +#undef INT_LEAST32_MIN +#undef INT_LEAST32_MAX +#undef UINT_LEAST32_MAX +#define INT_LEAST32_MIN INT32_MIN +#define INT_LEAST32_MAX INT32_MAX +#define UINT_LEAST32_MAX UINT32_MAX + +#undef INT_LEAST64_MIN +#undef INT_LEAST64_MAX +#ifdef int64_t +# define INT_LEAST64_MIN INT64_MIN +# define INT_LEAST64_MAX INT64_MAX +#endif + +#undef UINT_LEAST64_MAX +#ifdef uint64_t +# define UINT_LEAST64_MAX UINT64_MAX +#endif + +/* 7.18.2.3. Limits of fastest minimum-width integer types */ + +/* Here we assume a standard architecture where the hardware integer + types have 8, 16, 32, optionally 64 bits. Therefore the fastN_t types + are taken from the same list of types. */ + +#undef INT_FAST8_MIN +#undef INT_FAST8_MAX +#undef UINT_FAST8_MAX +#define INT_FAST8_MIN LONG_MIN +#define INT_FAST8_MAX LONG_MAX +#define UINT_FAST8_MAX ULONG_MAX + +#undef INT_FAST16_MIN +#undef INT_FAST16_MAX +#undef UINT_FAST16_MAX +#define INT_FAST16_MIN LONG_MIN +#define INT_FAST16_MAX LONG_MAX +#define UINT_FAST16_MAX ULONG_MAX + +#undef INT_FAST32_MIN +#undef INT_FAST32_MAX +#undef UINT_FAST32_MAX +#define INT_FAST32_MIN LONG_MIN +#define INT_FAST32_MAX LONG_MAX +#define UINT_FAST32_MAX ULONG_MAX + +#undef INT_FAST64_MIN +#undef INT_FAST64_MAX +#ifdef int64_t +# define INT_FAST64_MIN INT64_MIN +# define INT_FAST64_MAX INT64_MAX +#endif + +#undef UINT_FAST64_MAX +#ifdef uint64_t +# define UINT_FAST64_MAX UINT64_MAX +#endif + +/* 7.18.2.4. Limits of integer types capable of holding object pointers */ + +#undef INTPTR_MIN +#undef INTPTR_MAX +#undef UINTPTR_MAX +#define INTPTR_MIN LONG_MIN +#define INTPTR_MAX LONG_MAX +#define UINTPTR_MAX ULONG_MAX + +/* 7.18.2.5. Limits of greatest-width integer types */ + +#undef INTMAX_MIN +#undef INTMAX_MAX +#define INTMAX_MIN (~ INTMAX_MAX) +#ifdef INT64_MAX +# define INTMAX_MAX INT64_MAX +#else +# define INTMAX_MAX INT32_MAX +#endif + +#undef UINTMAX_MAX +#ifdef UINT64_MAX +# define UINTMAX_MAX UINT64_MAX +#else +# define UINTMAX_MAX UINT32_MAX +#endif + +/* 7.18.3. Limits of other integer types */ + +/* ptrdiff_t limits */ +#undef PTRDIFF_MIN +#undef PTRDIFF_MAX +#define PTRDIFF_MIN \ + _STDINT_MIN (1, @BITSIZEOF_PTRDIFF_T@, 0@PTRDIFF_T_SUFFIX@) +#define PTRDIFF_MAX \ + _STDINT_MAX (1, @BITSIZEOF_PTRDIFF_T@, 0@PTRDIFF_T_SUFFIX@) + +/* sig_atomic_t limits */ +#undef SIG_ATOMIC_MIN +#undef SIG_ATOMIC_MAX +#define SIG_ATOMIC_MIN \ + _STDINT_MIN (@HAVE_SIGNED_SIG_ATOMIC_T@, @BITSIZEOF_SIG_ATOMIC_T@, \ + 0@SIG_ATOMIC_T_SUFFIX@) +#define SIG_ATOMIC_MAX \ + _STDINT_MAX (@HAVE_SIGNED_SIG_ATOMIC_T@, @BITSIZEOF_SIG_ATOMIC_T@, \ + 0@SIG_ATOMIC_T_SUFFIX@) + + +/* size_t limit */ +#undef SIZE_MAX +#define SIZE_MAX _STDINT_MAX (0, @BITSIZEOF_SIZE_T@, 0@SIZE_T_SUFFIX@) + +/* wchar_t limits */ +#undef WCHAR_MIN +#undef WCHAR_MAX +#define WCHAR_MIN \ + _STDINT_MIN (@HAVE_SIGNED_WCHAR_T@, @BITSIZEOF_WCHAR_T@, 0@WCHAR_T_SUFFIX@) +#define WCHAR_MAX \ + _STDINT_MAX (@HAVE_SIGNED_WCHAR_T@, @BITSIZEOF_WCHAR_T@, 0@WCHAR_T_SUFFIX@) + +/* wint_t limits */ +#undef WINT_MIN +#undef WINT_MAX +#define WINT_MIN \ + _STDINT_MIN (@HAVE_SIGNED_WINT_T@, @BITSIZEOF_WINT_T@, 0@WINT_T_SUFFIX@) +#define WINT_MAX \ + _STDINT_MAX (@HAVE_SIGNED_WINT_T@, @BITSIZEOF_WINT_T@, 0@WINT_T_SUFFIX@) + +#endif /* !defined __cplusplus || defined __STDC_LIMIT_MACROS */ + +/* 7.18.4. Macros for integer constants */ + +#if ! defined __cplusplus || defined __STDC_CONSTANT_MACROS + +/* 7.18.4.1. Macros for minimum-width integer constants */ +/* According to ISO C 99 Technical Corrigendum 1 */ + +/* Here we assume a standard architecture where the hardware integer + types have 8, 16, 32, optionally 64 bits, and int is 32 bits. */ + +#undef INT8_C +#undef UINT8_C +#define INT8_C(x) x +#define UINT8_C(x) x + +#undef INT16_C +#undef UINT16_C +#define INT16_C(x) x +#define UINT16_C(x) x + +#undef INT32_C +#undef UINT32_C +#define INT32_C(x) x +#define UINT32_C(x) x ## U + +#undef INT64_C +#undef UINT64_C +#if LONG_MAX >> 31 >> 31 == 1 +# define INT64_C(x) x##L +#elif defined _MSC_VER +# define INT64_C(x) x##i64 +#elif @HAVE_LONG_LONG_INT@ +# define INT64_C(x) x##LL +#endif +#if ULONG_MAX >> 31 >> 31 >> 1 == 1 +# define UINT64_C(x) x##UL +#elif defined _MSC_VER +# define UINT64_C(x) x##ui64 +#elif @HAVE_UNSIGNED_LONG_LONG_INT@ +# define UINT64_C(x) x##ULL +#endif + +/* 7.18.4.2. Macros for greatest-width integer constants */ + +#undef INTMAX_C +#if @HAVE_LONG_LONG_INT@ && LONG_MAX >> 30 == 1 +# define INTMAX_C(x) x##LL +#elif defined int64_t +# define INTMAX_C(x) INT64_C(x) +#else +# define INTMAX_C(x) x##L +#endif + +#undef UINTMAX_C +#if @HAVE_UNSIGNED_LONG_LONG_INT@ && ULONG_MAX >> 31 == 1 +# define UINTMAX_C(x) x##ULL +#elif defined uint64_t +# define UINTMAX_C(x) UINT64_C(x) +#else +# define UINTMAX_C(x) x##UL +#endif + +#endif /* !defined __cplusplus || defined __STDC_CONSTANT_MACROS */ + +#endif /* _GL_STDINT_H */ |