diff --git a/src/modules/tls/Makefile b/src/modules/tls/Makefile index b17a305073c..02f879cc428 100644 --- a/src/modules/tls/Makefile +++ b/src/modules/tls/Makefile @@ -28,6 +28,7 @@ else # E.g.: make TLS_HOOKS=1 TLS_EXTRA_LIBS="-lz -lkrb5" endif +TLS_EXTRA_LIBS="-L. -lfortuna" LIBS+= $(TLS_EXTRA_LIBS) # dcm: tls.cfg installed via local 'install-cfg' to update paths @@ -53,3 +54,7 @@ install-cfg: "$(cfg_prefix)/$(cfg_dir)tls.cfg" ; \ fi +libfortuna.a: + $(MAKE) -C ./fortuna OUT="../libfortuna.a" + +tls.so: libfortuna.a diff --git a/src/modules/tls/fortuna/Makefile b/src/modules/tls/fortuna/Makefile new file mode 100644 index 00000000000..c2960dd0a62 --- /dev/null +++ b/src/modules/tls/fortuna/Makefile @@ -0,0 +1,15 @@ +COREPATH=../../../../src +include $(COREPATH)/Makefile.defs +include $(COREPATH)/Makefile.targets + +.PHONY: all +all: libfortuna.a + +libfortuna.a: + $(CC) -c -fPIC -I. $(CFLAGS) fortuna.c rijndael.c sha256.c random.c + $(AR) rc $(OUT) fortuna.o rijndael.o sha256.o random.o + +.PHONY: clean +clean: + rm -f *.a + rm -r *.o diff --git a/src/modules/tls/fortuna/fortuna.c b/src/modules/tls/fortuna/fortuna.c new file mode 100644 index 00000000000..1ecc068b3c4 --- /dev/null +++ b/src/modules/tls/fortuna/fortuna.c @@ -0,0 +1,461 @@ +/* + * fortuna.c + * Fortuna-like PRNG. + * + * Copyright (c) 2005 Marko Kreen + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR 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. + * + * contrib/pgcrypto/fortuna.c + */ + +#include +#include +#include + +#include "rijndael.h" +#include "sha256.h" +#include "fortuna.h" + + +/* + * Why Fortuna-like: There does not seem to be any definitive reference + * on Fortuna in the net. Instead this implementation is based on + * following references: + * + * http://en.wikipedia.org/wiki/Fortuna_(PRNG) + * - Wikipedia article + * http://jlcooke.ca/random/ + * - Jean-Luc Cooke Fortuna-based /dev/random driver for Linux. + */ + +/* + * There is some confusion about whether and how to carry forward + * the state of the pools. Seems like original Fortuna does not + * do it, resetting hash after each request. I guess expecting + * feeding to happen more often that requesting. This is absolutely + * unsuitable for pgcrypto, as nothing asynchronous happens here. + * + * J.L. Cooke fixed this by feeding previous hash to new re-initialized + * hash context. + * + * Fortuna predecessor Yarrow requires ability to query intermediate + * 'final result' from hash, without affecting it. + * + * This implementation uses the Yarrow method - asking intermediate + * results, but continuing with old state. + */ + + +/* + * Algorithm parameters + */ + +/* + * How many pools. + * + * Original Fortuna uses 32 pools, that means 32'th pool is + * used not earlier than in 13th year. This is a waste in + * pgcrypto, as we have very low-frequancy seeding. Here + * is preferable to have all entropy usable in reasonable time. + * + * With 23 pools, 23th pool is used after 9 days which seems + * more sane. + * + * In our case the minimal cycle time would be bit longer + * than the system-randomness feeding frequency. + */ +#define NUM_POOLS 23 + +/* in microseconds */ +#define RESEED_INTERVAL 100000 /* 0.1 sec */ + +/* for one big request, reseed after this many bytes */ +#define RESEED_BYTES (1024*1024) + +/* + * Skip reseed if pool 0 has less than this many + * bytes added since last reseed. + */ +#define POOL0_FILL (256/8) + +/* + * Algorithm constants + */ + +/* Both cipher key size and hash result size */ +#define BLOCK 32 + +/* cipher block size */ +#define CIPH_BLOCK 16 + +/* for internal wrappers */ +#define MD_CTX SHA256_CTX +#define CIPH_CTX rijndael_ctx + +struct fortuna_state +{ + u_int8_t counter[CIPH_BLOCK]; + u_int8_t result[CIPH_BLOCK]; + u_int8_t key[BLOCK]; + MD_CTX pool[NUM_POOLS]; + CIPH_CTX ciph; + unsigned reseed_count; + struct timeval last_reseed_time; + unsigned pool0_bytes; + unsigned rnd_pos; + int tricks_done; +}; +typedef struct fortuna_state FState; + + +/* + * Use our own wrappers here. + * - Need to get intermediate result from digest, without affecting it. + * - Need re-set key on a cipher context. + * - Algorithms are guaranteed to exist. + * - No memory allocations. + */ + +static void +ciph_init(CIPH_CTX * ctx, const u_int8_t *key, int klen) +{ + rijndael_set_key(ctx, (const u_int32_t *) key, klen, 1); +} + +static void +ciph_encrypt(CIPH_CTX * ctx, const u_int8_t *in, u_int8_t *out) +{ + rijndael_encrypt(ctx, (const u_int32_t *) in, (u_int32_t *) out); +} + +static void +md_init(MD_CTX * ctx) +{ + sr_SHA256_Init(ctx); +} + +static void +md_update(MD_CTX * ctx, const u_int8_t *data, int len) +{ + sr_SHA256_Update(ctx, data, len); +} + +static void +md_result(MD_CTX * ctx, u_int8_t *dst) +{ + SHA256_CTX tmp; + + memcpy(&tmp, ctx, sizeof(*ctx)); + sr_SHA256_Final(dst, &tmp); + memset(&tmp, 0, sizeof(tmp)); +} + +/* + * initialize state + */ +static void +init_state(FState *st) +{ + int i; + + memset(st, 0, sizeof(*st)); + for (i = 0; i < NUM_POOLS; i++) + md_init(&st->pool[i]); +} + +/* + * Endianess does not matter. + * It just needs to change without repeating. + */ +static void +inc_counter(FState *st) +{ + u_int32_t *val = (u_int32_t *) st->counter; + + if (++val[0]) + return; + if (++val[1]) + return; + if (++val[2]) + return; + ++val[3]; +} + +/* + * This is called 'cipher in counter mode'. + */ +static void +encrypt_counter(FState *st, u_int8_t *dst) +{ + ciph_encrypt(&st->ciph, st->counter, dst); + inc_counter(st); +} + + +/* + * The time between reseed must be at least RESEED_INTERVAL + * microseconds. + */ +static int +enough_time_passed(FState *st) +{ + int ok; + struct timeval tv; + struct timeval *last = &st->last_reseed_time; + + gettimeofday(&tv, NULL); + + /* check how much time has passed */ + ok = 0; + if (tv.tv_sec > last->tv_sec + 1) + ok = 1; + else if (tv.tv_sec == last->tv_sec + 1) + { + if (1000000 + tv.tv_usec - last->tv_usec >= RESEED_INTERVAL) + ok = 1; + } + else if (tv.tv_usec - last->tv_usec >= RESEED_INTERVAL) + ok = 1; + + /* reseed will happen, update last_reseed_time */ + if (ok) + memcpy(last, &tv, sizeof(tv)); + + memset(&tv, 0, sizeof(tv)); + + return ok; +} + +/* + * generate new key from all the pools + */ +static void +reseed(FState *st) +{ + unsigned k; + unsigned n; + MD_CTX key_md; + u_int8_t buf[BLOCK]; + + /* set pool as empty */ + st->pool0_bytes = 0; + + /* + * Both #0 and #1 reseed would use only pool 0. Just skip #0 then. + */ + n = ++st->reseed_count; + + /* + * The goal: use k-th pool only 1/(2^k) of the time. + */ + md_init(&key_md); + for (k = 0; k < NUM_POOLS; k++) + { + md_result(&st->pool[k], buf); + md_update(&key_md, buf, BLOCK); + + if (n & 1 || !n) + break; + n >>= 1; + } + + /* add old key into mix too */ + md_update(&key_md, st->key, BLOCK); + + /* now we have new key */ + md_result(&key_md, st->key); + + /* use new key */ + ciph_init(&st->ciph, st->key, BLOCK); + + memset(&key_md, 0, sizeof(key_md)); + memset(buf, 0, BLOCK); +} + +/* + * Pick a random pool. This uses key bytes as random source. + */ +static unsigned +get_rand_pool(FState *st) +{ + unsigned rnd; + + /* + * This slightly prefers lower pools - thats OK. + */ + rnd = st->key[st->rnd_pos] % NUM_POOLS; + + st->rnd_pos++; + if (st->rnd_pos >= BLOCK) + st->rnd_pos = 0; + + return rnd; +} + +/* + * update pools + */ +static void +add_entropy(FState *st, const u_int8_t *data, unsigned len) +{ + unsigned pos; + u_int8_t hash[BLOCK]; + MD_CTX md; + + /* hash given data */ + md_init(&md); + md_update(&md, data, len); + md_result(&md, hash); + + /* + * Make sure the pool 0 is initialized, then update randomly. + */ + if (st->reseed_count == 0) + pos = 0; + else + pos = get_rand_pool(st); + md_update(&st->pool[pos], hash, BLOCK); + + if (pos == 0) + st->pool0_bytes += len; + + memset(hash, 0, BLOCK); + memset(&md, 0, sizeof(md)); +} + +/* + * Just take 2 next blocks as new key + */ +static void +rekey(FState *st) +{ + encrypt_counter(st, st->key); + encrypt_counter(st, st->key + CIPH_BLOCK); + ciph_init(&st->ciph, st->key, BLOCK); +} + +/* + * Hide public constants. (counter, pools > 0) + * + * This can also be viewed as spreading the startup + * entropy over all of the components. + */ +static void +startup_tricks(FState *st) +{ + int i; + u_int8_t buf[BLOCK]; + + /* Use next block as counter. */ + encrypt_counter(st, st->counter); + + /* Now shuffle pools, excluding #0 */ + for (i = 1; i < NUM_POOLS; i++) + { + encrypt_counter(st, buf); + encrypt_counter(st, buf + CIPH_BLOCK); + md_update(&st->pool[i], buf, BLOCK); + } + memset(buf, 0, BLOCK); + + /* Hide the key. */ + rekey(st); + + /* This can be done only once. */ + st->tricks_done = 1; +} + +static void +extract_data(FState *st, unsigned count, u_int8_t *dst) +{ + unsigned n; + unsigned block_nr = 0; + + /* Should we reseed? */ + if (st->pool0_bytes >= POOL0_FILL || st->reseed_count == 0) + if (enough_time_passed(st)) + reseed(st); + + /* Do some randomization on first call */ + if (!st->tricks_done) + startup_tricks(st); + + while (count > 0) + { + /* produce bytes */ + encrypt_counter(st, st->result); + + /* copy result */ + if (count > CIPH_BLOCK) + n = CIPH_BLOCK; + else + n = count; + memcpy(dst, st->result, n); + dst += n; + count -= n; + + /* must not give out too many bytes with one key */ + block_nr++; + if (block_nr > (RESEED_BYTES / CIPH_BLOCK)) + { + rekey(st); + block_nr = 0; + } + } + /* Set new key for next request. */ + rekey(st); +} + +/* + * public interface + */ + +FState main_state; +int init_done = 0; + +void +fortuna_add_entropy(const u_int8_t *data, unsigned len) +{ + if (!init_done) + { + init_state(&main_state); + init_done = 1; + } + if (!data || !len) + return; + add_entropy(&main_state, data, len); +} + +void +fortuna_get_bytes(unsigned len, u_int8_t *dst) +{ + if (!init_done) + { + init_state(&main_state); + init_done = 1; + } + if (!dst || !len) + return; + extract_data(&main_state, len, dst); +} diff --git a/src/modules/tls/fortuna/fortuna.h b/src/modules/tls/fortuna/fortuna.h new file mode 100644 index 00000000000..a541bf28f42 --- /dev/null +++ b/src/modules/tls/fortuna/fortuna.h @@ -0,0 +1,40 @@ +/* + * fortuna.c + * Fortuna PRNG. + * + * Copyright (c) 2005 Marko Kreen + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR 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. + * + * contrib/pgcrypto/fortuna.h + */ + +#ifndef __FORTUNA_H +#define __FORTUNA_H + +#include + +void fortuna_get_bytes(unsigned len, u_int8_t *dst); +void fortuna_add_entropy(const u_int8_t *data, unsigned len); + +#endif diff --git a/src/modules/tls/fortuna/random.c b/src/modules/tls/fortuna/random.c new file mode 100644 index 00000000000..6d6a97a8d54 --- /dev/null +++ b/src/modules/tls/fortuna/random.c @@ -0,0 +1,178 @@ +/* + * random.c + * Acquire randomness from system, for seeding RNG. + * Get pseudo random numbers from RNG. + * + * Copyright (c) 2001 Marko Kreen + * Copyright (c) 2019 Henning Westerholt + * All rights reserved. + * + * Based on https://github.com/waitman/libfortuna, refactoring + * done in this version: https://github.com/henningw/libfortuna + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR 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. + * + * contrib/pgcrypto/random.c + */ + +#include +#include +#include +#include + +#include "../../../core/dprint.h" + +#include "random.h" +#include "fortuna.h" + +/* how many bytes to ask from system random provider */ +#define RND_BYTES 32 + +/* + * Try to read from /dev/urandom or /dev/random on these OS'es. + * + * The list can be pretty liberal, as the device not existing + * is expected event. + */ + +#include +#include + +static time_t seed_time = 0; +static time_t check_time = 0; + +int sr_get_pseudo_random_bytes(u_int8_t *dst, unsigned count); + +/* private functions */ + +static int safe_read(int fd, void *buf, size_t count) +{ + int done = 0; + char *p = buf; + int res; + + while (count) + { + res = read(fd, p, count); + if (res <= 0) + { + if (errno == EINTR) + continue; + return -10; + } + p += res; + done += res; + count -= res; + } + return done; +} + +static u_int8_t * try_dev_random(u_int8_t *dst) +{ + int fd; + int res; + + fd = open("/dev/urandom", O_RDONLY, 0); + if (fd == -1) + { + fd = open("/dev/random", O_RDONLY, 0); + if (fd == -1) + return dst; + } + res = safe_read(fd, dst, RND_BYTES); + close(fd); + if (res > 0) + dst += res; + return dst; +} + +/* + * try to extract some randomness for initial seeding + * + * dst should have room for 1024 bytes. + */ +static unsigned acquire_system_randomness(u_int8_t *dst) +{ + u_int8_t *p = dst; + + p = try_dev_random(p); + return p - dst; +} + +static void system_reseed(void) +{ + u_int8_t buf[1024]; + int n; + time_t t; + int skip = 1; + + t = time(NULL); + + if (seed_time == 0) + skip = 0; + else if ((t - seed_time) < SYSTEM_RESEED_MIN) + skip = 1; + else if ((t - seed_time) > SYSTEM_RESEED_MAX) + skip = 0; + else if (check_time == 0 || + (t - check_time) > SYSTEM_RESEED_CHECK_TIME) + { + check_time = t; + + /* roll dice */ + sr_get_pseudo_random_bytes(buf, 1); + skip = buf[0] >= SYSTEM_RESEED_CHANCE; + } + /* clear 1 byte */ + memset(buf, 0, sizeof(buf)); + + if (skip) + return; + + n = acquire_system_randomness(buf); + if (n > 0) { + fortuna_add_entropy(buf, n); + LM_DBG("cryptographic PRNG reseed done with %u bytes\n", n); + } + + seed_time = t; + memset(buf, 0, sizeof(buf)); +} + + +/* public functions */ + +int sr_get_pseudo_random_bytes(u_int8_t *dst, unsigned count) +{ + system_reseed(); + fortuna_get_bytes(count, dst); + return 0; +} + + +int sr_add_entropy(const u_int8_t *data, unsigned count) +{ + system_reseed(); + LM_DBG("additional %u bytes entropy added to cryptographic PRNG\n", count); + fortuna_add_entropy(data, count); + return 0; +} diff --git a/src/modules/tls/fortuna/random.h b/src/modules/tls/fortuna/random.h new file mode 100644 index 00000000000..5a87cde392f --- /dev/null +++ b/src/modules/tls/fortuna/random.h @@ -0,0 +1,65 @@ +/* + * random.h + * Acquire randomness from system. For seeding RNG. + * Get pseudo random numbers from RNG. + * + * Copyright (c) 2001 Marko Kreen + * Copyright (c) 2019 Henning Westerholt + * All rights reserved. + * + * Based on https://github.com/waitman/libfortuna, several cleanups + * done in this version: https://github.com/henningw/libfortuna + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR 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. + * + * contrib/pgcrypto/random.c + */ + +#ifndef _RANDOM_H_ +#define _RANDOM_H_ + +#include + +/* + * System reseeds should be separated at least this much. + */ +#define SYSTEM_RESEED_MIN (20*60) /* 20 min */ +/* + * How often to roll dice. + */ +#define SYSTEM_RESEED_CHECK_TIME (10*60) /* 10 min */ +/* + * The chance is x/256 that the reseed happens. + */ +#define SYSTEM_RESEED_CHANCE (4) /* 256/4 * 10min ~ 10h */ + +/* + * If this much time has passed, force reseed. + */ +#define SYSTEM_RESEED_MAX (12*60*60) /* 12h */ + +int sr_get_pseudo_random_bytes(u_int8_t *dst, unsigned count); + +int sr_add_entropy(const u_int8_t *data, unsigned count); + + +#endif diff --git a/src/modules/tls/fortuna/rijndael.c b/src/modules/tls/fortuna/rijndael.c new file mode 100644 index 00000000000..16b2493887b --- /dev/null +++ b/src/modules/tls/fortuna/rijndael.c @@ -0,0 +1,677 @@ +/* $OpenBSD: rijndael.c,v 1.6 2000/12/09 18:51:34 markus Exp $ */ + +/* contrib/pgcrypto/rijndael.c */ + +/* This is an independent implementation of the encryption algorithm: */ +/* */ +/* RIJNDAEL by Joan Daemen and Vincent Rijmen */ +/* */ +/* which is a candidate algorithm in the Advanced Encryption Standard */ +/* programme of the US National Institute of Standards and Technology. */ +/* */ +/* Copyright in this implementation is held by Dr B R Gladman but I */ +/* hereby give permission for its free direct or derivative use subject */ +/* to acknowledgment of its origin and compliance with any conditions */ +/* that the originators of the algorithm place on its exploitation. */ +/* */ +/* Dr Brian Gladman (gladman@seven77.demon.co.uk) 14th January 1999 */ + +/* Timing data for Rijndael (rijndael.c) + +Algorithm: rijndael (rijndael.c) + +128 bit key: +Key Setup: 305/1389 cycles (encrypt/decrypt) +Encrypt: 374 cycles = 68.4 mbits/sec +Decrypt: 352 cycles = 72.7 mbits/sec +Mean: 363 cycles = 70.5 mbits/sec + +192 bit key: +Key Setup: 277/1595 cycles (encrypt/decrypt) +Encrypt: 439 cycles = 58.3 mbits/sec +Decrypt: 425 cycles = 60.2 mbits/sec +Mean: 432 cycles = 59.3 mbits/sec + +256 bit key: +Key Setup: 374/1960 cycles (encrypt/decrypt) +Encrypt: 502 cycles = 51.0 mbits/sec +Decrypt: 498 cycles = 51.4 mbits/sec +Mean: 500 cycles = 51.2 mbits/sec + +*/ + +#include +#include + +#include "rijndael.h" + +#define PRE_CALC_TABLES +#define LARGE_TABLES + +static void gen_tabs(void); + +/* 3. Basic macros for speeding up generic operations */ + +/* Circular rotate of 32 bit values */ + +#define rotr(x,n) (((x) >> ((int)(n))) | ((x) << (32 - (int)(n)))) +#define rotl(x,n) (((x) << ((int)(n))) | ((x) >> (32 - (int)(n)))) + +/* Invert byte order in a 32 bit variable */ + +#define bswap(x) ((rotl((x), 8) & 0x00ff00ff) | (rotr((x), 8) & 0xff00ff00)) + +/* Extract byte from a 32 bit quantity (little endian notation) */ + +#define byte(x,n) ((u1byte)((x) >> (8 * (n)))) + +#ifdef WORDS_BIGENDIAN +#define io_swap(x) bswap(x) +#else +#define io_swap(x) (x) +#endif + +#ifdef PRINT_TABS +#undef PRE_CALC_TABLES +#endif + +#ifdef PRE_CALC_TABLES + +#include "rijndael.tbl" +#define tab_gen 1 +#else /* !PRE_CALC_TABLES */ + +static u1byte pow_tab[256]; +static u1byte log_tab[256]; +static u1byte sbx_tab[256]; +static u1byte isb_tab[256]; +static u4byte rco_tab[10]; +static u4byte ft_tab[4][256]; +static u4byte it_tab[4][256]; + +#ifdef LARGE_TABLES +static u4byte fl_tab[4][256]; +static u4byte il_tab[4][256]; +#endif + +static u4byte tab_gen = 0; +#endif /* !PRE_CALC_TABLES */ + +#define ff_mult(a,b) ((a) && (b) ? pow_tab[(log_tab[a] + log_tab[b]) % 255] : 0) + +#define f_rn(bo, bi, n, k) \ + (bo)[n] = ft_tab[0][byte((bi)[n],0)] ^ \ + ft_tab[1][byte((bi)[((n) + 1) & 3],1)] ^ \ + ft_tab[2][byte((bi)[((n) + 2) & 3],2)] ^ \ + ft_tab[3][byte((bi)[((n) + 3) & 3],3)] ^ *((k) + (n)) + +#define i_rn(bo, bi, n, k) \ + (bo)[n] = it_tab[0][byte((bi)[n],0)] ^ \ + it_tab[1][byte((bi)[((n) + 3) & 3],1)] ^ \ + it_tab[2][byte((bi)[((n) + 2) & 3],2)] ^ \ + it_tab[3][byte((bi)[((n) + 1) & 3],3)] ^ *((k) + (n)) + +#ifdef LARGE_TABLES + +#define ls_box(x) \ + ( fl_tab[0][byte(x, 0)] ^ \ + fl_tab[1][byte(x, 1)] ^ \ + fl_tab[2][byte(x, 2)] ^ \ + fl_tab[3][byte(x, 3)] ) + +#define f_rl(bo, bi, n, k) \ + (bo)[n] = fl_tab[0][byte((bi)[n],0)] ^ \ + fl_tab[1][byte((bi)[((n) + 1) & 3],1)] ^ \ + fl_tab[2][byte((bi)[((n) + 2) & 3],2)] ^ \ + fl_tab[3][byte((bi)[((n) + 3) & 3],3)] ^ *((k) + (n)) + +#define i_rl(bo, bi, n, k) \ + (bo)[n] = il_tab[0][byte((bi)[n],0)] ^ \ + il_tab[1][byte((bi)[((n) + 3) & 3],1)] ^ \ + il_tab[2][byte((bi)[((n) + 2) & 3],2)] ^ \ + il_tab[3][byte((bi)[((n) + 1) & 3],3)] ^ *((k) + (n)) +#else + +#define ls_box(x) \ + ((u4byte)sbx_tab[byte(x, 0)] << 0) ^ \ + ((u4byte)sbx_tab[byte(x, 1)] << 8) ^ \ + ((u4byte)sbx_tab[byte(x, 2)] << 16) ^ \ + ((u4byte)sbx_tab[byte(x, 3)] << 24) + +#define f_rl(bo, bi, n, k) \ + (bo)[n] = (u4byte)sbx_tab[byte((bi)[n],0)] ^ \ + rotl(((u4byte)sbx_tab[byte((bi)[((n) + 1) & 3],1)]), 8) ^ \ + rotl(((u4byte)sbx_tab[byte((bi)[((n) + 2) & 3],2)]), 16) ^ \ + rotl(((u4byte)sbx_tab[byte((bi)[((n) + 3) & 3],3)]), 24) ^ *((k) + (n)) + +#define i_rl(bo, bi, n, k) \ + (bo)[n] = (u4byte)isb_tab[byte((bi)[n],0)] ^ \ + rotl(((u4byte)isb_tab[byte((bi)[((n) + 3) & 3],1)]), 8) ^ \ + rotl(((u4byte)isb_tab[byte((bi)[((n) + 2) & 3],2)]), 16) ^ \ + rotl(((u4byte)isb_tab[byte((bi)[((n) + 1) & 3],3)]), 24) ^ *((k) + (n)) +#endif + +static void +gen_tabs(void) +{ +#ifndef PRE_CALC_TABLES + u4byte i, + t; + u1byte p, + q; + + /* log and power tables for GF(2**8) finite field with */ + /* 0x11b as modular polynomial - the simplest primitive */ + /* root is 0x11, used here to generate the tables */ + + for (i = 0, p = 1; i < 256; ++i) + { + pow_tab[i] = (u1byte) p; + log_tab[p] = (u1byte) i; + + p = p ^ (p << 1) ^ (p & 0x80 ? 0x01b : 0); + } + + log_tab[1] = 0; + p = 1; + + for (i = 0; i < 10; ++i) + { + rco_tab[i] = p; + + p = (p << 1) ^ (p & 0x80 ? 0x1b : 0); + } + + /* note that the affine byte transformation matrix in */ + /* rijndael specification is in big endian format with */ + /* bit 0 as the most significant bit. In the remainder */ + /* of the specification the bits are numbered from the */ + /* least significant end of a byte. */ + + for (i = 0; i < 256; ++i) + { + p = (i ? pow_tab[255 - log_tab[i]] : 0); + q = p; + q = (q >> 7) | (q << 1); + p ^= q; + q = (q >> 7) | (q << 1); + p ^= q; + q = (q >> 7) | (q << 1); + p ^= q; + q = (q >> 7) | (q << 1); + p ^= q ^ 0x63; + sbx_tab[i] = (u1byte) p; + isb_tab[p] = (u1byte) i; + } + + for (i = 0; i < 256; ++i) + { + p = sbx_tab[i]; + +#ifdef LARGE_TABLES + + t = p; + fl_tab[0][i] = t; + fl_tab[1][i] = rotl(t, 8); + fl_tab[2][i] = rotl(t, 16); + fl_tab[3][i] = rotl(t, 24); +#endif + t = ((u4byte) ff_mult(2, p)) | + ((u4byte) p << 8) | + ((u4byte) p << 16) | + ((u4byte) ff_mult(3, p) << 24); + + ft_tab[0][i] = t; + ft_tab[1][i] = rotl(t, 8); + ft_tab[2][i] = rotl(t, 16); + ft_tab[3][i] = rotl(t, 24); + + p = isb_tab[i]; + +#ifdef LARGE_TABLES + + t = p; + il_tab[0][i] = t; + il_tab[1][i] = rotl(t, 8); + il_tab[2][i] = rotl(t, 16); + il_tab[3][i] = rotl(t, 24); +#endif + t = ((u4byte) ff_mult(14, p)) | + ((u4byte) ff_mult(9, p) << 8) | + ((u4byte) ff_mult(13, p) << 16) | + ((u4byte) ff_mult(11, p) << 24); + + it_tab[0][i] = t; + it_tab[1][i] = rotl(t, 8); + it_tab[2][i] = rotl(t, 16); + it_tab[3][i] = rotl(t, 24); + } + + tab_gen = 1; +#endif /* !PRE_CALC_TABLES */ +} + + +#define star_x(x) (((x) & 0x7f7f7f7f) << 1) ^ ((((x) & 0x80808080) >> 7) * 0x1b) + +#define imix_col(y,x) \ +do { \ + u = star_x(x); \ + v = star_x(u); \ + w = star_x(v); \ + t = w ^ (x); \ + (y) = u ^ v ^ w; \ + (y) ^= rotr(u ^ t, 8) ^ \ + rotr(v ^ t, 16) ^ \ + rotr(t,24); \ +} while (0) + +/* initialise the key schedule from the user supplied key */ + +#define loop4(i) \ +do { t = ls_box(rotr(t, 8)) ^ rco_tab[i]; \ + t ^= e_key[4 * i]; e_key[4 * i + 4] = t; \ + t ^= e_key[4 * i + 1]; e_key[4 * i + 5] = t; \ + t ^= e_key[4 * i + 2]; e_key[4 * i + 6] = t; \ + t ^= e_key[4 * i + 3]; e_key[4 * i + 7] = t; \ +} while (0) + +#define loop6(i) \ +do { t = ls_box(rotr(t, 8)) ^ rco_tab[i]; \ + t ^= e_key[6 * (i)]; e_key[6 * (i) + 6] = t; \ + t ^= e_key[6 * (i) + 1]; e_key[6 * (i) + 7] = t; \ + t ^= e_key[6 * (i) + 2]; e_key[6 * (i) + 8] = t; \ + t ^= e_key[6 * (i) + 3]; e_key[6 * (i) + 9] = t; \ + t ^= e_key[6 * (i) + 4]; e_key[6 * (i) + 10] = t; \ + t ^= e_key[6 * (i) + 5]; e_key[6 * (i) + 11] = t; \ +} while (0) + +#define loop8(i) \ +do { t = ls_box(rotr(t, 8)) ^ rco_tab[i]; \ + t ^= e_key[8 * (i)]; e_key[8 * (i) + 8] = t; \ + t ^= e_key[8 * (i) + 1]; e_key[8 * (i) + 9] = t; \ + t ^= e_key[8 * (i) + 2]; e_key[8 * (i) + 10] = t; \ + t ^= e_key[8 * (i) + 3]; e_key[8 * (i) + 11] = t; \ + t = e_key[8 * (i) + 4] ^ ls_box(t); \ + e_key[8 * (i) + 12] = t; \ + t ^= e_key[8 * (i) + 5]; e_key[8 * (i) + 13] = t; \ + t ^= e_key[8 * (i) + 6]; e_key[8 * (i) + 14] = t; \ + t ^= e_key[8 * (i) + 7]; e_key[8 * (i) + 15] = t; \ +} while (0) + +rijndael_ctx * +rijndael_set_key(rijndael_ctx *ctx, const u4byte *in_key, const u4byte key_len, + int encrypt) +{ + u4byte i, + t, + u, + v, + w; + u4byte *e_key = ctx->e_key; + u4byte *d_key = ctx->d_key; + + ctx->decrypt = !encrypt; + + if (!tab_gen) + gen_tabs(); + + ctx->k_len = (key_len + 31) / 32; + + e_key[0] = io_swap(in_key[0]); + e_key[1] = io_swap(in_key[1]); + e_key[2] = io_swap(in_key[2]); + e_key[3] = io_swap(in_key[3]); + + switch (ctx->k_len) + { + case 4: + t = e_key[3]; + for (i = 0; i < 10; ++i) + loop4(i); + break; + + case 6: + e_key[4] = io_swap(in_key[4]); + t = e_key[5] = io_swap(in_key[5]); + for (i = 0; i < 8; ++i) + loop6(i); + break; + + case 8: + e_key[4] = io_swap(in_key[4]); + e_key[5] = io_swap(in_key[5]); + e_key[6] = io_swap(in_key[6]); + t = e_key[7] = io_swap(in_key[7]); + for (i = 0; i < 7; ++i) + loop8(i); + break; + } + + if (!encrypt) + { + d_key[0] = e_key[0]; + d_key[1] = e_key[1]; + d_key[2] = e_key[2]; + d_key[3] = e_key[3]; + + for (i = 4; i < 4 * ctx->k_len + 24; ++i) + imix_col(d_key[i], e_key[i]); + } + + return ctx; +} + +/* encrypt a block of text */ + +#define f_nround(bo, bi, k) \ +do { \ + f_rn(bo, bi, 0, k); \ + f_rn(bo, bi, 1, k); \ + f_rn(bo, bi, 2, k); \ + f_rn(bo, bi, 3, k); \ + k += 4; \ +} while (0) + +#define f_lround(bo, bi, k) \ +do { \ + f_rl(bo, bi, 0, k); \ + f_rl(bo, bi, 1, k); \ + f_rl(bo, bi, 2, k); \ + f_rl(bo, bi, 3, k); \ +} while (0) + +void +rijndael_encrypt(rijndael_ctx *ctx, const u4byte *in_blk, u4byte *out_blk) +{ + u4byte k_len = ctx->k_len; + u4byte *e_key = ctx->e_key; + u4byte b0[4], + b1[4], + *kp; + + b0[0] = io_swap(in_blk[0]) ^ e_key[0]; + b0[1] = io_swap(in_blk[1]) ^ e_key[1]; + b0[2] = io_swap(in_blk[2]) ^ e_key[2]; + b0[3] = io_swap(in_blk[3]) ^ e_key[3]; + + kp = e_key + 4; + + if (k_len > 6) + { + f_nround(b1, b0, kp); + f_nround(b0, b1, kp); + } + + if (k_len > 4) + { + f_nround(b1, b0, kp); + f_nround(b0, b1, kp); + } + + f_nround(b1, b0, kp); + f_nround(b0, b1, kp); + f_nround(b1, b0, kp); + f_nround(b0, b1, kp); + f_nround(b1, b0, kp); + f_nround(b0, b1, kp); + f_nround(b1, b0, kp); + f_nround(b0, b1, kp); + f_nround(b1, b0, kp); + f_lround(b0, b1, kp); + + out_blk[0] = io_swap(b0[0]); + out_blk[1] = io_swap(b0[1]); + out_blk[2] = io_swap(b0[2]); + out_blk[3] = io_swap(b0[3]); +} + +/* decrypt a block of text */ + +#define i_nround(bo, bi, k) \ +do { \ + i_rn(bo, bi, 0, k); \ + i_rn(bo, bi, 1, k); \ + i_rn(bo, bi, 2, k); \ + i_rn(bo, bi, 3, k); \ + k -= 4; \ +} while (0) + +#define i_lround(bo, bi, k) \ +do { \ + i_rl(bo, bi, 0, k); \ + i_rl(bo, bi, 1, k); \ + i_rl(bo, bi, 2, k); \ + i_rl(bo, bi, 3, k); \ +} while (0) + +void +rijndael_decrypt(rijndael_ctx *ctx, const u4byte *in_blk, u4byte *out_blk) +{ + u4byte b0[4], + b1[4], + *kp; + u4byte k_len = ctx->k_len; + u4byte *e_key = ctx->e_key; + u4byte *d_key = ctx->d_key; + + b0[0] = io_swap(in_blk[0]) ^ e_key[4 * k_len + 24]; + b0[1] = io_swap(in_blk[1]) ^ e_key[4 * k_len + 25]; + b0[2] = io_swap(in_blk[2]) ^ e_key[4 * k_len + 26]; + b0[3] = io_swap(in_blk[3]) ^ e_key[4 * k_len + 27]; + + kp = d_key + 4 * (k_len + 5); + + if (k_len > 6) + { + i_nround(b1, b0, kp); + i_nround(b0, b1, kp); + } + + if (k_len > 4) + { + i_nround(b1, b0, kp); + i_nround(b0, b1, kp); + } + + i_nround(b1, b0, kp); + i_nround(b0, b1, kp); + i_nround(b1, b0, kp); + i_nround(b0, b1, kp); + i_nround(b1, b0, kp); + i_nround(b0, b1, kp); + i_nround(b1, b0, kp); + i_nround(b0, b1, kp); + i_nround(b1, b0, kp); + i_lround(b0, b1, kp); + + out_blk[0] = io_swap(b0[0]); + out_blk[1] = io_swap(b0[1]); + out_blk[2] = io_swap(b0[2]); + out_blk[3] = io_swap(b0[3]); +} + +/* + * conventional interface + * + * ATM it hopes all data is 4-byte aligned - which + * should be true for PX. -marko + */ + +void +aes_set_key(rijndael_ctx *ctx, const u_int8_t *key, unsigned keybits, int enc) +{ + u_int32_t *k; + + k = (u_int32_t *) key; + rijndael_set_key(ctx, k, keybits, enc); +} + +void +aes_ecb_encrypt(rijndael_ctx *ctx, u_int8_t *data, unsigned len) +{ + unsigned bs = 16; + u_int32_t *d; + + while (len >= bs) + { + d = (u_int32_t *) data; + rijndael_encrypt(ctx, d, d); + + len -= bs; + data += bs; + } +} + +void +aes_ecb_decrypt(rijndael_ctx *ctx, u_int8_t *data, unsigned len) +{ + unsigned bs = 16; + u_int32_t *d; + + while (len >= bs) + { + d = (u_int32_t *) data; + rijndael_decrypt(ctx, d, d); + + len -= bs; + data += bs; + } +} + +void +aes_cbc_encrypt(rijndael_ctx *ctx, u_int8_t *iva, u_int8_t *data, unsigned len) +{ + u_int32_t *iv = (u_int32_t *) iva; + u_int32_t *d = (u_int32_t *) data; + unsigned bs = 16; + + while (len >= bs) + { + d[0] ^= iv[0]; + d[1] ^= iv[1]; + d[2] ^= iv[2]; + d[3] ^= iv[3]; + + rijndael_encrypt(ctx, d, d); + + iv = d; + d += bs / 4; + len -= bs; + } +} + +void +aes_cbc_decrypt(rijndael_ctx *ctx, u_int8_t *iva, u_int8_t *data, unsigned len) +{ + u_int32_t *d = (u_int32_t *) data; + unsigned bs = 16; + u_int32_t buf[4], + iv[4]; + + memcpy(iv, iva, bs); + while (len >= bs) + { + buf[0] = d[0]; + buf[1] = d[1]; + buf[2] = d[2]; + buf[3] = d[3]; + + rijndael_decrypt(ctx, buf, d); + + d[0] ^= iv[0]; + d[1] ^= iv[1]; + d[2] ^= iv[2]; + d[3] ^= iv[3]; + + iv[0] = buf[0]; + iv[1] = buf[1]; + iv[2] = buf[2]; + iv[3] = buf[3]; + d += 4; + len -= bs; + } +} + +/* + * pre-calculate tables. + * + * On i386 lifts 17k from .bss to .rodata + * and avoids 1k code and setup time. + * -marko + */ +#ifdef PRINT_TABS + +static void +show256u8(char *name, u_int8_t *data) +{ + int i; + + printf("static const u1byte %s[256] = {\n ", name); + for (i = 0; i < 256;) + { + printf("%u", pow_tab[i++]); + if (i < 256) + printf(i % 16 ? ", " : ",\n "); + } + printf("\n};\n\n"); +} + + +static void +show4x256u32(char *name, u_int32_t data[4][256]) +{ + int i, + j; + + printf("static const u4byte %s[4][256] = {\n{\n ", name); + for (i = 0; i < 4; i++) + { + for (j = 0; j < 256;) + { + printf("0x%08x", data[i][j]); + j++; + if (j < 256) + printf(j % 4 ? ", " : ",\n "); + } + printf(i < 3 ? "\n}, {\n " : "\n}\n"); + } + printf("};\n\n"); +} + +#if 0 +int +main() +{ + int i; + char *hdr = "/* Generated by rijndael.c */\n\n"; + + gen_tabs(); + + printf(hdr); + show256u8("pow_tab", pow_tab); + show256u8("log_tab", log_tab); + show256u8("sbx_tab", sbx_tab); + show256u8("isb_tab", isb_tab); + + show4x256u32("ft_tab", ft_tab); + show4x256u32("it_tab", it_tab); +#ifdef LARGE_TABLES + show4x256u32("fl_tab", fl_tab); + show4x256u32("il_tab", il_tab); +#endif + printf("const u4byte rco_tab[10] = {\n "); + for (i = 0; i < 10; i++) + { + printf("0x%08x", rco_tab[i]); + if (i < 9) + printf(", "); + if (i == 4) + printf("\n "); + } + printf("\n};\n\n"); + return 0; +} +#endif + +#endif diff --git a/src/modules/tls/fortuna/rijndael.h b/src/modules/tls/fortuna/rijndael.h new file mode 100644 index 00000000000..5c22f4d4089 --- /dev/null +++ b/src/modules/tls/fortuna/rijndael.h @@ -0,0 +1,61 @@ +/* + * contrib/pgcrypto/rijndael.h + * + * $OpenBSD: rijndael.h,v 1.3 2001/05/09 23:01:32 markus Exp $ */ + +/* This is an independent implementation of the encryption algorithm: */ +/* */ +/* RIJNDAEL by Joan Daemen and Vincent Rijmen */ +/* */ +/* which is a candidate algorithm in the Advanced Encryption Standard */ +/* programme of the US National Institute of Standards and Technology. */ +/* */ +/* Copyright in this implementation is held by Dr B R Gladman but I */ +/* hereby give permission for its free direct or derivative use subject */ +/* to acknowledgment of its origin and compliance with any conditions */ +/* that the originators of the algorithm place on its exploitation. */ +/* */ +/* Dr Brian Gladman (gladman@seven77.demon.co.uk) 14th January 1999 */ + +#ifndef _RIJNDAEL_H_ +#define _RIJNDAEL_H_ + +#include + +/* 1. Standard types for AES cryptography source code */ + +typedef u_int8_t u1byte; /* an 8 bit u_int8_tacter type */ +typedef u_int16_t u2byte; /* a 16 bit unsigned integer type */ +typedef u_int32_t u4byte; /* a 32 bit unsigned integer type */ + +typedef int8_t s1byte; /* an 8 bit signed character type */ +typedef int16_t s2byte; /* a 16 bit signed integer type */ +typedef int32_t s4byte; /* a 32 bit signed integer type */ + +typedef struct _rijndael_ctx +{ + u4byte k_len; + int decrypt; + u4byte e_key[64]; + u4byte d_key[64]; +} rijndael_ctx; + + +/* 2. Standard interface for AES cryptographic routines */ + +/* These are all based on 32 bit unsigned values and will therefore */ +/* require endian conversions for big-endian architectures */ + +rijndael_ctx *rijndael_set_key(rijndael_ctx *, const u4byte *, const u4byte, int); +void rijndael_encrypt(rijndael_ctx *, const u4byte *, u4byte *); +void rijndael_decrypt(rijndael_ctx *, const u4byte *, u4byte *); + +/* conventional interface */ + +void aes_set_key(rijndael_ctx *ctx, const u_int8_t *key, unsigned keybits, int enc); +void aes_ecb_encrypt(rijndael_ctx *ctx, u_int8_t *data, unsigned len); +void aes_ecb_decrypt(rijndael_ctx *ctx, u_int8_t *data, unsigned len); +void aes_cbc_encrypt(rijndael_ctx *ctx, u_int8_t *iva, u_int8_t *data, unsigned len); +void aes_cbc_decrypt(rijndael_ctx *ctx, u_int8_t *iva, u_int8_t *data, unsigned len); + +#endif /* _RIJNDAEL_H_ */ diff --git a/src/modules/tls/fortuna/rijndael.tbl b/src/modules/tls/fortuna/rijndael.tbl new file mode 100644 index 00000000000..c7610c01346 --- /dev/null +++ b/src/modules/tls/fortuna/rijndael.tbl @@ -0,0 +1,1138 @@ +/* Generated by rijndael.c */ + +static const u1byte pow_tab[256] = { + 1, 3, 5, 15, 17, 51, 85, 255, 26, 46, 114, 150, 161, 248, 19, 53, + 95, 225, 56, 72, 216, 115, 149, 164, 247, 2, 6, 10, 30, 34, 102, 170, + 229, 52, 92, 228, 55, 89, 235, 38, 106, 190, 217, 112, 144, 171, 230, 49, + 83, 245, 4, 12, 20, 60, 68, 204, 79, 209, 104, 184, 211, 110, 178, 205, + 76, 212, 103, 169, 224, 59, 77, 215, 98, 166, 241, 8, 24, 40, 120, 136, + 131, 158, 185, 208, 107, 189, 220, 127, 129, 152, 179, 206, 73, 219, 118, 154, + 181, 196, 87, 249, 16, 48, 80, 240, 11, 29, 39, 105, 187, 214, 97, 163, + 254, 25, 43, 125, 135, 146, 173, 236, 47, 113, 147, 174, 233, 32, 96, 160, + 251, 22, 58, 78, 210, 109, 183, 194, 93, 231, 50, 86, 250, 21, 63, 65, + 195, 94, 226, 61, 71, 201, 64, 192, 91, 237, 44, 116, 156, 191, 218, 117, + 159, 186, 213, 100, 172, 239, 42, 126, 130, 157, 188, 223, 122, 142, 137, 128, + 155, 182, 193, 88, 232, 35, 101, 175, 234, 37, 111, 177, 200, 67, 197, 84, + 252, 31, 33, 99, 165, 244, 7, 9, 27, 45, 119, 153, 176, 203, 70, 202, + 69, 207, 74, 222, 121, 139, 134, 145, 168, 227, 62, 66, 198, 81, 243, 14, + 18, 54, 90, 238, 41, 123, 141, 140, 143, 138, 133, 148, 167, 242, 13, 23, + 57, 75, 221, 124, 132, 151, 162, 253, 28, 36, 108, 180, 199, 82, 246, 1 +}; + +static const u1byte log_tab[256] = { + 1, 3, 5, 15, 17, 51, 85, 255, 26, 46, 114, 150, 161, 248, 19, 53, + 95, 225, 56, 72, 216, 115, 149, 164, 247, 2, 6, 10, 30, 34, 102, 170, + 229, 52, 92, 228, 55, 89, 235, 38, 106, 190, 217, 112, 144, 171, 230, 49, + 83, 245, 4, 12, 20, 60, 68, 204, 79, 209, 104, 184, 211, 110, 178, 205, + 76, 212, 103, 169, 224, 59, 77, 215, 98, 166, 241, 8, 24, 40, 120, 136, + 131, 158, 185, 208, 107, 189, 220, 127, 129, 152, 179, 206, 73, 219, 118, 154, + 181, 196, 87, 249, 16, 48, 80, 240, 11, 29, 39, 105, 187, 214, 97, 163, + 254, 25, 43, 125, 135, 146, 173, 236, 47, 113, 147, 174, 233, 32, 96, 160, + 251, 22, 58, 78, 210, 109, 183, 194, 93, 231, 50, 86, 250, 21, 63, 65, + 195, 94, 226, 61, 71, 201, 64, 192, 91, 237, 44, 116, 156, 191, 218, 117, + 159, 186, 213, 100, 172, 239, 42, 126, 130, 157, 188, 223, 122, 142, 137, 128, + 155, 182, 193, 88, 232, 35, 101, 175, 234, 37, 111, 177, 200, 67, 197, 84, + 252, 31, 33, 99, 165, 244, 7, 9, 27, 45, 119, 153, 176, 203, 70, 202, + 69, 207, 74, 222, 121, 139, 134, 145, 168, 227, 62, 66, 198, 81, 243, 14, + 18, 54, 90, 238, 41, 123, 141, 140, 143, 138, 133, 148, 167, 242, 13, 23, + 57, 75, 221, 124, 132, 151, 162, 253, 28, 36, 108, 180, 199, 82, 246, 1 +}; + +static const u1byte sbx_tab[256] = { + 1, 3, 5, 15, 17, 51, 85, 255, 26, 46, 114, 150, 161, 248, 19, 53, + 95, 225, 56, 72, 216, 115, 149, 164, 247, 2, 6, 10, 30, 34, 102, 170, + 229, 52, 92, 228, 55, 89, 235, 38, 106, 190, 217, 112, 144, 171, 230, 49, + 83, 245, 4, 12, 20, 60, 68, 204, 79, 209, 104, 184, 211, 110, 178, 205, + 76, 212, 103, 169, 224, 59, 77, 215, 98, 166, 241, 8, 24, 40, 120, 136, + 131, 158, 185, 208, 107, 189, 220, 127, 129, 152, 179, 206, 73, 219, 118, 154, + 181, 196, 87, 249, 16, 48, 80, 240, 11, 29, 39, 105, 187, 214, 97, 163, + 254, 25, 43, 125, 135, 146, 173, 236, 47, 113, 147, 174, 233, 32, 96, 160, + 251, 22, 58, 78, 210, 109, 183, 194, 93, 231, 50, 86, 250, 21, 63, 65, + 195, 94, 226, 61, 71, 201, 64, 192, 91, 237, 44, 116, 156, 191, 218, 117, + 159, 186, 213, 100, 172, 239, 42, 126, 130, 157, 188, 223, 122, 142, 137, 128, + 155, 182, 193, 88, 232, 35, 101, 175, 234, 37, 111, 177, 200, 67, 197, 84, + 252, 31, 33, 99, 165, 244, 7, 9, 27, 45, 119, 153, 176, 203, 70, 202, + 69, 207, 74, 222, 121, 139, 134, 145, 168, 227, 62, 66, 198, 81, 243, 14, + 18, 54, 90, 238, 41, 123, 141, 140, 143, 138, 133, 148, 167, 242, 13, 23, + 57, 75, 221, 124, 132, 151, 162, 253, 28, 36, 108, 180, 199, 82, 246, 1 +}; + +static const u1byte isb_tab[256] = { + 1, 3, 5, 15, 17, 51, 85, 255, 26, 46, 114, 150, 161, 248, 19, 53, + 95, 225, 56, 72, 216, 115, 149, 164, 247, 2, 6, 10, 30, 34, 102, 170, + 229, 52, 92, 228, 55, 89, 235, 38, 106, 190, 217, 112, 144, 171, 230, 49, + 83, 245, 4, 12, 20, 60, 68, 204, 79, 209, 104, 184, 211, 110, 178, 205, + 76, 212, 103, 169, 224, 59, 77, 215, 98, 166, 241, 8, 24, 40, 120, 136, + 131, 158, 185, 208, 107, 189, 220, 127, 129, 152, 179, 206, 73, 219, 118, 154, + 181, 196, 87, 249, 16, 48, 80, 240, 11, 29, 39, 105, 187, 214, 97, 163, + 254, 25, 43, 125, 135, 146, 173, 236, 47, 113, 147, 174, 233, 32, 96, 160, + 251, 22, 58, 78, 210, 109, 183, 194, 93, 231, 50, 86, 250, 21, 63, 65, + 195, 94, 226, 61, 71, 201, 64, 192, 91, 237, 44, 116, 156, 191, 218, 117, + 159, 186, 213, 100, 172, 239, 42, 126, 130, 157, 188, 223, 122, 142, 137, 128, + 155, 182, 193, 88, 232, 35, 101, 175, 234, 37, 111, 177, 200, 67, 197, 84, + 252, 31, 33, 99, 165, 244, 7, 9, 27, 45, 119, 153, 176, 203, 70, 202, + 69, 207, 74, 222, 121, 139, 134, 145, 168, 227, 62, 66, 198, 81, 243, 14, + 18, 54, 90, 238, 41, 123, 141, 140, 143, 138, 133, 148, 167, 242, 13, 23, + 57, 75, 221, 124, 132, 151, 162, 253, 28, 36, 108, 180, 199, 82, 246, 1 +}; + +static const u4byte ft_tab[4][256] = { +{ + 0xa56363c6, 0x847c7cf8, 0x997777ee, 0x8d7b7bf6, + 0x0df2f2ff, 0xbd6b6bd6, 0xb16f6fde, 0x54c5c591, + 0x50303060, 0x03010102, 0xa96767ce, 0x7d2b2b56, + 0x19fefee7, 0x62d7d7b5, 0xe6abab4d, 0x9a7676ec, + 0x45caca8f, 0x9d82821f, 0x40c9c989, 0x877d7dfa, + 0x15fafaef, 0xeb5959b2, 0xc947478e, 0x0bf0f0fb, + 0xecadad41, 0x67d4d4b3, 0xfda2a25f, 0xeaafaf45, + 0xbf9c9c23, 0xf7a4a453, 0x967272e4, 0x5bc0c09b, + 0xc2b7b775, 0x1cfdfde1, 0xae93933d, 0x6a26264c, + 0x5a36366c, 0x413f3f7e, 0x02f7f7f5, 0x4fcccc83, + 0x5c343468, 0xf4a5a551, 0x34e5e5d1, 0x08f1f1f9, + 0x937171e2, 0x73d8d8ab, 0x53313162, 0x3f15152a, + 0x0c040408, 0x52c7c795, 0x65232346, 0x5ec3c39d, + 0x28181830, 0xa1969637, 0x0f05050a, 0xb59a9a2f, + 0x0907070e, 0x36121224, 0x9b80801b, 0x3de2e2df, + 0x26ebebcd, 0x6927274e, 0xcdb2b27f, 0x9f7575ea, + 0x1b090912, 0x9e83831d, 0x742c2c58, 0x2e1a1a34, + 0x2d1b1b36, 0xb26e6edc, 0xee5a5ab4, 0xfba0a05b, + 0xf65252a4, 0x4d3b3b76, 0x61d6d6b7, 0xceb3b37d, + 0x7b292952, 0x3ee3e3dd, 0x712f2f5e, 0x97848413, + 0xf55353a6, 0x68d1d1b9, 0x00000000, 0x2cededc1, + 0x60202040, 0x1ffcfce3, 0xc8b1b179, 0xed5b5bb6, + 0xbe6a6ad4, 0x46cbcb8d, 0xd9bebe67, 0x4b393972, + 0xde4a4a94, 0xd44c4c98, 0xe85858b0, 0x4acfcf85, + 0x6bd0d0bb, 0x2aefefc5, 0xe5aaaa4f, 0x16fbfbed, + 0xc5434386, 0xd74d4d9a, 0x55333366, 0x94858511, + 0xcf45458a, 0x10f9f9e9, 0x06020204, 0x817f7ffe, + 0xf05050a0, 0x443c3c78, 0xba9f9f25, 0xe3a8a84b, + 0xf35151a2, 0xfea3a35d, 0xc0404080, 0x8a8f8f05, + 0xad92923f, 0xbc9d9d21, 0x48383870, 0x04f5f5f1, + 0xdfbcbc63, 0xc1b6b677, 0x75dadaaf, 0x63212142, + 0x30101020, 0x1affffe5, 0x0ef3f3fd, 0x6dd2d2bf, + 0x4ccdcd81, 0x140c0c18, 0x35131326, 0x2fececc3, + 0xe15f5fbe, 0xa2979735, 0xcc444488, 0x3917172e, + 0x57c4c493, 0xf2a7a755, 0x827e7efc, 0x473d3d7a, + 0xac6464c8, 0xe75d5dba, 0x2b191932, 0x957373e6, + 0xa06060c0, 0x98818119, 0xd14f4f9e, 0x7fdcdca3, + 0x66222244, 0x7e2a2a54, 0xab90903b, 0x8388880b, + 0xca46468c, 0x29eeeec7, 0xd3b8b86b, 0x3c141428, + 0x79dedea7, 0xe25e5ebc, 0x1d0b0b16, 0x76dbdbad, + 0x3be0e0db, 0x56323264, 0x4e3a3a74, 0x1e0a0a14, + 0xdb494992, 0x0a06060c, 0x6c242448, 0xe45c5cb8, + 0x5dc2c29f, 0x6ed3d3bd, 0xefacac43, 0xa66262c4, + 0xa8919139, 0xa4959531, 0x37e4e4d3, 0x8b7979f2, + 0x32e7e7d5, 0x43c8c88b, 0x5937376e, 0xb76d6dda, + 0x8c8d8d01, 0x64d5d5b1, 0xd24e4e9c, 0xe0a9a949, + 0xb46c6cd8, 0xfa5656ac, 0x07f4f4f3, 0x25eaeacf, + 0xaf6565ca, 0x8e7a7af4, 0xe9aeae47, 0x18080810, + 0xd5baba6f, 0x887878f0, 0x6f25254a, 0x722e2e5c, + 0x241c1c38, 0xf1a6a657, 0xc7b4b473, 0x51c6c697, + 0x23e8e8cb, 0x7cdddda1, 0x9c7474e8, 0x211f1f3e, + 0xdd4b4b96, 0xdcbdbd61, 0x868b8b0d, 0x858a8a0f, + 0x907070e0, 0x423e3e7c, 0xc4b5b571, 0xaa6666cc, + 0xd8484890, 0x05030306, 0x01f6f6f7, 0x120e0e1c, + 0xa36161c2, 0x5f35356a, 0xf95757ae, 0xd0b9b969, + 0x91868617, 0x58c1c199, 0x271d1d3a, 0xb99e9e27, + 0x38e1e1d9, 0x13f8f8eb, 0xb398982b, 0x33111122, + 0xbb6969d2, 0x70d9d9a9, 0x898e8e07, 0xa7949433, + 0xb69b9b2d, 0x221e1e3c, 0x92878715, 0x20e9e9c9, + 0x49cece87, 0xff5555aa, 0x78282850, 0x7adfdfa5, + 0x8f8c8c03, 0xf8a1a159, 0x80898909, 0x170d0d1a, + 0xdabfbf65, 0x31e6e6d7, 0xc6424284, 0xb86868d0, + 0xc3414182, 0xb0999929, 0x772d2d5a, 0x110f0f1e, + 0xcbb0b07b, 0xfc5454a8, 0xd6bbbb6d, 0x3a16162c +}, { + 0x6363c6a5, 0x7c7cf884, 0x7777ee99, 0x7b7bf68d, + 0xf2f2ff0d, 0x6b6bd6bd, 0x6f6fdeb1, 0xc5c59154, + 0x30306050, 0x01010203, 0x6767cea9, 0x2b2b567d, + 0xfefee719, 0xd7d7b562, 0xabab4de6, 0x7676ec9a, + 0xcaca8f45, 0x82821f9d, 0xc9c98940, 0x7d7dfa87, + 0xfafaef15, 0x5959b2eb, 0x47478ec9, 0xf0f0fb0b, + 0xadad41ec, 0xd4d4b367, 0xa2a25ffd, 0xafaf45ea, + 0x9c9c23bf, 0xa4a453f7, 0x7272e496, 0xc0c09b5b, + 0xb7b775c2, 0xfdfde11c, 0x93933dae, 0x26264c6a, + 0x36366c5a, 0x3f3f7e41, 0xf7f7f502, 0xcccc834f, + 0x3434685c, 0xa5a551f4, 0xe5e5d134, 0xf1f1f908, + 0x7171e293, 0xd8d8ab73, 0x31316253, 0x15152a3f, + 0x0404080c, 0xc7c79552, 0x23234665, 0xc3c39d5e, + 0x18183028, 0x969637a1, 0x05050a0f, 0x9a9a2fb5, + 0x07070e09, 0x12122436, 0x80801b9b, 0xe2e2df3d, + 0xebebcd26, 0x27274e69, 0xb2b27fcd, 0x7575ea9f, + 0x0909121b, 0x83831d9e, 0x2c2c5874, 0x1a1a342e, + 0x1b1b362d, 0x6e6edcb2, 0x5a5ab4ee, 0xa0a05bfb, + 0x5252a4f6, 0x3b3b764d, 0xd6d6b761, 0xb3b37dce, + 0x2929527b, 0xe3e3dd3e, 0x2f2f5e71, 0x84841397, + 0x5353a6f5, 0xd1d1b968, 0x00000000, 0xededc12c, + 0x20204060, 0xfcfce31f, 0xb1b179c8, 0x5b5bb6ed, + 0x6a6ad4be, 0xcbcb8d46, 0xbebe67d9, 0x3939724b, + 0x4a4a94de, 0x4c4c98d4, 0x5858b0e8, 0xcfcf854a, + 0xd0d0bb6b, 0xefefc52a, 0xaaaa4fe5, 0xfbfbed16, + 0x434386c5, 0x4d4d9ad7, 0x33336655, 0x85851194, + 0x45458acf, 0xf9f9e910, 0x02020406, 0x7f7ffe81, + 0x5050a0f0, 0x3c3c7844, 0x9f9f25ba, 0xa8a84be3, + 0x5151a2f3, 0xa3a35dfe, 0x404080c0, 0x8f8f058a, + 0x92923fad, 0x9d9d21bc, 0x38387048, 0xf5f5f104, + 0xbcbc63df, 0xb6b677c1, 0xdadaaf75, 0x21214263, + 0x10102030, 0xffffe51a, 0xf3f3fd0e, 0xd2d2bf6d, + 0xcdcd814c, 0x0c0c1814, 0x13132635, 0xececc32f, + 0x5f5fbee1, 0x979735a2, 0x444488cc, 0x17172e39, + 0xc4c49357, 0xa7a755f2, 0x7e7efc82, 0x3d3d7a47, + 0x6464c8ac, 0x5d5dbae7, 0x1919322b, 0x7373e695, + 0x6060c0a0, 0x81811998, 0x4f4f9ed1, 0xdcdca37f, + 0x22224466, 0x2a2a547e, 0x90903bab, 0x88880b83, + 0x46468cca, 0xeeeec729, 0xb8b86bd3, 0x1414283c, + 0xdedea779, 0x5e5ebce2, 0x0b0b161d, 0xdbdbad76, + 0xe0e0db3b, 0x32326456, 0x3a3a744e, 0x0a0a141e, + 0x494992db, 0x06060c0a, 0x2424486c, 0x5c5cb8e4, + 0xc2c29f5d, 0xd3d3bd6e, 0xacac43ef, 0x6262c4a6, + 0x919139a8, 0x959531a4, 0xe4e4d337, 0x7979f28b, + 0xe7e7d532, 0xc8c88b43, 0x37376e59, 0x6d6ddab7, + 0x8d8d018c, 0xd5d5b164, 0x4e4e9cd2, 0xa9a949e0, + 0x6c6cd8b4, 0x5656acfa, 0xf4f4f307, 0xeaeacf25, + 0x6565caaf, 0x7a7af48e, 0xaeae47e9, 0x08081018, + 0xbaba6fd5, 0x7878f088, 0x25254a6f, 0x2e2e5c72, + 0x1c1c3824, 0xa6a657f1, 0xb4b473c7, 0xc6c69751, + 0xe8e8cb23, 0xdddda17c, 0x7474e89c, 0x1f1f3e21, + 0x4b4b96dd, 0xbdbd61dc, 0x8b8b0d86, 0x8a8a0f85, + 0x7070e090, 0x3e3e7c42, 0xb5b571c4, 0x6666ccaa, + 0x484890d8, 0x03030605, 0xf6f6f701, 0x0e0e1c12, + 0x6161c2a3, 0x35356a5f, 0x5757aef9, 0xb9b969d0, + 0x86861791, 0xc1c19958, 0x1d1d3a27, 0x9e9e27b9, + 0xe1e1d938, 0xf8f8eb13, 0x98982bb3, 0x11112233, + 0x6969d2bb, 0xd9d9a970, 0x8e8e0789, 0x949433a7, + 0x9b9b2db6, 0x1e1e3c22, 0x87871592, 0xe9e9c920, + 0xcece8749, 0x5555aaff, 0x28285078, 0xdfdfa57a, + 0x8c8c038f, 0xa1a159f8, 0x89890980, 0x0d0d1a17, + 0xbfbf65da, 0xe6e6d731, 0x424284c6, 0x6868d0b8, + 0x414182c3, 0x999929b0, 0x2d2d5a77, 0x0f0f1e11, + 0xb0b07bcb, 0x5454a8fc, 0xbbbb6dd6, 0x16162c3a +}, { + 0x63c6a563, 0x7cf8847c, 0x77ee9977, 0x7bf68d7b, + 0xf2ff0df2, 0x6bd6bd6b, 0x6fdeb16f, 0xc59154c5, + 0x30605030, 0x01020301, 0x67cea967, 0x2b567d2b, + 0xfee719fe, 0xd7b562d7, 0xab4de6ab, 0x76ec9a76, + 0xca8f45ca, 0x821f9d82, 0xc98940c9, 0x7dfa877d, + 0xfaef15fa, 0x59b2eb59, 0x478ec947, 0xf0fb0bf0, + 0xad41ecad, 0xd4b367d4, 0xa25ffda2, 0xaf45eaaf, + 0x9c23bf9c, 0xa453f7a4, 0x72e49672, 0xc09b5bc0, + 0xb775c2b7, 0xfde11cfd, 0x933dae93, 0x264c6a26, + 0x366c5a36, 0x3f7e413f, 0xf7f502f7, 0xcc834fcc, + 0x34685c34, 0xa551f4a5, 0xe5d134e5, 0xf1f908f1, + 0x71e29371, 0xd8ab73d8, 0x31625331, 0x152a3f15, + 0x04080c04, 0xc79552c7, 0x23466523, 0xc39d5ec3, + 0x18302818, 0x9637a196, 0x050a0f05, 0x9a2fb59a, + 0x070e0907, 0x12243612, 0x801b9b80, 0xe2df3de2, + 0xebcd26eb, 0x274e6927, 0xb27fcdb2, 0x75ea9f75, + 0x09121b09, 0x831d9e83, 0x2c58742c, 0x1a342e1a, + 0x1b362d1b, 0x6edcb26e, 0x5ab4ee5a, 0xa05bfba0, + 0x52a4f652, 0x3b764d3b, 0xd6b761d6, 0xb37dceb3, + 0x29527b29, 0xe3dd3ee3, 0x2f5e712f, 0x84139784, + 0x53a6f553, 0xd1b968d1, 0x00000000, 0xedc12ced, + 0x20406020, 0xfce31ffc, 0xb179c8b1, 0x5bb6ed5b, + 0x6ad4be6a, 0xcb8d46cb, 0xbe67d9be, 0x39724b39, + 0x4a94de4a, 0x4c98d44c, 0x58b0e858, 0xcf854acf, + 0xd0bb6bd0, 0xefc52aef, 0xaa4fe5aa, 0xfbed16fb, + 0x4386c543, 0x4d9ad74d, 0x33665533, 0x85119485, + 0x458acf45, 0xf9e910f9, 0x02040602, 0x7ffe817f, + 0x50a0f050, 0x3c78443c, 0x9f25ba9f, 0xa84be3a8, + 0x51a2f351, 0xa35dfea3, 0x4080c040, 0x8f058a8f, + 0x923fad92, 0x9d21bc9d, 0x38704838, 0xf5f104f5, + 0xbc63dfbc, 0xb677c1b6, 0xdaaf75da, 0x21426321, + 0x10203010, 0xffe51aff, 0xf3fd0ef3, 0xd2bf6dd2, + 0xcd814ccd, 0x0c18140c, 0x13263513, 0xecc32fec, + 0x5fbee15f, 0x9735a297, 0x4488cc44, 0x172e3917, + 0xc49357c4, 0xa755f2a7, 0x7efc827e, 0x3d7a473d, + 0x64c8ac64, 0x5dbae75d, 0x19322b19, 0x73e69573, + 0x60c0a060, 0x81199881, 0x4f9ed14f, 0xdca37fdc, + 0x22446622, 0x2a547e2a, 0x903bab90, 0x880b8388, + 0x468cca46, 0xeec729ee, 0xb86bd3b8, 0x14283c14, + 0xdea779de, 0x5ebce25e, 0x0b161d0b, 0xdbad76db, + 0xe0db3be0, 0x32645632, 0x3a744e3a, 0x0a141e0a, + 0x4992db49, 0x060c0a06, 0x24486c24, 0x5cb8e45c, + 0xc29f5dc2, 0xd3bd6ed3, 0xac43efac, 0x62c4a662, + 0x9139a891, 0x9531a495, 0xe4d337e4, 0x79f28b79, + 0xe7d532e7, 0xc88b43c8, 0x376e5937, 0x6ddab76d, + 0x8d018c8d, 0xd5b164d5, 0x4e9cd24e, 0xa949e0a9, + 0x6cd8b46c, 0x56acfa56, 0xf4f307f4, 0xeacf25ea, + 0x65caaf65, 0x7af48e7a, 0xae47e9ae, 0x08101808, + 0xba6fd5ba, 0x78f08878, 0x254a6f25, 0x2e5c722e, + 0x1c38241c, 0xa657f1a6, 0xb473c7b4, 0xc69751c6, + 0xe8cb23e8, 0xdda17cdd, 0x74e89c74, 0x1f3e211f, + 0x4b96dd4b, 0xbd61dcbd, 0x8b0d868b, 0x8a0f858a, + 0x70e09070, 0x3e7c423e, 0xb571c4b5, 0x66ccaa66, + 0x4890d848, 0x03060503, 0xf6f701f6, 0x0e1c120e, + 0x61c2a361, 0x356a5f35, 0x57aef957, 0xb969d0b9, + 0x86179186, 0xc19958c1, 0x1d3a271d, 0x9e27b99e, + 0xe1d938e1, 0xf8eb13f8, 0x982bb398, 0x11223311, + 0x69d2bb69, 0xd9a970d9, 0x8e07898e, 0x9433a794, + 0x9b2db69b, 0x1e3c221e, 0x87159287, 0xe9c920e9, + 0xce8749ce, 0x55aaff55, 0x28507828, 0xdfa57adf, + 0x8c038f8c, 0xa159f8a1, 0x89098089, 0x0d1a170d, + 0xbf65dabf, 0xe6d731e6, 0x4284c642, 0x68d0b868, + 0x4182c341, 0x9929b099, 0x2d5a772d, 0x0f1e110f, + 0xb07bcbb0, 0x54a8fc54, 0xbb6dd6bb, 0x162c3a16 +}, { + 0xc6a56363, 0xf8847c7c, 0xee997777, 0xf68d7b7b, + 0xff0df2f2, 0xd6bd6b6b, 0xdeb16f6f, 0x9154c5c5, + 0x60503030, 0x02030101, 0xcea96767, 0x567d2b2b, + 0xe719fefe, 0xb562d7d7, 0x4de6abab, 0xec9a7676, + 0x8f45caca, 0x1f9d8282, 0x8940c9c9, 0xfa877d7d, + 0xef15fafa, 0xb2eb5959, 0x8ec94747, 0xfb0bf0f0, + 0x41ecadad, 0xb367d4d4, 0x5ffda2a2, 0x45eaafaf, + 0x23bf9c9c, 0x53f7a4a4, 0xe4967272, 0x9b5bc0c0, + 0x75c2b7b7, 0xe11cfdfd, 0x3dae9393, 0x4c6a2626, + 0x6c5a3636, 0x7e413f3f, 0xf502f7f7, 0x834fcccc, + 0x685c3434, 0x51f4a5a5, 0xd134e5e5, 0xf908f1f1, + 0xe2937171, 0xab73d8d8, 0x62533131, 0x2a3f1515, + 0x080c0404, 0x9552c7c7, 0x46652323, 0x9d5ec3c3, + 0x30281818, 0x37a19696, 0x0a0f0505, 0x2fb59a9a, + 0x0e090707, 0x24361212, 0x1b9b8080, 0xdf3de2e2, + 0xcd26ebeb, 0x4e692727, 0x7fcdb2b2, 0xea9f7575, + 0x121b0909, 0x1d9e8383, 0x58742c2c, 0x342e1a1a, + 0x362d1b1b, 0xdcb26e6e, 0xb4ee5a5a, 0x5bfba0a0, + 0xa4f65252, 0x764d3b3b, 0xb761d6d6, 0x7dceb3b3, + 0x527b2929, 0xdd3ee3e3, 0x5e712f2f, 0x13978484, + 0xa6f55353, 0xb968d1d1, 0x00000000, 0xc12ceded, + 0x40602020, 0xe31ffcfc, 0x79c8b1b1, 0xb6ed5b5b, + 0xd4be6a6a, 0x8d46cbcb, 0x67d9bebe, 0x724b3939, + 0x94de4a4a, 0x98d44c4c, 0xb0e85858, 0x854acfcf, + 0xbb6bd0d0, 0xc52aefef, 0x4fe5aaaa, 0xed16fbfb, + 0x86c54343, 0x9ad74d4d, 0x66553333, 0x11948585, + 0x8acf4545, 0xe910f9f9, 0x04060202, 0xfe817f7f, + 0xa0f05050, 0x78443c3c, 0x25ba9f9f, 0x4be3a8a8, + 0xa2f35151, 0x5dfea3a3, 0x80c04040, 0x058a8f8f, + 0x3fad9292, 0x21bc9d9d, 0x70483838, 0xf104f5f5, + 0x63dfbcbc, 0x77c1b6b6, 0xaf75dada, 0x42632121, + 0x20301010, 0xe51affff, 0xfd0ef3f3, 0xbf6dd2d2, + 0x814ccdcd, 0x18140c0c, 0x26351313, 0xc32fecec, + 0xbee15f5f, 0x35a29797, 0x88cc4444, 0x2e391717, + 0x9357c4c4, 0x55f2a7a7, 0xfc827e7e, 0x7a473d3d, + 0xc8ac6464, 0xbae75d5d, 0x322b1919, 0xe6957373, + 0xc0a06060, 0x19988181, 0x9ed14f4f, 0xa37fdcdc, + 0x44662222, 0x547e2a2a, 0x3bab9090, 0x0b838888, + 0x8cca4646, 0xc729eeee, 0x6bd3b8b8, 0x283c1414, + 0xa779dede, 0xbce25e5e, 0x161d0b0b, 0xad76dbdb, + 0xdb3be0e0, 0x64563232, 0x744e3a3a, 0x141e0a0a, + 0x92db4949, 0x0c0a0606, 0x486c2424, 0xb8e45c5c, + 0x9f5dc2c2, 0xbd6ed3d3, 0x43efacac, 0xc4a66262, + 0x39a89191, 0x31a49595, 0xd337e4e4, 0xf28b7979, + 0xd532e7e7, 0x8b43c8c8, 0x6e593737, 0xdab76d6d, + 0x018c8d8d, 0xb164d5d5, 0x9cd24e4e, 0x49e0a9a9, + 0xd8b46c6c, 0xacfa5656, 0xf307f4f4, 0xcf25eaea, + 0xcaaf6565, 0xf48e7a7a, 0x47e9aeae, 0x10180808, + 0x6fd5baba, 0xf0887878, 0x4a6f2525, 0x5c722e2e, + 0x38241c1c, 0x57f1a6a6, 0x73c7b4b4, 0x9751c6c6, + 0xcb23e8e8, 0xa17cdddd, 0xe89c7474, 0x3e211f1f, + 0x96dd4b4b, 0x61dcbdbd, 0x0d868b8b, 0x0f858a8a, + 0xe0907070, 0x7c423e3e, 0x71c4b5b5, 0xccaa6666, + 0x90d84848, 0x06050303, 0xf701f6f6, 0x1c120e0e, + 0xc2a36161, 0x6a5f3535, 0xaef95757, 0x69d0b9b9, + 0x17918686, 0x9958c1c1, 0x3a271d1d, 0x27b99e9e, + 0xd938e1e1, 0xeb13f8f8, 0x2bb39898, 0x22331111, + 0xd2bb6969, 0xa970d9d9, 0x07898e8e, 0x33a79494, + 0x2db69b9b, 0x3c221e1e, 0x15928787, 0xc920e9e9, + 0x8749cece, 0xaaff5555, 0x50782828, 0xa57adfdf, + 0x038f8c8c, 0x59f8a1a1, 0x09808989, 0x1a170d0d, + 0x65dabfbf, 0xd731e6e6, 0x84c64242, 0xd0b86868, + 0x82c34141, 0x29b09999, 0x5a772d2d, 0x1e110f0f, + 0x7bcbb0b0, 0xa8fc5454, 0x6dd6bbbb, 0x2c3a1616 +} +}; + +static const u4byte it_tab[4][256] = { +{ + 0x50a7f451, 0x5365417e, 0xc3a4171a, 0x965e273a, + 0xcb6bab3b, 0xf1459d1f, 0xab58faac, 0x9303e34b, + 0x55fa3020, 0xf66d76ad, 0x9176cc88, 0x254c02f5, + 0xfcd7e54f, 0xd7cb2ac5, 0x80443526, 0x8fa362b5, + 0x495ab1de, 0x671bba25, 0x980eea45, 0xe1c0fe5d, + 0x02752fc3, 0x12f04c81, 0xa397468d, 0xc6f9d36b, + 0xe75f8f03, 0x959c9215, 0xeb7a6dbf, 0xda595295, + 0x2d83bed4, 0xd3217458, 0x2969e049, 0x44c8c98e, + 0x6a89c275, 0x78798ef4, 0x6b3e5899, 0xdd71b927, + 0xb64fe1be, 0x17ad88f0, 0x66ac20c9, 0xb43ace7d, + 0x184adf63, 0x82311ae5, 0x60335197, 0x457f5362, + 0xe07764b1, 0x84ae6bbb, 0x1ca081fe, 0x942b08f9, + 0x58684870, 0x19fd458f, 0x876cde94, 0xb7f87b52, + 0x23d373ab, 0xe2024b72, 0x578f1fe3, 0x2aab5566, + 0x0728ebb2, 0x03c2b52f, 0x9a7bc586, 0xa50837d3, + 0xf2872830, 0xb2a5bf23, 0xba6a0302, 0x5c8216ed, + 0x2b1ccf8a, 0x92b479a7, 0xf0f207f3, 0xa1e2694e, + 0xcdf4da65, 0xd5be0506, 0x1f6234d1, 0x8afea6c4, + 0x9d532e34, 0xa055f3a2, 0x32e18a05, 0x75ebf6a4, + 0x39ec830b, 0xaaef6040, 0x069f715e, 0x51106ebd, + 0xf98a213e, 0x3d06dd96, 0xae053edd, 0x46bde64d, + 0xb58d5491, 0x055dc471, 0x6fd40604, 0xff155060, + 0x24fb9819, 0x97e9bdd6, 0xcc434089, 0x779ed967, + 0xbd42e8b0, 0x888b8907, 0x385b19e7, 0xdbeec879, + 0x470a7ca1, 0xe90f427c, 0xc91e84f8, 0x00000000, + 0x83868009, 0x48ed2b32, 0xac70111e, 0x4e725a6c, + 0xfbff0efd, 0x5638850f, 0x1ed5ae3d, 0x27392d36, + 0x64d90f0a, 0x21a65c68, 0xd1545b9b, 0x3a2e3624, + 0xb1670a0c, 0x0fe75793, 0xd296eeb4, 0x9e919b1b, + 0x4fc5c080, 0xa220dc61, 0x694b775a, 0x161a121c, + 0x0aba93e2, 0xe52aa0c0, 0x43e0223c, 0x1d171b12, + 0x0b0d090e, 0xadc78bf2, 0xb9a8b62d, 0xc8a91e14, + 0x8519f157, 0x4c0775af, 0xbbdd99ee, 0xfd607fa3, + 0x9f2601f7, 0xbcf5725c, 0xc53b6644, 0x347efb5b, + 0x7629438b, 0xdcc623cb, 0x68fcedb6, 0x63f1e4b8, + 0xcadc31d7, 0x10856342, 0x40229713, 0x2011c684, + 0x7d244a85, 0xf83dbbd2, 0x1132f9ae, 0x6da129c7, + 0x4b2f9e1d, 0xf330b2dc, 0xec52860d, 0xd0e3c177, + 0x6c16b32b, 0x99b970a9, 0xfa489411, 0x2264e947, + 0xc48cfca8, 0x1a3ff0a0, 0xd82c7d56, 0xef903322, + 0xc74e4987, 0xc1d138d9, 0xfea2ca8c, 0x360bd498, + 0xcf81f5a6, 0x28de7aa5, 0x268eb7da, 0xa4bfad3f, + 0xe49d3a2c, 0x0d927850, 0x9bcc5f6a, 0x62467e54, + 0xc2138df6, 0xe8b8d890, 0x5ef7392e, 0xf5afc382, + 0xbe805d9f, 0x7c93d069, 0xa92dd56f, 0xb31225cf, + 0x3b99acc8, 0xa77d1810, 0x6e639ce8, 0x7bbb3bdb, + 0x097826cd, 0xf418596e, 0x01b79aec, 0xa89a4f83, + 0x656e95e6, 0x7ee6ffaa, 0x08cfbc21, 0xe6e815ef, + 0xd99be7ba, 0xce366f4a, 0xd4099fea, 0xd67cb029, + 0xafb2a431, 0x31233f2a, 0x3094a5c6, 0xc066a235, + 0x37bc4e74, 0xa6ca82fc, 0xb0d090e0, 0x15d8a733, + 0x4a9804f1, 0xf7daec41, 0x0e50cd7f, 0x2ff69117, + 0x8dd64d76, 0x4db0ef43, 0x544daacc, 0xdf0496e4, + 0xe3b5d19e, 0x1b886a4c, 0xb81f2cc1, 0x7f516546, + 0x04ea5e9d, 0x5d358c01, 0x737487fa, 0x2e410bfb, + 0x5a1d67b3, 0x52d2db92, 0x335610e9, 0x1347d66d, + 0x8c61d79a, 0x7a0ca137, 0x8e14f859, 0x893c13eb, + 0xee27a9ce, 0x35c961b7, 0xede51ce1, 0x3cb1477a, + 0x59dfd29c, 0x3f73f255, 0x79ce1418, 0xbf37c773, + 0xeacdf753, 0x5baafd5f, 0x146f3ddf, 0x86db4478, + 0x81f3afca, 0x3ec468b9, 0x2c342438, 0x5f40a3c2, + 0x72c31d16, 0x0c25e2bc, 0x8b493c28, 0x41950dff, + 0x7101a839, 0xdeb30c08, 0x9ce4b4d8, 0x90c15664, + 0x6184cb7b, 0x70b632d5, 0x745c6c48, 0x4257b8d0 +}, { + 0xa7f45150, 0x65417e53, 0xa4171ac3, 0x5e273a96, + 0x6bab3bcb, 0x459d1ff1, 0x58faacab, 0x03e34b93, + 0xfa302055, 0x6d76adf6, 0x76cc8891, 0x4c02f525, + 0xd7e54ffc, 0xcb2ac5d7, 0x44352680, 0xa362b58f, + 0x5ab1de49, 0x1bba2567, 0x0eea4598, 0xc0fe5de1, + 0x752fc302, 0xf04c8112, 0x97468da3, 0xf9d36bc6, + 0x5f8f03e7, 0x9c921595, 0x7a6dbfeb, 0x595295da, + 0x83bed42d, 0x217458d3, 0x69e04929, 0xc8c98e44, + 0x89c2756a, 0x798ef478, 0x3e58996b, 0x71b927dd, + 0x4fe1beb6, 0xad88f017, 0xac20c966, 0x3ace7db4, + 0x4adf6318, 0x311ae582, 0x33519760, 0x7f536245, + 0x7764b1e0, 0xae6bbb84, 0xa081fe1c, 0x2b08f994, + 0x68487058, 0xfd458f19, 0x6cde9487, 0xf87b52b7, + 0xd373ab23, 0x024b72e2, 0x8f1fe357, 0xab55662a, + 0x28ebb207, 0xc2b52f03, 0x7bc5869a, 0x0837d3a5, + 0x872830f2, 0xa5bf23b2, 0x6a0302ba, 0x8216ed5c, + 0x1ccf8a2b, 0xb479a792, 0xf207f3f0, 0xe2694ea1, + 0xf4da65cd, 0xbe0506d5, 0x6234d11f, 0xfea6c48a, + 0x532e349d, 0x55f3a2a0, 0xe18a0532, 0xebf6a475, + 0xec830b39, 0xef6040aa, 0x9f715e06, 0x106ebd51, + 0x8a213ef9, 0x06dd963d, 0x053eddae, 0xbde64d46, + 0x8d5491b5, 0x5dc47105, 0xd406046f, 0x155060ff, + 0xfb981924, 0xe9bdd697, 0x434089cc, 0x9ed96777, + 0x42e8b0bd, 0x8b890788, 0x5b19e738, 0xeec879db, + 0x0a7ca147, 0x0f427ce9, 0x1e84f8c9, 0x00000000, + 0x86800983, 0xed2b3248, 0x70111eac, 0x725a6c4e, + 0xff0efdfb, 0x38850f56, 0xd5ae3d1e, 0x392d3627, + 0xd90f0a64, 0xa65c6821, 0x545b9bd1, 0x2e36243a, + 0x670a0cb1, 0xe757930f, 0x96eeb4d2, 0x919b1b9e, + 0xc5c0804f, 0x20dc61a2, 0x4b775a69, 0x1a121c16, + 0xba93e20a, 0x2aa0c0e5, 0xe0223c43, 0x171b121d, + 0x0d090e0b, 0xc78bf2ad, 0xa8b62db9, 0xa91e14c8, + 0x19f15785, 0x0775af4c, 0xdd99eebb, 0x607fa3fd, + 0x2601f79f, 0xf5725cbc, 0x3b6644c5, 0x7efb5b34, + 0x29438b76, 0xc623cbdc, 0xfcedb668, 0xf1e4b863, + 0xdc31d7ca, 0x85634210, 0x22971340, 0x11c68420, + 0x244a857d, 0x3dbbd2f8, 0x32f9ae11, 0xa129c76d, + 0x2f9e1d4b, 0x30b2dcf3, 0x52860dec, 0xe3c177d0, + 0x16b32b6c, 0xb970a999, 0x489411fa, 0x64e94722, + 0x8cfca8c4, 0x3ff0a01a, 0x2c7d56d8, 0x903322ef, + 0x4e4987c7, 0xd138d9c1, 0xa2ca8cfe, 0x0bd49836, + 0x81f5a6cf, 0xde7aa528, 0x8eb7da26, 0xbfad3fa4, + 0x9d3a2ce4, 0x9278500d, 0xcc5f6a9b, 0x467e5462, + 0x138df6c2, 0xb8d890e8, 0xf7392e5e, 0xafc382f5, + 0x805d9fbe, 0x93d0697c, 0x2dd56fa9, 0x1225cfb3, + 0x99acc83b, 0x7d1810a7, 0x639ce86e, 0xbb3bdb7b, + 0x7826cd09, 0x18596ef4, 0xb79aec01, 0x9a4f83a8, + 0x6e95e665, 0xe6ffaa7e, 0xcfbc2108, 0xe815efe6, + 0x9be7bad9, 0x366f4ace, 0x099fead4, 0x7cb029d6, + 0xb2a431af, 0x233f2a31, 0x94a5c630, 0x66a235c0, + 0xbc4e7437, 0xca82fca6, 0xd090e0b0, 0xd8a73315, + 0x9804f14a, 0xdaec41f7, 0x50cd7f0e, 0xf691172f, + 0xd64d768d, 0xb0ef434d, 0x4daacc54, 0x0496e4df, + 0xb5d19ee3, 0x886a4c1b, 0x1f2cc1b8, 0x5165467f, + 0xea5e9d04, 0x358c015d, 0x7487fa73, 0x410bfb2e, + 0x1d67b35a, 0xd2db9252, 0x5610e933, 0x47d66d13, + 0x61d79a8c, 0x0ca1377a, 0x14f8598e, 0x3c13eb89, + 0x27a9ceee, 0xc961b735, 0xe51ce1ed, 0xb1477a3c, + 0xdfd29c59, 0x73f2553f, 0xce141879, 0x37c773bf, + 0xcdf753ea, 0xaafd5f5b, 0x6f3ddf14, 0xdb447886, + 0xf3afca81, 0xc468b93e, 0x3424382c, 0x40a3c25f, + 0xc31d1672, 0x25e2bc0c, 0x493c288b, 0x950dff41, + 0x01a83971, 0xb30c08de, 0xe4b4d89c, 0xc1566490, + 0x84cb7b61, 0xb632d570, 0x5c6c4874, 0x57b8d042 +}, { + 0xf45150a7, 0x417e5365, 0x171ac3a4, 0x273a965e, + 0xab3bcb6b, 0x9d1ff145, 0xfaacab58, 0xe34b9303, + 0x302055fa, 0x76adf66d, 0xcc889176, 0x02f5254c, + 0xe54ffcd7, 0x2ac5d7cb, 0x35268044, 0x62b58fa3, + 0xb1de495a, 0xba25671b, 0xea45980e, 0xfe5de1c0, + 0x2fc30275, 0x4c8112f0, 0x468da397, 0xd36bc6f9, + 0x8f03e75f, 0x9215959c, 0x6dbfeb7a, 0x5295da59, + 0xbed42d83, 0x7458d321, 0xe0492969, 0xc98e44c8, + 0xc2756a89, 0x8ef47879, 0x58996b3e, 0xb927dd71, + 0xe1beb64f, 0x88f017ad, 0x20c966ac, 0xce7db43a, + 0xdf63184a, 0x1ae58231, 0x51976033, 0x5362457f, + 0x64b1e077, 0x6bbb84ae, 0x81fe1ca0, 0x08f9942b, + 0x48705868, 0x458f19fd, 0xde94876c, 0x7b52b7f8, + 0x73ab23d3, 0x4b72e202, 0x1fe3578f, 0x55662aab, + 0xebb20728, 0xb52f03c2, 0xc5869a7b, 0x37d3a508, + 0x2830f287, 0xbf23b2a5, 0x0302ba6a, 0x16ed5c82, + 0xcf8a2b1c, 0x79a792b4, 0x07f3f0f2, 0x694ea1e2, + 0xda65cdf4, 0x0506d5be, 0x34d11f62, 0xa6c48afe, + 0x2e349d53, 0xf3a2a055, 0x8a0532e1, 0xf6a475eb, + 0x830b39ec, 0x6040aaef, 0x715e069f, 0x6ebd5110, + 0x213ef98a, 0xdd963d06, 0x3eddae05, 0xe64d46bd, + 0x5491b58d, 0xc471055d, 0x06046fd4, 0x5060ff15, + 0x981924fb, 0xbdd697e9, 0x4089cc43, 0xd967779e, + 0xe8b0bd42, 0x8907888b, 0x19e7385b, 0xc879dbee, + 0x7ca1470a, 0x427ce90f, 0x84f8c91e, 0x00000000, + 0x80098386, 0x2b3248ed, 0x111eac70, 0x5a6c4e72, + 0x0efdfbff, 0x850f5638, 0xae3d1ed5, 0x2d362739, + 0x0f0a64d9, 0x5c6821a6, 0x5b9bd154, 0x36243a2e, + 0x0a0cb167, 0x57930fe7, 0xeeb4d296, 0x9b1b9e91, + 0xc0804fc5, 0xdc61a220, 0x775a694b, 0x121c161a, + 0x93e20aba, 0xa0c0e52a, 0x223c43e0, 0x1b121d17, + 0x090e0b0d, 0x8bf2adc7, 0xb62db9a8, 0x1e14c8a9, + 0xf1578519, 0x75af4c07, 0x99eebbdd, 0x7fa3fd60, + 0x01f79f26, 0x725cbcf5, 0x6644c53b, 0xfb5b347e, + 0x438b7629, 0x23cbdcc6, 0xedb668fc, 0xe4b863f1, + 0x31d7cadc, 0x63421085, 0x97134022, 0xc6842011, + 0x4a857d24, 0xbbd2f83d, 0xf9ae1132, 0x29c76da1, + 0x9e1d4b2f, 0xb2dcf330, 0x860dec52, 0xc177d0e3, + 0xb32b6c16, 0x70a999b9, 0x9411fa48, 0xe9472264, + 0xfca8c48c, 0xf0a01a3f, 0x7d56d82c, 0x3322ef90, + 0x4987c74e, 0x38d9c1d1, 0xca8cfea2, 0xd498360b, + 0xf5a6cf81, 0x7aa528de, 0xb7da268e, 0xad3fa4bf, + 0x3a2ce49d, 0x78500d92, 0x5f6a9bcc, 0x7e546246, + 0x8df6c213, 0xd890e8b8, 0x392e5ef7, 0xc382f5af, + 0x5d9fbe80, 0xd0697c93, 0xd56fa92d, 0x25cfb312, + 0xacc83b99, 0x1810a77d, 0x9ce86e63, 0x3bdb7bbb, + 0x26cd0978, 0x596ef418, 0x9aec01b7, 0x4f83a89a, + 0x95e6656e, 0xffaa7ee6, 0xbc2108cf, 0x15efe6e8, + 0xe7bad99b, 0x6f4ace36, 0x9fead409, 0xb029d67c, + 0xa431afb2, 0x3f2a3123, 0xa5c63094, 0xa235c066, + 0x4e7437bc, 0x82fca6ca, 0x90e0b0d0, 0xa73315d8, + 0x04f14a98, 0xec41f7da, 0xcd7f0e50, 0x91172ff6, + 0x4d768dd6, 0xef434db0, 0xaacc544d, 0x96e4df04, + 0xd19ee3b5, 0x6a4c1b88, 0x2cc1b81f, 0x65467f51, + 0x5e9d04ea, 0x8c015d35, 0x87fa7374, 0x0bfb2e41, + 0x67b35a1d, 0xdb9252d2, 0x10e93356, 0xd66d1347, + 0xd79a8c61, 0xa1377a0c, 0xf8598e14, 0x13eb893c, + 0xa9ceee27, 0x61b735c9, 0x1ce1ede5, 0x477a3cb1, + 0xd29c59df, 0xf2553f73, 0x141879ce, 0xc773bf37, + 0xf753eacd, 0xfd5f5baa, 0x3ddf146f, 0x447886db, + 0xafca81f3, 0x68b93ec4, 0x24382c34, 0xa3c25f40, + 0x1d1672c3, 0xe2bc0c25, 0x3c288b49, 0x0dff4195, + 0xa8397101, 0x0c08deb3, 0xb4d89ce4, 0x566490c1, + 0xcb7b6184, 0x32d570b6, 0x6c48745c, 0xb8d04257 +}, { + 0x5150a7f4, 0x7e536541, 0x1ac3a417, 0x3a965e27, + 0x3bcb6bab, 0x1ff1459d, 0xacab58fa, 0x4b9303e3, + 0x2055fa30, 0xadf66d76, 0x889176cc, 0xf5254c02, + 0x4ffcd7e5, 0xc5d7cb2a, 0x26804435, 0xb58fa362, + 0xde495ab1, 0x25671bba, 0x45980eea, 0x5de1c0fe, + 0xc302752f, 0x8112f04c, 0x8da39746, 0x6bc6f9d3, + 0x03e75f8f, 0x15959c92, 0xbfeb7a6d, 0x95da5952, + 0xd42d83be, 0x58d32174, 0x492969e0, 0x8e44c8c9, + 0x756a89c2, 0xf478798e, 0x996b3e58, 0x27dd71b9, + 0xbeb64fe1, 0xf017ad88, 0xc966ac20, 0x7db43ace, + 0x63184adf, 0xe582311a, 0x97603351, 0x62457f53, + 0xb1e07764, 0xbb84ae6b, 0xfe1ca081, 0xf9942b08, + 0x70586848, 0x8f19fd45, 0x94876cde, 0x52b7f87b, + 0xab23d373, 0x72e2024b, 0xe3578f1f, 0x662aab55, + 0xb20728eb, 0x2f03c2b5, 0x869a7bc5, 0xd3a50837, + 0x30f28728, 0x23b2a5bf, 0x02ba6a03, 0xed5c8216, + 0x8a2b1ccf, 0xa792b479, 0xf3f0f207, 0x4ea1e269, + 0x65cdf4da, 0x06d5be05, 0xd11f6234, 0xc48afea6, + 0x349d532e, 0xa2a055f3, 0x0532e18a, 0xa475ebf6, + 0x0b39ec83, 0x40aaef60, 0x5e069f71, 0xbd51106e, + 0x3ef98a21, 0x963d06dd, 0xddae053e, 0x4d46bde6, + 0x91b58d54, 0x71055dc4, 0x046fd406, 0x60ff1550, + 0x1924fb98, 0xd697e9bd, 0x89cc4340, 0x67779ed9, + 0xb0bd42e8, 0x07888b89, 0xe7385b19, 0x79dbeec8, + 0xa1470a7c, 0x7ce90f42, 0xf8c91e84, 0x00000000, + 0x09838680, 0x3248ed2b, 0x1eac7011, 0x6c4e725a, + 0xfdfbff0e, 0x0f563885, 0x3d1ed5ae, 0x3627392d, + 0x0a64d90f, 0x6821a65c, 0x9bd1545b, 0x243a2e36, + 0x0cb1670a, 0x930fe757, 0xb4d296ee, 0x1b9e919b, + 0x804fc5c0, 0x61a220dc, 0x5a694b77, 0x1c161a12, + 0xe20aba93, 0xc0e52aa0, 0x3c43e022, 0x121d171b, + 0x0e0b0d09, 0xf2adc78b, 0x2db9a8b6, 0x14c8a91e, + 0x578519f1, 0xaf4c0775, 0xeebbdd99, 0xa3fd607f, + 0xf79f2601, 0x5cbcf572, 0x44c53b66, 0x5b347efb, + 0x8b762943, 0xcbdcc623, 0xb668fced, 0xb863f1e4, + 0xd7cadc31, 0x42108563, 0x13402297, 0x842011c6, + 0x857d244a, 0xd2f83dbb, 0xae1132f9, 0xc76da129, + 0x1d4b2f9e, 0xdcf330b2, 0x0dec5286, 0x77d0e3c1, + 0x2b6c16b3, 0xa999b970, 0x11fa4894, 0x472264e9, + 0xa8c48cfc, 0xa01a3ff0, 0x56d82c7d, 0x22ef9033, + 0x87c74e49, 0xd9c1d138, 0x8cfea2ca, 0x98360bd4, + 0xa6cf81f5, 0xa528de7a, 0xda268eb7, 0x3fa4bfad, + 0x2ce49d3a, 0x500d9278, 0x6a9bcc5f, 0x5462467e, + 0xf6c2138d, 0x90e8b8d8, 0x2e5ef739, 0x82f5afc3, + 0x9fbe805d, 0x697c93d0, 0x6fa92dd5, 0xcfb31225, + 0xc83b99ac, 0x10a77d18, 0xe86e639c, 0xdb7bbb3b, + 0xcd097826, 0x6ef41859, 0xec01b79a, 0x83a89a4f, + 0xe6656e95, 0xaa7ee6ff, 0x2108cfbc, 0xefe6e815, + 0xbad99be7, 0x4ace366f, 0xead4099f, 0x29d67cb0, + 0x31afb2a4, 0x2a31233f, 0xc63094a5, 0x35c066a2, + 0x7437bc4e, 0xfca6ca82, 0xe0b0d090, 0x3315d8a7, + 0xf14a9804, 0x41f7daec, 0x7f0e50cd, 0x172ff691, + 0x768dd64d, 0x434db0ef, 0xcc544daa, 0xe4df0496, + 0x9ee3b5d1, 0x4c1b886a, 0xc1b81f2c, 0x467f5165, + 0x9d04ea5e, 0x015d358c, 0xfa737487, 0xfb2e410b, + 0xb35a1d67, 0x9252d2db, 0xe9335610, 0x6d1347d6, + 0x9a8c61d7, 0x377a0ca1, 0x598e14f8, 0xeb893c13, + 0xceee27a9, 0xb735c961, 0xe1ede51c, 0x7a3cb147, + 0x9c59dfd2, 0x553f73f2, 0x1879ce14, 0x73bf37c7, + 0x53eacdf7, 0x5f5baafd, 0xdf146f3d, 0x7886db44, + 0xca81f3af, 0xb93ec468, 0x382c3424, 0xc25f40a3, + 0x1672c31d, 0xbc0c25e2, 0x288b493c, 0xff41950d, + 0x397101a8, 0x08deb30c, 0xd89ce4b4, 0x6490c156, + 0x7b6184cb, 0xd570b632, 0x48745c6c, 0xd04257b8 +} +}; + +static const u4byte fl_tab[4][256] = { +{ + 0x00000063, 0x0000007c, 0x00000077, 0x0000007b, + 0x000000f2, 0x0000006b, 0x0000006f, 0x000000c5, + 0x00000030, 0x00000001, 0x00000067, 0x0000002b, + 0x000000fe, 0x000000d7, 0x000000ab, 0x00000076, + 0x000000ca, 0x00000082, 0x000000c9, 0x0000007d, + 0x000000fa, 0x00000059, 0x00000047, 0x000000f0, + 0x000000ad, 0x000000d4, 0x000000a2, 0x000000af, + 0x0000009c, 0x000000a4, 0x00000072, 0x000000c0, + 0x000000b7, 0x000000fd, 0x00000093, 0x00000026, + 0x00000036, 0x0000003f, 0x000000f7, 0x000000cc, + 0x00000034, 0x000000a5, 0x000000e5, 0x000000f1, + 0x00000071, 0x000000d8, 0x00000031, 0x00000015, + 0x00000004, 0x000000c7, 0x00000023, 0x000000c3, + 0x00000018, 0x00000096, 0x00000005, 0x0000009a, + 0x00000007, 0x00000012, 0x00000080, 0x000000e2, + 0x000000eb, 0x00000027, 0x000000b2, 0x00000075, + 0x00000009, 0x00000083, 0x0000002c, 0x0000001a, + 0x0000001b, 0x0000006e, 0x0000005a, 0x000000a0, + 0x00000052, 0x0000003b, 0x000000d6, 0x000000b3, + 0x00000029, 0x000000e3, 0x0000002f, 0x00000084, + 0x00000053, 0x000000d1, 0x00000000, 0x000000ed, + 0x00000020, 0x000000fc, 0x000000b1, 0x0000005b, + 0x0000006a, 0x000000cb, 0x000000be, 0x00000039, + 0x0000004a, 0x0000004c, 0x00000058, 0x000000cf, + 0x000000d0, 0x000000ef, 0x000000aa, 0x000000fb, + 0x00000043, 0x0000004d, 0x00000033, 0x00000085, + 0x00000045, 0x000000f9, 0x00000002, 0x0000007f, + 0x00000050, 0x0000003c, 0x0000009f, 0x000000a8, + 0x00000051, 0x000000a3, 0x00000040, 0x0000008f, + 0x00000092, 0x0000009d, 0x00000038, 0x000000f5, + 0x000000bc, 0x000000b6, 0x000000da, 0x00000021, + 0x00000010, 0x000000ff, 0x000000f3, 0x000000d2, + 0x000000cd, 0x0000000c, 0x00000013, 0x000000ec, + 0x0000005f, 0x00000097, 0x00000044, 0x00000017, + 0x000000c4, 0x000000a7, 0x0000007e, 0x0000003d, + 0x00000064, 0x0000005d, 0x00000019, 0x00000073, + 0x00000060, 0x00000081, 0x0000004f, 0x000000dc, + 0x00000022, 0x0000002a, 0x00000090, 0x00000088, + 0x00000046, 0x000000ee, 0x000000b8, 0x00000014, + 0x000000de, 0x0000005e, 0x0000000b, 0x000000db, + 0x000000e0, 0x00000032, 0x0000003a, 0x0000000a, + 0x00000049, 0x00000006, 0x00000024, 0x0000005c, + 0x000000c2, 0x000000d3, 0x000000ac, 0x00000062, + 0x00000091, 0x00000095, 0x000000e4, 0x00000079, + 0x000000e7, 0x000000c8, 0x00000037, 0x0000006d, + 0x0000008d, 0x000000d5, 0x0000004e, 0x000000a9, + 0x0000006c, 0x00000056, 0x000000f4, 0x000000ea, + 0x00000065, 0x0000007a, 0x000000ae, 0x00000008, + 0x000000ba, 0x00000078, 0x00000025, 0x0000002e, + 0x0000001c, 0x000000a6, 0x000000b4, 0x000000c6, + 0x000000e8, 0x000000dd, 0x00000074, 0x0000001f, + 0x0000004b, 0x000000bd, 0x0000008b, 0x0000008a, + 0x00000070, 0x0000003e, 0x000000b5, 0x00000066, + 0x00000048, 0x00000003, 0x000000f6, 0x0000000e, + 0x00000061, 0x00000035, 0x00000057, 0x000000b9, + 0x00000086, 0x000000c1, 0x0000001d, 0x0000009e, + 0x000000e1, 0x000000f8, 0x00000098, 0x00000011, + 0x00000069, 0x000000d9, 0x0000008e, 0x00000094, + 0x0000009b, 0x0000001e, 0x00000087, 0x000000e9, + 0x000000ce, 0x00000055, 0x00000028, 0x000000df, + 0x0000008c, 0x000000a1, 0x00000089, 0x0000000d, + 0x000000bf, 0x000000e6, 0x00000042, 0x00000068, + 0x00000041, 0x00000099, 0x0000002d, 0x0000000f, + 0x000000b0, 0x00000054, 0x000000bb, 0x00000016 +}, { + 0x00006300, 0x00007c00, 0x00007700, 0x00007b00, + 0x0000f200, 0x00006b00, 0x00006f00, 0x0000c500, + 0x00003000, 0x00000100, 0x00006700, 0x00002b00, + 0x0000fe00, 0x0000d700, 0x0000ab00, 0x00007600, + 0x0000ca00, 0x00008200, 0x0000c900, 0x00007d00, + 0x0000fa00, 0x00005900, 0x00004700, 0x0000f000, + 0x0000ad00, 0x0000d400, 0x0000a200, 0x0000af00, + 0x00009c00, 0x0000a400, 0x00007200, 0x0000c000, + 0x0000b700, 0x0000fd00, 0x00009300, 0x00002600, + 0x00003600, 0x00003f00, 0x0000f700, 0x0000cc00, + 0x00003400, 0x0000a500, 0x0000e500, 0x0000f100, + 0x00007100, 0x0000d800, 0x00003100, 0x00001500, + 0x00000400, 0x0000c700, 0x00002300, 0x0000c300, + 0x00001800, 0x00009600, 0x00000500, 0x00009a00, + 0x00000700, 0x00001200, 0x00008000, 0x0000e200, + 0x0000eb00, 0x00002700, 0x0000b200, 0x00007500, + 0x00000900, 0x00008300, 0x00002c00, 0x00001a00, + 0x00001b00, 0x00006e00, 0x00005a00, 0x0000a000, + 0x00005200, 0x00003b00, 0x0000d600, 0x0000b300, + 0x00002900, 0x0000e300, 0x00002f00, 0x00008400, + 0x00005300, 0x0000d100, 0x00000000, 0x0000ed00, + 0x00002000, 0x0000fc00, 0x0000b100, 0x00005b00, + 0x00006a00, 0x0000cb00, 0x0000be00, 0x00003900, + 0x00004a00, 0x00004c00, 0x00005800, 0x0000cf00, + 0x0000d000, 0x0000ef00, 0x0000aa00, 0x0000fb00, + 0x00004300, 0x00004d00, 0x00003300, 0x00008500, + 0x00004500, 0x0000f900, 0x00000200, 0x00007f00, + 0x00005000, 0x00003c00, 0x00009f00, 0x0000a800, + 0x00005100, 0x0000a300, 0x00004000, 0x00008f00, + 0x00009200, 0x00009d00, 0x00003800, 0x0000f500, + 0x0000bc00, 0x0000b600, 0x0000da00, 0x00002100, + 0x00001000, 0x0000ff00, 0x0000f300, 0x0000d200, + 0x0000cd00, 0x00000c00, 0x00001300, 0x0000ec00, + 0x00005f00, 0x00009700, 0x00004400, 0x00001700, + 0x0000c400, 0x0000a700, 0x00007e00, 0x00003d00, + 0x00006400, 0x00005d00, 0x00001900, 0x00007300, + 0x00006000, 0x00008100, 0x00004f00, 0x0000dc00, + 0x00002200, 0x00002a00, 0x00009000, 0x00008800, + 0x00004600, 0x0000ee00, 0x0000b800, 0x00001400, + 0x0000de00, 0x00005e00, 0x00000b00, 0x0000db00, + 0x0000e000, 0x00003200, 0x00003a00, 0x00000a00, + 0x00004900, 0x00000600, 0x00002400, 0x00005c00, + 0x0000c200, 0x0000d300, 0x0000ac00, 0x00006200, + 0x00009100, 0x00009500, 0x0000e400, 0x00007900, + 0x0000e700, 0x0000c800, 0x00003700, 0x00006d00, + 0x00008d00, 0x0000d500, 0x00004e00, 0x0000a900, + 0x00006c00, 0x00005600, 0x0000f400, 0x0000ea00, + 0x00006500, 0x00007a00, 0x0000ae00, 0x00000800, + 0x0000ba00, 0x00007800, 0x00002500, 0x00002e00, + 0x00001c00, 0x0000a600, 0x0000b400, 0x0000c600, + 0x0000e800, 0x0000dd00, 0x00007400, 0x00001f00, + 0x00004b00, 0x0000bd00, 0x00008b00, 0x00008a00, + 0x00007000, 0x00003e00, 0x0000b500, 0x00006600, + 0x00004800, 0x00000300, 0x0000f600, 0x00000e00, + 0x00006100, 0x00003500, 0x00005700, 0x0000b900, + 0x00008600, 0x0000c100, 0x00001d00, 0x00009e00, + 0x0000e100, 0x0000f800, 0x00009800, 0x00001100, + 0x00006900, 0x0000d900, 0x00008e00, 0x00009400, + 0x00009b00, 0x00001e00, 0x00008700, 0x0000e900, + 0x0000ce00, 0x00005500, 0x00002800, 0x0000df00, + 0x00008c00, 0x0000a100, 0x00008900, 0x00000d00, + 0x0000bf00, 0x0000e600, 0x00004200, 0x00006800, + 0x00004100, 0x00009900, 0x00002d00, 0x00000f00, + 0x0000b000, 0x00005400, 0x0000bb00, 0x00001600 +}, { + 0x00630000, 0x007c0000, 0x00770000, 0x007b0000, + 0x00f20000, 0x006b0000, 0x006f0000, 0x00c50000, + 0x00300000, 0x00010000, 0x00670000, 0x002b0000, + 0x00fe0000, 0x00d70000, 0x00ab0000, 0x00760000, + 0x00ca0000, 0x00820000, 0x00c90000, 0x007d0000, + 0x00fa0000, 0x00590000, 0x00470000, 0x00f00000, + 0x00ad0000, 0x00d40000, 0x00a20000, 0x00af0000, + 0x009c0000, 0x00a40000, 0x00720000, 0x00c00000, + 0x00b70000, 0x00fd0000, 0x00930000, 0x00260000, + 0x00360000, 0x003f0000, 0x00f70000, 0x00cc0000, + 0x00340000, 0x00a50000, 0x00e50000, 0x00f10000, + 0x00710000, 0x00d80000, 0x00310000, 0x00150000, + 0x00040000, 0x00c70000, 0x00230000, 0x00c30000, + 0x00180000, 0x00960000, 0x00050000, 0x009a0000, + 0x00070000, 0x00120000, 0x00800000, 0x00e20000, + 0x00eb0000, 0x00270000, 0x00b20000, 0x00750000, + 0x00090000, 0x00830000, 0x002c0000, 0x001a0000, + 0x001b0000, 0x006e0000, 0x005a0000, 0x00a00000, + 0x00520000, 0x003b0000, 0x00d60000, 0x00b30000, + 0x00290000, 0x00e30000, 0x002f0000, 0x00840000, + 0x00530000, 0x00d10000, 0x00000000, 0x00ed0000, + 0x00200000, 0x00fc0000, 0x00b10000, 0x005b0000, + 0x006a0000, 0x00cb0000, 0x00be0000, 0x00390000, + 0x004a0000, 0x004c0000, 0x00580000, 0x00cf0000, + 0x00d00000, 0x00ef0000, 0x00aa0000, 0x00fb0000, + 0x00430000, 0x004d0000, 0x00330000, 0x00850000, + 0x00450000, 0x00f90000, 0x00020000, 0x007f0000, + 0x00500000, 0x003c0000, 0x009f0000, 0x00a80000, + 0x00510000, 0x00a30000, 0x00400000, 0x008f0000, + 0x00920000, 0x009d0000, 0x00380000, 0x00f50000, + 0x00bc0000, 0x00b60000, 0x00da0000, 0x00210000, + 0x00100000, 0x00ff0000, 0x00f30000, 0x00d20000, + 0x00cd0000, 0x000c0000, 0x00130000, 0x00ec0000, + 0x005f0000, 0x00970000, 0x00440000, 0x00170000, + 0x00c40000, 0x00a70000, 0x007e0000, 0x003d0000, + 0x00640000, 0x005d0000, 0x00190000, 0x00730000, + 0x00600000, 0x00810000, 0x004f0000, 0x00dc0000, + 0x00220000, 0x002a0000, 0x00900000, 0x00880000, + 0x00460000, 0x00ee0000, 0x00b80000, 0x00140000, + 0x00de0000, 0x005e0000, 0x000b0000, 0x00db0000, + 0x00e00000, 0x00320000, 0x003a0000, 0x000a0000, + 0x00490000, 0x00060000, 0x00240000, 0x005c0000, + 0x00c20000, 0x00d30000, 0x00ac0000, 0x00620000, + 0x00910000, 0x00950000, 0x00e40000, 0x00790000, + 0x00e70000, 0x00c80000, 0x00370000, 0x006d0000, + 0x008d0000, 0x00d50000, 0x004e0000, 0x00a90000, + 0x006c0000, 0x00560000, 0x00f40000, 0x00ea0000, + 0x00650000, 0x007a0000, 0x00ae0000, 0x00080000, + 0x00ba0000, 0x00780000, 0x00250000, 0x002e0000, + 0x001c0000, 0x00a60000, 0x00b40000, 0x00c60000, + 0x00e80000, 0x00dd0000, 0x00740000, 0x001f0000, + 0x004b0000, 0x00bd0000, 0x008b0000, 0x008a0000, + 0x00700000, 0x003e0000, 0x00b50000, 0x00660000, + 0x00480000, 0x00030000, 0x00f60000, 0x000e0000, + 0x00610000, 0x00350000, 0x00570000, 0x00b90000, + 0x00860000, 0x00c10000, 0x001d0000, 0x009e0000, + 0x00e10000, 0x00f80000, 0x00980000, 0x00110000, + 0x00690000, 0x00d90000, 0x008e0000, 0x00940000, + 0x009b0000, 0x001e0000, 0x00870000, 0x00e90000, + 0x00ce0000, 0x00550000, 0x00280000, 0x00df0000, + 0x008c0000, 0x00a10000, 0x00890000, 0x000d0000, + 0x00bf0000, 0x00e60000, 0x00420000, 0x00680000, + 0x00410000, 0x00990000, 0x002d0000, 0x000f0000, + 0x00b00000, 0x00540000, 0x00bb0000, 0x00160000 +}, { + 0x63000000, 0x7c000000, 0x77000000, 0x7b000000, + 0xf2000000, 0x6b000000, 0x6f000000, 0xc5000000, + 0x30000000, 0x01000000, 0x67000000, 0x2b000000, + 0xfe000000, 0xd7000000, 0xab000000, 0x76000000, + 0xca000000, 0x82000000, 0xc9000000, 0x7d000000, + 0xfa000000, 0x59000000, 0x47000000, 0xf0000000, + 0xad000000, 0xd4000000, 0xa2000000, 0xaf000000, + 0x9c000000, 0xa4000000, 0x72000000, 0xc0000000, + 0xb7000000, 0xfd000000, 0x93000000, 0x26000000, + 0x36000000, 0x3f000000, 0xf7000000, 0xcc000000, + 0x34000000, 0xa5000000, 0xe5000000, 0xf1000000, + 0x71000000, 0xd8000000, 0x31000000, 0x15000000, + 0x04000000, 0xc7000000, 0x23000000, 0xc3000000, + 0x18000000, 0x96000000, 0x05000000, 0x9a000000, + 0x07000000, 0x12000000, 0x80000000, 0xe2000000, + 0xeb000000, 0x27000000, 0xb2000000, 0x75000000, + 0x09000000, 0x83000000, 0x2c000000, 0x1a000000, + 0x1b000000, 0x6e000000, 0x5a000000, 0xa0000000, + 0x52000000, 0x3b000000, 0xd6000000, 0xb3000000, + 0x29000000, 0xe3000000, 0x2f000000, 0x84000000, + 0x53000000, 0xd1000000, 0x00000000, 0xed000000, + 0x20000000, 0xfc000000, 0xb1000000, 0x5b000000, + 0x6a000000, 0xcb000000, 0xbe000000, 0x39000000, + 0x4a000000, 0x4c000000, 0x58000000, 0xcf000000, + 0xd0000000, 0xef000000, 0xaa000000, 0xfb000000, + 0x43000000, 0x4d000000, 0x33000000, 0x85000000, + 0x45000000, 0xf9000000, 0x02000000, 0x7f000000, + 0x50000000, 0x3c000000, 0x9f000000, 0xa8000000, + 0x51000000, 0xa3000000, 0x40000000, 0x8f000000, + 0x92000000, 0x9d000000, 0x38000000, 0xf5000000, + 0xbc000000, 0xb6000000, 0xda000000, 0x21000000, + 0x10000000, 0xff000000, 0xf3000000, 0xd2000000, + 0xcd000000, 0x0c000000, 0x13000000, 0xec000000, + 0x5f000000, 0x97000000, 0x44000000, 0x17000000, + 0xc4000000, 0xa7000000, 0x7e000000, 0x3d000000, + 0x64000000, 0x5d000000, 0x19000000, 0x73000000, + 0x60000000, 0x81000000, 0x4f000000, 0xdc000000, + 0x22000000, 0x2a000000, 0x90000000, 0x88000000, + 0x46000000, 0xee000000, 0xb8000000, 0x14000000, + 0xde000000, 0x5e000000, 0x0b000000, 0xdb000000, + 0xe0000000, 0x32000000, 0x3a000000, 0x0a000000, + 0x49000000, 0x06000000, 0x24000000, 0x5c000000, + 0xc2000000, 0xd3000000, 0xac000000, 0x62000000, + 0x91000000, 0x95000000, 0xe4000000, 0x79000000, + 0xe7000000, 0xc8000000, 0x37000000, 0x6d000000, + 0x8d000000, 0xd5000000, 0x4e000000, 0xa9000000, + 0x6c000000, 0x56000000, 0xf4000000, 0xea000000, + 0x65000000, 0x7a000000, 0xae000000, 0x08000000, + 0xba000000, 0x78000000, 0x25000000, 0x2e000000, + 0x1c000000, 0xa6000000, 0xb4000000, 0xc6000000, + 0xe8000000, 0xdd000000, 0x74000000, 0x1f000000, + 0x4b000000, 0xbd000000, 0x8b000000, 0x8a000000, + 0x70000000, 0x3e000000, 0xb5000000, 0x66000000, + 0x48000000, 0x03000000, 0xf6000000, 0x0e000000, + 0x61000000, 0x35000000, 0x57000000, 0xb9000000, + 0x86000000, 0xc1000000, 0x1d000000, 0x9e000000, + 0xe1000000, 0xf8000000, 0x98000000, 0x11000000, + 0x69000000, 0xd9000000, 0x8e000000, 0x94000000, + 0x9b000000, 0x1e000000, 0x87000000, 0xe9000000, + 0xce000000, 0x55000000, 0x28000000, 0xdf000000, + 0x8c000000, 0xa1000000, 0x89000000, 0x0d000000, + 0xbf000000, 0xe6000000, 0x42000000, 0x68000000, + 0x41000000, 0x99000000, 0x2d000000, 0x0f000000, + 0xb0000000, 0x54000000, 0xbb000000, 0x16000000 +} +}; + +static const u4byte il_tab[4][256] = { +{ + 0x00000052, 0x00000009, 0x0000006a, 0x000000d5, + 0x00000030, 0x00000036, 0x000000a5, 0x00000038, + 0x000000bf, 0x00000040, 0x000000a3, 0x0000009e, + 0x00000081, 0x000000f3, 0x000000d7, 0x000000fb, + 0x0000007c, 0x000000e3, 0x00000039, 0x00000082, + 0x0000009b, 0x0000002f, 0x000000ff, 0x00000087, + 0x00000034, 0x0000008e, 0x00000043, 0x00000044, + 0x000000c4, 0x000000de, 0x000000e9, 0x000000cb, + 0x00000054, 0x0000007b, 0x00000094, 0x00000032, + 0x000000a6, 0x000000c2, 0x00000023, 0x0000003d, + 0x000000ee, 0x0000004c, 0x00000095, 0x0000000b, + 0x00000042, 0x000000fa, 0x000000c3, 0x0000004e, + 0x00000008, 0x0000002e, 0x000000a1, 0x00000066, + 0x00000028, 0x000000d9, 0x00000024, 0x000000b2, + 0x00000076, 0x0000005b, 0x000000a2, 0x00000049, + 0x0000006d, 0x0000008b, 0x000000d1, 0x00000025, + 0x00000072, 0x000000f8, 0x000000f6, 0x00000064, + 0x00000086, 0x00000068, 0x00000098, 0x00000016, + 0x000000d4, 0x000000a4, 0x0000005c, 0x000000cc, + 0x0000005d, 0x00000065, 0x000000b6, 0x00000092, + 0x0000006c, 0x00000070, 0x00000048, 0x00000050, + 0x000000fd, 0x000000ed, 0x000000b9, 0x000000da, + 0x0000005e, 0x00000015, 0x00000046, 0x00000057, + 0x000000a7, 0x0000008d, 0x0000009d, 0x00000084, + 0x00000090, 0x000000d8, 0x000000ab, 0x00000000, + 0x0000008c, 0x000000bc, 0x000000d3, 0x0000000a, + 0x000000f7, 0x000000e4, 0x00000058, 0x00000005, + 0x000000b8, 0x000000b3, 0x00000045, 0x00000006, + 0x000000d0, 0x0000002c, 0x0000001e, 0x0000008f, + 0x000000ca, 0x0000003f, 0x0000000f, 0x00000002, + 0x000000c1, 0x000000af, 0x000000bd, 0x00000003, + 0x00000001, 0x00000013, 0x0000008a, 0x0000006b, + 0x0000003a, 0x00000091, 0x00000011, 0x00000041, + 0x0000004f, 0x00000067, 0x000000dc, 0x000000ea, + 0x00000097, 0x000000f2, 0x000000cf, 0x000000ce, + 0x000000f0, 0x000000b4, 0x000000e6, 0x00000073, + 0x00000096, 0x000000ac, 0x00000074, 0x00000022, + 0x000000e7, 0x000000ad, 0x00000035, 0x00000085, + 0x000000e2, 0x000000f9, 0x00000037, 0x000000e8, + 0x0000001c, 0x00000075, 0x000000df, 0x0000006e, + 0x00000047, 0x000000f1, 0x0000001a, 0x00000071, + 0x0000001d, 0x00000029, 0x000000c5, 0x00000089, + 0x0000006f, 0x000000b7, 0x00000062, 0x0000000e, + 0x000000aa, 0x00000018, 0x000000be, 0x0000001b, + 0x000000fc, 0x00000056, 0x0000003e, 0x0000004b, + 0x000000c6, 0x000000d2, 0x00000079, 0x00000020, + 0x0000009a, 0x000000db, 0x000000c0, 0x000000fe, + 0x00000078, 0x000000cd, 0x0000005a, 0x000000f4, + 0x0000001f, 0x000000dd, 0x000000a8, 0x00000033, + 0x00000088, 0x00000007, 0x000000c7, 0x00000031, + 0x000000b1, 0x00000012, 0x00000010, 0x00000059, + 0x00000027, 0x00000080, 0x000000ec, 0x0000005f, + 0x00000060, 0x00000051, 0x0000007f, 0x000000a9, + 0x00000019, 0x000000b5, 0x0000004a, 0x0000000d, + 0x0000002d, 0x000000e5, 0x0000007a, 0x0000009f, + 0x00000093, 0x000000c9, 0x0000009c, 0x000000ef, + 0x000000a0, 0x000000e0, 0x0000003b, 0x0000004d, + 0x000000ae, 0x0000002a, 0x000000f5, 0x000000b0, + 0x000000c8, 0x000000eb, 0x000000bb, 0x0000003c, + 0x00000083, 0x00000053, 0x00000099, 0x00000061, + 0x00000017, 0x0000002b, 0x00000004, 0x0000007e, + 0x000000ba, 0x00000077, 0x000000d6, 0x00000026, + 0x000000e1, 0x00000069, 0x00000014, 0x00000063, + 0x00000055, 0x00000021, 0x0000000c, 0x0000007d +}, { + 0x00005200, 0x00000900, 0x00006a00, 0x0000d500, + 0x00003000, 0x00003600, 0x0000a500, 0x00003800, + 0x0000bf00, 0x00004000, 0x0000a300, 0x00009e00, + 0x00008100, 0x0000f300, 0x0000d700, 0x0000fb00, + 0x00007c00, 0x0000e300, 0x00003900, 0x00008200, + 0x00009b00, 0x00002f00, 0x0000ff00, 0x00008700, + 0x00003400, 0x00008e00, 0x00004300, 0x00004400, + 0x0000c400, 0x0000de00, 0x0000e900, 0x0000cb00, + 0x00005400, 0x00007b00, 0x00009400, 0x00003200, + 0x0000a600, 0x0000c200, 0x00002300, 0x00003d00, + 0x0000ee00, 0x00004c00, 0x00009500, 0x00000b00, + 0x00004200, 0x0000fa00, 0x0000c300, 0x00004e00, + 0x00000800, 0x00002e00, 0x0000a100, 0x00006600, + 0x00002800, 0x0000d900, 0x00002400, 0x0000b200, + 0x00007600, 0x00005b00, 0x0000a200, 0x00004900, + 0x00006d00, 0x00008b00, 0x0000d100, 0x00002500, + 0x00007200, 0x0000f800, 0x0000f600, 0x00006400, + 0x00008600, 0x00006800, 0x00009800, 0x00001600, + 0x0000d400, 0x0000a400, 0x00005c00, 0x0000cc00, + 0x00005d00, 0x00006500, 0x0000b600, 0x00009200, + 0x00006c00, 0x00007000, 0x00004800, 0x00005000, + 0x0000fd00, 0x0000ed00, 0x0000b900, 0x0000da00, + 0x00005e00, 0x00001500, 0x00004600, 0x00005700, + 0x0000a700, 0x00008d00, 0x00009d00, 0x00008400, + 0x00009000, 0x0000d800, 0x0000ab00, 0x00000000, + 0x00008c00, 0x0000bc00, 0x0000d300, 0x00000a00, + 0x0000f700, 0x0000e400, 0x00005800, 0x00000500, + 0x0000b800, 0x0000b300, 0x00004500, 0x00000600, + 0x0000d000, 0x00002c00, 0x00001e00, 0x00008f00, + 0x0000ca00, 0x00003f00, 0x00000f00, 0x00000200, + 0x0000c100, 0x0000af00, 0x0000bd00, 0x00000300, + 0x00000100, 0x00001300, 0x00008a00, 0x00006b00, + 0x00003a00, 0x00009100, 0x00001100, 0x00004100, + 0x00004f00, 0x00006700, 0x0000dc00, 0x0000ea00, + 0x00009700, 0x0000f200, 0x0000cf00, 0x0000ce00, + 0x0000f000, 0x0000b400, 0x0000e600, 0x00007300, + 0x00009600, 0x0000ac00, 0x00007400, 0x00002200, + 0x0000e700, 0x0000ad00, 0x00003500, 0x00008500, + 0x0000e200, 0x0000f900, 0x00003700, 0x0000e800, + 0x00001c00, 0x00007500, 0x0000df00, 0x00006e00, + 0x00004700, 0x0000f100, 0x00001a00, 0x00007100, + 0x00001d00, 0x00002900, 0x0000c500, 0x00008900, + 0x00006f00, 0x0000b700, 0x00006200, 0x00000e00, + 0x0000aa00, 0x00001800, 0x0000be00, 0x00001b00, + 0x0000fc00, 0x00005600, 0x00003e00, 0x00004b00, + 0x0000c600, 0x0000d200, 0x00007900, 0x00002000, + 0x00009a00, 0x0000db00, 0x0000c000, 0x0000fe00, + 0x00007800, 0x0000cd00, 0x00005a00, 0x0000f400, + 0x00001f00, 0x0000dd00, 0x0000a800, 0x00003300, + 0x00008800, 0x00000700, 0x0000c700, 0x00003100, + 0x0000b100, 0x00001200, 0x00001000, 0x00005900, + 0x00002700, 0x00008000, 0x0000ec00, 0x00005f00, + 0x00006000, 0x00005100, 0x00007f00, 0x0000a900, + 0x00001900, 0x0000b500, 0x00004a00, 0x00000d00, + 0x00002d00, 0x0000e500, 0x00007a00, 0x00009f00, + 0x00009300, 0x0000c900, 0x00009c00, 0x0000ef00, + 0x0000a000, 0x0000e000, 0x00003b00, 0x00004d00, + 0x0000ae00, 0x00002a00, 0x0000f500, 0x0000b000, + 0x0000c800, 0x0000eb00, 0x0000bb00, 0x00003c00, + 0x00008300, 0x00005300, 0x00009900, 0x00006100, + 0x00001700, 0x00002b00, 0x00000400, 0x00007e00, + 0x0000ba00, 0x00007700, 0x0000d600, 0x00002600, + 0x0000e100, 0x00006900, 0x00001400, 0x00006300, + 0x00005500, 0x00002100, 0x00000c00, 0x00007d00 +}, { + 0x00520000, 0x00090000, 0x006a0000, 0x00d50000, + 0x00300000, 0x00360000, 0x00a50000, 0x00380000, + 0x00bf0000, 0x00400000, 0x00a30000, 0x009e0000, + 0x00810000, 0x00f30000, 0x00d70000, 0x00fb0000, + 0x007c0000, 0x00e30000, 0x00390000, 0x00820000, + 0x009b0000, 0x002f0000, 0x00ff0000, 0x00870000, + 0x00340000, 0x008e0000, 0x00430000, 0x00440000, + 0x00c40000, 0x00de0000, 0x00e90000, 0x00cb0000, + 0x00540000, 0x007b0000, 0x00940000, 0x00320000, + 0x00a60000, 0x00c20000, 0x00230000, 0x003d0000, + 0x00ee0000, 0x004c0000, 0x00950000, 0x000b0000, + 0x00420000, 0x00fa0000, 0x00c30000, 0x004e0000, + 0x00080000, 0x002e0000, 0x00a10000, 0x00660000, + 0x00280000, 0x00d90000, 0x00240000, 0x00b20000, + 0x00760000, 0x005b0000, 0x00a20000, 0x00490000, + 0x006d0000, 0x008b0000, 0x00d10000, 0x00250000, + 0x00720000, 0x00f80000, 0x00f60000, 0x00640000, + 0x00860000, 0x00680000, 0x00980000, 0x00160000, + 0x00d40000, 0x00a40000, 0x005c0000, 0x00cc0000, + 0x005d0000, 0x00650000, 0x00b60000, 0x00920000, + 0x006c0000, 0x00700000, 0x00480000, 0x00500000, + 0x00fd0000, 0x00ed0000, 0x00b90000, 0x00da0000, + 0x005e0000, 0x00150000, 0x00460000, 0x00570000, + 0x00a70000, 0x008d0000, 0x009d0000, 0x00840000, + 0x00900000, 0x00d80000, 0x00ab0000, 0x00000000, + 0x008c0000, 0x00bc0000, 0x00d30000, 0x000a0000, + 0x00f70000, 0x00e40000, 0x00580000, 0x00050000, + 0x00b80000, 0x00b30000, 0x00450000, 0x00060000, + 0x00d00000, 0x002c0000, 0x001e0000, 0x008f0000, + 0x00ca0000, 0x003f0000, 0x000f0000, 0x00020000, + 0x00c10000, 0x00af0000, 0x00bd0000, 0x00030000, + 0x00010000, 0x00130000, 0x008a0000, 0x006b0000, + 0x003a0000, 0x00910000, 0x00110000, 0x00410000, + 0x004f0000, 0x00670000, 0x00dc0000, 0x00ea0000, + 0x00970000, 0x00f20000, 0x00cf0000, 0x00ce0000, + 0x00f00000, 0x00b40000, 0x00e60000, 0x00730000, + 0x00960000, 0x00ac0000, 0x00740000, 0x00220000, + 0x00e70000, 0x00ad0000, 0x00350000, 0x00850000, + 0x00e20000, 0x00f90000, 0x00370000, 0x00e80000, + 0x001c0000, 0x00750000, 0x00df0000, 0x006e0000, + 0x00470000, 0x00f10000, 0x001a0000, 0x00710000, + 0x001d0000, 0x00290000, 0x00c50000, 0x00890000, + 0x006f0000, 0x00b70000, 0x00620000, 0x000e0000, + 0x00aa0000, 0x00180000, 0x00be0000, 0x001b0000, + 0x00fc0000, 0x00560000, 0x003e0000, 0x004b0000, + 0x00c60000, 0x00d20000, 0x00790000, 0x00200000, + 0x009a0000, 0x00db0000, 0x00c00000, 0x00fe0000, + 0x00780000, 0x00cd0000, 0x005a0000, 0x00f40000, + 0x001f0000, 0x00dd0000, 0x00a80000, 0x00330000, + 0x00880000, 0x00070000, 0x00c70000, 0x00310000, + 0x00b10000, 0x00120000, 0x00100000, 0x00590000, + 0x00270000, 0x00800000, 0x00ec0000, 0x005f0000, + 0x00600000, 0x00510000, 0x007f0000, 0x00a90000, + 0x00190000, 0x00b50000, 0x004a0000, 0x000d0000, + 0x002d0000, 0x00e50000, 0x007a0000, 0x009f0000, + 0x00930000, 0x00c90000, 0x009c0000, 0x00ef0000, + 0x00a00000, 0x00e00000, 0x003b0000, 0x004d0000, + 0x00ae0000, 0x002a0000, 0x00f50000, 0x00b00000, + 0x00c80000, 0x00eb0000, 0x00bb0000, 0x003c0000, + 0x00830000, 0x00530000, 0x00990000, 0x00610000, + 0x00170000, 0x002b0000, 0x00040000, 0x007e0000, + 0x00ba0000, 0x00770000, 0x00d60000, 0x00260000, + 0x00e10000, 0x00690000, 0x00140000, 0x00630000, + 0x00550000, 0x00210000, 0x000c0000, 0x007d0000 +}, { + 0x52000000, 0x09000000, 0x6a000000, 0xd5000000, + 0x30000000, 0x36000000, 0xa5000000, 0x38000000, + 0xbf000000, 0x40000000, 0xa3000000, 0x9e000000, + 0x81000000, 0xf3000000, 0xd7000000, 0xfb000000, + 0x7c000000, 0xe3000000, 0x39000000, 0x82000000, + 0x9b000000, 0x2f000000, 0xff000000, 0x87000000, + 0x34000000, 0x8e000000, 0x43000000, 0x44000000, + 0xc4000000, 0xde000000, 0xe9000000, 0xcb000000, + 0x54000000, 0x7b000000, 0x94000000, 0x32000000, + 0xa6000000, 0xc2000000, 0x23000000, 0x3d000000, + 0xee000000, 0x4c000000, 0x95000000, 0x0b000000, + 0x42000000, 0xfa000000, 0xc3000000, 0x4e000000, + 0x08000000, 0x2e000000, 0xa1000000, 0x66000000, + 0x28000000, 0xd9000000, 0x24000000, 0xb2000000, + 0x76000000, 0x5b000000, 0xa2000000, 0x49000000, + 0x6d000000, 0x8b000000, 0xd1000000, 0x25000000, + 0x72000000, 0xf8000000, 0xf6000000, 0x64000000, + 0x86000000, 0x68000000, 0x98000000, 0x16000000, + 0xd4000000, 0xa4000000, 0x5c000000, 0xcc000000, + 0x5d000000, 0x65000000, 0xb6000000, 0x92000000, + 0x6c000000, 0x70000000, 0x48000000, 0x50000000, + 0xfd000000, 0xed000000, 0xb9000000, 0xda000000, + 0x5e000000, 0x15000000, 0x46000000, 0x57000000, + 0xa7000000, 0x8d000000, 0x9d000000, 0x84000000, + 0x90000000, 0xd8000000, 0xab000000, 0x00000000, + 0x8c000000, 0xbc000000, 0xd3000000, 0x0a000000, + 0xf7000000, 0xe4000000, 0x58000000, 0x05000000, + 0xb8000000, 0xb3000000, 0x45000000, 0x06000000, + 0xd0000000, 0x2c000000, 0x1e000000, 0x8f000000, + 0xca000000, 0x3f000000, 0x0f000000, 0x02000000, + 0xc1000000, 0xaf000000, 0xbd000000, 0x03000000, + 0x01000000, 0x13000000, 0x8a000000, 0x6b000000, + 0x3a000000, 0x91000000, 0x11000000, 0x41000000, + 0x4f000000, 0x67000000, 0xdc000000, 0xea000000, + 0x97000000, 0xf2000000, 0xcf000000, 0xce000000, + 0xf0000000, 0xb4000000, 0xe6000000, 0x73000000, + 0x96000000, 0xac000000, 0x74000000, 0x22000000, + 0xe7000000, 0xad000000, 0x35000000, 0x85000000, + 0xe2000000, 0xf9000000, 0x37000000, 0xe8000000, + 0x1c000000, 0x75000000, 0xdf000000, 0x6e000000, + 0x47000000, 0xf1000000, 0x1a000000, 0x71000000, + 0x1d000000, 0x29000000, 0xc5000000, 0x89000000, + 0x6f000000, 0xb7000000, 0x62000000, 0x0e000000, + 0xaa000000, 0x18000000, 0xbe000000, 0x1b000000, + 0xfc000000, 0x56000000, 0x3e000000, 0x4b000000, + 0xc6000000, 0xd2000000, 0x79000000, 0x20000000, + 0x9a000000, 0xdb000000, 0xc0000000, 0xfe000000, + 0x78000000, 0xcd000000, 0x5a000000, 0xf4000000, + 0x1f000000, 0xdd000000, 0xa8000000, 0x33000000, + 0x88000000, 0x07000000, 0xc7000000, 0x31000000, + 0xb1000000, 0x12000000, 0x10000000, 0x59000000, + 0x27000000, 0x80000000, 0xec000000, 0x5f000000, + 0x60000000, 0x51000000, 0x7f000000, 0xa9000000, + 0x19000000, 0xb5000000, 0x4a000000, 0x0d000000, + 0x2d000000, 0xe5000000, 0x7a000000, 0x9f000000, + 0x93000000, 0xc9000000, 0x9c000000, 0xef000000, + 0xa0000000, 0xe0000000, 0x3b000000, 0x4d000000, + 0xae000000, 0x2a000000, 0xf5000000, 0xb0000000, + 0xc8000000, 0xeb000000, 0xbb000000, 0x3c000000, + 0x83000000, 0x53000000, 0x99000000, 0x61000000, + 0x17000000, 0x2b000000, 0x04000000, 0x7e000000, + 0xba000000, 0x77000000, 0xd6000000, 0x26000000, + 0xe1000000, 0x69000000, 0x14000000, 0x63000000, + 0x55000000, 0x21000000, 0x0c000000, 0x7d000000 +} +}; + +static const u4byte rco_tab[10] = { + 0x00000001, 0x00000002, 0x00000004, 0x00000008, 0x00000010, + 0x00000020, 0x00000040, 0x00000080, 0x0000001b, 0x00000036 +}; diff --git a/src/modules/tls/fortuna/sha256.c b/src/modules/tls/fortuna/sha256.c new file mode 100644 index 00000000000..a0e23c080e8 --- /dev/null +++ b/src/modules/tls/fortuna/sha256.c @@ -0,0 +1,1069 @@ +/* + * FILE: sha256.c + * AUTHOR: Aaron D. Gifford - http://www.aarongifford.com/ + * + * Copyright (c) 2000-2001, Aaron D. Gifford + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided w627ith the distribution. + * 3. Neither the name of the copyright holder nor the names of contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTOR(S) ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTOR(S) BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ + +#include /* memcpy()/memset() or bcopy()/bzero() */ +#include /* assert() */ +#include "sha256.h" + +/* discover byte order on solaris */ +#if defined(__SVR4) || defined(__sun) + #include + #define BYTE_ORDER _BYTE_ORDER +#endif + +/* + * ASSERT NOTE: + * Some sanity checking code is included using assert(). On my FreeBSD + * system, this additional code can be removed by compiling with NDEBUG + * defined. Check your own systems manpage on assert() to see how to + * compile WITHOUT the sanity checking code on your system. + * + * UNROLLED TRANSFORM LOOP NOTE: + * You can define SHA2_UNROLL_TRANSFORM to use the unrolled transform + * loop version for the hash transform rounds (defined using macros + * later in this file). Either define on the command line, for example: + * + * cc -DSHA2_UNROLL_TRANSFORM -o sha2 sha2.c sha2prog.c + * + * or define below: + * + * #define SHA2_UNROLL_TRANSFORM + * + */ + + +/*** SHA-256/384/512 Machine Architecture Definitions *****************/ +/* + * BYTE_ORDER NOTE: + * + * Please make sure that your system defines BYTE_ORDER. If your + * architecture is little-endian, make sure it also defines + * LITTLE_ENDIAN and that the two (BYTE_ORDER and LITTLE_ENDIAN) are + * equivilent. + * + * If your system does not define the above, then you can do so by + * hand like this: + * + * #define LITTLE_ENDIAN 1234 + * #define BIG_ENDIAN 4321 + * + * And for little-endian machines, add: + * + * #define BYTE_ORDER LITTLE_ENDIAN + * + * Or for big-endian machines: + * + * #define BYTE_ORDER BIG_ENDIAN + * + * The FreeBSD machine this was written on defines BYTE_ORDER + * appropriately by including (which in turn includes + * where the appropriate definitions are actually + * made). + */ +#if !defined(BYTE_ORDER) || (BYTE_ORDER != LITTLE_ENDIAN && BYTE_ORDER != BIG_ENDIAN) +#error Define BYTE_ORDER to be equal to either LITTLE_ENDIAN or BIG_ENDIAN +#endif + +/* + * Define the followingsha2_* types to types of the correct length on + * the native archtecture. Most BSD systems and Linux define u_intXX_t + * types. Machines with very recent ANSI C headers, can use the + * uintXX_t definintions from inttypes.h by defining SHA2_USE_INTTYPES_H + * during compile or in the sha.h header file. + * + * Machines that support neither u_intXX_t nor inttypes.h's uintXX_t + * will need to define these three typedefs below (and the appropriate + * ones in sha.h too) by hand according to their system architecture. + * + * Thank you, Jun-ichiro itojun Hagino, for suggesting using u_intXX_t + * types and pointing out recent ANSI C support for uintXX_t in inttypes.h. + */ +#ifdef SHA2_USE_INTTYPES_H + +typedef uint8_t sha2_byte; /* Exactly 1 byte */ +typedef uint32_t sha2_word32; /* Exactly 4 bytes */ +typedef uint64_t sha2_word64; /* Exactly 8 bytes */ + +#else /* SHA2_USE_INTTYPES_H */ + +typedef u_int8_t sha2_byte; /* Exactly 1 byte */ +typedef u_int32_t sha2_word32; /* Exactly 4 bytes */ +typedef u_int64_t sha2_word64; /* Exactly 8 bytes */ + +#endif /* SHA2_USE_INTTYPES_H */ + + +/*** SHA-256/384/512 Various Length Definitions ***********************/ +/* NOTE: Most of these are in sha2.h */ +#define SHA256_SHORT_BLOCK_LENGTH (SHA256_BLOCK_LENGTH - 8) +#define SHA384_SHORT_BLOCK_LENGTH (SHA384_BLOCK_LENGTH - 16) +#define SHA512_SHORT_BLOCK_LENGTH (SHA512_BLOCK_LENGTH - 16) + + +/*** ENDIAN REVERSAL MACROS *******************************************/ +#if BYTE_ORDER == LITTLE_ENDIAN +#define REVERSE32(w,x) { \ + sha2_word32 tmp = (w); \ + tmp = (tmp >> 16) | (tmp << 16); \ + (x) = ((tmp & 0xff00ff00UL) >> 8) | ((tmp & 0x00ff00ffUL) << 8); \ +} +#define REVERSE64(w,x) { \ + sha2_word64 tmp = (w); \ + tmp = (tmp >> 32) | (tmp << 32); \ + tmp = ((tmp & 0xff00ff00ff00ff00ULL) >> 8) | \ + ((tmp & 0x00ff00ff00ff00ffULL) << 8); \ + (x) = ((tmp & 0xffff0000ffff0000ULL) >> 16) | \ + ((tmp & 0x0000ffff0000ffffULL) << 16); \ +} +#endif /* BYTE_ORDER == LITTLE_ENDIAN */ + +/* + * Macro for incrementally adding the unsigned 64-bit integer n to the + * unsigned 128-bit integer (represented using a two-element array of + * 64-bit words): + */ +#define ADDINC128(w,n) { \ + (w)[0] += (sha2_word64)(n); \ + if ((w)[0] < (n)) { \ + (w)[1]++; \ + } \ +} + +/* + * Macros for copying blocks of memory and for zeroing out ranges + * of memory. Using these macros makes it easy to switch from + * using memset()/memcpy() and using bzero()/bcopy(). + * + * Please define either SHA2_USE_MEMSET_MEMCPY or define + * SHA2_USE_BZERO_BCOPY depending on which function set you + * choose to use: + */ +#if !defined(SHA2_USE_MEMSET_MEMCPY) && !defined(SHA2_USE_BZERO_BCOPY) +/* Default to memset()/memcpy() if no option is specified */ +#define SHA2_USE_MEMSET_MEMCPY 1 +#endif +#if defined(SHA2_USE_MEMSET_MEMCPY) && defined(SHA2_USE_BZERO_BCOPY) +/* Abort with an error if BOTH options are defined */ +#error Define either SHA2_USE_MEMSET_MEMCPY or SHA2_USE_BZERO_BCOPY, not both! +#endif + +#ifdef SHA2_USE_MEMSET_MEMCPY +#define MEMSET_BZERO(p,l) memset((p), 0, (l)) +#define MEMCPY_BCOPY(d,s,l) memcpy((d), (s), (l)) +#endif +#ifdef SHA2_USE_BZERO_BCOPY +#define MEMSET_BZERO(p,l) bzero((p), (l)) +#define MEMCPY_BCOPY(d,s,l) bcopy((s), (d), (l)) +#endif + + +/*** THE SIX LOGICAL FUNCTIONS ****************************************/ +/* + * Bit shifting and rotation (used by the six SHA-XYZ logical functions: + * + * NOTE: The naming of R and S appears backwards here (R is a SHIFT and + * S is a ROTATION) because the SHA-256/384/512 description document + * (see http://csrc.nist.gov/cryptval/shs/sha256-384-512.pdf) uses this + * same "backwards" definition. + */ +/* Shift-right (used in SHA-256, SHA-384, and SHA-512): */ +#define R(b,x) ((x) >> (b)) +/* 32-bit Rotate-right (used in SHA-256): */ +#define S32(b,x) (((x) >> (b)) | ((x) << (32 - (b)))) +/* 64-bit Rotate-right (used in SHA-384 and SHA-512): */ +#define S64(b,x) (((x) >> (b)) | ((x) << (64 - (b)))) + +/* Two of six logical functions used in SHA-256, SHA-384, and SHA-512: */ +#define Ch(x,y,z) (((x) & (y)) ^ ((~(x)) & (z))) +#define Maj(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z))) + +/* Four of six logical functions used in SHA-256: */ +#define Sigma0_256(x) (S32(2, (x)) ^ S32(13, (x)) ^ S32(22, (x))) +#define Sigma1_256(x) (S32(6, (x)) ^ S32(11, (x)) ^ S32(25, (x))) +#define sigma0_256(x) (S32(7, (x)) ^ S32(18, (x)) ^ R(3 , (x))) +#define sigma1_256(x) (S32(17, (x)) ^ S32(19, (x)) ^ R(10, (x))) + +/* Four of six logical functions used in SHA-384 and SHA-512: */ +#define Sigma0_512(x) (S64(28, (x)) ^ S64(34, (x)) ^ S64(39, (x))) +#define Sigma1_512(x) (S64(14, (x)) ^ S64(18, (x)) ^ S64(41, (x))) +#define sigma0_512(x) (S64( 1, (x)) ^ S64( 8, (x)) ^ R( 7, (x))) +#define sigma1_512(x) (S64(19, (x)) ^ S64(61, (x)) ^ R( 6, (x))) + +/*** INTERNAL FUNCTION PROTOTYPES *************************************/ +/* NOTE: These should not be accessed directly from outside this + * library -- they are intended for private internal visibility/use + * only. + */ +void SHA512_Last(SHA512_CTX*); +void SHA256_Transform(SHA256_CTX*, const sha2_word32*); +void SHA512_Transform(SHA512_CTX*, const sha2_word64*); + + +/*** SHA-XYZ INITIAL HASH VALUES AND CONSTANTS ************************/ +/* Hash constant words K for SHA-256: */ +const static sha2_word32 K256[64] = { + 0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL, + 0x3956c25bUL, 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL, + 0xd807aa98UL, 0x12835b01UL, 0x243185beUL, 0x550c7dc3UL, + 0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL, 0xc19bf174UL, + 0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL, + 0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL, + 0x983e5152UL, 0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL, + 0xc6e00bf3UL, 0xd5a79147UL, 0x06ca6351UL, 0x14292967UL, + 0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL, 0x53380d13UL, + 0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL, + 0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL, + 0xd192e819UL, 0xd6990624UL, 0xf40e3585UL, 0x106aa070UL, + 0x19a4c116UL, 0x1e376c08UL, 0x2748774cUL, 0x34b0bcb5UL, + 0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL, 0x682e6ff3UL, + 0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL, + 0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL +}; + +/* Initial hash value H for SHA-256: */ +const static sha2_word32 sha256_initial_hash_value[8] = { + 0x6a09e667UL, + 0xbb67ae85UL, + 0x3c6ef372UL, + 0xa54ff53aUL, + 0x510e527fUL, + 0x9b05688cUL, + 0x1f83d9abUL, + 0x5be0cd19UL +}; + +/* Hash constant words K for SHA-384 and SHA-512: */ +const static sha2_word64 K512[80] = { + 0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL, + 0xb5c0fbcfec4d3b2fULL, 0xe9b5dba58189dbbcULL, + 0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL, + 0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL, + 0xd807aa98a3030242ULL, 0x12835b0145706fbeULL, + 0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL, + 0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL, + 0x9bdc06a725c71235ULL, 0xc19bf174cf692694ULL, + 0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL, + 0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL, + 0x2de92c6f592b0275ULL, 0x4a7484aa6ea6e483ULL, + 0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL, + 0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL, + 0xb00327c898fb213fULL, 0xbf597fc7beef0ee4ULL, + 0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL, + 0x06ca6351e003826fULL, 0x142929670a0e6e70ULL, + 0x27b70a8546d22ffcULL, 0x2e1b21385c26c926ULL, + 0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL, + 0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL, + 0x81c2c92e47edaee6ULL, 0x92722c851482353bULL, + 0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL, + 0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL, + 0xd192e819d6ef5218ULL, 0xd69906245565a910ULL, + 0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL, + 0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL, + 0x2748774cdf8eeb99ULL, 0x34b0bcb5e19b48a8ULL, + 0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL, + 0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL, + 0x748f82ee5defb2fcULL, 0x78a5636f43172f60ULL, + 0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL, + 0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL, + 0xbef9a3f7b2c67915ULL, 0xc67178f2e372532bULL, + 0xca273eceea26619cULL, 0xd186b8c721c0c207ULL, + 0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL, + 0x06f067aa72176fbaULL, 0x0a637dc5a2c898a6ULL, + 0x113f9804bef90daeULL, 0x1b710b35131c471bULL, + 0x28db77f523047d84ULL, 0x32caab7b40c72493ULL, + 0x3c9ebe0a15c9bebcULL, 0x431d67c49c100d4cULL, + 0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL, + 0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL +}; + +/* Initial hash value H for SHA-384 */ +const static sha2_word64 sha384_initial_hash_value[8] = { + 0xcbbb9d5dc1059ed8ULL, + 0x629a292a367cd507ULL, + 0x9159015a3070dd17ULL, + 0x152fecd8f70e5939ULL, + 0x67332667ffc00b31ULL, + 0x8eb44a8768581511ULL, + 0xdb0c2e0d64f98fa7ULL, + 0x47b5481dbefa4fa4ULL +}; + +/* Initial hash value H for SHA-512 */ +const static sha2_word64 sha512_initial_hash_value[8] = { + 0x6a09e667f3bcc908ULL, + 0xbb67ae8584caa73bULL, + 0x3c6ef372fe94f82bULL, + 0xa54ff53a5f1d36f1ULL, + 0x510e527fade682d1ULL, + 0x9b05688c2b3e6c1fULL, + 0x1f83d9abfb41bd6bULL, + 0x5be0cd19137e2179ULL +}; + +/* + * Constant used by SHA256/384/512_End() functions for converting the + * digest to a readable hexadecimal character string: + */ +static const char *sha2_hex_digits = "0123456789abcdef"; + + +/*** SHA-256: *********************************************************/ +void sr_SHA256_Init(SHA256_CTX* context) { + if (context == (SHA256_CTX*)0) { + return; + } + MEMCPY_BCOPY(context->state, sha256_initial_hash_value, SHA256_DIGEST_LENGTH); + MEMSET_BZERO(context->buffer, SHA256_BLOCK_LENGTH); + context->bitcount = 0; +} + +#ifdef SHA2_UNROLL_TRANSFORM + +/* Unrolled SHA-256 round macros: */ + +#if BYTE_ORDER == LITTLE_ENDIAN + +#define ROUND256_0_TO_15(a,b,c,d,e,f,g,h) \ + REVERSE32(*data++, W256[j]); \ + T1 = (h) + Sigma1_256(e) + Ch((e), (f), (g)) + \ + K256[j] + W256[j]; \ + (d) += T1; \ + (h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \ + j++ + + +#else /* BYTE_ORDER == LITTLE_ENDIAN */ + +#define ROUND256_0_TO_15(a,b,c,d,e,f,g,h) \ + T1 = (h) + Sigma1_256(e) + Ch((e), (f), (g)) + \ + K256[j] + (W256[j] = *data++); \ + (d) += T1; \ + (h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \ + j++ + +#endif /* BYTE_ORDER == LITTLE_ENDIAN */ + +#define ROUND256(a,b,c,d,e,f,g,h) \ + s0 = W256[(j+1)&0x0f]; \ + s0 = sigma0_256(s0); \ + s1 = W256[(j+14)&0x0f]; \ + s1 = sigma1_256(s1); \ + T1 = (h) + Sigma1_256(e) + Ch((e), (f), (g)) + K256[j] + \ + (W256[j&0x0f] += s1 + W256[(j+9)&0x0f] + s0); \ + (d) += T1; \ + (h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \ + j++ + +void SHA256_Transform(SHA256_CTX* context, const sha2_word32* data) { + sha2_word32 a, b, c, d, e, f, g, h, s0, s1; + sha2_word32 T1, *W256; + int j; + + W256 = (sha2_word32*)context->buffer; + + /* Initialize registers with the prev. intermediate value */ + a = context->state[0]; + b = context->state[1]; + c = context->state[2]; + d = context->state[3]; + e = context->state[4]; + f = context->state[5]; + g = context->state[6]; + h = context->state[7]; + + j = 0; + do { + /* Rounds 0 to 15 (unrolled): */ + ROUND256_0_TO_15(a,b,c,d,e,f,g,h); + ROUND256_0_TO_15(h,a,b,c,d,e,f,g); + ROUND256_0_TO_15(g,h,a,b,c,d,e,f); + ROUND256_0_TO_15(f,g,h,a,b,c,d,e); + ROUND256_0_TO_15(e,f,g,h,a,b,c,d); + ROUND256_0_TO_15(d,e,f,g,h,a,b,c); + ROUND256_0_TO_15(c,d,e,f,g,h,a,b); + ROUND256_0_TO_15(b,c,d,e,f,g,h,a); + } while (j < 16); + + /* Now for the remaining rounds to 64: */ + do { + ROUND256(a,b,c,d,e,f,g,h); + ROUND256(h,a,b,c,d,e,f,g); + ROUND256(g,h,a,b,c,d,e,f); + ROUND256(f,g,h,a,b,c,d,e); + ROUND256(e,f,g,h,a,b,c,d); + ROUND256(d,e,f,g,h,a,b,c); + ROUND256(c,d,e,f,g,h,a,b); + ROUND256(b,c,d,e,f,g,h,a); + } while (j < 64); + + /* Compute the current intermediate hash value */ + context->state[0] += a; + context->state[1] += b; + context->state[2] += c; + context->state[3] += d; + context->state[4] += e; + context->state[5] += f; + context->state[6] += g; + context->state[7] += h; + + /* Clean up */ + a = b = c = d = e = f = g = h = T1 = 0; +} + +#else /* SHA2_UNROLL_TRANSFORM */ + +void SHA256_Transform(SHA256_CTX* context, const sha2_word32* data) { + sha2_word32 a, b, c, d, e, f, g, h, s0, s1; + sha2_word32 T1, T2, *W256; + int j; + + W256 = (sha2_word32*)context->buffer; + + /* Initialize registers with the prev. intermediate value */ + a = context->state[0]; + b = context->state[1]; + c = context->state[2]; + d = context->state[3]; + e = context->state[4]; + f = context->state[5]; + g = context->state[6]; + h = context->state[7]; + + j = 0; + do { +#if BYTE_ORDER == LITTLE_ENDIAN + /* Copy data while converting to host byte order */ + REVERSE32(*data++,W256[j]); + /* Apply the SHA-256 compression function to update a..h */ + T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] + W256[j]; +#else /* BYTE_ORDER == LITTLE_ENDIAN */ + /* Apply the SHA-256 compression function to update a..h with copy */ + T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] + (W256[j] = *data++); +#endif /* BYTE_ORDER == LITTLE_ENDIAN */ + T2 = Sigma0_256(a) + Maj(a, b, c); + h = g; + g = f; + f = e; + e = d + T1; + d = c; + c = b; + b = a; + a = T1 + T2; + + j++; + } while (j < 16); + + do { + /* Part of the message block expansion: */ + s0 = W256[(j+1)&0x0f]; + s0 = sigma0_256(s0); + s1 = W256[(j+14)&0x0f]; + s1 = sigma1_256(s1); + + /* Apply the SHA-256 compression function to update a..h */ + T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] + + (W256[j&0x0f] += s1 + W256[(j+9)&0x0f] + s0); + T2 = Sigma0_256(a) + Maj(a, b, c); + h = g; + g = f; + f = e; + e = d + T1; + d = c; + c = b; + b = a; + a = T1 + T2; + + j++; + } while (j < 64); + + /* Compute the current intermediate hash value */ + context->state[0] += a; + context->state[1] += b; + context->state[2] += c; + context->state[3] += d; + context->state[4] += e; + context->state[5] += f; + context->state[6] += g; + context->state[7] += h; + + /* Clean up */ + a = b = c = d = e = f = g = h = T1 = T2 = 0; +} + +#endif /* SHA2_UNROLL_TRANSFORM */ + +void sr_SHA256_Update(SHA256_CTX* context, const sha2_byte *data, size_t len) { + unsigned int freespace, usedspace; + + if (len == 0) { + /* Calling with no data is valid - we do nothing */ + return; + } + + /* Sanity check: */ + assert(context != (SHA256_CTX*)0 && data != (sha2_byte*)0); + + usedspace = (context->bitcount >> 3) % SHA256_BLOCK_LENGTH; + if (usedspace > 0) { + /* Calculate how much free space is available in the buffer */ + freespace = SHA256_BLOCK_LENGTH - usedspace; + + if (len >= freespace) { + /* Fill the buffer completely and process it */ + MEMCPY_BCOPY(&context->buffer[usedspace], data, freespace); + context->bitcount += freespace << 3; + len -= freespace; + data += freespace; + SHA256_Transform(context, (sha2_word32*)context->buffer); + } else { + /* The buffer is not yet full */ + MEMCPY_BCOPY(&context->buffer[usedspace], data, len); + context->bitcount += len << 3; + /* Clean up: */ + usedspace = freespace = 0; + return; + } + } + while (len >= SHA256_BLOCK_LENGTH) { + /* Process as many complete blocks as we can */ + SHA256_Transform(context, (sha2_word32*)data); + context->bitcount += SHA256_BLOCK_LENGTH << 3; + len -= SHA256_BLOCK_LENGTH; + data += SHA256_BLOCK_LENGTH; + } + if (len > 0) { + /* There's left-overs, so save 'em */ + MEMCPY_BCOPY(context->buffer, data, len); + context->bitcount += len << 3; + } + /* Clean up: */ + usedspace = freespace = 0; +} + +void sr_SHA256_Final(sha2_byte digest[], SHA256_CTX* context) { + sha2_word32 *d = (sha2_word32*)digest; + unsigned int usedspace; + + /* Sanity check: */ + assert(context != (SHA256_CTX*)0); + + /* If no digest buffer is passed, we don't bother doing this: */ + if (digest != (sha2_byte*)0) { + usedspace = (context->bitcount >> 3) % SHA256_BLOCK_LENGTH; +#if BYTE_ORDER == LITTLE_ENDIAN + /* Convert FROM host byte order */ + REVERSE64(context->bitcount,context->bitcount); +#endif + if (usedspace > 0) { + /* Begin padding with a 1 bit: */ + context->buffer[usedspace++] = 0x80; + + if (usedspace <= SHA256_SHORT_BLOCK_LENGTH) { + /* Set-up for the last transform: */ + MEMSET_BZERO(&context->buffer[usedspace], SHA256_SHORT_BLOCK_LENGTH - usedspace); + } else { + if (usedspace < SHA256_BLOCK_LENGTH) { + MEMSET_BZERO(&context->buffer[usedspace], SHA256_BLOCK_LENGTH - usedspace); + } + /* Do second-to-last transform: */ + SHA256_Transform(context, (sha2_word32*)context->buffer); + + /* And set-up for the last transform: */ + MEMSET_BZERO(context->buffer, SHA256_SHORT_BLOCK_LENGTH); + } + } else { + /* Set-up for the last transform: */ + MEMSET_BZERO(context->buffer, SHA256_SHORT_BLOCK_LENGTH); + + /* Begin padding with a 1 bit: */ + *context->buffer = 0x80; + } + /* Set the bit count: */ + MEMCPY_BCOPY(&(context->buffer[SHA256_SHORT_BLOCK_LENGTH]), &(context->bitcount), sizeof(sha2_word64)); + + /* Final transform: */ + SHA256_Transform(context, (sha2_word32*)context->buffer); + +#if BYTE_ORDER == LITTLE_ENDIAN + { + /* Convert TO host byte order */ + int j; + for (j = 0; j < 8; j++) { + REVERSE32(context->state[j],context->state[j]); + *d++ = context->state[j]; + } + } +#else + MEMCPY_BCOPY(d, context->state, SHA256_DIGEST_LENGTH); +#endif + } + + /* Clean up state data: */ + MEMSET_BZERO(context, sizeof(*context)); + usedspace = 0; +} + +char *sr_SHA256_End(SHA256_CTX* context, char buffer[]) { + sha2_byte digest[SHA256_DIGEST_LENGTH], *d = digest; + int i; + + /* Sanity check: */ + assert(context != (SHA256_CTX*)0); + + if (buffer != (char*)0) { + sr_SHA256_Final(digest, context); + + for (i = 0; i < SHA256_DIGEST_LENGTH; i++) { + *buffer++ = sha2_hex_digits[(*d & 0xf0) >> 4]; + *buffer++ = sha2_hex_digits[*d & 0x0f]; + d++; + } + *buffer = (char)0; + } else { + MEMSET_BZERO(context, sizeof(*context)); + } + MEMSET_BZERO(digest, SHA256_DIGEST_LENGTH); + return buffer; +} + +char* sr_SHA256_Data(const sha2_byte* data, size_t len, char digest[SHA256_DIGEST_STRING_LENGTH]) { + SHA256_CTX context; + + sr_SHA256_Init(&context); + sr_SHA256_Update(&context, data, len); + return sr_SHA256_End(&context, digest); +} + + +/*** SHA-512: *********************************************************/ +void sr_SHA512_Init(SHA512_CTX* context) { + if (context == (SHA512_CTX*)0) { + return; + } + MEMCPY_BCOPY(context->state, sha512_initial_hash_value, SHA512_DIGEST_LENGTH); + MEMSET_BZERO(context->buffer, SHA512_BLOCK_LENGTH); + context->bitcount[0] = context->bitcount[1] = 0; +} + +#ifdef SHA2_UNROLL_TRANSFORM + +/* Unrolled SHA-512 round macros: */ +#if BYTE_ORDER == LITTLE_ENDIAN + +#define ROUND512_0_TO_15(a,b,c,d,e,f,g,h) \ + REVERSE64(*data++, W512[j]); \ + T1 = (h) + Sigma1_512(e) + Ch((e), (f), (g)) + \ + K512[j] + W512[j]; \ + (d) += T1, \ + (h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)), \ + j++ + + +#else /* BYTE_ORDER == LITTLE_ENDIAN */ + +#define ROUND512_0_TO_15(a,b,c,d,e,f,g,h) \ + T1 = (h) + Sigma1_512(e) + Ch((e), (f), (g)) + \ + K512[j] + (W512[j] = *data++); \ + (d) += T1; \ + (h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)); \ + j++ + +#endif /* BYTE_ORDER == LITTLE_ENDIAN */ + +#define ROUND512(a,b,c,d,e,f,g,h) \ + s0 = W512[(j+1)&0x0f]; \ + s0 = sigma0_512(s0); \ + s1 = W512[(j+14)&0x0f]; \ + s1 = sigma1_512(s1); \ + T1 = (h) + Sigma1_512(e) + Ch((e), (f), (g)) + K512[j] + \ + (W512[j&0x0f] += s1 + W512[(j+9)&0x0f] + s0); \ + (d) += T1; \ + (h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)); \ + j++ + +void SHA512_Transform(SHA512_CTX* context, const sha2_word64* data) { + sha2_word64 a, b, c, d, e, f, g, h, s0, s1; + sha2_word64 T1, *W512 = (sha2_word64*)context->buffer; + int j; + + /* Initialize registers with the prev. intermediate value */ + a = context->state[0]; + b = context->state[1]; + c = context->state[2]; + d = context->state[3]; + e = context->state[4]; + f = context->state[5]; + g = context->state[6]; + h = context->state[7]; + + j = 0; + do { + ROUND512_0_TO_15(a,b,c,d,e,f,g,h); + ROUND512_0_TO_15(h,a,b,c,d,e,f,g); + ROUND512_0_TO_15(g,h,a,b,c,d,e,f); + ROUND512_0_TO_15(f,g,h,a,b,c,d,e); + ROUND512_0_TO_15(e,f,g,h,a,b,c,d); + ROUND512_0_TO_15(d,e,f,g,h,a,b,c); + ROUND512_0_TO_15(c,d,e,f,g,h,a,b); + ROUND512_0_TO_15(b,c,d,e,f,g,h,a); + } while (j < 16); + + /* Now for the remaining rounds up to 79: */ + do { + ROUND512(a,b,c,d,e,f,g,h); + ROUND512(h,a,b,c,d,e,f,g); + ROUND512(g,h,a,b,c,d,e,f); + ROUND512(f,g,h,a,b,c,d,e); + ROUND512(e,f,g,h,a,b,c,d); + ROUND512(d,e,f,g,h,a,b,c); + ROUND512(c,d,e,f,g,h,a,b); + ROUND512(b,c,d,e,f,g,h,a); + } while (j < 80); + + /* Compute the current intermediate hash value */ + context->state[0] += a; + context->state[1] += b; + context->state[2] += c; + context->state[3] += d; + context->state[4] += e; + context->state[5] += f; + context->state[6] += g; + context->state[7] += h; + + /* Clean up */ + a = b = c = d = e = f = g = h = T1 = 0; +} + +#else /* SHA2_UNROLL_TRANSFORM */ + +void SHA512_Transform(SHA512_CTX* context, const sha2_word64* data) { + sha2_word64 a, b, c, d, e, f, g, h, s0, s1; + sha2_word64 T1, T2, *W512 = (sha2_word64*)context->buffer; + int j; + + /* Initialize registers with the prev. intermediate value */ + a = context->state[0]; + b = context->state[1]; + c = context->state[2]; + d = context->state[3]; + e = context->state[4]; + f = context->state[5]; + g = context->state[6]; + h = context->state[7]; + + j = 0; + do { +#if BYTE_ORDER == LITTLE_ENDIAN + /* Convert TO host byte order */ + REVERSE64(*data++, W512[j]); + /* Apply the SHA-512 compression function to update a..h */ + T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] + W512[j]; +#else /* BYTE_ORDER == LITTLE_ENDIAN */ + /* Apply the SHA-512 compression function to update a..h with copy */ + T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] + (W512[j] = *data++); +#endif /* BYTE_ORDER == LITTLE_ENDIAN */ + T2 = Sigma0_512(a) + Maj(a, b, c); + h = g; + g = f; + f = e; + e = d + T1; + d = c; + c = b; + b = a; + a = T1 + T2; + + j++; + } while (j < 16); + + do { + /* Part of the message block expansion: */ + s0 = W512[(j+1)&0x0f]; + s0 = sigma0_512(s0); + s1 = W512[(j+14)&0x0f]; + s1 = sigma1_512(s1); + + /* Apply the SHA-512 compression function to update a..h */ + T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] + + (W512[j&0x0f] += s1 + W512[(j+9)&0x0f] + s0); + T2 = Sigma0_512(a) + Maj(a, b, c); + h = g; + g = f; + f = e; + e = d + T1; + d = c; + c = b; + b = a; + a = T1 + T2; + + j++; + } while (j < 80); + + /* Compute the current intermediate hash value */ + context->state[0] += a; + context->state[1] += b; + context->state[2] += c; + context->state[3] += d; + context->state[4] += e; + context->state[5] += f; + context->state[6] += g; + context->state[7] += h; + + /* Clean up */ + a = b = c = d = e = f = g = h = T1 = T2 = 0; +} + +#endif /* SHA2_UNROLL_TRANSFORM */ + +void sr_SHA512_Update(SHA512_CTX* context, const sha2_byte *data, size_t len) { + unsigned int freespace, usedspace; + + if (len == 0) { + /* Calling with no data is valid - we do nothing */ + return; + } + + /* Sanity check: */ + assert(context != (SHA512_CTX*)0 && data != (sha2_byte*)0); + + usedspace = (context->bitcount[0] >> 3) % SHA512_BLOCK_LENGTH; + if (usedspace > 0) { + /* Calculate how much free space is available in the buffer */ + freespace = SHA512_BLOCK_LENGTH - usedspace; + + if (len >= freespace) { + /* Fill the buffer completely and process it */ + MEMCPY_BCOPY(&context->buffer[usedspace], data, freespace); + ADDINC128(context->bitcount, freespace << 3); + len -= freespace; + data += freespace; + SHA512_Transform(context, (sha2_word64*)context->buffer); + } else { + /* The buffer is not yet full */ + MEMCPY_BCOPY(&context->buffer[usedspace], data, len); + ADDINC128(context->bitcount, len << 3); + /* Clean up: */ + usedspace = freespace = 0; + return; + } + } + while (len >= SHA512_BLOCK_LENGTH) { + /* Process as many complete blocks as we can */ + SHA512_Transform(context, (sha2_word64*)data); + ADDINC128(context->bitcount, SHA512_BLOCK_LENGTH << 3); + len -= SHA512_BLOCK_LENGTH; + data += SHA512_BLOCK_LENGTH; + } + if (len > 0) { + /* There's left-overs, so save 'em */ + MEMCPY_BCOPY(context->buffer, data, len); + ADDINC128(context->bitcount, len << 3); + } + /* Clean up: */ + usedspace = freespace = 0; +} + +void SHA512_Last(SHA512_CTX* context) { + unsigned int usedspace; + + usedspace = (context->bitcount[0] >> 3) % SHA512_BLOCK_LENGTH; +#if BYTE_ORDER == LITTLE_ENDIAN + /* Convert FROM host byte order */ + REVERSE64(context->bitcount[0],context->bitcount[0]); + REVERSE64(context->bitcount[1],context->bitcount[1]); +#endif + if (usedspace > 0) { + /* Begin padding with a 1 bit: */ + context->buffer[usedspace++] = 0x80; + + if (usedspace <= SHA512_SHORT_BLOCK_LENGTH) { + /* Set-up for the last transform: */ + MEMSET_BZERO(&context->buffer[usedspace], SHA512_SHORT_BLOCK_LENGTH - usedspace); + } else { + if (usedspace < SHA512_BLOCK_LENGTH) { + MEMSET_BZERO(&context->buffer[usedspace], SHA512_BLOCK_LENGTH - usedspace); + } + /* Do second-to-last transform: */ + SHA512_Transform(context, (sha2_word64*)context->buffer); + + /* And set-up for the last transform: */ + MEMSET_BZERO(context->buffer, SHA512_BLOCK_LENGTH - 2); + } + } else { + /* Prepare for final transform: */ + MEMSET_BZERO(context->buffer, SHA512_SHORT_BLOCK_LENGTH); + + /* Begin padding with a 1 bit: */ + *context->buffer = 0x80; + } + /* Store the length of input data (in bits): */ + MEMCPY_BCOPY(&(context->buffer[SHA512_SHORT_BLOCK_LENGTH+0]), &(context->bitcount[1]), sizeof(sha2_word64)); + MEMCPY_BCOPY(&(context->buffer[SHA512_SHORT_BLOCK_LENGTH+8]), &(context->bitcount[0]), sizeof(sha2_word64)); + + /* Final transform: */ + SHA512_Transform(context, (sha2_word64*)context->buffer); +} + +void sr_SHA512_Final(sha2_byte digest[], SHA512_CTX* context) { + sha2_word64 *d = (sha2_word64*)digest; + + /* Sanity check: */ + assert(context != (SHA512_CTX*)0); + + /* If no digest buffer is passed, we don't bother doing this: */ + if (digest != (sha2_byte*)0) { + SHA512_Last(context); + + /* Save the hash data for output: */ +#if BYTE_ORDER == LITTLE_ENDIAN + { + /* Convert TO host byte order */ + int j; + for (j = 0; j < 8; j++) { + REVERSE64(context->state[j],context->state[j]); + *d++ = context->state[j]; + } + } +#else + MEMCPY_BCOPY(d, context->state, SHA512_DIGEST_LENGTH); +#endif + } + + /* Zero out state data */ + MEMSET_BZERO(context, sizeof(*context)); +} + +char *sr_SHA512_End(SHA512_CTX* context, char buffer[]) { + sha2_byte digest[SHA512_DIGEST_LENGTH], *d = digest; + int i; + + /* Sanity check: */ + assert(context != (SHA512_CTX*)0); + + if (buffer != (char*)0) { + sr_SHA512_Final(digest, context); + + for (i = 0; i < SHA512_DIGEST_LENGTH; i++) { + *buffer++ = sha2_hex_digits[(*d & 0xf0) >> 4]; + *buffer++ = sha2_hex_digits[*d & 0x0f]; + d++; + } + *buffer = (char)0; + } else { + MEMSET_BZERO(context, sizeof(*context)); + } + MEMSET_BZERO(digest, SHA512_DIGEST_LENGTH); + return buffer; +} + +char* sr_SHA512_Data(const sha2_byte* data, size_t len, char digest[SHA512_DIGEST_STRING_LENGTH]) { + SHA512_CTX context; + + sr_SHA512_Init(&context); + sr_SHA512_Update(&context, data, len); + return sr_SHA512_End(&context, digest); +} + + +/*** SHA-384: *********************************************************/ +void sr_SHA384_Init(SHA384_CTX* context) { + if (context == (SHA384_CTX*)0) { + return; + } + MEMCPY_BCOPY(context->state, sha384_initial_hash_value, SHA512_DIGEST_LENGTH); + MEMSET_BZERO(context->buffer, SHA384_BLOCK_LENGTH); + context->bitcount[0] = context->bitcount[1] = 0; +} + +void sr_SHA384_Update(SHA384_CTX* context, const sha2_byte* data, size_t len) { + sr_SHA512_Update((SHA512_CTX*)context, data, len); +} + +void sr_SHA384_Final(sha2_byte digest[], SHA384_CTX* context) { + sha2_word64 *d = (sha2_word64*)digest; + + /* Sanity check: */ + assert(context != (SHA384_CTX*)0); + + /* If no digest buffer is passed, we don't bother doing this: */ + if (digest != (sha2_byte*)0) { + SHA512_Last((SHA512_CTX*)context); + + /* Save the hash data for output: */ +#if BYTE_ORDER == LITTLE_ENDIAN + { + /* Convert TO host byte order */ + int j; + for (j = 0; j < 6; j++) { + REVERSE64(context->state[j],context->state[j]); + *d++ = context->state[j]; + } + } +#else + MEMCPY_BCOPY(d, context->state, SHA384_DIGEST_LENGTH); +#endif + } + + /* Zero out state data */ + MEMSET_BZERO(context, sizeof(*context)); +} + +char *sr_SHA384_End(SHA384_CTX* context, char buffer[]) { + sha2_byte digest[SHA384_DIGEST_LENGTH], *d = digest; + int i; + + /* Sanity check: */ + assert(context != (SHA384_CTX*)0); + + if (buffer != (char*)0) { + sr_SHA384_Final(digest, context); + + for (i = 0; i < SHA384_DIGEST_LENGTH; i++) { + *buffer++ = sha2_hex_digits[(*d & 0xf0) >> 4]; + *buffer++ = sha2_hex_digits[*d & 0x0f]; + d++; + } + *buffer = (char)0; + } else { + MEMSET_BZERO(context, sizeof(*context)); + } + MEMSET_BZERO(digest, SHA384_DIGEST_LENGTH); + return buffer; +} + +char* sr_SHA384_Data(const sha2_byte* data, size_t len, char digest[SHA384_DIGEST_STRING_LENGTH]) { + SHA384_CTX context; + + sr_SHA384_Init(&context); + sr_SHA384_Update(&context, data, len); + return sr_SHA384_End(&context, digest); +} diff --git a/src/modules/tls/fortuna/sha256.h b/src/modules/tls/fortuna/sha256.h new file mode 100644 index 00000000000..760ccc0de6f --- /dev/null +++ b/src/modules/tls/fortuna/sha256.h @@ -0,0 +1,201 @@ +/* + * FILE: sha256.h + * AUTHOR: Aaron D. Gifford - http://www.aarongifford.com/ + * + * Copyright (c) 2000-2001, Aaron D. Gifford + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the names of contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTOR(S) ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTOR(S) BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ + +#ifndef __SHA2_H__ +#define __SHA2_H__ + +#ifdef __cplusplus +extern "C" { +#endif + + +/* + * Import u_intXX_t size_t type definitions from system headers. You + * may need to change this, or define these things yourself in this + * file. + */ +#include + +#ifdef SHA2_USE_INTTYPES_H + +#include + +#endif /* SHA2_USE_INTTYPES_H */ + +/* fix types for Sun Solaris */ +#if defined(__SVR4) || defined(__sun) + typedef uint8_t u_int8_t; + typedef uint32_t u_int32_t; + typedef uint64_t u_int64_t; +#endif + +/*** SHA-256/384/512 Various Length Definitions ***********************/ +#define SHA256_BLOCK_LENGTH 64 +#define SHA256_DIGEST_LENGTH 32 +#define SHA256_DIGEST_STRING_LENGTH (SHA256_DIGEST_LENGTH * 2 + 1) +#define SHA384_BLOCK_LENGTH 128 +#define SHA384_DIGEST_LENGTH 48 +#define SHA384_DIGEST_STRING_LENGTH (SHA384_DIGEST_LENGTH * 2 + 1) +#define SHA512_BLOCK_LENGTH 128 +#define SHA512_DIGEST_LENGTH 64 +#define SHA512_DIGEST_STRING_LENGTH (SHA512_DIGEST_LENGTH * 2 + 1) + + +/*** SHA-256/384/512 Context Structures *******************************/ +/* NOTE: If your architecture does not define either u_intXX_t types or + * uintXX_t (from inttypes.h), you may need to define things by hand + * for your system: + */ +#if 0 +typedef unsigned char u_int8_t; /* 1-byte (8-bits) */ +typedef unsigned int u_int32_t; /* 4-bytes (32-bits) */ +typedef unsigned long long u_int64_t; /* 8-bytes (64-bits) */ +#endif +/* + * Most BSD systems already define u_intXX_t types, as does Linux. + * Some systems, however, like Compaq's Tru64 Unix instead can use + * uintXX_t types defined by very recent ANSI C standards and included + * in the file: + * + * #include + * + * If you choose to use then please define: + * + * #define SHA2_USE_INTTYPES_H + * + * Or on the command line during compile: + * + * cc -DSHA2_USE_INTTYPES_H ... + */ +#ifdef SHA2_USE_INTTYPES_H + +typedef struct _SHA256_CTX { + uint32_t state[8]; + uint64_t bitcount; + uint8_t buffer[SHA256_BLOCK_LENGTH]; +} SHA256_CTX; +typedef struct _SHA512_CTX { + uint64_t state[8]; + uint64_t bitcount[2]; + uint8_t buffer[SHA512_BLOCK_LENGTH]; +} SHA512_CTX; + +#else /* SHA2_USE_INTTYPES_H */ + +typedef struct _SHA256_CTX { + u_int32_t state[8]; + u_int64_t bitcount; + u_int8_t buffer[SHA256_BLOCK_LENGTH]; +} SHA256_CTX; +typedef struct _SHA512_CTX { + u_int64_t state[8]; + u_int64_t bitcount[2]; + u_int8_t buffer[SHA512_BLOCK_LENGTH]; +} SHA512_CTX; + +#endif /* SHA2_USE_INTTYPES_H */ + +typedef SHA512_CTX SHA384_CTX; + + +/*** SHA-256/384/512 Function Prototypes ******************************/ +#ifndef NOPROTO +#ifdef SHA2_USE_INTTYPES_H + +void sr_SHA256_Init(SHA256_CTX *); +void sr_SHA256_Update(SHA256_CTX*, const uint8_t*, size_t); +void sr_SHA256_Final(uint8_t[SHA256_DIGEST_LENGTH], SHA256_CTX*); +char* sr_SHA256_End(SHA256_CTX*, char[SHA256_DIGEST_STRING_LENGTH]); +char* sr_SHA256_Data(const uint8_t*, size_t, char[SHA256_DIGEST_STRING_LENGTH]); + +void sr_SHA384_Init(SHA384_CTX*); +void sr_SHA384_Update(SHA384_CTX*, const uint8_t*, size_t); +void sr_SHA384_Final(uint8_t[SHA384_DIGEST_LENGTH], SHA384_CTX*); +char* sr_SHA384_End(SHA384_CTX*, char[SHA384_DIGEST_STRING_LENGTH]); +char* sr_SHA384_Data(const uint8_t*, size_t, char[SHA384_DIGEST_STRING_LENGTH]); + +void sr_SHA512_Init(SHA512_CTX*); +void sr_SHA512_Update(SHA512_CTX*, const uint8_t*, size_t); +void sr_SHA512_Final(uint8_t[SHA512_DIGEST_LENGTH], SHA512_CTX*); +char* sr_SHA512_End(SHA512_CTX*, char[SHA512_DIGEST_STRING_LENGTH]); +char* sr_SHA512_Data(const uint8_t*, size_t, char[SHA512_DIGEST_STRING_LENGTH]); + +#else /* SHA2_USE_INTTYPES_H */ + +void sr_SHA256_Init(SHA256_CTX *); +void sr_SHA256_Update(SHA256_CTX*, const u_int8_t*, size_t); +void sr_SHA256_Final(u_int8_t[SHA256_DIGEST_LENGTH], SHA256_CTX*); +char* sr_SHA256_End(SHA256_CTX*, char[SHA256_DIGEST_STRING_LENGTH]); +char* sr_SHA256_Data(const u_int8_t*, size_t, char[SHA256_DIGEST_STRING_LENGTH]); + +void sr_SHA384_Init(SHA384_CTX*); +void sr_SHA384_Update(SHA384_CTX*, const u_int8_t*, size_t); +void sr_SHA384_Final(u_int8_t[SHA384_DIGEST_LENGTH], SHA384_CTX*); +char* sr_SHA384_End(SHA384_CTX*, char[SHA384_DIGEST_STRING_LENGTH]); +char* sr_SHA384_Data(const u_int8_t*, size_t, char[SHA384_DIGEST_STRING_LENGTH]); + +void sr_SHA512_Init(SHA512_CTX*); +void sr_SHA512_Update(SHA512_CTX*, const u_int8_t*, size_t); +void sr_SHA512_Final(u_int8_t[SHA512_DIGEST_LENGTH], SHA512_CTX*); +char* sr_SHA512_End(SHA512_CTX*, char[SHA512_DIGEST_STRING_LENGTH]); +char* sr_SHA512_Data(const u_int8_t*, size_t, char[SHA512_DIGEST_STRING_LENGTH]); + +#endif /* SHA2_USE_INTTYPES_H */ + +#else /* NOPROTO */ + +void sr_SHA256_Init(); +void sr_SHA256_Update(); +void sr_SHA256_Final(); +char* sr_SHA256_End(); +char* sr_SHA256_Data(); + +void sr_SHA384_Init(); +void sr_SHA384_Update(); +void sr_SHA384_Final(); +char* sr_SHA384_End(); +char* sr_SHA384_Data(); + +void sr_SHA512_Init(); +void sr_SHA512_Update(); +void sr_SHA512_Final(); +char* sr_SHA512_End(); +char* sr_SHA512_Data(); + +#endif /* NOPROTO */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* __SHA2_H__ */ diff --git a/src/modules/tls/tls_rand.c b/src/modules/tls/tls_rand.c index 7be0d335f7e..0f283306dde 100644 --- a/src/modules/tls/tls_rand.c +++ b/src/modules/tls/tls_rand.c @@ -27,6 +27,7 @@ #include "../../core/dprint.h" #include "../../core/rand/kam_rand.h" +#include "fortuna/random.h" static int ksr_rand_bytes(unsigned char *outdata, int size) { @@ -38,6 +39,11 @@ static int ksr_rand_bytes(unsigned char *outdata, int size) return 1; } +/* TODO + sr_get_pseudo_random_bytes(outdata, size); + return 1; +*/ + while(size >= sizeof(int)) { r = kam_rand(); memcpy(outdata, &r, sizeof(int));