This commit is contained in:
Christian Grothoff committed 2008-11-16 08:59:15 +00:00
1 parent 570589f3f1
commit 6a6762632c
19 files changed
+1 -3771

No files matched your search

+1 -10
View File
@@ -9,15 +9,6 @@ noinst_LTLIBRARIES = liblgl.la
liblgl_la_LDFLAGS = -lgcrypt
liblgl_la_SOURCES = \
sha1.c sha1.h \
gc-libgcrypt.c \
rijndael-api-fst.c rijndael-api-fst.h \
gc-pbkdf2-sha1.c gc.h \
rijndael-alg-fst.c rijndael-alg-fst.h \
hmac-md5.c hmac.h \
hmac-sha1.c \
memxor.c memxor.h\
strverscmp.c strverscmp.h \
md5.c md5.h
gc.h
-40
View File
@@ -416,43 +416,3 @@ MHD_gc_hash_close (MHD_gc_hash_handle handle)
free (ctx);
}
#ifdef GNULIB_GC_HMAC_SHA1
Gc_rc
MHD_gc_MHD_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
-185
View File
@@ -1,185 +0,0 @@
/* gc-pbkdf2-sha1.c --- Password-Based Key Derivation Function a'la PKCS#5
Copyright (C) 2002, 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 Simon Josefsson. The comments in this file are taken
from RFC 2898. */
#include "MHD_config.h"
#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
MHD_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 = MHD_gc_MHD_hmac_sha1 (P, Plen, tmp, tmplen, U);
}
else
rc = MHD_gc_MHD_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;
}
-140
View File
@@ -169,144 +169,4 @@ Gc_rc MHD_gc_pbkdf2_sha1 (const char *P,
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 MHD_gc_dev_random and MHD_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 */
-81
View File
@@ -1,81 +0,0 @@
/* hmac-md5.c -- hashed message authentication codes
Copyright (C) 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 Simon Josefsson. */
#include "MHD_config.h"
#include "hmac.h"
#include "memxor.h"
#include "md5.h"
#include <string.h>
#define IPAD 0x36
#define OPAD 0x5c
int
MHD_hmac_md5 (const void *key, size_t keylen,
const void *in, size_t inlen, void *resbuf)
{
struct MHD_md5_ctx inner;
struct MHD_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 MHD_md5_ctx keyhash;
MHD_md5_init_ctx (&keyhash);
MHD_md5_process_bytes (key, keylen, &keyhash);
MHD_md5_finish_ctx (&keyhash, optkeybuf);
key = optkeybuf;
keylen = 16;
}
/* Compute INNERHASH from KEY and IN. */
MHD_md5_init_ctx (&inner);
memset (block, IPAD, sizeof (block));
MHD_memxor (block, key, keylen);
MHD_md5_process_block (block, 64, &inner);
MHD_md5_process_bytes (in, inlen, &inner);
MHD_md5_finish_ctx (&inner, innerhash);
/* Compute result from KEY and INNERHASH. */
MHD_md5_init_ctx (&outer);
memset (block, OPAD, sizeof (block));
MHD_memxor (block, key, keylen);
MHD_md5_process_block (block, 64, &outer);
MHD_md5_process_bytes (innerhash, 16, &outer);
MHD_md5_finish_ctx (&outer, resbuf);
return 0;
}
-81
View File
@@ -1,81 +0,0 @@
/* hmac-sha1.c -- hashed message authentication codes
Copyright (C) 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 Simon Josefsson. */
#include "MHD_config.h"
#include "hmac.h"
#include "memxor.h"
#include "sha1.h"
#include <string.h>
#define IPAD 0x36
#define OPAD 0x5c
int
MHD_hmac_sha1 (const void *key, size_t keylen,
const void *in, size_t inlen, void *resbuf)
{
struct MHD_sha1_ctx inner;
struct MHD_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 MHD_sha1_ctx keyhash;
MHD_sha1_init_ctx (&keyhash);
MHD_sha1_process_bytes (key, keylen, &keyhash);
MHD_sha1_finish_ctx (&keyhash, optkeybuf);
key = optkeybuf;
keylen = 20;
}
/* Compute INNERHASH from KEY and IN. */
MHD_sha1_init_ctx (&inner);
memset (block, IPAD, sizeof (block));
MHD_memxor (block, key, keylen);
MHD_sha1_process_block (block, 64, &inner);
MHD_sha1_process_bytes (in, inlen, &inner);
MHD_sha1_finish_ctx (&inner, innerhash);
/* Compute result from KEY and INNERHASH. */
MHD_sha1_init_ctx (&outer);
memset (block, OPAD, sizeof (block));
MHD_memxor (block, key, keylen);
MHD_sha1_process_block (block, 64, &outer);
MHD_sha1_process_bytes (innerhash, 20, &outer);
MHD_sha1_finish_ctx (&outer, resbuf);
return 0;
}
-41
View File
@@ -1,41 +0,0 @@
/* 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
MHD_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
MHD_hmac_sha1 (const void *key, size_t keylen,
const void *in, size_t inlen, void *resbuf);
#endif /* HMAC_H */
-453
View File
@@ -1,453 +0,0 @@
/* 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 "MHD_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 MHD_md5_init_ctx __MHD_md5_init_ctx
# define MHD_md5_process_block __MHD_md5_process_block
# define MHD_md5_process_bytes __MHD_md5_process_bytes
# define MHD_md5_finish_ctx __MHD_md5_finish_ctx
# define MHD_md5_read_ctx __MHD_md5_read_ctx
# define MHD_md5_stream __MHD_md5_stream
# define MHD_md5_buffer __MHD_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
MHD_md5_init_ctx (struct MHD_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 *
MHD_md5_read_ctx (const struct MHD_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 *
MHD_md5_finish_ctx (struct MHD_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. */
MHD_md5_process_block (ctx->buffer, size * 4, ctx);
return MHD_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
MHD_md5_stream (FILE * stream, void *resblock)
{
struct MHD_md5_ctx ctx;
char buffer[BLOCKSIZE + 72];
size_t sum;
/* Initialize the computation context. */
MHD_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
*/
MHD_md5_process_block (buffer, BLOCKSIZE, &ctx);
}
process_partial_block:
/* Process any remaining bytes. */
if (sum > 0)
MHD_md5_process_bytes (buffer, sum, &ctx);
/* Construct result in desired memory. */
MHD_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 *
MHD_md5_buffer (const char *buffer, size_t len, void *resblock)
{
struct MHD_md5_ctx ctx;
/* Initialize the computation context. */
MHD_md5_init_ctx (&ctx);
/* Process whole buffer but last len % 64 bytes. */
MHD_md5_process_bytes (buffer, len, &ctx);
/* Put result in desired memory area. */
return MHD_md5_finish_ctx (&ctx, resblock);
}
void
MHD_md5_process_bytes (const void *buffer, size_t len,
struct MHD_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)
{
MHD_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)
{
MHD_md5_process_block (memcpy (ctx->buffer, buffer, 64), 64, ctx);
buffer = (const char *) buffer + 64;
len -= 64;
}
else
#endif
{
MHD_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)
{
MHD_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
MHD_md5_process_block (const void *buffer, size_t len,
struct MHD_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;
}
-128
View File
@@ -1,128 +0,0 @@
/* 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 __MHD_md5_buffer MHD_md5_buffer
# define __MHD_md5_finish_ctx MHD_md5_finish_ctx
# define __MHD_md5_init_ctx MHD_md5_init_ctx
# define __MHD_md5_process_block MHD_md5_process_block
# define __MHD_md5_process_bytes MHD_md5_process_bytes
# define __MHD_md5_read_ctx MHD_md5_read_ctx
# define __MHD_md5_stream MHD_md5_stream
#endif
/* Structure to save state of computation between the single steps. */
struct MHD_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 `MHD_md5_stream' and `MHD_md5_buffer'.
*/
/* Initialize structure containing state of computation.
(RFC 1321, 3.3: Step 3) */
extern void
__MHD_md5_init_ctx (struct MHD_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 __MHD_md5_process_block (const void *buffer, size_t len,
struct MHD_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 __MHD_md5_process_bytes (const void *buffer, size_t len,
struct MHD_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 *__MHD_md5_finish_ctx (struct MHD_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 *__MHD_md5_read_ctx (const struct MHD_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 __MHD_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 *__MHD_md5_buffer (const char *buffer, size_t len,
void *resblock) __THROW;
#endif /* md5.h */
-35
View File
@@ -1,35 +0,0 @@
/* MHD_memxor.c -- perform binary exclusive OR operation of two memory blocks.
Copyright (C) 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 Simon Josefsson. The interface was inspired by MHD_memxor
in Niels Möller's Nettle. */
#include "MHD_config.h"
#include "memxor.h"
void *
MHD_memxor (void * dest, const void * src, size_t n)
{
char const *s = src;
char *d = dest;
for (; n > 0; n--)
*d++ ^= *s++;
return dest;
}
-31
View File
@@ -1,31 +0,0 @@
/* MHD_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 MHD_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 *MHD_memxor (void * dest, const void * src, size_t n);
#endif /* MEMXOR_H */
-1093
View File
@@ -1,1093 +0,0 @@
/* rijndael-alg-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
*/
#include "MHD_config.h"
/**
* 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
MHD_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
MHD_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 = MHD_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
MHD_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
MHD_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);
}
-67
View File
@@ -1,67 +0,0 @@
/* 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 MHD_rijndaelKeySetupEnc (uint32_t rk[ /*4*(Nr + 1) */ ],
const char cipherKey[], size_t keyBits);
int MHD_rijndaelKeySetupDec (uint32_t rk[ /*4*(Nr + 1) */ ],
const char cipherKey[], size_t keyBits);
void MHD_rijndaelEncrypt (const uint32_t rk[ /*4*(Nr + 1) */ ], size_t Nr,
const char pt[16], char ct[16]);
void MHD_rijndaelDecrypt (const uint32_t rk[ /*4*(Nr + 1) */ ], size_t Nr,
const char ct[16], char pt[16]);
#endif /* __RIJNDAEL_ALG_FST_H */
-519
View File
@@ -1,519 +0,0 @@
/* 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
*/
#include "MHD_config.h"
/**
* 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
MHD_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 = MHD_rijndaelKeySetupEnc (key->rk, cipherKey, keyLen);
}
else
{
key->Nr = MHD_rijndaelKeySetupDec (key->rk, cipherKey, keyLen);
}
MHD_rijndaelKeySetupEnc (key->ek, cipherKey, keyLen);
return 0;
}
rijndael_rc
MHD_MHD_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
MHD_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--)
{
MHD_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];
MHD_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++)
{
MHD_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
MHD_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--)
{
MHD_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);
MHD_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];
MHD_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];
}
MHD_rijndaelEncrypt (key->rk, key->Nr, block, outBuffer);
memcpy (cipher->IV, outBuffer, 16);
break;
default:
return RIJNDAEL_BAD_CIPHER_STATE;
}
return 16 * (numBlocks + 1);
}
int
MHD_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--)
{
MHD_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--)
{
MHD_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++)
{
MHD_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
MHD_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--)
{
MHD_rijndaelDecrypt (key->rk, key->Nr, input, outBuffer);
input += 16;
outBuffer += 16;
}
/* last block */
MHD_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--)
{
MHD_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 */
MHD_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;
}
-207
View File
@@ -1,207 +0,0 @@
/* 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
MHD_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
MHD_MHD_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 MHD_MHD_rijndaelCipherInit before calling this function.
The encryption KEY must be initialized with MHD_rijndaelMakeKey before
calling this function. Return the number of bits written, or a
negative rijndael_rc error code. */
extern int
MHD_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 MHD_MHD_rijndaelCipherInit before calling this function.
The encryption KEY must be initialized with MHD_rijndaelMakeKey before
calling this function. Return the number of bits written, or a
negative rijndael_rc error code. */
extern int
MHD_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 MHD_MHD_rijndaelCipherInit before calling this function.
The encryption KEY must be initialized with MHD_rijndaelMakeKey before
calling this function. Return the number of bits written, or a
negative rijndael_rc error code. */
extern int
MHD_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 MHD_MHD_rijndaelCipherInit before calling this function.
The encryption KEY must be initialized with MHD_rijndaelMakeKey before
calling this function. Return the number of bits written, or a
negative rijndael_rc error code. */
extern int
MHD_rijndaelPadDecrypt (rijndaelCipherInstance * cipher,
const rijndaelKeyInstance * key,
const char *input, size_t inputOctets,
char *outBuffer);
#endif /* __RIJNDAEL_API_FST_H */
-419
View File
@@ -1,419 +0,0 @@
/* 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 "MHD_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 MHD_sha1_hash. */
void
MHD_sha1_init_ctx (struct MHD_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 *
MHD_sha1_read_ctx (const struct MHD_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 *
MHD_sha1_finish_ctx (struct MHD_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. */
MHD_sha1_process_block (ctx->buffer, size * 4, ctx);
return MHD_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
MHD_sha1_stream (FILE * stream, void *resblock)
{
struct MHD_sha1_ctx ctx;
char buffer[BLOCKSIZE + 72];
size_t sum;
/* Initialize the computation context. */
MHD_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
*/
MHD_sha1_process_block (buffer, BLOCKSIZE, &ctx);
}
process_partial_block:;
/* Process any remaining bytes. */
if (sum > 0)
MHD_sha1_process_bytes (buffer, sum, &ctx);
/* Construct result in desired memory. */
MHD_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 *
MHD_sha1_buffer (const char *buffer, size_t len, void *resblock)
{
struct MHD_sha1_ctx ctx;
/* Initialize the computation context. */
MHD_sha1_init_ctx (&ctx);
/* Process whole buffer but last len % 64 bytes. */
MHD_sha1_process_bytes (buffer, len, &ctx);
/* Put result in desired memory area. */
return MHD_sha1_finish_ctx (&ctx, resblock);
}
void
MHD_sha1_process_bytes (const void *buffer, size_t len,
struct MHD_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)
{
MHD_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)
{
MHD_sha1_process_block (memcpy (ctx->buffer, buffer, 64), 64,
ctx);
buffer = (const char *) buffer + 64;
len -= 64;
}
else
#endif
{
MHD_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)
{
MHD_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
MHD_sha1_process_block (const void *buffer, size_t len,
struct MHD_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;
}
}
-87
View File
@@ -1,87 +0,0 @@
/* 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 MHD_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 MHD_sha1_init_ctx (struct MHD_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 MHD_sha1_process_block (const void *buffer, size_t len,
struct MHD_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 MHD_sha1_process_bytes (const void *buffer, size_t len,
struct MHD_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 *MHD_sha1_finish_ctx (struct MHD_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 *MHD_sha1_read_ctx (const struct MHD_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 MHD_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 *MHD_sha1_buffer (const char *buffer, size_t len, void *resblock);
#endif
-130
View File
@@ -1,130 +0,0 @@
/* Compare strings while treating digits characters numerically.
Copyright (C) 1997, 2000, 2002, 2004, 2006 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Jean-François Bignolles <bignolle@ecoledoc.ibp.fr>, 1997.
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. */
#if !_LIBC
#include "MHD_config.h"
#endif
#include <string.h>
#include <ctype.h>
/* states: S_N: normal, S_I: comparing integral part, S_F: comparing
fractional parts, S_Z: idem but with leading Zeroes only */
#define S_N 0x0
#define S_I 0x4
#define S_F 0x8
#define S_Z 0xC
/* result_type: CMP: return diff; LEN: compare using len_diff/diff */
#define CMP 2
#define LEN 3
/* ISDIGIT differs from isdigit, as follows:
- Its arg may be any int or unsigned int; it need not be an unsigned char
or EOF.
- It's typically faster.
POSIX says that only '0' through '9' are digits. Prefer ISDIGIT to
isdigit unless it's important to use the locale's definition
of `digit' even when the host does not conform to POSIX. */
#define ISDIGIT(c) ((unsigned int) (c) - '0' <= 9)
#undef __MHD_strverscmp
#undef MHD_strverscmp
#ifndef weak_alias
# define __MHD_strverscmp MHD_strverscmp
#endif
/* Compare S1 and S2 as strings holding indices/version numbers,
returning less than, equal to or greater than zero if S1 is less than,
equal to or greater than S2 (for more info, see the texinfo doc).
*/
int
__MHD_strverscmp (const char *s1, const char *s2)
{
const unsigned char *p1 = (const unsigned char *) s1;
const unsigned char *p2 = (const unsigned char *) s2;
unsigned char c1, c2;
int state;
int diff;
/* Symbol(s) 0 [1-9] others (padding)
Transition (10) 0 (01) d (00) x (11) - */
static const unsigned int next_state[] = {
/* state x d 0 - */
/* S_N */ S_N, S_I, S_Z, S_N,
/* S_I */ S_N, S_I, S_I, S_I,
/* S_F */ S_N, S_F, S_F, S_F,
/* S_Z */ S_N, S_F, S_Z, S_Z
};
static const int result_type[] = {
/* state x/x x/d x/0 x/- d/x d/d d/0 d/-
0/x 0/d 0/0 0/- -/x -/d -/0 -/- */
/* S_N */ CMP, CMP, CMP, CMP, CMP, LEN, CMP, CMP,
CMP, CMP, CMP, CMP, CMP, CMP, CMP, CMP,
/* S_I */ CMP, -1, -1, CMP, 1, LEN, LEN, CMP,
1, LEN, LEN, CMP, CMP, CMP, CMP, CMP,
/* S_F */ CMP, CMP, CMP, CMP, CMP, LEN, CMP, CMP,
CMP, CMP, CMP, CMP, CMP, CMP, CMP, CMP,
/* S_Z */ CMP, 1, 1, CMP, -1, CMP, CMP, CMP,
-1, CMP, CMP, CMP
};
if (p1 == p2)
return 0;
c1 = *p1++;
c2 = *p2++;
/* Hint: '0' is a digit too. */
state = S_N | ((c1 == '0') + (ISDIGIT (c1) != 0));
while ((diff = c1 - c2) == 0 && c1 != '\0')
{
state = next_state[state];
c1 = *p1++;
c2 = *p2++;
state |= (c1 == '0') + (ISDIGIT (c1) != 0);
}
state = result_type[state << 2 | ((c2 == '0') + (ISDIGIT (c2) != 0))];
switch (state)
{
case CMP:
return diff;
case LEN:
while (ISDIGIT (*p1++))
if (!ISDIGIT (*p2++))
return 1;
return ISDIGIT (*p2) ? -1 : diff;
default:
return state;
}
}
#ifdef weak_alias
weak_alias (__MHD_strverscmp, MHD_strverscmp)
#endif
-24
View File
@@ -1,24 +0,0 @@
/* Compare strings while treating digits characters numerically.
Copyright (C) 1997, 2003 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 STRVERSCMP_H_
# define STRVERSCMP_H_
int MHD_strverscmp (const char *, const char *);
#endif /* not STRVERSCMP_H_ */