add the 'ead' package (emergency access daemon),
authorFelix Fietkau <nbd@openwrt.org>
Wed, 24 Dec 2008 10:42:12 +0000 (10:42 +0000)
committerFelix Fietkau <nbd@openwrt.org>
Wed, 24 Dec 2008 10:42:12 +0000 (10:42 +0000)
which can provide remote access to your device, even if the ip
and firewall settings are broken

SVN-Revision: 13738

69 files changed:
package/ead/Makefile [new file with mode: 0644]
package/ead/src/Makefile [new file with mode: 0644]
package/ead/src/aes.c [new file with mode: 0644]
package/ead/src/ead-client.c [new file with mode: 0644]
package/ead/src/ead-crypt.c [new file with mode: 0644]
package/ead/src/ead-crypt.h [new file with mode: 0644]
package/ead/src/ead-pcap.h [new file with mode: 0644]
package/ead/src/ead.c [new file with mode: 0644]
package/ead/src/ead.h [new file with mode: 0644]
package/ead/src/filter.c [new file with mode: 0644]
package/ead/src/libbridge.h [new file with mode: 0644]
package/ead/src/libbridge_init.c [new file with mode: 0644]
package/ead/src/libbridge_private.h [new file with mode: 0644]
package/ead/src/list.h [new file with mode: 0644]
package/ead/src/passwd [new file with mode: 0644]
package/ead/src/pfc.c [new file with mode: 0644]
package/ead/src/pw_encrypt_md5.c [new file with mode: 0644]
package/ead/src/sha1.c [new file with mode: 0644]
package/ead/src/tinysrp/Makefile.am [new file with mode: 0644]
package/ead/src/tinysrp/Makefile.in [new file with mode: 0644]
package/ead/src/tinysrp/Notes [new file with mode: 0644]
package/ead/src/tinysrp/acconfig.h [new file with mode: 0644]
package/ead/src/tinysrp/acinclude.m4 [new file with mode: 0644]
package/ead/src/tinysrp/aclocal.m4 [new file with mode: 0644]
package/ead/src/tinysrp/bn.h [new file with mode: 0644]
package/ead/src/tinysrp/bn_add.c [new file with mode: 0644]
package/ead/src/tinysrp/bn_asm.c [new file with mode: 0644]
package/ead/src/tinysrp/bn_ctx.c [new file with mode: 0644]
package/ead/src/tinysrp/bn_div.c [new file with mode: 0644]
package/ead/src/tinysrp/bn_exp.c [new file with mode: 0644]
package/ead/src/tinysrp/bn_lcl.h [new file with mode: 0644]
package/ead/src/tinysrp/bn_lib.c [new file with mode: 0644]
package/ead/src/tinysrp/bn_mul.c [new file with mode: 0644]
package/ead/src/tinysrp/bn_prime.h [new file with mode: 0644]
package/ead/src/tinysrp/bn_shift.c [new file with mode: 0644]
package/ead/src/tinysrp/bn_sqr.c [new file with mode: 0644]
package/ead/src/tinysrp/bn_word.c [new file with mode: 0644]
package/ead/src/tinysrp/clitest.c [new file with mode: 0644]
package/ead/src/tinysrp/config.h.in [new file with mode: 0644]
package/ead/src/tinysrp/configure [new file with mode: 0755]
package/ead/src/tinysrp/configure.in [new file with mode: 0644]
package/ead/src/tinysrp/install-sh [new file with mode: 0755]
package/ead/src/tinysrp/missing [new file with mode: 0755]
package/ead/src/tinysrp/mkinstalldirs [new file with mode: 0755]
package/ead/src/tinysrp/srvtest.c [new file with mode: 0644]
package/ead/src/tinysrp/stamp-h.in [new file with mode: 0644]
package/ead/src/tinysrp/t_client.c [new file with mode: 0644]
package/ead/src/tinysrp/t_client.h [new file with mode: 0644]
package/ead/src/tinysrp/t_conf.c [new file with mode: 0644]
package/ead/src/tinysrp/t_conv.c [new file with mode: 0644]
package/ead/src/tinysrp/t_defines.h [new file with mode: 0644]
package/ead/src/tinysrp/t_getconf.c [new file with mode: 0644]
package/ead/src/tinysrp/t_getpass.c [new file with mode: 0644]
package/ead/src/tinysrp/t_math.c [new file with mode: 0644]
package/ead/src/tinysrp/t_misc.c [new file with mode: 0644]
package/ead/src/tinysrp/t_pw.c [new file with mode: 0644]
package/ead/src/tinysrp/t_pwd.h [new file with mode: 0644]
package/ead/src/tinysrp/t_read.c [new file with mode: 0644]
package/ead/src/tinysrp/t_read.h [new file with mode: 0644]
package/ead/src/tinysrp/t_server.c [new file with mode: 0644]
package/ead/src/tinysrp/t_server.h [new file with mode: 0644]
package/ead/src/tinysrp/t_sha.c [new file with mode: 0644]
package/ead/src/tinysrp/t_sha.h [new file with mode: 0644]
package/ead/src/tinysrp/t_truerand.c [new file with mode: 0644]
package/ead/src/tinysrp/tconf.c [new file with mode: 0644]
package/ead/src/tinysrp/tinysrp.c [new file with mode: 0644]
package/ead/src/tinysrp/tinysrp.h [new file with mode: 0644]
package/ead/src/tinysrp/tpasswd [new file with mode: 0644]
package/ead/src/tinysrp/tphrase.c [new file with mode: 0644]

diff --git a/package/ead/Makefile b/package/ead/Makefile
new file mode 100644 (file)
index 0000000..280b51d
--- /dev/null
@@ -0,0 +1,53 @@
+# 
+# Copyright (C) 2006-2008 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+# $Id$
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=ead
+PKG_RELEASE:=1
+
+PKG_BUILD_DEPENDS:=pcap
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/ead
+  SECTION:=net
+  CATEGORY:=Base system
+  TITLE:=Emergency Access Daemon
+  URL:=http://bridge.sourceforge.net/
+endef
+
+define Package/ead/description
+  Provides remote access to your device even if IP and firewall
+  configuration settings are defunct
+endef
+
+CONFIGURE_PATH = tinysrp
+
+TARGET_CFLAGS += \
+       -I$(PKG_BUILD_DIR) \
+       -I$(PKG_BUILD_DIR)/tinysrp \
+       -I$(STAGING_DIR)/usr/include
+
+MAKE_FLAGS += \
+       CONFIGURE_ARGS="$(CONFIGURE_ARGS)" \
+       LIBS="$(PKG_BUILD_DIR)/tinysrp/libtinysrp.a" \
+       LIBS_EAD="$(PKG_BUILD_DIR)/tinysrp/libtinysrp.a $(STAGING_DIR)/usr/lib/libpcap.a" \
+       CFLAGS="$(TARGET_CFLAGS)"
+
+define Build/Prepare
+       mkdir -p $(PKG_BUILD_DIR)
+       $(CP) ./src/* $(PKG_BUILD_DIR)/
+endef
+
+define Package/ead/install
+       $(INSTALL_DIR) $(1)/sbin
+       $(INSTALL_BIN) $(PKG_BUILD_DIR)/ead $(1)/sbin/
+endef
+
+$(eval $(call BuildPackage,ead))
diff --git a/package/ead/src/Makefile b/package/ead/src/Makefile
new file mode 100644 (file)
index 0000000..0b68f60
--- /dev/null
@@ -0,0 +1,33 @@
+CC       = gcc
+CPPFLAGS = -I. -Itinysrp
+CFLAGS   = -Os -Wall
+LDFLAGS         =
+LIBS    = tinysrp/libtinysrp.a
+LIBS_EAD = $(LIBS) -lpcap
+CONFIGURE_ARGS =
+
+all: ead ead-client
+
+obj = ead-crypt.o
+
+tinysrp/Makefile:
+       cd tinysrp; ./configure $(CONFIGURE_ARGS)
+
+tinysrp/libtinysrp.a: tinysrp/Makefile
+       -$(MAKE) -C tinysrp CFLAGS="$(CFLAGS)"
+
+%.o: %.c $(wildcard *.h) tinysrp/libtinysrp.a
+       $(CC) $(CPPFLAGS) $(CFLAGS) -c $< -o $@
+
+ead.o: filter.c
+ead-crypt.o: aes.c sha1.c
+
+ead: ead.o $(obj) tinysrp/libtinysrp.a
+       $(CC) -o $@ $< $(obj) $(LDFLAGS) $(LIBS_EAD)
+
+ead-client: ead-client.o $(obj)
+       $(CC) -o $@ $< $(obj) $(LDFLAGS) $(LIBS)
+
+clean:
+       rm -f *.o ead ead-client
+       if [ -f tinysrp/Makefile ]; then $(MAKE) -C tinysrp distclean; fi
diff --git a/package/ead/src/aes.c b/package/ead/src/aes.c
new file mode 100644 (file)
index 0000000..6f9db34
--- /dev/null
@@ -0,0 +1,1061 @@
+/*
+ * AES (Rijndael) cipher
+ *
+ * Modifications to public domain implementation:
+ * - support only 128-bit keys
+ * - cleanup
+ * - use C pre-processor to make it easier to change S table access
+ * - added option (AES_SMALL_TABLES) for reducing code size by about 8 kB at
+ *   cost of reduced throughput (quite small difference on Pentium 4,
+ *   10-25% when using -O1 or -O2 optimization)
+ *
+ * Copyright (c) 2003-2005, Jouni Malinen <j@w1.fi>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Alternatively, this software may be distributed under the terms of BSD
+ * license.
+ *
+ * See README and COPYING for more details.
+ */
+
+/*
+ * rijndael-alg-fst.c
+ *
+ * @version 3.0 (December 2000)
+ *
+ * Optimised ANSI C code for the Rijndael cipher (now AES)
+ *
+ * @author Vincent Rijmen <vincent.rijmen@esat.kuleuven.ac.be>
+ * @author Antoon Bosselaers <antoon.bosselaers@esat.kuleuven.ac.be>
+ * @author Paulo Barreto <paulo.barreto@terra.com.br>
+ *
+ * This code is hereby placed in the public domain.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/* #define FULL_UNROLL */
+#define AES_SMALL_TABLES
+
+typedef uint8_t u8;
+typedef uint16_t u16;
+typedef uint32_t u32;
+
+/*
+Te0[x] = S [x].[02, 01, 01, 03];
+Te1[x] = S [x].[03, 02, 01, 01];
+Te2[x] = S [x].[01, 03, 02, 01];
+Te3[x] = S [x].[01, 01, 03, 02];
+Te4[x] = S [x].[01, 01, 01, 01];
+
+Td0[x] = Si[x].[0e, 09, 0d, 0b];
+Td1[x] = Si[x].[0b, 0e, 09, 0d];
+Td2[x] = Si[x].[0d, 0b, 0e, 09];
+Td3[x] = Si[x].[09, 0d, 0b, 0e];
+Td4[x] = Si[x].[01, 01, 01, 01];
+*/
+
+static const u32 Te0[256] = {
+    0xc66363a5U, 0xf87c7c84U, 0xee777799U, 0xf67b7b8dU,
+    0xfff2f20dU, 0xd66b6bbdU, 0xde6f6fb1U, 0x91c5c554U,
+    0x60303050U, 0x02010103U, 0xce6767a9U, 0x562b2b7dU,
+    0xe7fefe19U, 0xb5d7d762U, 0x4dababe6U, 0xec76769aU,
+    0x8fcaca45U, 0x1f82829dU, 0x89c9c940U, 0xfa7d7d87U,
+    0xeffafa15U, 0xb25959ebU, 0x8e4747c9U, 0xfbf0f00bU,
+    0x41adadecU, 0xb3d4d467U, 0x5fa2a2fdU, 0x45afafeaU,
+    0x239c9cbfU, 0x53a4a4f7U, 0xe4727296U, 0x9bc0c05bU,
+    0x75b7b7c2U, 0xe1fdfd1cU, 0x3d9393aeU, 0x4c26266aU,
+    0x6c36365aU, 0x7e3f3f41U, 0xf5f7f702U, 0x83cccc4fU,
+    0x6834345cU, 0x51a5a5f4U, 0xd1e5e534U, 0xf9f1f108U,
+    0xe2717193U, 0xabd8d873U, 0x62313153U, 0x2a15153fU,
+    0x0804040cU, 0x95c7c752U, 0x46232365U, 0x9dc3c35eU,
+    0x30181828U, 0x379696a1U, 0x0a05050fU, 0x2f9a9ab5U,
+    0x0e070709U, 0x24121236U, 0x1b80809bU, 0xdfe2e23dU,
+    0xcdebeb26U, 0x4e272769U, 0x7fb2b2cdU, 0xea75759fU,
+    0x1209091bU, 0x1d83839eU, 0x582c2c74U, 0x341a1a2eU,
+    0x361b1b2dU, 0xdc6e6eb2U, 0xb45a5aeeU, 0x5ba0a0fbU,
+    0xa45252f6U, 0x763b3b4dU, 0xb7d6d661U, 0x7db3b3ceU,
+    0x5229297bU, 0xdde3e33eU, 0x5e2f2f71U, 0x13848497U,
+    0xa65353f5U, 0xb9d1d168U, 0x00000000U, 0xc1eded2cU,
+    0x40202060U, 0xe3fcfc1fU, 0x79b1b1c8U, 0xb65b5bedU,
+    0xd46a6abeU, 0x8dcbcb46U, 0x67bebed9U, 0x7239394bU,
+    0x944a4adeU, 0x984c4cd4U, 0xb05858e8U, 0x85cfcf4aU,
+    0xbbd0d06bU, 0xc5efef2aU, 0x4faaaae5U, 0xedfbfb16U,
+    0x864343c5U, 0x9a4d4dd7U, 0x66333355U, 0x11858594U,
+    0x8a4545cfU, 0xe9f9f910U, 0x04020206U, 0xfe7f7f81U,
+    0xa05050f0U, 0x783c3c44U, 0x259f9fbaU, 0x4ba8a8e3U,
+    0xa25151f3U, 0x5da3a3feU, 0x804040c0U, 0x058f8f8aU,
+    0x3f9292adU, 0x219d9dbcU, 0x70383848U, 0xf1f5f504U,
+    0x63bcbcdfU, 0x77b6b6c1U, 0xafdada75U, 0x42212163U,
+    0x20101030U, 0xe5ffff1aU, 0xfdf3f30eU, 0xbfd2d26dU,
+    0x81cdcd4cU, 0x180c0c14U, 0x26131335U, 0xc3ecec2fU,
+    0xbe5f5fe1U, 0x359797a2U, 0x884444ccU, 0x2e171739U,
+    0x93c4c457U, 0x55a7a7f2U, 0xfc7e7e82U, 0x7a3d3d47U,
+    0xc86464acU, 0xba5d5de7U, 0x3219192bU, 0xe6737395U,
+    0xc06060a0U, 0x19818198U, 0x9e4f4fd1U, 0xa3dcdc7fU,
+    0x44222266U, 0x542a2a7eU, 0x3b9090abU, 0x0b888883U,
+    0x8c4646caU, 0xc7eeee29U, 0x6bb8b8d3U, 0x2814143cU,
+    0xa7dede79U, 0xbc5e5ee2U, 0x160b0b1dU, 0xaddbdb76U,
+    0xdbe0e03bU, 0x64323256U, 0x743a3a4eU, 0x140a0a1eU,
+    0x924949dbU, 0x0c06060aU, 0x4824246cU, 0xb85c5ce4U,
+    0x9fc2c25dU, 0xbdd3d36eU, 0x43acacefU, 0xc46262a6U,
+    0x399191a8U, 0x319595a4U, 0xd3e4e437U, 0xf279798bU,
+    0xd5e7e732U, 0x8bc8c843U, 0x6e373759U, 0xda6d6db7U,
+    0x018d8d8cU, 0xb1d5d564U, 0x9c4e4ed2U, 0x49a9a9e0U,
+    0xd86c6cb4U, 0xac5656faU, 0xf3f4f407U, 0xcfeaea25U,
+    0xca6565afU, 0xf47a7a8eU, 0x47aeaee9U, 0x10080818U,
+    0x6fbabad5U, 0xf0787888U, 0x4a25256fU, 0x5c2e2e72U,
+    0x381c1c24U, 0x57a6a6f1U, 0x73b4b4c7U, 0x97c6c651U,
+    0xcbe8e823U, 0xa1dddd7cU, 0xe874749cU, 0x3e1f1f21U,
+    0x964b4bddU, 0x61bdbddcU, 0x0d8b8b86U, 0x0f8a8a85U,
+    0xe0707090U, 0x7c3e3e42U, 0x71b5b5c4U, 0xcc6666aaU,
+    0x904848d8U, 0x06030305U, 0xf7f6f601U, 0x1c0e0e12U,
+    0xc26161a3U, 0x6a35355fU, 0xae5757f9U, 0x69b9b9d0U,
+    0x17868691U, 0x99c1c158U, 0x3a1d1d27U, 0x279e9eb9U,
+    0xd9e1e138U, 0xebf8f813U, 0x2b9898b3U, 0x22111133U,
+    0xd26969bbU, 0xa9d9d970U, 0x078e8e89U, 0x339494a7U,
+    0x2d9b9bb6U, 0x3c1e1e22U, 0x15878792U, 0xc9e9e920U,
+    0x87cece49U, 0xaa5555ffU, 0x50282878U, 0xa5dfdf7aU,
+    0x038c8c8fU, 0x59a1a1f8U, 0x09898980U, 0x1a0d0d17U,
+    0x65bfbfdaU, 0xd7e6e631U, 0x844242c6U, 0xd06868b8U,
+    0x824141c3U, 0x299999b0U, 0x5a2d2d77U, 0x1e0f0f11U,
+    0x7bb0b0cbU, 0xa85454fcU, 0x6dbbbbd6U, 0x2c16163aU,
+};
+#ifndef AES_SMALL_TABLES
+static const u32 Te1[256] = {
+    0xa5c66363U, 0x84f87c7cU, 0x99ee7777U, 0x8df67b7bU,
+    0x0dfff2f2U, 0xbdd66b6bU, 0xb1de6f6fU, 0x5491c5c5U,
+    0x50603030U, 0x03020101U, 0xa9ce6767U, 0x7d562b2bU,
+    0x19e7fefeU, 0x62b5d7d7U, 0xe64dababU, 0x9aec7676U,
+    0x458fcacaU, 0x9d1f8282U, 0x4089c9c9U, 0x87fa7d7dU,
+    0x15effafaU, 0xebb25959U, 0xc98e4747U, 0x0bfbf0f0U,
+    0xec41adadU, 0x67b3d4d4U, 0xfd5fa2a2U, 0xea45afafU,
+    0xbf239c9cU, 0xf753a4a4U, 0x96e47272U, 0x5b9bc0c0U,
+    0xc275b7b7U, 0x1ce1fdfdU, 0xae3d9393U, 0x6a4c2626U,
+    0x5a6c3636U, 0x417e3f3fU, 0x02f5f7f7U, 0x4f83ccccU,
+    0x5c683434U, 0xf451a5a5U, 0x34d1e5e5U, 0x08f9f1f1U,
+    0x93e27171U, 0x73abd8d8U, 0x53623131U, 0x3f2a1515U,
+    0x0c080404U, 0x5295c7c7U, 0x65462323U, 0x5e9dc3c3U,
+    0x28301818U, 0xa1379696U, 0x0f0a0505U, 0xb52f9a9aU,
+    0x090e0707U, 0x36241212U, 0x9b1b8080U, 0x3ddfe2e2U,
+    0x26cdebebU, 0x694e2727U, 0xcd7fb2b2U, 0x9fea7575U,
+    0x1b120909U, 0x9e1d8383U, 0x74582c2cU, 0x2e341a1aU,
+    0x2d361b1bU, 0xb2dc6e6eU, 0xeeb45a5aU, 0xfb5ba0a0U,
+    0xf6a45252U, 0x4d763b3bU, 0x61b7d6d6U, 0xce7db3b3U,
+    0x7b522929U, 0x3edde3e3U, 0x715e2f2fU, 0x97138484U,
+    0xf5a65353U, 0x68b9d1d1U, 0x00000000U, 0x2cc1ededU,
+    0x60402020U, 0x1fe3fcfcU, 0xc879b1b1U, 0xedb65b5bU,
+    0xbed46a6aU, 0x468dcbcbU, 0xd967bebeU, 0x4b723939U,
+    0xde944a4aU, 0xd4984c4cU, 0xe8b05858U, 0x4a85cfcfU,
+    0x6bbbd0d0U, 0x2ac5efefU, 0xe54faaaaU, 0x16edfbfbU,
+    0xc5864343U, 0xd79a4d4dU, 0x55663333U, 0x94118585U,
+    0xcf8a4545U, 0x10e9f9f9U, 0x06040202U, 0x81fe7f7fU,
+    0xf0a05050U, 0x44783c3cU, 0xba259f9fU, 0xe34ba8a8U,
+    0xf3a25151U, 0xfe5da3a3U, 0xc0804040U, 0x8a058f8fU,
+    0xad3f9292U, 0xbc219d9dU, 0x48703838U, 0x04f1f5f5U,
+    0xdf63bcbcU, 0xc177b6b6U, 0x75afdadaU, 0x63422121U,
+    0x30201010U, 0x1ae5ffffU, 0x0efdf3f3U, 0x6dbfd2d2U,
+    0x4c81cdcdU, 0x14180c0cU, 0x35261313U, 0x2fc3ececU,
+    0xe1be5f5fU, 0xa2359797U, 0xcc884444U, 0x392e1717U,
+    0x5793c4c4U, 0xf255a7a7U, 0x82fc7e7eU, 0x477a3d3dU,
+    0xacc86464U, 0xe7ba5d5dU, 0x2b321919U, 0x95e67373U,
+    0xa0c06060U, 0x98198181U, 0xd19e4f4fU, 0x7fa3dcdcU,
+    0x66442222U, 0x7e542a2aU, 0xab3b9090U, 0x830b8888U,
+    0xca8c4646U, 0x29c7eeeeU, 0xd36bb8b8U, 0x3c281414U,
+    0x79a7dedeU, 0xe2bc5e5eU, 0x1d160b0bU, 0x76addbdbU,
+    0x3bdbe0e0U, 0x56643232U, 0x4e743a3aU, 0x1e140a0aU,
+    0xdb924949U, 0x0a0c0606U, 0x6c482424U, 0xe4b85c5cU,
+    0x5d9fc2c2U, 0x6ebdd3d3U, 0xef43acacU, 0xa6c46262U,
+    0xa8399191U, 0xa4319595U, 0x37d3e4e4U, 0x8bf27979U,
+    0x32d5e7e7U, 0x438bc8c8U, 0x596e3737U, 0xb7da6d6dU,
+    0x8c018d8dU, 0x64b1d5d5U, 0xd29c4e4eU, 0xe049a9a9U,
+    0xb4d86c6cU, 0xfaac5656U, 0x07f3f4f4U, 0x25cfeaeaU,
+    0xafca6565U, 0x8ef47a7aU, 0xe947aeaeU, 0x18100808U,
+    0xd56fbabaU, 0x88f07878U, 0x6f4a2525U, 0x725c2e2eU,
+    0x24381c1cU, 0xf157a6a6U, 0xc773b4b4U, 0x5197c6c6U,
+    0x23cbe8e8U, 0x7ca1ddddU, 0x9ce87474U, 0x213e1f1fU,
+    0xdd964b4bU, 0xdc61bdbdU, 0x860d8b8bU, 0x850f8a8aU,
+    0x90e07070U, 0x427c3e3eU, 0xc471b5b5U, 0xaacc6666U,
+    0xd8904848U, 0x05060303U, 0x01f7f6f6U, 0x121c0e0eU,
+    0xa3c26161U, 0x5f6a3535U, 0xf9ae5757U, 0xd069b9b9U,
+    0x91178686U, 0x5899c1c1U, 0x273a1d1dU, 0xb9279e9eU,
+    0x38d9e1e1U, 0x13ebf8f8U, 0xb32b9898U, 0x33221111U,
+    0xbbd26969U, 0x70a9d9d9U, 0x89078e8eU, 0xa7339494U,
+    0xb62d9b9bU, 0x223c1e1eU, 0x92158787U, 0x20c9e9e9U,
+    0x4987ceceU, 0xffaa5555U, 0x78502828U, 0x7aa5dfdfU,
+    0x8f038c8cU, 0xf859a1a1U, 0x80098989U, 0x171a0d0dU,
+    0xda65bfbfU, 0x31d7e6e6U, 0xc6844242U, 0xb8d06868U,
+    0xc3824141U, 0xb0299999U, 0x775a2d2dU, 0x111e0f0fU,
+    0xcb7bb0b0U, 0xfca85454U, 0xd66dbbbbU, 0x3a2c1616U,
+};
+static const u32 Te2[256] = {
+    0x63a5c663U, 0x7c84f87cU, 0x7799ee77U, 0x7b8df67bU,
+    0xf20dfff2U, 0x6bbdd66bU, 0x6fb1de6fU, 0xc55491c5U,
+    0x30506030U, 0x01030201U, 0x67a9ce67U, 0x2b7d562bU,
+    0xfe19e7feU, 0xd762b5d7U, 0xabe64dabU, 0x769aec76U,
+    0xca458fcaU, 0x829d1f82U, 0xc94089c9U, 0x7d87fa7dU,
+    0xfa15effaU, 0x59ebb259U, 0x47c98e47U, 0xf00bfbf0U,
+    0xadec41adU, 0xd467b3d4U, 0xa2fd5fa2U, 0xafea45afU,
+    0x9cbf239cU, 0xa4f753a4U, 0x7296e472U, 0xc05b9bc0U,
+    0xb7c275b7U, 0xfd1ce1fdU, 0x93ae3d93U, 0x266a4c26U,
+    0x365a6c36U, 0x3f417e3fU, 0xf702f5f7U, 0xcc4f83ccU,
+    0x345c6834U, 0xa5f451a5U, 0xe534d1e5U, 0xf108f9f1U,
+    0x7193e271U, 0xd873abd8U, 0x31536231U, 0x153f2a15U,
+    0x040c0804U, 0xc75295c7U, 0x23654623U, 0xc35e9dc3U,
+    0x18283018U, 0x96a13796U, 0x050f0a05U, 0x9ab52f9aU,
+    0x07090e07U, 0x12362412U, 0x809b1b80U, 0xe23ddfe2U,
+    0xeb26cdebU, 0x27694e27U, 0xb2cd7fb2U, 0x759fea75U,
+    0x091b1209U, 0x839e1d83U, 0x2c74582cU, 0x1a2e341aU,
+    0x1b2d361bU, 0x6eb2dc6eU, 0x5aeeb45aU, 0xa0fb5ba0U,
+    0x52f6a452U, 0x3b4d763bU, 0xd661b7d6U, 0xb3ce7db3U,
+    0x297b5229U, 0xe33edde3U, 0x2f715e2fU, 0x84971384U,
+    0x53f5a653U, 0xd168b9d1U, 0x00000000U, 0xed2cc1edU,
+    0x20604020U, 0xfc1fe3fcU, 0xb1c879b1U, 0x5bedb65bU,
+    0x6abed46aU, 0xcb468dcbU, 0xbed967beU, 0x394b7239U,
+    0x4ade944aU, 0x4cd4984cU, 0x58e8b058U, 0xcf4a85cfU,
+    0xd06bbbd0U, 0xef2ac5efU, 0xaae54faaU, 0xfb16edfbU,
+    0x43c58643U, 0x4dd79a4dU, 0x33556633U, 0x85941185U,
+    0x45cf8a45U, 0xf910e9f9U, 0x02060402U, 0x7f81fe7fU,
+    0x50f0a050U, 0x3c44783cU, 0x9fba259fU, 0xa8e34ba8U,
+    0x51f3a251U, 0xa3fe5da3U, 0x40c08040U, 0x8f8a058fU,
+    0x92ad3f92U, 0x9dbc219dU, 0x38487038U, 0xf504f1f5U,
+    0xbcdf63bcU, 0xb6c177b6U, 0xda75afdaU, 0x21634221U,
+    0x10302010U, 0xff1ae5ffU, 0xf30efdf3U, 0xd26dbfd2U,
+    0xcd4c81cdU, 0x0c14180cU, 0x13352613U, 0xec2fc3ecU,
+    0x5fe1be5fU, 0x97a23597U, 0x44cc8844U, 0x17392e17U,
+    0xc45793c4U, 0xa7f255a7U, 0x7e82fc7eU, 0x3d477a3dU,
+    0x64acc864U, 0x5de7ba5dU, 0x192b3219U, 0x7395e673U,
+    0x60a0c060U, 0x81981981U, 0x4fd19e4fU, 0xdc7fa3dcU,
+    0x22664422U, 0x2a7e542aU, 0x90ab3b90U, 0x88830b88U,
+    0x46ca8c46U, 0xee29c7eeU, 0xb8d36bb8U, 0x143c2814U,
+    0xde79a7deU, 0x5ee2bc5eU, 0x0b1d160bU, 0xdb76addbU,
+    0xe03bdbe0U, 0x32566432U, 0x3a4e743aU, 0x0a1e140aU,
+    0x49db9249U, 0x060a0c06U, 0x246c4824U, 0x5ce4b85cU,
+    0xc25d9fc2U, 0xd36ebdd3U, 0xacef43acU, 0x62a6c462U,
+    0x91a83991U, 0x95a43195U, 0xe437d3e4U, 0x798bf279U,
+    0xe732d5e7U, 0xc8438bc8U, 0x37596e37U, 0x6db7da6dU,
+    0x8d8c018dU, 0xd564b1d5U, 0x4ed29c4eU, 0xa9e049a9U,
+    0x6cb4d86cU, 0x56faac56U, 0xf407f3f4U, 0xea25cfeaU,
+    0x65afca65U, 0x7a8ef47aU, 0xaee947aeU, 0x08181008U,
+    0xbad56fbaU, 0x7888f078U, 0x256f4a25U, 0x2e725c2eU,
+    0x1c24381cU, 0xa6f157a6U, 0xb4c773b4U, 0xc65197c6U,
+    0xe823cbe8U, 0xdd7ca1ddU, 0x749ce874U, 0x1f213e1fU,
+    0x4bdd964bU, 0xbddc61bdU, 0x8b860d8bU, 0x8a850f8aU,
+    0x7090e070U, 0x3e427c3eU, 0xb5c471b5U, 0x66aacc66U,
+    0x48d89048U, 0x03050603U, 0xf601f7f6U, 0x0e121c0eU,
+    0x61a3c261U, 0x355f6a35U, 0x57f9ae57U, 0xb9d069b9U,
+    0x86911786U, 0xc15899c1U, 0x1d273a1dU, 0x9eb9279eU,
+    0xe138d9e1U, 0xf813ebf8U, 0x98b32b98U, 0x11332211U,
+    0x69bbd269U, 0xd970a9d9U, 0x8e89078eU, 0x94a73394U,
+    0x9bb62d9bU, 0x1e223c1eU, 0x87921587U, 0xe920c9e9U,
+    0xce4987ceU, 0x55ffaa55U, 0x28785028U, 0xdf7aa5dfU,
+    0x8c8f038cU, 0xa1f859a1U, 0x89800989U, 0x0d171a0dU,
+    0xbfda65bfU, 0xe631d7e6U, 0x42c68442U, 0x68b8d068U,
+    0x41c38241U, 0x99b02999U, 0x2d775a2dU, 0x0f111e0fU,
+    0xb0cb7bb0U, 0x54fca854U, 0xbbd66dbbU, 0x163a2c16U,
+};
+static const u32 Te3[256] = {
+
+    0x6363a5c6U, 0x7c7c84f8U, 0x777799eeU, 0x7b7b8df6U,
+    0xf2f20dffU, 0x6b6bbdd6U, 0x6f6fb1deU, 0xc5c55491U,
+    0x30305060U, 0x01010302U, 0x6767a9ceU, 0x2b2b7d56U,
+    0xfefe19e7U, 0xd7d762b5U, 0xababe64dU, 0x76769aecU,
+    0xcaca458fU, 0x82829d1fU, 0xc9c94089U, 0x7d7d87faU,
+    0xfafa15efU, 0x5959ebb2U, 0x4747c98eU, 0xf0f00bfbU,
+    0xadadec41U, 0xd4d467b3U, 0xa2a2fd5fU, 0xafafea45U,
+    0x9c9cbf23U, 0xa4a4f753U, 0x727296e4U, 0xc0c05b9bU,
+    0xb7b7c275U, 0xfdfd1ce1U, 0x9393ae3dU, 0x26266a4cU,
+    0x36365a6cU, 0x3f3f417eU, 0xf7f702f5U, 0xcccc4f83U,
+    0x34345c68U, 0xa5a5f451U, 0xe5e534d1U, 0xf1f108f9U,
+    0x717193e2U, 0xd8d873abU, 0x31315362U, 0x15153f2aU,
+    0x04040c08U, 0xc7c75295U, 0x23236546U, 0xc3c35e9dU,
+    0x18182830U, 0x9696a137U, 0x05050f0aU, 0x9a9ab52fU,
+    0x0707090eU, 0x12123624U, 0x80809b1bU, 0xe2e23ddfU,
+    0xebeb26cdU, 0x2727694eU, 0xb2b2cd7fU, 0x75759feaU,
+    0x09091b12U, 0x83839e1dU, 0x2c2c7458U, 0x1a1a2e34U,
+    0x1b1b2d36U, 0x6e6eb2dcU, 0x5a5aeeb4U, 0xa0a0fb5bU,
+    0x5252f6a4U, 0x3b3b4d76U, 0xd6d661b7U, 0xb3b3ce7dU,
+    0x29297b52U, 0xe3e33eddU, 0x2f2f715eU, 0x84849713U,
+    0x5353f5a6U, 0xd1d168b9U, 0x00000000U, 0xeded2cc1U,
+    0x20206040U, 0xfcfc1fe3U, 0xb1b1c879U, 0x5b5bedb6U,
+    0x6a6abed4U, 0xcbcb468dU, 0xbebed967U, 0x39394b72U,
+    0x4a4ade94U, 0x4c4cd498U, 0x5858e8b0U, 0xcfcf4a85U,
+    0xd0d06bbbU, 0xefef2ac5U, 0xaaaae54fU, 0xfbfb16edU,
+    0x4343c586U, 0x4d4dd79aU, 0x33335566U, 0x85859411U,
+    0x4545cf8aU, 0xf9f910e9U, 0x02020604U, 0x7f7f81feU,
+    0x5050f0a0U, 0x3c3c4478U, 0x9f9fba25U, 0xa8a8e34bU,
+    0x5151f3a2U, 0xa3a3fe5dU, 0x4040c080U, 0x8f8f8a05U,
+    0x9292ad3fU, 0x9d9dbc21U, 0x38384870U, 0xf5f504f1U,
+    0xbcbcdf63U, 0xb6b6c177U, 0xdada75afU, 0x21216342U,
+    0x10103020U, 0xffff1ae5U, 0xf3f30efdU, 0xd2d26dbfU,
+    0xcdcd4c81U, 0x0c0c1418U, 0x13133526U, 0xecec2fc3U,
+    0x5f5fe1beU, 0x9797a235U, 0x4444cc88U, 0x1717392eU,
+    0xc4c45793U, 0xa7a7f255U, 0x7e7e82fcU, 0x3d3d477aU,
+    0x6464acc8U, 0x5d5de7baU, 0x19192b32U, 0x737395e6U,
+    0x6060a0c0U, 0x81819819U, 0x4f4fd19eU, 0xdcdc7fa3U,
+    0x22226644U, 0x2a2a7e54U, 0x9090ab3bU, 0x8888830bU,
+    0x4646ca8cU, 0xeeee29c7U, 0xb8b8d36bU, 0x14143c28U,
+    0xdede79a7U, 0x5e5ee2bcU, 0x0b0b1d16U, 0xdbdb76adU,
+    0xe0e03bdbU, 0x32325664U, 0x3a3a4e74U, 0x0a0a1e14U,
+    0x4949db92U, 0x06060a0cU, 0x24246c48U, 0x5c5ce4b8U,
+    0xc2c25d9fU, 0xd3d36ebdU, 0xacacef43U, 0x6262a6c4U,
+    0x9191a839U, 0x9595a431U, 0xe4e437d3U, 0x79798bf2U,
+    0xe7e732d5U, 0xc8c8438bU, 0x3737596eU, 0x6d6db7daU,
+    0x8d8d8c01U, 0xd5d564b1U, 0x4e4ed29cU, 0xa9a9e049U,
+    0x6c6cb4d8U, 0x5656faacU, 0xf4f407f3U, 0xeaea25cfU,
+    0x6565afcaU, 0x7a7a8ef4U, 0xaeaee947U, 0x08081810U,
+    0xbabad56fU, 0x787888f0U, 0x25256f4aU, 0x2e2e725cU,
+    0x1c1c2438U, 0xa6a6f157U, 0xb4b4c773U, 0xc6c65197U,
+    0xe8e823cbU, 0xdddd7ca1U, 0x74749ce8U, 0x1f1f213eU,
+    0x4b4bdd96U, 0xbdbddc61U, 0x8b8b860dU, 0x8a8a850fU,
+    0x707090e0U, 0x3e3e427cU, 0xb5b5c471U, 0x6666aaccU,
+    0x4848d890U, 0x03030506U, 0xf6f601f7U, 0x0e0e121cU,
+    0x6161a3c2U, 0x35355f6aU, 0x5757f9aeU, 0xb9b9d069U,
+    0x86869117U, 0xc1c15899U, 0x1d1d273aU, 0x9e9eb927U,
+    0xe1e138d9U, 0xf8f813ebU, 0x9898b32bU, 0x11113322U,
+    0x6969bbd2U, 0xd9d970a9U, 0x8e8e8907U, 0x9494a733U,
+    0x9b9bb62dU, 0x1e1e223cU, 0x87879215U, 0xe9e920c9U,
+    0xcece4987U, 0x5555ffaaU, 0x28287850U, 0xdfdf7aa5U,
+    0x8c8c8f03U, 0xa1a1f859U, 0x89898009U, 0x0d0d171aU,
+    0xbfbfda65U, 0xe6e631d7U, 0x4242c684U, 0x6868b8d0U,
+    0x4141c382U, 0x9999b029U, 0x2d2d775aU, 0x0f0f111eU,
+    0xb0b0cb7bU, 0x5454fca8U, 0xbbbbd66dU, 0x16163a2cU,
+};
+static const u32 Te4[256] = {
+    0x63636363U, 0x7c7c7c7cU, 0x77777777U, 0x7b7b7b7bU,
+    0xf2f2f2f2U, 0x6b6b6b6bU, 0x6f6f6f6fU, 0xc5c5c5c5U,
+    0x30303030U, 0x01010101U, 0x67676767U, 0x2b2b2b2bU,
+    0xfefefefeU, 0xd7d7d7d7U, 0xababababU, 0x76767676U,
+    0xcacacacaU, 0x82828282U, 0xc9c9c9c9U, 0x7d7d7d7dU,
+    0xfafafafaU, 0x59595959U, 0x47474747U, 0xf0f0f0f0U,
+    0xadadadadU, 0xd4d4d4d4U, 0xa2a2a2a2U, 0xafafafafU,
+    0x9c9c9c9cU, 0xa4a4a4a4U, 0x72727272U, 0xc0c0c0c0U,
+    0xb7b7b7b7U, 0xfdfdfdfdU, 0x93939393U, 0x26262626U,
+    0x36363636U, 0x3f3f3f3fU, 0xf7f7f7f7U, 0xccccccccU,
+    0x34343434U, 0xa5a5a5a5U, 0xe5e5e5e5U, 0xf1f1f1f1U,
+    0x71717171U, 0xd8d8d8d8U, 0x31313131U, 0x15151515U,
+    0x04040404U, 0xc7c7c7c7U, 0x23232323U, 0xc3c3c3c3U,
+    0x18181818U, 0x96969696U, 0x05050505U, 0x9a9a9a9aU,
+    0x07070707U, 0x12121212U, 0x80808080U, 0xe2e2e2e2U,
+    0xebebebebU, 0x27272727U, 0xb2b2b2b2U, 0x75757575U,
+    0x09090909U, 0x83838383U, 0x2c2c2c2cU, 0x1a1a1a1aU,
+    0x1b1b1b1bU, 0x6e6e6e6eU, 0x5a5a5a5aU, 0xa0a0a0a0U,
+    0x52525252U, 0x3b3b3b3bU, 0xd6d6d6d6U, 0xb3b3b3b3U,
+    0x29292929U, 0xe3e3e3e3U, 0x2f2f2f2fU, 0x84848484U,
+    0x53535353U, 0xd1d1d1d1U, 0x00000000U, 0xededededU,
+    0x20202020U, 0xfcfcfcfcU, 0xb1b1b1b1U, 0x5b5b5b5bU,
+    0x6a6a6a6aU, 0xcbcbcbcbU, 0xbebebebeU, 0x39393939U,
+    0x4a4a4a4aU, 0x4c4c4c4cU, 0x58585858U, 0xcfcfcfcfU,
+    0xd0d0d0d0U, 0xefefefefU, 0xaaaaaaaaU, 0xfbfbfbfbU,
+    0x43434343U, 0x4d4d4d4dU, 0x33333333U, 0x85858585U,
+    0x45454545U, 0xf9f9f9f9U, 0x02020202U, 0x7f7f7f7fU,
+    0x50505050U, 0x3c3c3c3cU, 0x9f9f9f9fU, 0xa8a8a8a8U,
+    0x51515151U, 0xa3a3a3a3U, 0x40404040U, 0x8f8f8f8fU,
+    0x92929292U, 0x9d9d9d9dU, 0x38383838U, 0xf5f5f5f5U,
+    0xbcbcbcbcU, 0xb6b6b6b6U, 0xdadadadaU, 0x21212121U,
+    0x10101010U, 0xffffffffU, 0xf3f3f3f3U, 0xd2d2d2d2U,
+    0xcdcdcdcdU, 0x0c0c0c0cU, 0x13131313U, 0xececececU,
+    0x5f5f5f5fU, 0x97979797U, 0x44444444U, 0x17171717U,
+    0xc4c4c4c4U, 0xa7a7a7a7U, 0x7e7e7e7eU, 0x3d3d3d3dU,
+    0x64646464U, 0x5d5d5d5dU, 0x19191919U, 0x73737373U,
+    0x60606060U, 0x81818181U, 0x4f4f4f4fU, 0xdcdcdcdcU,
+    0x22222222U, 0x2a2a2a2aU, 0x90909090U, 0x88888888U,
+    0x46464646U, 0xeeeeeeeeU, 0xb8b8b8b8U, 0x14141414U,
+    0xdedededeU, 0x5e5e5e5eU, 0x0b0b0b0bU, 0xdbdbdbdbU,
+    0xe0e0e0e0U, 0x32323232U, 0x3a3a3a3aU, 0x0a0a0a0aU,
+    0x49494949U, 0x06060606U, 0x24242424U, 0x5c5c5c5cU,
+    0xc2c2c2c2U, 0xd3d3d3d3U, 0xacacacacU, 0x62626262U,
+    0x91919191U, 0x95959595U, 0xe4e4e4e4U, 0x79797979U,
+    0xe7e7e7e7U, 0xc8c8c8c8U, 0x37373737U, 0x6d6d6d6dU,
+    0x8d8d8d8dU, 0xd5d5d5d5U, 0x4e4e4e4eU, 0xa9a9a9a9U,
+    0x6c6c6c6cU, 0x56565656U, 0xf4f4f4f4U, 0xeaeaeaeaU,
+    0x65656565U, 0x7a7a7a7aU, 0xaeaeaeaeU, 0x08080808U,
+    0xbabababaU, 0x78787878U, 0x25252525U, 0x2e2e2e2eU,
+    0x1c1c1c1cU, 0xa6a6a6a6U, 0xb4b4b4b4U, 0xc6c6c6c6U,
+    0xe8e8e8e8U, 0xddddddddU, 0x74747474U, 0x1f1f1f1fU,
+    0x4b4b4b4bU, 0xbdbdbdbdU, 0x8b8b8b8bU, 0x8a8a8a8aU,
+    0x70707070U, 0x3e3e3e3eU, 0xb5b5b5b5U, 0x66666666U,
+    0x48484848U, 0x03030303U, 0xf6f6f6f6U, 0x0e0e0e0eU,
+    0x61616161U, 0x35353535U, 0x57575757U, 0xb9b9b9b9U,
+    0x86868686U, 0xc1c1c1c1U, 0x1d1d1d1dU, 0x9e9e9e9eU,
+    0xe1e1e1e1U, 0xf8f8f8f8U, 0x98989898U, 0x11111111U,
+    0x69696969U, 0xd9d9d9d9U, 0x8e8e8e8eU, 0x94949494U,
+    0x9b9b9b9bU, 0x1e1e1e1eU, 0x87878787U, 0xe9e9e9e9U,
+    0xcecececeU, 0x55555555U, 0x28282828U, 0xdfdfdfdfU,
+    0x8c8c8c8cU, 0xa1a1a1a1U, 0x89898989U, 0x0d0d0d0dU,
+    0xbfbfbfbfU, 0xe6e6e6e6U, 0x42424242U, 0x68686868U,
+    0x41414141U, 0x99999999U, 0x2d2d2d2dU, 0x0f0f0f0fU,
+    0xb0b0b0b0U, 0x54545454U, 0xbbbbbbbbU, 0x16161616U,
+};
+#endif /* AES_SMALL_TABLES */
+static const u32 Td0[256] = {
+    0x51f4a750U, 0x7e416553U, 0x1a17a4c3U, 0x3a275e96U,
+    0x3bab6bcbU, 0x1f9d45f1U, 0xacfa58abU, 0x4be30393U,
+    0x2030fa55U, 0xad766df6U, 0x88cc7691U, 0xf5024c25U,
+    0x4fe5d7fcU, 0xc52acbd7U, 0x26354480U, 0xb562a38fU,
+    0xdeb15a49U, 0x25ba1b67U, 0x45ea0e98U, 0x5dfec0e1U,
+    0xc32f7502U, 0x814cf012U, 0x8d4697a3U, 0x6bd3f9c6U,
+    0x038f5fe7U, 0x15929c95U, 0xbf6d7aebU, 0x955259daU,
+    0xd4be832dU, 0x587421d3U, 0x49e06929U, 0x8ec9c844U,
+    0x75c2896aU, 0xf48e7978U, 0x99583e6bU, 0x27b971ddU,
+    0xbee14fb6U, 0xf088ad17U, 0xc920ac66U, 0x7dce3ab4U,
+    0x63df4a18U, 0xe51a3182U, 0x97513360U, 0x62537f45U,
+    0xb16477e0U, 0xbb6bae84U, 0xfe81a01cU, 0xf9082b94U,
+    0x70486858U, 0x8f45fd19U, 0x94de6c87U, 0x527bf8b7U,
+    0xab73d323U, 0x724b02e2U, 0xe31f8f57U, 0x6655ab2aU,
+    0xb2eb2807U, 0x2fb5c203U, 0x86c57b9aU, 0xd33708a5U,
+    0x302887f2U, 0x23bfa5b2U, 0x02036abaU, 0xed16825cU,
+    0x8acf1c2bU, 0xa779b492U, 0xf307f2f0U, 0x4e69e2a1U,
+    0x65daf4cdU, 0x0605bed5U, 0xd134621fU, 0xc4a6fe8aU,
+    0x342e539dU, 0xa2f355a0U, 0x058ae132U, 0xa4f6eb75U,
+    0x0b83ec39U, 0x4060efaaU, 0x5e719f06U, 0xbd6e1051U,
+    0x3e218af9U, 0x96dd063dU, 0xdd3e05aeU, 0x4de6bd46U,
+    0x91548db5U, 0x71c45d05U, 0x0406d46fU, 0x605015ffU,
+    0x1998fb24U, 0xd6bde997U, 0x894043ccU, 0x67d99e77U,
+    0xb0e842bdU, 0x07898b88U, 0xe7195b38U, 0x79c8eedbU,
+    0xa17c0a47U, 0x7c420fe9U, 0xf8841ec9U, 0x00000000U,
+    0x09808683U, 0x322bed48U, 0x1e1170acU, 0x6c5a724eU,
+    0xfd0efffbU, 0x0f853856U, 0x3daed51eU, 0x362d3927U,
+    0x0a0fd964U, 0x685ca621U, 0x9b5b54d1U, 0x24362e3aU,
+    0x0c0a67b1U, 0x9357e70fU, 0xb4ee96d2U, 0x1b9b919eU,
+    0x80c0c54fU, 0x61dc20a2U, 0x5a774b69U, 0x1c121a16U,
+    0xe293ba0aU, 0xc0a02ae5U, 0x3c22e043U, 0x121b171dU,
+    0x0e090d0bU, 0xf28bc7adU, 0x2db6a8b9U, 0x141ea9c8U,
+    0x57f11985U, 0xaf75074cU, 0xee99ddbbU, 0xa37f60fdU,
+    0xf701269fU, 0x5c72f5bcU, 0x44663bc5U, 0x5bfb7e34U,
+    0x8b432976U, 0xcb23c6dcU, 0xb6edfc68U, 0xb8e4f163U,
+    0xd731dccaU, 0x42638510U, 0x13972240U, 0x84c61120U,
+    0x854a247dU, 0xd2bb3df8U, 0xaef93211U, 0xc729a16dU,
+    0x1d9e2f4bU, 0xdcb230f3U, 0x0d8652ecU, 0x77c1e3d0U,
+    0x2bb3166cU, 0xa970b999U, 0x119448faU, 0x47e96422U,
+    0xa8fc8cc4U, 0xa0f03f1aU, 0x567d2cd8U, 0x223390efU,
+    0x87494ec7U, 0xd938d1c1U, 0x8ccaa2feU, 0x98d40b36U,
+    0xa6f581cfU, 0xa57ade28U, 0xdab78e26U, 0x3fadbfa4U,
+    0x2c3a9de4U, 0x5078920dU, 0x6a5fcc9bU, 0x547e4662U,
+    0xf68d13c2U, 0x90d8b8e8U, 0x2e39f75eU, 0x82c3aff5U,
+    0x9f5d80beU, 0x69d0937cU, 0x6fd52da9U, 0xcf2512b3U,
+    0xc8ac993bU, 0x10187da7U, 0xe89c636eU, 0xdb3bbb7bU,
+    0xcd267809U, 0x6e5918f4U, 0xec9ab701U, 0x834f9aa8U,
+    0xe6956e65U, 0xaaffe67eU, 0x21bccf08U, 0xef15e8e6U,
+    0xbae79bd9U, 0x4a6f36ceU, 0xea9f09d4U, 0x29b07cd6U,
+    0x31a4b2afU, 0x2a3f2331U, 0xc6a59430U, 0x35a266c0U,
+    0x744ebc37U, 0xfc82caa6U, 0xe090d0b0U, 0x33a7d815U,
+    0xf104984aU, 0x41ecdaf7U, 0x7fcd500eU, 0x1791f62fU,
+    0x764dd68dU, 0x43efb04dU, 0xccaa4d54U, 0xe49604dfU,
+    0x9ed1b5e3U, 0x4c6a881bU, 0xc12c1fb8U, 0x4665517fU,
+    0x9d5eea04U, 0x018c355dU, 0xfa877473U, 0xfb0b412eU,
+    0xb3671d5aU, 0x92dbd252U, 0xe9105633U, 0x6dd64713U,
+    0x9ad7618cU, 0x37a10c7aU, 0x59f8148eU, 0xeb133c89U,
+    0xcea927eeU, 0xb761c935U, 0xe11ce5edU, 0x7a47b13cU,
+    0x9cd2df59U, 0x55f2733fU, 0x1814ce79U, 0x73c737bfU,
+    0x53f7cdeaU, 0x5ffdaa5bU, 0xdf3d6f14U, 0x7844db86U,
+    0xcaaff381U, 0xb968c43eU, 0x3824342cU, 0xc2a3405fU,
+    0x161dc372U, 0xbce2250cU, 0x283c498bU, 0xff0d9541U,
+    0x39a80171U, 0x080cb3deU, 0xd8b4e49cU, 0x6456c190U,
+    0x7bcb8461U, 0xd532b670U, 0x486c5c74U, 0xd0b85742U,
+};
+#ifndef AES_SMALL_TABLES
+static const u32 Td1[256] = {
+    0x5051f4a7U, 0x537e4165U, 0xc31a17a4U, 0x963a275eU,
+    0xcb3bab6bU, 0xf11f9d45U, 0xabacfa58U, 0x934be303U,
+    0x552030faU, 0xf6ad766dU, 0x9188cc76U, 0x25f5024cU,
+    0xfc4fe5d7U, 0xd7c52acbU, 0x80263544U, 0x8fb562a3U,
+    0x49deb15aU, 0x6725ba1bU, 0x9845ea0eU, 0xe15dfec0U,
+    0x02c32f75U, 0x12814cf0U, 0xa38d4697U, 0xc66bd3f9U,
+    0xe7038f5fU, 0x9515929cU, 0xebbf6d7aU, 0xda955259U,
+    0x2dd4be83U, 0xd3587421U, 0x2949e069U, 0x448ec9c8U,
+    0x6a75c289U, 0x78f48e79U, 0x6b99583eU, 0xdd27b971U,
+    0xb6bee14fU, 0x17f088adU, 0x66c920acU, 0xb47dce3aU,
+    0x1863df4aU, 0x82e51a31U, 0x60975133U, 0x4562537fU,
+    0xe0b16477U, 0x84bb6baeU, 0x1cfe81a0U, 0x94f9082bU,
+    0x58704868U, 0x198f45fdU, 0x8794de6cU, 0xb7527bf8U,
+    0x23ab73d3U, 0xe2724b02U, 0x57e31f8fU, 0x2a6655abU,
+    0x07b2eb28U, 0x032fb5c2U, 0x9a86c57bU, 0xa5d33708U,
+    0xf2302887U, 0xb223bfa5U, 0xba02036aU, 0x5ced1682U,
+    0x2b8acf1cU, 0x92a779b4U, 0xf0f307f2U, 0xa14e69e2U,
+    0xcd65daf4U, 0xd50605beU, 0x1fd13462U, 0x8ac4a6feU,
+    0x9d342e53U, 0xa0a2f355U, 0x32058ae1U, 0x75a4f6ebU,
+    0x390b83ecU, 0xaa4060efU, 0x065e719fU, 0x51bd6e10U,
+    0xf93e218aU, 0x3d96dd06U, 0xaedd3e05U, 0x464de6bdU,
+    0xb591548dU, 0x0571c45dU, 0x6f0406d4U, 0xff605015U,
+    0x241998fbU, 0x97d6bde9U, 0xcc894043U, 0x7767d99eU,
+    0xbdb0e842U, 0x8807898bU, 0x38e7195bU, 0xdb79c8eeU,
+    0x47a17c0aU, 0xe97c420fU, 0xc9f8841eU, 0x00000000U,
+    0x83098086U, 0x48322bedU, 0xac1e1170U, 0x4e6c5a72U,
+    0xfbfd0effU, 0x560f8538U, 0x1e3daed5U, 0x27362d39U,
+    0x640a0fd9U, 0x21685ca6U, 0xd19b5b54U, 0x3a24362eU,
+    0xb10c0a67U, 0x0f9357e7U, 0xd2b4ee96U, 0x9e1b9b91U,
+    0x4f80c0c5U, 0xa261dc20U, 0x695a774bU, 0x161c121aU,
+    0x0ae293baU, 0xe5c0a02aU, 0x433c22e0U, 0x1d121b17U,
+    0x0b0e090dU, 0xadf28bc7U, 0xb92db6a8U, 0xc8141ea9U,
+    0x8557f119U, 0x4caf7507U, 0xbbee99ddU, 0xfda37f60U,
+    0x9ff70126U, 0xbc5c72f5U, 0xc544663bU, 0x345bfb7eU,
+    0x768b4329U, 0xdccb23c6U, 0x68b6edfcU, 0x63b8e4f1U,
+    0xcad731dcU, 0x10426385U, 0x40139722U, 0x2084c611U,
+    0x7d854a24U, 0xf8d2bb3dU, 0x11aef932U, 0x6dc729a1U,
+    0x4b1d9e2fU, 0xf3dcb230U, 0xec0d8652U, 0xd077c1e3U,
+    0x6c2bb316U, 0x99a970b9U, 0xfa119448U, 0x2247e964U,
+    0xc4a8fc8cU, 0x1aa0f03fU, 0xd8567d2cU, 0xef223390U,
+    0xc787494eU, 0xc1d938d1U, 0xfe8ccaa2U, 0x3698d40bU,
+    0xcfa6f581U, 0x28a57adeU, 0x26dab78eU, 0xa43fadbfU,
+    0xe42c3a9dU, 0x0d507892U, 0x9b6a5fccU, 0x62547e46U,
+    0xc2f68d13U, 0xe890d8b8U, 0x5e2e39f7U, 0xf582c3afU,
+    0xbe9f5d80U, 0x7c69d093U, 0xa96fd52dU, 0xb3cf2512U,
+    0x3bc8ac99U, 0xa710187dU, 0x6ee89c63U, 0x7bdb3bbbU,
+    0x09cd2678U, 0xf46e5918U, 0x01ec9ab7U, 0xa8834f9aU,
+    0x65e6956eU, 0x7eaaffe6U, 0x0821bccfU, 0xe6ef15e8U,
+    0xd9bae79bU, 0xce4a6f36U, 0xd4ea9f09U, 0xd629b07cU,
+    0xaf31a4b2U, 0x312a3f23U, 0x30c6a594U, 0xc035a266U,
+    0x37744ebcU, 0xa6fc82caU, 0xb0e090d0U, 0x1533a7d8U,
+    0x4af10498U, 0xf741ecdaU, 0x0e7fcd50U, 0x2f1791f6U,
+    0x8d764dd6U, 0x4d43efb0U, 0x54ccaa4dU, 0xdfe49604U,
+    0xe39ed1b5U, 0x1b4c6a88U, 0xb8c12c1fU, 0x7f466551U,
+    0x049d5eeaU, 0x5d018c35U, 0x73fa8774U, 0x2efb0b41U,
+    0x5ab3671dU, 0x5292dbd2U, 0x33e91056U, 0x136dd647U,
+    0x8c9ad761U, 0x7a37a10cU, 0x8e59f814U, 0x89eb133cU,
+    0xeecea927U, 0x35b761c9U, 0xede11ce5U, 0x3c7a47b1U,
+    0x599cd2dfU, 0x3f55f273U, 0x791814ceU, 0xbf73c737U,
+    0xea53f7cdU, 0x5b5ffdaaU, 0x14df3d6fU, 0x867844dbU,
+    0x81caaff3U, 0x3eb968c4U, 0x2c382434U, 0x5fc2a340U,
+    0x72161dc3U, 0x0cbce225U, 0x8b283c49U, 0x41ff0d95U,
+    0x7139a801U, 0xde080cb3U, 0x9cd8b4e4U, 0x906456c1U,
+    0x617bcb84U, 0x70d532b6U, 0x74486c5cU, 0x42d0b857U,
+};
+static const u32 Td2[256] = {
+    0xa75051f4U, 0x65537e41U, 0xa4c31a17U, 0x5e963a27U,
+    0x6bcb3babU, 0x45f11f9dU, 0x58abacfaU, 0x03934be3U,
+    0xfa552030U, 0x6df6ad76U, 0x769188ccU, 0x4c25f502U,
+    0xd7fc4fe5U, 0xcbd7c52aU, 0x44802635U, 0xa38fb562U,
+    0x5a49deb1U, 0x1b6725baU, 0x0e9845eaU, 0xc0e15dfeU,
+    0x7502c32fU, 0xf012814cU, 0x97a38d46U, 0xf9c66bd3U,
+    0x5fe7038fU, 0x9c951592U, 0x7aebbf6dU, 0x59da9552U,
+    0x832dd4beU, 0x21d35874U, 0x692949e0U, 0xc8448ec9U,
+    0x896a75c2U, 0x7978f48eU, 0x3e6b9958U, 0x71dd27b9U,
+    0x4fb6bee1U, 0xad17f088U, 0xac66c920U, 0x3ab47dceU,
+    0x4a1863dfU, 0x3182e51aU, 0x33609751U, 0x7f456253U,
+    0x77e0b164U, 0xae84bb6bU, 0xa01cfe81U, 0x2b94f908U,
+    0x68587048U, 0xfd198f45U, 0x6c8794deU, 0xf8b7527bU,
+    0xd323ab73U, 0x02e2724bU, 0x8f57e31fU, 0xab2a6655U,
+    0x2807b2ebU, 0xc2032fb5U, 0x7b9a86c5U, 0x08a5d337U,
+    0x87f23028U, 0xa5b223bfU, 0x6aba0203U, 0x825ced16U,
+    0x1c2b8acfU, 0xb492a779U, 0xf2f0f307U, 0xe2a14e69U,
+    0xf4cd65daU, 0xbed50605U, 0x621fd134U, 0xfe8ac4a6U,
+    0x539d342eU, 0x55a0a2f3U, 0xe132058aU, 0xeb75a4f6U,
+    0xec390b83U, 0xefaa4060U, 0x9f065e71U, 0x1051bd6eU,
+
+    0x8af93e21U, 0x063d96ddU, 0x05aedd3eU, 0xbd464de6U,
+    0x8db59154U, 0x5d0571c4U, 0xd46f0406U, 0x15ff6050U,
+    0xfb241998U, 0xe997d6bdU, 0x43cc8940U, 0x9e7767d9U,
+    0x42bdb0e8U, 0x8b880789U, 0x5b38e719U, 0xeedb79c8U,
+    0x0a47a17cU, 0x0fe97c42U, 0x1ec9f884U, 0x00000000U,
+    0x86830980U, 0xed48322bU, 0x70ac1e11U, 0x724e6c5aU,
+    0xfffbfd0eU, 0x38560f85U, 0xd51e3daeU, 0x3927362dU,
+    0xd9640a0fU, 0xa621685cU, 0x54d19b5bU, 0x2e3a2436U,
+    0x67b10c0aU, 0xe70f9357U, 0x96d2b4eeU, 0x919e1b9bU,
+    0xc54f80c0U, 0x20a261dcU, 0x4b695a77U, 0x1a161c12U,
+    0xba0ae293U, 0x2ae5c0a0U, 0xe0433c22U, 0x171d121bU,
+    0x0d0b0e09U, 0xc7adf28bU, 0xa8b92db6U, 0xa9c8141eU,
+    0x198557f1U, 0x074caf75U, 0xddbbee99U, 0x60fda37fU,
+    0x269ff701U, 0xf5bc5c72U, 0x3bc54466U, 0x7e345bfbU,
+    0x29768b43U, 0xc6dccb23U, 0xfc68b6edU, 0xf163b8e4U,
+    0xdccad731U, 0x85104263U, 0x22401397U, 0x112084c6U,
+    0x247d854aU, 0x3df8d2bbU, 0x3211aef9U, 0xa16dc729U,
+    0x2f4b1d9eU, 0x30f3dcb2U, 0x52ec0d86U, 0xe3d077c1U,
+    0x166c2bb3U, 0xb999a970U, 0x48fa1194U, 0x642247e9U,
+    0x8cc4a8fcU, 0x3f1aa0f0U, 0x2cd8567dU, 0x90ef2233U,
+    0x4ec78749U, 0xd1c1d938U, 0xa2fe8ccaU, 0x0b3698d4U,
+    0x81cfa6f5U, 0xde28a57aU, 0x8e26dab7U, 0xbfa43fadU,
+    0x9de42c3aU, 0x920d5078U, 0xcc9b6a5fU, 0x4662547eU,
+    0x13c2f68dU, 0xb8e890d8U, 0xf75e2e39U, 0xaff582c3U,
+    0x80be9f5dU, 0x937c69d0U, 0x2da96fd5U, 0x12b3cf25U,
+    0x993bc8acU, 0x7da71018U, 0x636ee89cU, 0xbb7bdb3bU,
+    0x7809cd26U, 0x18f46e59U, 0xb701ec9aU, 0x9aa8834fU,
+    0x6e65e695U, 0xe67eaaffU, 0xcf0821bcU, 0xe8e6ef15U,
+    0x9bd9bae7U, 0x36ce4a6fU, 0x09d4ea9fU, 0x7cd629b0U,
+    0xb2af31a4U, 0x23312a3fU, 0x9430c6a5U, 0x66c035a2U,
+    0xbc37744eU, 0xcaa6fc82U, 0xd0b0e090U, 0xd81533a7U,
+    0x984af104U, 0xdaf741ecU, 0x500e7fcdU, 0xf62f1791U,
+    0xd68d764dU, 0xb04d43efU, 0x4d54ccaaU, 0x04dfe496U,
+    0xb5e39ed1U, 0x881b4c6aU, 0x1fb8c12cU, 0x517f4665U,
+    0xea049d5eU, 0x355d018cU, 0x7473fa87U, 0x412efb0bU,
+    0x1d5ab367U, 0xd25292dbU, 0x5633e910U, 0x47136dd6U,
+    0x618c9ad7U, 0x0c7a37a1U, 0x148e59f8U, 0x3c89eb13U,
+    0x27eecea9U, 0xc935b761U, 0xe5ede11cU, 0xb13c7a47U,
+    0xdf599cd2U, 0x733f55f2U, 0xce791814U, 0x37bf73c7U,
+    0xcdea53f7U, 0xaa5b5ffdU, 0x6f14df3dU, 0xdb867844U,
+    0xf381caafU, 0xc43eb968U, 0x342c3824U, 0x405fc2a3U,
+    0xc372161dU, 0x250cbce2U, 0x498b283cU, 0x9541ff0dU,
+    0x017139a8U, 0xb3de080cU, 0xe49cd8b4U, 0xc1906456U,
+    0x84617bcbU, 0xb670d532U, 0x5c74486cU, 0x5742d0b8U,
+};
+static const u32 Td3[256] = {
+    0xf4a75051U, 0x4165537eU, 0x17a4c31aU, 0x275e963aU,
+    0xab6bcb3bU, 0x9d45f11fU, 0xfa58abacU, 0xe303934bU,
+    0x30fa5520U, 0x766df6adU, 0xcc769188U, 0x024c25f5U,
+    0xe5d7fc4fU, 0x2acbd7c5U, 0x35448026U, 0x62a38fb5U,
+    0xb15a49deU, 0xba1b6725U, 0xea0e9845U, 0xfec0e15dU,
+    0x2f7502c3U, 0x4cf01281U, 0x4697a38dU, 0xd3f9c66bU,
+    0x8f5fe703U, 0x929c9515U, 0x6d7aebbfU, 0x5259da95U,
+    0xbe832dd4U, 0x7421d358U, 0xe0692949U, 0xc9c8448eU,
+    0xc2896a75U, 0x8e7978f4U, 0x583e6b99U, 0xb971dd27U,
+    0xe14fb6beU, 0x88ad17f0U, 0x20ac66c9U, 0xce3ab47dU,
+    0xdf4a1863U, 0x1a3182e5U, 0x51336097U, 0x537f4562U,
+    0x6477e0b1U, 0x6bae84bbU, 0x81a01cfeU, 0x082b94f9U,
+    0x48685870U, 0x45fd198fU, 0xde6c8794U, 0x7bf8b752U,
+    0x73d323abU, 0x4b02e272U, 0x1f8f57e3U, 0x55ab2a66U,
+    0xeb2807b2U, 0xb5c2032fU, 0xc57b9a86U, 0x3708a5d3U,
+    0x2887f230U, 0xbfa5b223U, 0x036aba02U, 0x16825cedU,
+    0xcf1c2b8aU, 0x79b492a7U, 0x07f2f0f3U, 0x69e2a14eU,
+    0xdaf4cd65U, 0x05bed506U, 0x34621fd1U, 0xa6fe8ac4U,
+    0x2e539d34U, 0xf355a0a2U, 0x8ae13205U, 0xf6eb75a4U,
+    0x83ec390bU, 0x60efaa40U, 0x719f065eU, 0x6e1051bdU,
+    0x218af93eU, 0xdd063d96U, 0x3e05aeddU, 0xe6bd464dU,
+    0x548db591U, 0xc45d0571U, 0x06d46f04U, 0x5015ff60U,
+    0x98fb2419U, 0xbde997d6U, 0x4043cc89U, 0xd99e7767U,
+    0xe842bdb0U, 0x898b8807U, 0x195b38e7U, 0xc8eedb79U,
+    0x7c0a47a1U, 0x420fe97cU, 0x841ec9f8U, 0x00000000U,
+    0x80868309U, 0x2bed4832U, 0x1170ac1eU, 0x5a724e6cU,
+    0x0efffbfdU, 0x8538560fU, 0xaed51e3dU, 0x2d392736U,
+    0x0fd9640aU, 0x5ca62168U, 0x5b54d19bU, 0x362e3a24U,
+    0x0a67b10cU, 0x57e70f93U, 0xee96d2b4U, 0x9b919e1bU,
+    0xc0c54f80U, 0xdc20a261U, 0x774b695aU, 0x121a161cU,
+    0x93ba0ae2U, 0xa02ae5c0U, 0x22e0433cU, 0x1b171d12U,
+    0x090d0b0eU, 0x8bc7adf2U, 0xb6a8b92dU, 0x1ea9c814U,
+    0xf1198557U, 0x75074cafU, 0x99ddbbeeU, 0x7f60fda3U,
+    0x01269ff7U, 0x72f5bc5cU, 0x663bc544U, 0xfb7e345bU,
+    0x4329768bU, 0x23c6dccbU, 0xedfc68b6U, 0xe4f163b8U,
+    0x31dccad7U, 0x63851042U, 0x97224013U, 0xc6112084U,
+    0x4a247d85U, 0xbb3df8d2U, 0xf93211aeU, 0x29a16dc7U,
+    0x9e2f4b1dU, 0xb230f3dcU, 0x8652ec0dU, 0xc1e3d077U,
+    0xb3166c2bU, 0x70b999a9U, 0x9448fa11U, 0xe9642247U,
+    0xfc8cc4a8U, 0xf03f1aa0U, 0x7d2cd856U, 0x3390ef22U,
+    0x494ec787U, 0x38d1c1d9U, 0xcaa2fe8cU, 0xd40b3698U,
+    0xf581cfa6U, 0x7ade28a5U, 0xb78e26daU, 0xadbfa43fU,
+    0x3a9de42cU, 0x78920d50U, 0x5fcc9b6aU, 0x7e466254U,
+    0x8d13c2f6U, 0xd8b8e890U, 0x39f75e2eU, 0xc3aff582U,
+    0x5d80be9fU, 0xd0937c69U, 0xd52da96fU, 0x2512b3cfU,
+    0xac993bc8U, 0x187da710U, 0x9c636ee8U, 0x3bbb7bdbU,
+    0x267809cdU, 0x5918f46eU, 0x9ab701ecU, 0x4f9aa883U,
+    0x956e65e6U, 0xffe67eaaU, 0xbccf0821U, 0x15e8e6efU,
+    0xe79bd9baU, 0x6f36ce4aU, 0x9f09d4eaU, 0xb07cd629U,
+    0xa4b2af31U, 0x3f23312aU, 0xa59430c6U, 0xa266c035U,
+    0x4ebc3774U, 0x82caa6fcU, 0x90d0b0e0U, 0xa7d81533U,
+    0x04984af1U, 0xecdaf741U, 0xcd500e7fU, 0x91f62f17U,
+    0x4dd68d76U, 0xefb04d43U, 0xaa4d54ccU, 0x9604dfe4U,
+    0xd1b5e39eU, 0x6a881b4cU, 0x2c1fb8c1U, 0x65517f46U,
+    0x5eea049dU, 0x8c355d01U, 0x877473faU, 0x0b412efbU,
+    0x671d5ab3U, 0xdbd25292U, 0x105633e9U, 0xd647136dU,
+    0xd7618c9aU, 0xa10c7a37U, 0xf8148e59U, 0x133c89ebU,
+    0xa927eeceU, 0x61c935b7U, 0x1ce5ede1U, 0x47b13c7aU,
+    0xd2df599cU, 0xf2733f55U, 0x14ce7918U, 0xc737bf73U,
+    0xf7cdea53U, 0xfdaa5b5fU, 0x3d6f14dfU, 0x44db8678U,
+    0xaff381caU, 0x68c43eb9U, 0x24342c38U, 0xa3405fc2U,
+    0x1dc37216U, 0xe2250cbcU, 0x3c498b28U, 0x0d9541ffU,
+    0xa8017139U, 0x0cb3de08U, 0xb4e49cd8U, 0x56c19064U,
+    0xcb84617bU, 0x32b670d5U, 0x6c5c7448U, 0xb85742d0U,
+};
+static const u32 Td4[256] = {
+    0x52525252U, 0x09090909U, 0x6a6a6a6aU, 0xd5d5d5d5U,
+    0x30303030U, 0x36363636U, 0xa5a5a5a5U, 0x38383838U,
+    0xbfbfbfbfU, 0x40404040U, 0xa3a3a3a3U, 0x9e9e9e9eU,
+    0x81818181U, 0xf3f3f3f3U, 0xd7d7d7d7U, 0xfbfbfbfbU,
+    0x7c7c7c7cU, 0xe3e3e3e3U, 0x39393939U, 0x82828282U,
+    0x9b9b9b9bU, 0x2f2f2f2fU, 0xffffffffU, 0x87878787U,
+    0x34343434U, 0x8e8e8e8eU, 0x43434343U, 0x44444444U,
+    0xc4c4c4c4U, 0xdedededeU, 0xe9e9e9e9U, 0xcbcbcbcbU,
+    0x54545454U, 0x7b7b7b7bU, 0x94949494U, 0x32323232U,
+    0xa6a6a6a6U, 0xc2c2c2c2U, 0x23232323U, 0x3d3d3d3dU,
+    0xeeeeeeeeU, 0x4c4c4c4cU, 0x95959595U, 0x0b0b0b0bU,
+    0x42424242U, 0xfafafafaU, 0xc3c3c3c3U, 0x4e4e4e4eU,
+    0x08080808U, 0x2e2e2e2eU, 0xa1a1a1a1U, 0x66666666U,
+    0x28282828U, 0xd9d9d9d9U, 0x24242424U, 0xb2b2b2b2U,
+    0x76767676U, 0x5b5b5b5bU, 0xa2a2a2a2U, 0x49494949U,
+    0x6d6d6d6dU, 0x8b8b8b8bU, 0xd1d1d1d1U, 0x25252525U,
+    0x72727272U, 0xf8f8f8f8U, 0xf6f6f6f6U, 0x64646464U,
+    0x86868686U, 0x68686868U, 0x98989898U, 0x16161616U,
+    0xd4d4d4d4U, 0xa4a4a4a4U, 0x5c5c5c5cU, 0xccccccccU,
+    0x5d5d5d5dU, 0x65656565U, 0xb6b6b6b6U, 0x92929292U,
+    0x6c6c6c6cU, 0x70707070U, 0x48484848U, 0x50505050U,
+    0xfdfdfdfdU, 0xededededU, 0xb9b9b9b9U, 0xdadadadaU,
+    0x5e5e5e5eU, 0x15151515U, 0x46464646U, 0x57575757U,
+    0xa7a7a7a7U, 0x8d8d8d8dU, 0x9d9d9d9dU, 0x84848484U,
+    0x90909090U, 0xd8d8d8d8U, 0xababababU, 0x00000000U,
+    0x8c8c8c8cU, 0xbcbcbcbcU, 0xd3d3d3d3U, 0x0a0a0a0aU,
+    0xf7f7f7f7U, 0xe4e4e4e4U, 0x58585858U, 0x05050505U,
+    0xb8b8b8b8U, 0xb3b3b3b3U, 0x45454545U, 0x06060606U,
+    0xd0d0d0d0U, 0x2c2c2c2cU, 0x1e1e1e1eU, 0x8f8f8f8fU,
+    0xcacacacaU, 0x3f3f3f3fU, 0x0f0f0f0fU, 0x02020202U,
+    0xc1c1c1c1U, 0xafafafafU, 0xbdbdbdbdU, 0x03030303U,
+    0x01010101U, 0x13131313U, 0x8a8a8a8aU, 0x6b6b6b6bU,
+    0x3a3a3a3aU, 0x91919191U, 0x11111111U, 0x41414141U,
+    0x4f4f4f4fU, 0x67676767U, 0xdcdcdcdcU, 0xeaeaeaeaU,
+    0x97979797U, 0xf2f2f2f2U, 0xcfcfcfcfU, 0xcecececeU,
+    0xf0f0f0f0U, 0xb4b4b4b4U, 0xe6e6e6e6U, 0x73737373U,
+    0x96969696U, 0xacacacacU, 0x74747474U, 0x22222222U,
+    0xe7e7e7e7U, 0xadadadadU, 0x35353535U, 0x85858585U,
+    0xe2e2e2e2U, 0xf9f9f9f9U, 0x37373737U, 0xe8e8e8e8U,
+    0x1c1c1c1cU, 0x75757575U, 0xdfdfdfdfU, 0x6e6e6e6eU,
+    0x47474747U, 0xf1f1f1f1U, 0x1a1a1a1aU, 0x71717171U,
+    0x1d1d1d1dU, 0x29292929U, 0xc5c5c5c5U, 0x89898989U,
+    0x6f6f6f6fU, 0xb7b7b7b7U, 0x62626262U, 0x0e0e0e0eU,
+    0xaaaaaaaaU, 0x18181818U, 0xbebebebeU, 0x1b1b1b1bU,
+    0xfcfcfcfcU, 0x56565656U, 0x3e3e3e3eU, 0x4b4b4b4bU,
+    0xc6c6c6c6U, 0xd2d2d2d2U, 0x79797979U, 0x20202020U,
+    0x9a9a9a9aU, 0xdbdbdbdbU, 0xc0c0c0c0U, 0xfefefefeU,
+    0x78787878U, 0xcdcdcdcdU, 0x5a5a5a5aU, 0xf4f4f4f4U,
+    0x1f1f1f1fU, 0xddddddddU, 0xa8a8a8a8U, 0x33333333U,
+    0x88888888U, 0x07070707U, 0xc7c7c7c7U, 0x31313131U,
+    0xb1b1b1b1U, 0x12121212U, 0x10101010U, 0x59595959U,
+    0x27272727U, 0x80808080U, 0xececececU, 0x5f5f5f5fU,
+    0x60606060U, 0x51515151U, 0x7f7f7f7fU, 0xa9a9a9a9U,
+    0x19191919U, 0xb5b5b5b5U, 0x4a4a4a4aU, 0x0d0d0d0dU,
+    0x2d2d2d2dU, 0xe5e5e5e5U, 0x7a7a7a7aU, 0x9f9f9f9fU,
+    0x93939393U, 0xc9c9c9c9U, 0x9c9c9c9cU, 0xefefefefU,
+    0xa0a0a0a0U, 0xe0e0e0e0U, 0x3b3b3b3bU, 0x4d4d4d4dU,
+    0xaeaeaeaeU, 0x2a2a2a2aU, 0xf5f5f5f5U, 0xb0b0b0b0U,
+    0xc8c8c8c8U, 0xebebebebU, 0xbbbbbbbbU, 0x3c3c3c3cU,
+    0x83838383U, 0x53535353U, 0x99999999U, 0x61616161U,
+    0x17171717U, 0x2b2b2b2bU, 0x04040404U, 0x7e7e7e7eU,
+    0xbabababaU, 0x77777777U, 0xd6d6d6d6U, 0x26262626U,
+    0xe1e1e1e1U, 0x69696969U, 0x14141414U, 0x63636363U,
+    0x55555555U, 0x21212121U, 0x0c0c0c0cU, 0x7d7d7d7dU,
+};
+static const u32 rcon[] = {
+       0x01000000, 0x02000000, 0x04000000, 0x08000000,
+       0x10000000, 0x20000000, 0x40000000, 0x80000000,
+       0x1B000000, 0x36000000, /* for 128-bit blocks, Rijndael never uses more than 10 rcon values */
+};
+#else /* AES_SMALL_TABLES */
+static const u8 Td4s[256] = {
+    0x52U, 0x09U, 0x6aU, 0xd5U, 0x30U, 0x36U, 0xa5U, 0x38U,
+    0xbfU, 0x40U, 0xa3U, 0x9eU, 0x81U, 0xf3U, 0xd7U, 0xfbU,
+    0x7cU, 0xe3U, 0x39U, 0x82U, 0x9bU, 0x2fU, 0xffU, 0x87U,
+    0x34U, 0x8eU, 0x43U, 0x44U, 0xc4U, 0xdeU, 0xe9U, 0xcbU,
+    0x54U, 0x7bU, 0x94U, 0x32U, 0xa6U, 0xc2U, 0x23U, 0x3dU,
+    0xeeU, 0x4cU, 0x95U, 0x0bU, 0x42U, 0xfaU, 0xc3U, 0x4eU,
+    0x08U, 0x2eU, 0xa1U, 0x66U, 0x28U, 0xd9U, 0x24U, 0xb2U,
+    0x76U, 0x5bU, 0xa2U, 0x49U, 0x6dU, 0x8bU, 0xd1U, 0x25U,
+    0x72U, 0xf8U, 0xf6U, 0x64U, 0x86U, 0x68U, 0x98U, 0x16U,
+    0xd4U, 0xa4U, 0x5cU, 0xccU, 0x5dU, 0x65U, 0xb6U, 0x92U,
+    0x6cU, 0x70U, 0x48U, 0x50U, 0xfdU, 0xedU, 0xb9U, 0xdaU,
+    0x5eU, 0x15U, 0x46U, 0x57U, 0xa7U, 0x8dU, 0x9dU, 0x84U,
+    0x90U, 0xd8U, 0xabU, 0x00U, 0x8cU, 0xbcU, 0xd3U, 0x0aU,
+    0xf7U, 0xe4U, 0x58U, 0x05U, 0xb8U, 0xb3U, 0x45U, 0x06U,
+    0xd0U, 0x2cU, 0x1eU, 0x8fU, 0xcaU, 0x3fU, 0x0fU, 0x02U,
+    0xc1U, 0xafU, 0xbdU, 0x03U, 0x01U, 0x13U, 0x8aU, 0x6bU,
+    0x3aU, 0x91U, 0x11U, 0x41U, 0x4fU, 0x67U, 0xdcU, 0xeaU,
+    0x97U, 0xf2U, 0xcfU, 0xceU, 0xf0U, 0xb4U, 0xe6U, 0x73U,
+    0x96U, 0xacU, 0x74U, 0x22U, 0xe7U, 0xadU, 0x35U, 0x85U,
+    0xe2U, 0xf9U, 0x37U, 0xe8U, 0x1cU, 0x75U, 0xdfU, 0x6eU,
+    0x47U, 0xf1U, 0x1aU, 0x71U, 0x1dU, 0x29U, 0xc5U, 0x89U,
+    0x6fU, 0xb7U, 0x62U, 0x0eU, 0xaaU, 0x18U, 0xbeU, 0x1bU,
+    0xfcU, 0x56U, 0x3eU, 0x4bU, 0xc6U, 0xd2U, 0x79U, 0x20U,
+    0x9aU, 0xdbU, 0xc0U, 0xfeU, 0x78U, 0xcdU, 0x5aU, 0xf4U,
+    0x1fU, 0xddU, 0xa8U, 0x33U, 0x88U, 0x07U, 0xc7U, 0x31U,
+    0xb1U, 0x12U, 0x10U, 0x59U, 0x27U, 0x80U, 0xecU, 0x5fU,
+    0x60U, 0x51U, 0x7fU, 0xa9U, 0x19U, 0xb5U, 0x4aU, 0x0dU,
+    0x2dU, 0xe5U, 0x7aU, 0x9fU, 0x93U, 0xc9U, 0x9cU, 0xefU,
+    0xa0U, 0xe0U, 0x3bU, 0x4dU, 0xaeU, 0x2aU, 0xf5U, 0xb0U,
+    0xc8U, 0xebU, 0xbbU, 0x3cU, 0x83U, 0x53U, 0x99U, 0x61U,
+    0x17U, 0x2bU, 0x04U, 0x7eU, 0xbaU, 0x77U, 0xd6U, 0x26U,
+    0xe1U, 0x69U, 0x14U, 0x63U, 0x55U, 0x21U, 0x0cU, 0x7dU,
+};
+static const u8 rcons[] = {
+       0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1B, 0x36
+       /* for 128-bit blocks, Rijndael never uses more than 10 rcon values */
+};
+#endif /* AES_SMALL_TABLES */
+
+
+#ifndef AES_SMALL_TABLES
+
+#define RCON(i) rcon[(i)]
+
+#define TE0(i) Te0[((i) >> 24) & 0xff]
+#define TE1(i) Te1[((i) >> 16) & 0xff]
+#define TE2(i) Te2[((i) >> 8) & 0xff]
+#define TE3(i) Te3[(i) & 0xff]
+#define TE41(i) (Te4[((i) >> 24) & 0xff] & 0xff000000)
+#define TE42(i) (Te4[((i) >> 16) & 0xff] & 0x00ff0000)
+#define TE43(i) (Te4[((i) >> 8) & 0xff] & 0x0000ff00)
+#define TE44(i) (Te4[(i) & 0xff] & 0x000000ff)
+#define TE421(i) (Te4[((i) >> 16) & 0xff] & 0xff000000)
+#define TE432(i) (Te4[((i) >> 8) & 0xff] & 0x00ff0000)
+#define TE443(i) (Te4[(i) & 0xff] & 0x0000ff00)
+#define TE414(i) (Te4[((i) >> 24) & 0xff] & 0x000000ff)
+#define TE4(i) (Te4[(i)] & 0x000000ff)
+
+#define TD0(i) Td0[((i) >> 24) & 0xff]
+#define TD1(i) Td1[((i) >> 16) & 0xff]
+#define TD2(i) Td2[((i) >> 8) & 0xff]
+#define TD3(i) Td3[(i) & 0xff]
+#define TD41(i) (Td4[((i) >> 24) & 0xff] & 0xff000000)
+#define TD42(i) (Td4[((i) >> 16) & 0xff] & 0x00ff0000)
+#define TD43(i) (Td4[((i) >> 8) & 0xff] & 0x0000ff00)
+#define TD44(i) (Td4[(i) & 0xff] & 0x000000ff)
+#define TD0_(i) Td0[(i) & 0xff]
+#define TD1_(i) Td1[(i) & 0xff]
+#define TD2_(i) Td2[(i) & 0xff]
+#define TD3_(i) Td3[(i) & 0xff]
+
+#else /* AES_SMALL_TABLES */
+
+#define RCON(i) (rcons[(i)] << 24)
+
+static inline u32 rotr(u32 val, int bits)
+{
+       return (val >> bits) | (val << (32 - bits));
+}
+
+#define TE0(i) Te0[((i) >> 24) & 0xff]
+#define TE1(i) rotr(Te0[((i) >> 16) & 0xff], 8)
+#define TE2(i) rotr(Te0[((i) >> 8) & 0xff], 16)
+#define TE3(i) rotr(Te0[(i) & 0xff], 24)
+#define TE41(i) ((Te0[((i) >> 24) & 0xff] << 8) & 0xff000000)
+#define TE42(i) (Te0[((i) >> 16) & 0xff] & 0x00ff0000)
+#define TE43(i) (Te0[((i) >> 8) & 0xff] & 0x0000ff00)
+#define TE44(i) ((Te0[(i) & 0xff] >> 8) & 0x000000ff)
+#define TE421(i) ((Te0[((i) >> 16) & 0xff] << 8) & 0xff000000)
+#define TE432(i) (Te0[((i) >> 8) & 0xff] & 0x00ff0000)
+#define TE443(i) (Te0[(i) & 0xff] & 0x0000ff00)
+#define TE414(i) ((Te0[((i) >> 24) & 0xff] >> 8) & 0x000000ff)
+#define TE4(i) ((Te0[(i)] >> 8) & 0x000000ff)
+
+#define TD0(i) Td0[((i) >> 24) & 0xff]
+#define TD1(i) rotr(Td0[((i) >> 16) & 0xff], 8)
+#define TD2(i) rotr(Td0[((i) >> 8) & 0xff], 16)
+#define TD3(i) rotr(Td0[(i) & 0xff], 24)
+#define TD41(i) (Td4s[((i) >> 24) & 0xff] << 24)
+#define TD42(i) (Td4s[((i) >> 16) & 0xff] << 16)
+#define TD43(i) (Td4s[((i) >> 8) & 0xff] << 8)
+#define TD44(i) (Td4s[(i) & 0xff])
+#define TD0_(i) Td0[(i) & 0xff]
+#define TD1_(i) rotr(Td0[(i) & 0xff], 8)
+#define TD2_(i) rotr(Td0[(i) & 0xff], 16)
+#define TD3_(i) rotr(Td0[(i) & 0xff], 24)
+
+#endif /* AES_SMALL_TABLES */
+
+#define SWAP(x) (_lrotl(x, 8) & 0x00ff00ff | _lrotr(x, 8) & 0xff00ff00)
+
+#ifdef _MSC_VER
+#define GETU32(p) SWAP(*((u32 *)(p)))
+#define PUTU32(ct, st) { *((u32 *)(ct)) = SWAP((st)); }
+#else
+#define GETU32(pt) (((u32)(pt)[0] << 24) ^ ((u32)(pt)[1] << 16) ^ \
+((u32)(pt)[2] <<  8) ^ ((u32)(pt)[3]))
+#define PUTU32(ct, st) { \
+(ct)[0] = (u8)((st) >> 24); (ct)[1] = (u8)((st) >> 16); \
+(ct)[2] = (u8)((st) >>  8); (ct)[3] = (u8)(st); }
+#endif
+
+/**
+ * Expand the cipher key into the encryption key schedule.
+ *
+ * @return     the number of rounds for the given cipher key size.
+ */
+static void rijndaelKeySetupEnc(u32 rk[/*44*/], const u8 cipherKey[])
+{
+       int i;
+       u32 temp;
+
+       rk[0] = GETU32(cipherKey     );
+       rk[1] = GETU32(cipherKey +  4);
+       rk[2] = GETU32(cipherKey +  8);
+       rk[3] = GETU32(cipherKey + 12);
+       for (i = 0; i < 10; i++) {
+               temp  = rk[3];
+               rk[4] = rk[0] ^
+                       TE421(temp) ^ TE432(temp) ^ TE443(temp) ^ TE414(temp) ^
+                       RCON(i);
+               rk[5] = rk[1] ^ rk[4];
+               rk[6] = rk[2] ^ rk[5];
+               rk[7] = rk[3] ^ rk[6];
+               rk += 4;
+       }
+}
+
+#ifndef CONFIG_NO_AES_DECRYPT
+/**
+ * Expand the cipher key into the decryption key schedule.
+ *
+ * @return     the number of rounds for the given cipher key size.
+ */
+static void rijndaelKeySetupDec(u32 rk[/*44*/], const u8 cipherKey[])
+{
+       int Nr = 10, i, j;
+       u32 temp;
+
+       /* expand the cipher key: */
+       rijndaelKeySetupEnc(rk, cipherKey);
+       /* invert the order of the round keys: */
+       for (i = 0, j = 4*Nr; i < j; i += 4, j -= 4) {
+               temp = rk[i    ]; rk[i    ] = rk[j    ]; rk[j    ] = temp;
+               temp = rk[i + 1]; rk[i + 1] = rk[j + 1]; rk[j + 1] = temp;
+               temp = rk[i + 2]; rk[i + 2] = rk[j + 2]; rk[j + 2] = temp;
+               temp = rk[i + 3]; rk[i + 3] = rk[j + 3]; rk[j + 3] = temp;
+       }
+       /* apply the inverse MixColumn transform to all round keys but the
+        * first and the last: */
+       for (i = 1; i < Nr; i++) {
+               rk += 4;
+               for (j = 0; j < 4; j++) {
+                       rk[j] = TD0_(TE4((rk[j] >> 24)       )) ^
+                               TD1_(TE4((rk[j] >> 16) & 0xff)) ^
+                               TD2_(TE4((rk[j] >>  8) & 0xff)) ^
+                               TD3_(TE4((rk[j]      ) & 0xff));
+               }
+       }
+}
+#endif /* CONFIG_NO_AES_DECRYPT */
+
+#ifndef CONFIG_NO_AES_ENCRYPT
+static void rijndaelEncrypt(const u32 rk[/*44*/], const u8 pt[16], u8 ct[16])
+{
+       u32 s0, s1, s2, s3, t0, t1, t2, t3;
+       const int Nr = 10;
+#ifndef FULL_UNROLL
+       int r;
+#endif /* ?FULL_UNROLL */
+
+       /*
+        * map byte array block to cipher state
+        * and add initial round key:
+        */
+       s0 = GETU32(pt     ) ^ rk[0];
+       s1 = GETU32(pt +  4) ^ rk[1];
+       s2 = GETU32(pt +  8) ^ rk[2];
+       s3 = GETU32(pt + 12) ^ rk[3];
+
+#define ROUND(i,d,s) \
+d##0 = TE0(s##0) ^ TE1(s##1) ^ TE2(s##2) ^ TE3(s##3) ^ rk[4 * i]; \
+d##1 = TE0(s##1) ^ TE1(s##2) ^ TE2(s##3) ^ TE3(s##0) ^ rk[4 * i + 1]; \
+d##2 = TE0(s##2) ^ TE1(s##3) ^ TE2(s##0) ^ TE3(s##1) ^ rk[4 * i + 2]; \
+d##3 = TE0(s##3) ^ TE1(s##0) ^ TE2(s##1) ^ TE3(s##2) ^ rk[4 * i + 3]
+
+#ifdef FULL_UNROLL
+
+       ROUND(1,t,s);
+       ROUND(2,s,t);
+       ROUND(3,t,s);
+       ROUND(4,s,t);
+       ROUND(5,t,s);
+       ROUND(6,s,t);
+       ROUND(7,t,s);
+       ROUND(8,s,t);
+       ROUND(9,t,s);
+
+       rk += Nr << 2;
+
+#else  /* !FULL_UNROLL */
+
+       /* Nr - 1 full rounds: */
+       r = Nr >> 1;
+       for (;;) {
+               ROUND(1,t,s);
+               rk += 8;
+               if (--r == 0)
+                       break;
+               ROUND(0,s,t);
+       }
+
+#endif /* ?FULL_UNROLL */
+
+#undef ROUND
+
+       /*
+        * apply last round and
+        * map cipher state to byte array block:
+        */
+       s0 = TE41(t0) ^ TE42(t1) ^ TE43(t2) ^ TE44(t3) ^ rk[0];
+       PUTU32(ct     , s0);
+       s1 = TE41(t1) ^ TE42(t2) ^ TE43(t3) ^ TE44(t0) ^ rk[1];
+       PUTU32(ct +  4, s1);
+       s2 = TE41(t2) ^ TE42(t3) ^ TE43(t0) ^ TE44(t1) ^ rk[2];
+       PUTU32(ct +  8, s2);
+       s3 = TE41(t3) ^ TE42(t0) ^ TE43(t1) ^ TE44(t2) ^ rk[3];
+       PUTU32(ct + 12, s3);
+}
+#endif /* CONFIG_NO_AES_ENCRYPT */
+
+static void rijndaelDecrypt(const u32 rk[/*44*/], const u8 ct[16], u8 pt[16])
+{
+       u32 s0, s1, s2, s3, t0, t1, t2, t3;
+       const int Nr = 10;
+#ifndef FULL_UNROLL
+       int r;
+#endif /* ?FULL_UNROLL */
+
+       /*
+        * map byte array block to cipher state
+        * and add initial round key:
+        */
+       s0 = GETU32(ct     ) ^ rk[0];
+       s1 = GETU32(ct +  4) ^ rk[1];
+       s2 = GETU32(ct +  8) ^ rk[2];
+       s3 = GETU32(ct + 12) ^ rk[3];
+
+#define ROUND(i,d,s) \
+d##0 = TD0(s##0) ^ TD1(s##3) ^ TD2(s##2) ^ TD3(s##1) ^ rk[4 * i]; \
+d##1 = TD0(s##1) ^ TD1(s##0) ^ TD2(s##3) ^ TD3(s##2) ^ rk[4 * i + 1]; \
+d##2 = TD0(s##2) ^ TD1(s##1) ^ TD2(s##0) ^ TD3(s##3) ^ rk[4 * i + 2]; \
+d##3 = TD0(s##3) ^ TD1(s##2) ^ TD2(s##1) ^ TD3(s##0) ^ rk[4 * i + 3]
+
+#ifdef FULL_UNROLL
+
+       ROUND(1,t,s);
+       ROUND(2,s,t);
+       ROUND(3,t,s);
+       ROUND(4,s,t);
+       ROUND(5,t,s);
+       ROUND(6,s,t);
+       ROUND(7,t,s);
+       ROUND(8,s,t);
+       ROUND(9,t,s);
+
+       rk += Nr << 2;
+
+#else  /* !FULL_UNROLL */
+
+       /* Nr - 1 full rounds: */
+       r = Nr >> 1;
+       for (;;) {
+               ROUND(1,t,s);
+               rk += 8;
+               if (--r == 0)
+                       break;
+               ROUND(0,s,t);
+       }
+
+#endif /* ?FULL_UNROLL */
+
+#undef ROUND
+
+       /*
+        * apply last round and
+        * map cipher state to byte array block:
+        */
+       s0 = TD41(t0) ^ TD42(t3) ^ TD43(t2) ^ TD44(t1) ^ rk[0];
+       PUTU32(pt     , s0);
+       s1 = TD41(t1) ^ TD42(t0) ^ TD43(t3) ^ TD44(t2) ^ rk[1];
+       PUTU32(pt +  4, s1);
+       s2 = TD41(t2) ^ TD42(t1) ^ TD43(t0) ^ TD44(t3) ^ rk[2];
+       PUTU32(pt +  8, s2);
+       s3 = TD41(t3) ^ TD42(t2) ^ TD43(t1) ^ TD44(t0) ^ rk[3];
+       PUTU32(pt + 12, s3);
+}
+
+#define AES_PRIV_SIZE 44
diff --git a/package/ead/src/ead-client.c b/package/ead/src/ead-client.c
new file mode 100644 (file)
index 0000000..111dc8a
--- /dev/null
@@ -0,0 +1,405 @@
+/*
+ * Client for the Emergency Access Daemon
+ * Copyright (C) 2008 Felix Fietkau <nbd@openwrt.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/time.h>
+#include <netinet/in.h>
+#include <stdio.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <stdbool.h>
+#include <string.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <t_pwd.h>
+#include <t_read.h>
+#include <t_sha.h>
+#include <t_defines.h>
+#include <t_client.h>
+#include "ead.h"
+#include "ead-crypt.h"
+
+#include "pw_encrypt_md5.c"
+
+#define EAD_TIMEOUT    400
+#define EAD_TIMEOUT_LONG 2000
+
+static char msgbuf[1500];
+static struct ead_msg *msg = (struct ead_msg *) msgbuf;
+static uint16_t nid = 0xffff;
+struct sockaddr_in local, remote;
+static int s = 0;
+static int sockflags;
+
+static unsigned char *skey = NULL;
+static unsigned char bbuf[MAXPARAMLEN];
+static unsigned char saltbuf[MAXSALTLEN];
+static char *username = NULL;
+static char password[MAXPARAMLEN] = "";
+static char pw_md5[MD5_OUT_BUFSIZE];
+static char pw_salt[MAXSALTLEN];
+
+static struct t_client *tc = NULL;
+static struct t_num salt = { .data = saltbuf };
+static struct t_num *A, B;
+static struct t_preconf *tcp;
+static int auth_type = EAD_AUTH_DEFAULT;
+static int timeout = EAD_TIMEOUT;
+
+static void
+set_nonblock(int enable)
+{
+       if (enable == !!(sockflags & O_NONBLOCK));
+               return;
+
+       sockflags ^= O_NONBLOCK;
+       fcntl(s, F_SETFL, sockflags);
+}
+
+static int
+send_packet(int type, bool (*handler)(void), unsigned int max)
+{
+       struct timeval tv;
+       fd_set fds;
+       int nfds;
+       int len;
+       int res = 0;
+
+       type = htonl(type);
+       set_nonblock(0);
+       sendto(s, msgbuf, sizeof(struct ead_msg) + ntohl(msg->len), 0, (struct sockaddr *) &remote, sizeof(remote));
+       set_nonblock(1);
+
+       tv.tv_sec = timeout / 1000;
+       tv.tv_usec = (timeout % 1000) * 1000;
+
+       FD_ZERO(&fds);
+       do {
+               FD_SET(s, &fds);
+               nfds = select(s + 1, &fds, NULL, NULL, &tv);
+
+               if (nfds <= 0)
+                       break;
+
+               if (!FD_ISSET(s, &fds))
+                       break;
+
+               len = read(s, msgbuf, sizeof(msgbuf));
+               if (len < 0)
+                       break;
+
+               if (len < sizeof(struct ead_msg))
+                       continue;
+
+               if (len < sizeof(struct ead_msg) + ntohl(msg->len))
+                       continue;
+
+               if (msg->magic != htonl(EAD_MAGIC))
+                       continue;
+
+               if ((nid != 0xffff) && (ntohs(msg->nid) != nid))
+                       continue;
+
+               if (msg->type != type)
+                       continue;
+
+               if (handler())
+                       res++;
+
+               if ((max > 0) && (res >= max))
+                       break;
+       } while (1);
+
+       return res;
+}
+
+static void
+prepare_password(void)
+{
+       switch(auth_type) {
+       case EAD_AUTH_DEFAULT:
+               break;
+       case EAD_AUTH_MD5:
+               md5_crypt(pw_md5, (unsigned char *) password, (unsigned char *) pw_salt);
+               strncpy(password, pw_md5, sizeof(password));
+               break;
+       }
+}
+
+static bool
+handle_pong(void)
+{
+       struct ead_msg_pong *pong = EAD_DATA(msg, pong);
+       int len = msg->len - sizeof(struct ead_msg_pong);
+
+       pong->name[len] = 0;
+       auth_type = ntohs(pong->auth_type);
+       if (nid == 0xffff)
+               printf("%04x: %s\n", ntohs(msg->nid), pong->name);
+       return true;
+}
+
+static bool
+handle_prime(void)
+{
+       struct ead_msg_salt *sb = EAD_DATA(msg, salt);
+
+       salt.len = sb->len;
+       memcpy(salt.data, sb->salt, salt.len);
+
+       if (auth_type == EAD_AUTH_MD5) {
+               memcpy(pw_salt, sb->ext_salt, MAXSALTLEN);
+               pw_salt[MAXSALTLEN - 1] = 0;
+       }
+
+       tcp = t_getpreparam(sb->prime);
+       tc = t_clientopen(username, &tcp->modulus, &tcp->generator, &salt);
+       if (!tc) {
+               fprintf(stderr, "Client open failed\n");
+               return false;
+       }
+
+       return true;
+}
+
+static bool
+handle_b(void)
+{
+       struct ead_msg_number *num = EAD_DATA(msg, number);
+       int len = ntohl(msg->len) - sizeof(struct ead_msg_number);
+
+       B.data = bbuf;
+       B.len = len;
+       memcpy(bbuf, num->data, len);
+       return true;
+}
+
+static bool
+handle_none(void)
+{
+       return true;
+}
+
+static bool
+handle_done_auth(void)
+{
+       struct ead_msg_auth *auth = EAD_DATA(msg, auth);
+       if (t_clientverify(tc, auth->data) != 0) {
+               fprintf(stderr, "Client auth verify failed\n");
+               return false;
+       }
+       return true;
+}
+
+static bool
+handle_cmd_data(void)
+{
+       struct ead_msg_cmd_data *cmd = EAD_ENC_DATA(msg, cmd_data);
+       int datalen = ead_decrypt_message(msg) - sizeof(struct ead_msg_cmd_data);
+
+       if (datalen < 0)
+               return false;
+
+       if (datalen > 0) {
+               write(1, cmd->data, datalen);
+       }
+
+       return !!cmd->done;
+}
+static int
+send_ping(void)
+{
+       msg->type = htonl(EAD_TYPE_PING);
+       msg->len = 0;
+       return send_packet(EAD_TYPE_PONG, handle_pong, (nid == 0xffff ? 0 : 1));
+}
+
+static int
+send_username(void)
+{
+       msg->type = htonl(EAD_TYPE_SET_USERNAME);
+       msg->len = htonl(sizeof(struct ead_msg_user));
+       strcpy(EAD_DATA(msg, user)->username, username);
+       return send_packet(EAD_TYPE_ACK_USERNAME, handle_none, 1);
+}
+
+static int
+get_prime(void)
+{
+       msg->type = htonl(EAD_TYPE_GET_PRIME);
+       msg->len = 0;
+       return send_packet(EAD_TYPE_PRIME, handle_prime, 1);
+}
+
+static int
+send_a(void)
+{
+       struct ead_msg_number *num = EAD_DATA(msg, number);
+       A = t_clientgenexp(tc);
+       msg->type = htonl(EAD_TYPE_SEND_A);
+       msg->len = htonl(sizeof(struct ead_msg_number) + A->len);
+       memcpy(num->data, A->data, A->len);
+       return send_packet(EAD_TYPE_SEND_B, handle_b, 1);
+}
+
+static int
+send_auth(void)
+{
+       struct ead_msg_auth *auth = EAD_DATA(msg, auth);
+
+       prepare_password();
+       t_clientpasswd(tc, password);
+       skey = t_clientgetkey(tc, &B);
+       if (!skey)
+               return 0;
+
+       ead_set_key(skey);
+       msg->type = htonl(EAD_TYPE_SEND_AUTH);
+       msg->len = htonl(sizeof(struct ead_msg_auth));
+       memcpy(auth->data, t_clientresponse(tc), sizeof(auth->data));
+       return send_packet(EAD_TYPE_DONE_AUTH, handle_done_auth, 1);
+}
+
+static int
+send_command(const char *command)
+{
+       struct ead_msg_cmd *cmd = EAD_ENC_DATA(msg, cmd);
+
+       msg->type = htonl(EAD_TYPE_SEND_CMD);
+       cmd->type = htons(EAD_CMD_NORMAL);
+       cmd->timeout = htons(10);
+       strncpy((char *)cmd->data, command, 1024);
+       ead_encrypt_message(msg, sizeof(struct ead_msg_cmd) + strlen(command) + 1);
+       return send_packet(EAD_TYPE_RESULT_CMD, handle_cmd_data, 1);
+}
+
+
+static int
+usage(const char *prog)
+{
+       fprintf(stderr, "Usage: %s <node> <username>[:<password>]\n"
+               "\n"
+               "\n<node>:     Node ID (4 digits hex)\n"
+               "\n<username>: Username to authenticate with\n"
+               "\n"
+               "\nPassing no arguments shows a list of active nodes on the network\n"
+               "\n", prog);
+       return -1;
+}
+
+
+int main(int argc, char **argv)
+{
+       int val = 1;
+       char *st = NULL;
+       const char *command = NULL;
+
+       msg->magic = htonl(EAD_MAGIC);
+       msg->tid = 0;
+
+       memset(&local, 0, sizeof(local));
+       memset(&remote, 0, sizeof(remote));
+
+       remote.sin_family = AF_INET;
+       remote.sin_addr.s_addr = 0xffffffff;
+       remote.sin_port = htons(EAD_PORT);
+
+       local.sin_family = AF_INET;
+       local.sin_addr.s_addr = INADDR_ANY;
+       local.sin_port = 0;
+
+       switch(argc) {
+       case 4:
+               command = argv[3];
+               /* fall through */
+       case 3:
+               username = argv[2];
+               st = strchr(username, ':');
+               if (st) {
+                       *st = 0;
+                       st++;
+                       strncpy(password, st, sizeof(password));
+                       password[sizeof(password) - 1] = 0;
+                       /* hide command line password */
+                       memset(st, 0, strlen(st));
+               }
+               /* fall through */
+       case 2:
+               nid = strtoul(argv[1], &st, 16);
+               if (st && st[0] != 0)
+                       return usage(argv[0]);
+               /* fall through */
+       case 1:
+               break;
+       default:
+               return usage(argv[0]);
+       }
+
+       msg->nid = htons(nid);
+       s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
+       if (s < 0) {
+               perror("socket");
+               return -1;
+       }
+
+       setsockopt(s, SOL_SOCKET, SO_BROADCAST, &val, sizeof(val));
+
+       if (bind(s, (struct sockaddr *)&local, sizeof(local)) < 0) {
+               perror("bind");
+               return -1;
+       }
+       sockflags = fcntl(s, F_GETFL);
+
+       if (!send_ping()) {
+               fprintf(stderr, "No devices found\n");
+               return 1;
+       }
+
+       if (nid == 0xffff)
+               return 0;
+
+       if (!username || !password[0])
+               return 0;
+
+       if (!send_username()) {
+               fprintf(stderr, "Device did not accept user name\n");
+               return 1;
+       }
+       if (!get_prime()) {
+               fprintf(stderr, "Failed to get user password info\n");
+               return 1;
+       }
+
+       timeout = EAD_TIMEOUT_LONG;
+       if (!send_a()) {
+               fprintf(stderr, "Failed to send local authentication data\n");
+               return 1;
+       }
+       if (!send_auth()) {
+               fprintf(stderr, "Authentication failed\n");
+               return 1;
+       }
+       if (!command) {
+               fprintf(stderr, "Authentication succesful\n");
+               return 0;
+       }
+       if (!send_command(command)) {
+               fprintf(stderr, "Command failed\n");
+               return 1;
+       }
+
+       return 0;
+}
diff --git a/package/ead/src/ead-crypt.c b/package/ead/src/ead-crypt.c
new file mode 100644 (file)
index 0000000..0372172
--- /dev/null
@@ -0,0 +1,179 @@
+/*
+ * Copyright (C) 2008 Felix Fietkau <nbd@openwrt.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <stddef.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <stdbool.h>
+#include <string.h>
+#include <unistd.h>
+#include <stdio.h>
+#include "ead.h"
+
+#include "sha1.c"
+#include "aes.c"
+
+#if EAD_DEBUGLEVEL >= 1
+#define DEBUG(n, format, ...) do { \
+       if (EAD_DEBUGLEVEL >= n) \
+               fprintf(stderr, format, ##__VA_ARGS__); \
+} while (0);
+
+#else
+#define DEBUG(n, format, ...) do {} while(0)
+#endif
+
+
+static uint32_t aes_enc_ctx[AES_PRIV_SIZE];
+static uint32_t aes_dec_ctx[AES_PRIV_SIZE];
+static uint32_t ead_rx_iv;
+static uint32_t ead_tx_iv;
+static uint32_t ivofs_vec;
+static unsigned int ivofs_idx = 0;
+static uint32_t W[80]; /* work space for sha1 */
+
+#define EAD_ENC_PAD    64
+
+void
+ead_set_key(unsigned char *skey)
+{
+       uint32_t *ivp = (uint32_t *)skey;
+
+       memset(aes_enc_ctx, 0, sizeof(aes_enc_ctx));
+       memset(aes_dec_ctx, 0, sizeof(aes_dec_ctx));
+
+       /* first 32 bytes of skey are used as aes key for
+        * encryption and decryption */
+       rijndaelKeySetupEnc(aes_enc_ctx, skey);
+       rijndaelKeySetupDec(aes_dec_ctx, skey);
+
+       /* the following bytes are used as initialization vector for messages
+        * (highest byte cleared to avoid overflow) */
+       ivp += 8;
+       ead_rx_iv = ntohl(*ivp) & 0x00ffffff;
+       ead_tx_iv = ead_rx_iv;
+
+       /* the last bytes are used to feed the random iv increment */
+       ivp++;
+       ivofs_vec = *ivp;
+}
+
+
+static bool
+ead_check_rx_iv(uint32_t iv)
+{
+       if (iv <= ead_rx_iv)
+               return false;
+
+       if (iv > ead_rx_iv + EAD_MAX_IV_INCR)
+               return false;
+
+       ead_rx_iv = iv;
+       return true;
+}
+
+
+static uint32_t
+ead_get_tx_iv(void)
+{
+       unsigned int ofs;
+
+       ofs = 1 + ((ivofs_vec >> 2 * ivofs_idx) & 0x3);
+       ivofs_idx = (ivofs_idx + 1) % 16;
+       ead_tx_iv += ofs;
+
+       return ead_tx_iv;
+}
+
+static void
+ead_hash_message(struct ead_msg_encrypted *enc, uint32_t *hash, int len)
+{
+       unsigned char *data = (unsigned char *) enc;
+
+       /* hash the packet with the stored hash part initialized to zero */
+       sha_init(hash);
+       memset(enc->hash, 0, sizeof(enc->hash));
+       while (len > 0) {
+               sha_transform(hash, data, W);
+               len -= 64;
+               data += 64;
+       }
+}
+
+void
+ead_encrypt_message(struct ead_msg *msg, unsigned int len)
+{
+       struct ead_msg_encrypted *enc = EAD_DATA(msg, enc);
+       unsigned char *data = (unsigned char *) enc;
+       uint32_t hash[5];
+       int enclen, i;
+
+       len += sizeof(struct ead_msg_encrypted);
+       enc->pad = (EAD_ENC_PAD - (len % EAD_ENC_PAD)) % EAD_ENC_PAD;
+       enclen = len + enc->pad;
+       msg->len = htonl(enclen);
+       enc->iv = htonl(ead_get_tx_iv());
+
+       ead_hash_message(enc, hash, enclen);
+       for (i = 0; i < 5; i++)
+               enc->hash[i] = htonl(hash[i]);
+       DEBUG(2, "SHA1 generate (0x%08x), len=%d\n", enc->hash[0], enclen);
+
+       while (enclen > 0) {
+               rijndaelEncrypt(aes_enc_ctx, data, data);
+               data += 16;
+               enclen -= 16;
+       }
+}
+
+int
+ead_decrypt_message(struct ead_msg *msg)
+{
+       struct ead_msg_encrypted *enc = EAD_DATA(msg, enc);
+       unsigned char *data = (unsigned char *) enc;
+       uint32_t hash_old[5], hash_new[5];
+       int len = ntohl(msg->len);
+       int i, enclen = len;
+
+       if (!len || (len % EAD_ENC_PAD > 0))
+               return 0;
+
+       while (len > 0) {
+               rijndaelDecrypt(aes_dec_ctx, data, data);
+               data += 16;
+               len -= 16;
+       }
+
+       data = (unsigned char *) enc;
+
+       if (enc->pad >= EAD_ENC_PAD) {
+               DEBUG(2, "Invalid padding length\n");
+               return 0;
+       }
+
+       if (!ead_check_rx_iv(ntohl(enc->iv))) {
+               DEBUG(2, "RX IV mismatch (0x%08x <> 0x%08x)\n", ead_rx_iv, ntohl(enc->iv));
+               return 0;
+       }
+
+       for (i = 0; i < 5; i++)
+               hash_old[i] = ntohl(enc->hash[i]);
+       ead_hash_message(enc, hash_new, enclen);
+       if (memcmp(hash_old, hash_new, sizeof(hash_old)) != 0) {
+               DEBUG(2, "SHA1 mismatch (0x%08x != 0x%08x), len=%d\n", hash_old[0], hash_new[0], enclen);
+               return 0;
+       }
+
+       enclen -= enc->pad + sizeof(struct ead_msg_encrypted);
+       return enclen;
+}
diff --git a/package/ead/src/ead-crypt.h b/package/ead/src/ead-crypt.h
new file mode 100644 (file)
index 0000000..831ec8a
--- /dev/null
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2008 Felix Fietkau <nbd@openwrt.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __EAD_CRYPT_H
+#define __EAD_CRYPT_H
+
+extern void ead_set_key(unsigned char *skey);
+extern void ead_encrypt_message(struct ead_msg *msg, unsigned int len);
+extern int ead_decrypt_message(struct ead_msg *msg);
+
+#endif
diff --git a/package/ead/src/ead-pcap.h b/package/ead/src/ead-pcap.h
new file mode 100644 (file)
index 0000000..0652ab4
--- /dev/null
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2001-2003, Adam Dunkels.
+ * 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. The name of the author may not be used to endorse or promote
+ *    products derived from this software without specific prior
+ *    written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This file was part of the uIP TCP/IP stack.
+ *
+ */
+#ifndef __EAD_PCAP_H
+#define __EAD_PCAP_H
+
+#include <net/ethernet.h>
+#include <stdint.h>
+#include "ead.h"
+
+typedef uint8_t u8_t;
+typedef uint16_t u16_t;
+
+/* The UDP and IP headers. */
+struct ead_packet {
+  struct ether_header eh;
+  /* IP header. */
+  u8_t vhl,
+    tos,
+    len[2],
+    ipid[2],
+    ipoffset[2],
+    ttl,
+    proto;
+  u16_t ipchksum;
+  u16_t srcipaddr[2],
+    destipaddr[2];
+
+  /* UDP header. */
+  u16_t srcport,
+    destport;
+  u16_t udplen;
+  u16_t udpchksum;
+
+  struct ead_msg msg;
+} __attribute__((packed));
+
+#define UIP_PROTO_UDP  17
+#define UIP_IPH_LEN    20    /* Size of IP header */
+#define UIP_UDPH_LEN   8    /* Size of UDP header */
+#define UIP_IPUDPH_LEN (UIP_UDPH_LEN + UIP_IPH_LEN)
+
+#endif
diff --git a/package/ead/src/ead.c b/package/ead/src/ead.c
new file mode 100644 (file)
index 0000000..7367c38
--- /dev/null
@@ -0,0 +1,931 @@
+/*
+ * Emergency Access Daemon
+ * Copyright (C) 2008 Felix Fietkau <nbd@openwrt.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/select.h>
+#include <stdio.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <stdbool.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <pcap.h>
+#include <pcap-bpf.h>
+#include <t_pwd.h>
+#include <t_read.h>
+#include <t_sha.h>
+#include <t_defines.h>
+#include <t_server.h>
+
+#include "list.h"
+#include "ead.h"
+#include "ead-pcap.h"
+#include "ead-crypt.h"
+
+#include "filter.c"
+
+#ifdef linux
+#include "libbridge_init.c"
+#endif
+
+#define PASSWD_FILE    "/etc/passwd"
+
+#ifndef DEFAULT_IFNAME
+#define DEFAULT_IFNAME "eth0"
+#endif
+
+#ifndef DEFAULT_DEVNAME
+#define DEFAULT_DEVNAME "Unknown"
+#endif
+
+#define PCAP_MRU               1600
+#define PCAP_TIMEOUT   200
+
+#if EAD_DEBUGLEVEL >= 1
+#define DEBUG(n, format, ...) do { \
+       if (EAD_DEBUGLEVEL >= n) \
+               fprintf(stderr, format, ##__VA_ARGS__); \
+} while (0);
+
+#else
+#define DEBUG(n, format, ...) do {} while(0)
+#endif
+
+static char ethmac[6] = "\x00\x13\x37\x00\x00\x00"; /* last 3 bytes will be randomized */
+static pcap_t *pcap_fp = NULL;
+static pcap_t *pcap_fp_rx = NULL;
+static const char *ifname = DEFAULT_IFNAME;
+static char pktbuf_b[PCAP_MRU];
+static struct ead_packet *pktbuf = (struct ead_packet *)pktbuf_b;
+static u16_t nid = 0xffff; /* node id */
+static char username[32] = "";
+static int state = EAD_TYPE_SET_USERNAME;
+static const char *passwd_file = PASSWD_FILE;
+static const char password[MAXPARAMLEN];
+static bool child_pending = false;
+
+static unsigned char abuf[MAXPARAMLEN + 1];
+static unsigned char pwbuf[MAXPARAMLEN];
+static unsigned char saltbuf[MAXSALTLEN];
+static unsigned char pw_saltbuf[MAXSALTLEN];
+static struct list_head instances;
+static const char *dev_name = DEFAULT_DEVNAME;
+static bool nonfork = false;
+
+#ifdef linux
+static const char *brname = NULL;
+#endif
+
+struct ead_instance {
+       struct list_head list;
+       char name[16];
+       int pid;
+#ifdef linux
+       char bridge[16];
+       bool br_check;
+#endif
+};
+
+static struct t_pwent tpe = {
+       .name = username,
+       .index = 1,
+       .password.data = pwbuf,
+       .password.len = 0,
+       .salt.data = saltbuf,
+       .salt.len = 0,
+};
+struct t_confent *tce = NULL;
+static struct t_server *ts = NULL;
+static struct t_num A, *B = NULL;
+unsigned char *skey;
+
+static bool
+prepare_password(void)
+{
+       static char lbuf[1024];
+       unsigned char dig[SHA_DIGESTSIZE];
+       BigInteger x, v, n, g;
+       SHA1_CTX ctxt;
+       int ulen = strlen(username);
+       FILE *f;
+
+       lbuf[sizeof(lbuf) - 1] = 0;
+
+       f = fopen(passwd_file, "r");
+       if (!f)
+               return false;
+
+       while (fgets(lbuf, sizeof(lbuf) - 1, f) != NULL) {
+               char *str, *s2;
+
+               if (strncmp(lbuf, username, ulen) != 0)
+                       continue;
+
+               if (lbuf[ulen] != ':')
+                       continue;
+
+               str = &lbuf[ulen + 1];
+
+               if (strncmp(str, "$1$", 3) != 0)
+                       continue;
+
+               s2 = strchr(str + 3, '$');
+               if (!s2)
+                       continue;
+
+               if (s2 - str >= MAXSALTLEN)
+                       continue;
+
+               strncpy((char *) pw_saltbuf, str, s2 - str);
+               pw_saltbuf[s2 - str] = 0;
+
+               s2 = strchr(s2, ':');
+               if (!s2)
+                       continue;
+
+               *s2 = 0;
+               if (s2 - str >= MAXPARAMLEN)
+                       continue;
+
+               strncpy((char *)password, str, MAXPARAMLEN);
+               fclose(f);
+               goto hash_password;
+       }
+
+       /* not found */
+       fclose(f);
+       return false;
+
+hash_password:
+       tce = gettcid(tpe.index);
+       do {
+               t_random(tpe.password.data, SALTLEN);
+       } while (memcmp(saltbuf, (char *)dig, sizeof(saltbuf)) == 0);
+       if (saltbuf[0] == 0)
+               saltbuf[0] = 0xff;
+
+       n = BigIntegerFromBytes(tce->modulus.data, tce->modulus.len);
+       g = BigIntegerFromBytes(tce->generator.data, tce->generator.len);
+       v = BigIntegerFromInt(0);
+
+       SHA1Init(&ctxt);
+       SHA1Update(&ctxt, (unsigned char *) username, strlen(username));
+       SHA1Update(&ctxt, (unsigned char *) ":", 1);
+       SHA1Update(&ctxt, (unsigned char *) password, strlen(password));
+       SHA1Final(dig, &ctxt);
+
+       SHA1Init(&ctxt);
+       SHA1Update(&ctxt, saltbuf, tpe.salt.len);
+       SHA1Update(&ctxt, dig, sizeof(dig));
+       SHA1Final(dig, &ctxt);
+
+       /* x = H(s, H(u, ':', p)) */
+       x = BigIntegerFromBytes(dig, sizeof(dig));
+
+       BigIntegerModExp(v, g, x, n);
+       tpe.password.len = BigIntegerToBytes(v, (unsigned char *)pwbuf);
+
+       BigIntegerFree(v);
+       BigIntegerFree(x);
+       BigIntegerFree(g);
+       BigIntegerFree(n);
+       return true;
+}
+
+static u16_t
+chksum(u16_t sum, const u8_t *data, u16_t len)
+{
+       u16_t t;
+       const u8_t *dataptr;
+       const u8_t *last_byte;
+
+       dataptr = data;
+       last_byte = data + len - 1;
+
+       while(dataptr < last_byte) {    /* At least two more bytes */
+               t = (dataptr[0] << 8) + dataptr[1];
+               sum += t;
+               if(sum < t) {
+                       sum++;          /* carry */
+               }
+               dataptr += 2;
+       }
+
+       if(dataptr == last_byte) {
+               t = (dataptr[0] << 8) + 0;
+               sum += t;
+               if(sum < t) {
+                       sum++;          /* carry */
+               }
+       }
+
+       /* Return sum in host byte order. */
+       return sum;
+}
+
+static void
+ead_send_packet_clone(struct ead_packet *pkt)
+{
+       u16_t len, sum;
+
+       memcpy(pktbuf, pkt, offsetof(struct ead_packet, msg));
+       memcpy(pktbuf->eh.ether_shost, ethmac, 6);
+       memcpy(pktbuf->eh.ether_dhost, pkt->eh.ether_shost, 6);
+
+       /* ip header */
+       len = sizeof(struct ead_packet) - sizeof(struct ether_header) + ntohl(pktbuf->msg.len);
+       pktbuf->len[0] = len >> 8;
+       pktbuf->len[1] = len & 0xff;
+       memcpy(pktbuf->srcipaddr, pkt->destipaddr, 4);
+       memcpy(pktbuf->destipaddr, pkt->srcipaddr, 4);
+
+       /* ip checksum */
+       pktbuf->ipchksum = 0;
+       sum = chksum(0, (void *) &pktbuf->vhl, UIP_IPH_LEN);
+       if (sum == 0)
+               sum = 0xffff;
+       pktbuf->ipchksum = htons(~sum);
+
+       /* udp header */
+       pktbuf->srcport = pkt->destport;
+       pktbuf->destport = pkt->srcport;
+
+       /* udp checksum */
+       len -= UIP_IPH_LEN;
+       pktbuf->udplen = htons(len);
+       pktbuf->udpchksum = 0;
+       sum = len + UIP_PROTO_UDP;
+       sum = chksum(sum, (void *) &pktbuf->srcipaddr[0], 8); /* src, dest ip */
+       sum = chksum(sum, (void *) &pktbuf->srcport, len);
+       if (sum == 0)
+               sum = 0xffff;
+       pktbuf->udpchksum = htons(~sum);
+       pcap_sendpacket(pcap_fp, (void *) pktbuf, sizeof(struct ead_packet) + ntohl(pktbuf->msg.len));
+}
+
+static void
+set_state(int nstate)
+{
+       if (state == nstate)
+               return;
+
+       if (nstate < state) {
+               if ((nstate < EAD_TYPE_GET_PRIME) &&
+                       (state >= EAD_TYPE_GET_PRIME)) {
+                       t_serverclose(ts);
+                       ts = NULL;
+               }
+               goto done;
+       }
+
+       switch(state) {
+       case EAD_TYPE_SET_USERNAME:
+               if (!prepare_password())
+                       goto error;
+               ts = t_serveropenraw(&tpe, tce);
+               if (!ts)
+                       goto error;
+               break;
+       case EAD_TYPE_GET_PRIME:
+               B = t_servergenexp(ts);
+               break;
+       case EAD_TYPE_SEND_A:
+               skey = t_servergetkey(ts, &A);
+               if (!skey)
+                       goto error;
+
+               ead_set_key(skey);
+               break;
+       }
+done:
+       state = nstate;
+error:
+       return;
+}
+
+static bool
+handle_ping(struct ead_packet *pkt, int len, int *nstate)
+{
+       struct ead_msg *msg = &pktbuf->msg;
+       struct ead_msg_pong *pong = EAD_DATA(msg, pong);
+       int slen;
+
+       slen = strlen(dev_name);
+       if (slen > 1024)
+               slen = 1024;
+
+       msg->len = htonl(sizeof(struct ead_msg_pong) + slen);
+       strncpy(pong->name, dev_name, slen);
+       pong->name[len] = 0;
+       pong->auth_type = htons(EAD_AUTH_MD5);
+
+       return true;
+}
+
+static bool
+handle_set_username(struct ead_packet *pkt, int len, int *nstate)
+{
+       struct ead_msg *msg = &pkt->msg;
+       struct ead_msg_user *user = EAD_DATA(msg, user);
+
+       set_state(EAD_TYPE_SET_USERNAME); /* clear old state */
+       strncpy(username, user->username, sizeof(username));
+       username[sizeof(username)] = 0;
+
+       msg = &pktbuf->msg;
+       msg->len = 0;
+
+       *nstate = EAD_TYPE_GET_PRIME;
+       return true;
+}
+
+static bool
+handle_get_prime(struct ead_packet *pkt, int len, int *nstate)
+{
+       struct ead_msg *msg = &pktbuf->msg;
+       struct ead_msg_salt *salt = EAD_DATA(msg, salt);
+
+       msg->len = htonl(sizeof(struct ead_msg_salt));
+       salt->prime = tce->index - 1;
+       salt->len = ts->s.len;
+       memcpy(salt->salt, ts->s.data, ts->s.len);
+       memcpy(salt->ext_salt, pw_saltbuf, MAXSALTLEN);
+
+       *nstate = EAD_TYPE_SEND_A;
+       return true;
+}
+
+static bool
+handle_send_a(struct ead_packet *pkt, int len, int *nstate)
+{
+       struct ead_msg *msg = &pkt->msg;
+       struct ead_msg_number *number = EAD_DATA(msg, number);
+       len = ntohl(msg->len) - sizeof(struct ead_msg_number);
+
+       if (len > MAXPARAMLEN + 1)
+               return false;
+
+       A.len = len;
+       A.data = abuf;
+       memcpy(A.data, number->data, len);
+
+       msg = &pktbuf->msg;
+       number = EAD_DATA(msg, number);
+       msg->len = htonl(sizeof(struct ead_msg_number) + B->len);
+       memcpy(number->data, B->data, B->len);
+
+       *nstate = EAD_TYPE_SEND_AUTH;
+       return true;
+}
+
+static bool
+handle_send_auth(struct ead_packet *pkt, int len, int *nstate)
+{
+       struct ead_msg *msg = &pkt->msg;
+       struct ead_msg_auth *auth = EAD_DATA(msg, auth);
+
+       if (t_serververify(ts, auth->data) != 0) {
+               DEBUG(2, "Client authentication failed\n");
+               *nstate = EAD_TYPE_SET_USERNAME;
+               return false;
+       }
+
+       msg = &pktbuf->msg;
+       auth = EAD_DATA(msg, auth);
+       msg->len = htonl(sizeof(struct ead_msg_auth));
+
+       DEBUG(2, "Client authentication successful\n");
+       memcpy(auth->data, t_serverresponse(ts), sizeof(auth->data));
+
+       *nstate = EAD_TYPE_SEND_CMD;
+       return true;
+}
+
+static bool
+handle_send_cmd(struct ead_packet *pkt, int len, int *nstate)
+{
+       struct ead_msg *msg = &pkt->msg;
+       struct ead_msg_cmd *cmd = EAD_ENC_DATA(msg, cmd);
+       struct ead_msg_cmd_data *cmddata;
+       struct timeval tv, to, tn;
+       int pfd[2], fd;
+       fd_set fds;
+       pid_t pid;
+       bool stream = false;
+       int timeout;
+       int type;
+       int datalen;
+
+       datalen = ead_decrypt_message(msg) - sizeof(struct ead_msg_cmd);
+       if (datalen <= 0)
+               return false;
+
+       type = ntohs(cmd->type);
+       timeout = ntohs(cmd->timeout);
+
+       FD_ZERO(&fds);
+       cmd->data[datalen] = 0;
+       switch(type) {
+       case EAD_CMD_NORMAL:
+               if (pipe(pfd) < 0)
+                       return false;
+
+               fcntl(pfd[0], F_SETFL, O_NONBLOCK | fcntl(pfd[0], F_GETFL));
+               child_pending = true;
+               pid = fork();
+               if (pid == 0) {
+                       close(pfd[0]);
+                       fd = open("/dev/null", O_RDWR);
+                       if (fd > 0) {
+                               dup2(fd, 0);
+                               dup2(pfd[1], 1);
+                               dup2(pfd[1], 2);
+                       }
+                       system((char *)cmd->data);
+                       exit(0);
+               } else if (pid > 0) {
+                       close(pfd[1]);
+                       if (!timeout)
+                               timeout = EAD_CMD_TIMEOUT;
+
+                       stream = true;
+                       break;
+               }
+               return false;
+       case EAD_CMD_BACKGROUND:
+               pid = fork();
+               if (pid == 0) {
+                       /* close stdin, stdout, stderr, replace with fd to /dev/null */
+                       fd = open("/dev/null", O_RDWR);
+                       if (fd > 0) {
+                               dup2(fd, 0);
+                               dup2(fd, 1);
+                               dup2(fd, 2);
+                       }
+                       system((char *)cmd->data);
+                       exit(0);
+               } else if (pid > 0) {
+                       break;
+               }
+               return false;
+       default:
+               return false;
+       }
+
+       msg = &pktbuf->msg;
+       cmddata = EAD_ENC_DATA(msg, cmd_data);
+
+       if (stream) {
+               int nfds, bytes;
+
+               /* send keepalive packets every 200 ms so that the client doesn't timeout */
+               gettimeofday(&to, NULL);
+               memcpy(&tn, &to, sizeof(tn));
+               tv.tv_usec = PCAP_TIMEOUT * 1000;
+               tv.tv_sec = 0;
+               do {
+                       cmddata->done = 0;
+                       FD_SET(pfd[0], &fds);
+                       nfds = select(pfd[0] + 1, &fds, NULL, NULL, &tv);
+                       bytes = 0;
+                       if (nfds > 0) {
+                               bytes = read(pfd[0], cmddata->data, 1024);
+                               if (bytes < 0)
+                                       bytes = 0;
+                       }
+                       if (!bytes && !child_pending)
+                               break;
+                       DEBUG(3, "Sending %d bytes of console data, type=%d, timeout=%d\n", bytes, ntohl(msg->type), timeout);
+                       ead_encrypt_message(msg, sizeof(struct ead_msg_cmd_data) + bytes);
+                       ead_send_packet_clone(pkt);
+                       gettimeofday(&tn, NULL);
+               } while (tn.tv_sec < to.tv_sec + timeout);
+               if (child_pending) {
+                       kill(pid, SIGKILL);
+                       return false;
+               }
+       }
+       cmddata->done = 1;
+       ead_encrypt_message(msg, sizeof(struct ead_msg_cmd_data));
+
+       return true;
+}
+
+
+
+static void
+parse_message(struct ead_packet *pkt, int len)
+{
+       bool (*handler)(struct ead_packet *pkt, int len, int *nstate);
+       int min_len = sizeof(struct ead_packet);
+       int nstate = state;
+       int type = ntohl(pkt->msg.type);
+
+       if ((type >= EAD_TYPE_GET_PRIME) &&
+               (state != type))
+               return;
+
+       switch(type) {
+       case EAD_TYPE_PING:
+               handler = handle_ping;
+               break;
+       case EAD_TYPE_SET_USERNAME:
+               handler = handle_set_username;
+               min_len += sizeof(struct ead_msg_user);
+               break;
+       case EAD_TYPE_GET_PRIME:
+               handler = handle_get_prime;
+               break;
+       case EAD_TYPE_SEND_A:
+               handler = handle_send_a;
+               min_len += sizeof(struct ead_msg_number);
+               break;
+       case EAD_TYPE_SEND_AUTH:
+               handler = handle_send_auth;
+               min_len += sizeof(struct ead_msg_auth);
+               break;
+       case EAD_TYPE_SEND_CMD:
+               handler = handle_send_cmd;
+               min_len += sizeof(struct ead_msg_cmd) + sizeof(struct ead_msg_encrypted);
+               break;
+       default:
+               return;
+       }
+
+       if (len < min_len) {
+               DEBUG(2, "discarding packet: message too small\n");
+               return;
+       }
+
+       pktbuf->msg.magic = htonl(EAD_MAGIC);
+       pktbuf->msg.type = htonl(type + 1);
+       pktbuf->msg.nid = htons(nid);
+       pktbuf->msg.len = 0;
+
+       if (handler(pkt, len, &nstate)) {
+               DEBUG(2, "sending response to packet type %d: %d\n", type + 1, ntohl(pktbuf->msg.len));
+               /* format response packet */
+               ead_send_packet_clone(pkt);
+       }
+       set_state(nstate);
+}
+
+static void
+handle_packet(u_char *user, const struct pcap_pkthdr *h, const u_char *bytes)
+{
+       struct ead_packet *pkt = (struct ead_packet *) bytes;
+
+       if (h->len < sizeof(struct ead_packet))
+               return;
+
+       if (pkt->eh.ether_type != htons(ETHERTYPE_IP))
+               return;
+
+       if (memcmp(pkt->eh.ether_dhost, "\xff\xff\xff\xff\xff\xff", 6) != 0)
+               return;
+
+       if (pkt->proto != UIP_PROTO_UDP)
+               return;
+
+       if (pkt->destport != htons(EAD_PORT))
+               return;
+
+       if (pkt->msg.magic != htonl(EAD_MAGIC))
+               return;
+
+       if (h->len < sizeof(struct ead_packet) + ntohl(pkt->msg.len))
+               return;
+
+       if ((pkt->msg.nid != 0xffff) &&
+               (pkt->msg.nid != htons(nid)))
+               return;
+
+       parse_message(pkt, h->len);
+}
+
+static void
+ead_pcap_reopen(bool first)
+{
+       static char errbuf[PCAP_ERRBUF_SIZE] = "";
+
+       if (pcap_fp_rx != pcap_fp)
+               pcap_close(pcap_fp_rx);
+
+       if (pcap_fp)
+               pcap_close(pcap_fp);
+
+       pcap_fp_rx = pcap_fp;
+       do {
+               pcap_fp = pcap_open_live(ifname, PCAP_MRU, 1, PCAP_TIMEOUT, errbuf);
+#ifdef linux
+               if (brname) {
+                       pcap_fp_rx = pcap_open_live(brname, PCAP_MRU, 1, PCAP_TIMEOUT, errbuf);
+                       if (!pcap_fp_rx)
+                               pcap_fp_rx = pcap_fp;
+               }
+#endif
+               pcap_setfilter(pcap_fp_rx, &pktfilter);
+               if (first && !pcap_fp) {
+                       DEBUG(1, "WARNING: unable to open interface '%s'\n", ifname);
+                       first = false;
+               }
+               if (!pcap_fp)
+                       sleep(1);
+       } while (!pcap_fp);
+}
+
+
+static void
+ead_pktloop(void)
+{
+       while (1) {
+               if (pcap_dispatch(pcap_fp_rx, 1, handle_packet, NULL) < 0) {
+                       ead_pcap_reopen(false);
+                       continue;
+               }
+       }
+}
+
+
+static int
+usage(const char *prog)
+{
+       fprintf(stderr, "Usage: %s [<options>]\n"
+               "Options:\n"
+               "\t-B             Run in background mode\n"
+               "\t-d <device>    Set the device to listen on\n"
+               "\t-D <name>      Set the name of the device visible to clients\n"
+               "\t-p <file>      Set the password file for authenticating\n"
+               "\t-P <file>      Write a pidfile\n"
+               "\n", prog);
+       return -1;
+}
+
+static void
+server_handle_sigchld(int sig)
+{
+       struct ead_instance *in;
+       struct list_head *p;
+       int pid = 0;
+       wait(&pid);
+
+       list_for_each(p, &instances) {
+               in = list_entry(p, struct ead_instance, list);
+               if (pid != in->pid)
+                       continue;
+
+               in->pid = 0;
+               break;
+       }
+}
+
+static void
+instance_handle_sigchld(int sig)
+{
+       int pid = 0;
+       wait(&pid);
+       child_pending = false;
+}
+
+static void
+start_server(struct ead_instance *i)
+{
+       if (!nonfork) {
+               i->pid = fork();
+               if (i->pid != 0) {
+                       if (i->pid < 0)
+                               i->pid = 0;
+                       return;
+               }
+       }
+
+       signal(SIGCHLD, instance_handle_sigchld);
+       ifname = i->name;
+#ifdef linux
+       if (i->bridge[0])
+               brname = i->bridge;
+#endif
+       ead_pcap_reopen(true);
+       ead_pktloop();
+       pcap_close(pcap_fp);
+       if (pcap_fp_rx != pcap_fp)
+               pcap_close(pcap_fp_rx);
+
+       exit(0);
+}
+
+
+static void
+start_servers(bool restart)
+{
+       struct ead_instance *in;
+       struct list_head *p;
+
+       list_for_each(p, &instances) {
+               in = list_entry(p, struct ead_instance, list);
+               if (in->pid > 0)
+                       continue;
+
+               sleep(1);
+               start_server(in);
+       }
+}
+
+static void
+stop_server(struct ead_instance *in, bool do_free)
+{
+       if (in->pid > 0)
+               kill(in->pid, SIGKILL);
+       in->pid = 0;
+       if (do_free) {
+               list_del(&in->list);
+               free(in);
+       }
+}
+
+static void
+server_handle_sigint(int sig)
+{
+       struct ead_instance *in;
+       struct list_head *p, *tmp;
+
+       list_for_each_safe(p, tmp, &instances) {
+               in = list_entry(p, struct ead_instance, list);
+               stop_server(in, true);
+       }
+       exit(1);
+}
+
+#ifdef linux
+static int
+check_bridge_port(const char *br, const char *port, void *arg)
+{
+       struct ead_instance *in;
+       struct list_head *p, *tmp;
+
+       list_for_each(p, &instances) {
+               in = list_entry(p, struct ead_instance, list);
+
+               if (strcmp(in->name, port) != 0)
+                       continue;
+
+               in->br_check = true;
+               if (strcmp(in->bridge, br) == 0)
+                       break;
+
+               strncpy(in->bridge, br, sizeof(in->bridge));
+               DEBUG(2, "assigning port %s to bridge %s\n", in->name, in->bridge);
+               stop_server(in, false);
+       }
+       return 0;
+}
+
+static int
+check_bridge(const char *name, void *arg)
+{
+       br_foreach_port(name, check_bridge_port, arg);
+       return 0;
+}
+#endif
+
+static void
+check_all_interfaces(void)
+{
+#ifdef linux
+       struct ead_instance *in;
+       struct list_head *p, *tmp;
+
+       br_foreach_bridge(check_bridge, NULL);
+
+       /* look for interfaces that are no longer part of a bridge */
+       list_for_each(p, &instances) {
+               in = list_entry(p, struct ead_instance, list);
+
+               if (in->br_check) {
+                       in->br_check = false;
+               } else if (in->bridge[0]) {
+                       DEBUG(2, "removing port %s from bridge %s\n", in->name, in->bridge);
+                       in->bridge[0] = 0;
+                       stop_server(in, false);
+               }
+       }
+#endif
+}
+
+
+int main(int argc, char **argv)
+{
+       struct ead_instance *in;
+       struct timeval tv;
+       int fd, ch;
+       const char *pidfile = NULL;
+       bool background = false;
+       int n_iface = 0;
+
+       if (argc == 1)
+               return usage(argv[0]);
+
+       INIT_LIST_HEAD(&instances);
+       while ((ch = getopt(argc, argv, "Bd:D:fhp:P:")) != -1) {
+               switch(ch) {
+               case 'B':
+                       background = true;
+                       break;
+               case 'f':
+                       nonfork = true;
+                       break;
+               case 'h':
+                       return usage(argv[0]);
+               case 'd':
+                       in = malloc(sizeof(struct ead_instance));
+                       memset(in, 0, sizeof(struct ead_instance));
+                       INIT_LIST_HEAD(&in->list);
+                       strncpy(in->name, optarg, sizeof(in->name) - 1);
+                       list_add(&in->list, &instances);
+                       n_iface++;
+                       break;
+               case 'D':
+                       dev_name = optarg;
+                       break;
+               case 'p':
+                       passwd_file = optarg;
+                       break;
+               case 'P':
+                       pidfile = optarg;
+                       break;
+               }
+       }
+       signal(SIGCHLD, server_handle_sigchld);
+       signal(SIGINT, server_handle_sigint);
+       signal(SIGTERM, server_handle_sigint);
+       signal(SIGKILL, server_handle_sigint);
+
+       if (!n_iface) {
+               fprintf(stderr, "Error: ead needs at least one interface\n");
+               return -1;
+       }
+
+       if (background) {
+               if (fork() > 0)
+                       exit(0);
+
+               fd = open("/dev/null", O_RDWR);
+               dup2(fd, 0);
+               dup2(fd, 1);
+               dup2(fd, 2);
+       }
+
+       if (pidfile) {
+               char pid[8];
+               int len;
+
+               unlink(pidfile);
+               fd = open(pidfile, O_CREAT|O_WRONLY|O_EXCL, 0644);
+               if (fd > 0) {
+                       len = sprintf(pid, "%d\n", getpid());
+                       write(fd, pid, len);
+                       close(fd);
+               }
+       }
+
+       /* randomize the mac address */
+       fd = open("/dev/urandom", O_RDONLY);
+       if (fd < 0) {
+               perror("open");
+               exit(1);
+       }
+       read(fd, ethmac + 3, 3);
+       close(fd);
+       nid = *(((u16_t *) ethmac) + 2);
+
+       start_servers(false);
+#ifdef linux
+       br_init();
+#endif
+       tv.tv_sec = 1;
+       tv.tv_usec = 0;
+       while (1) {
+               check_all_interfaces();
+               start_servers(true);
+               sleep(1);
+       }
+#ifdef linux
+       br_shutdown();
+#endif
+
+       return 0;
+}
diff --git a/package/ead/src/ead.h b/package/ead/src/ead.h
new file mode 100644 (file)
index 0000000..3bd64f9
--- /dev/null
@@ -0,0 +1,134 @@
+/*
+ * Copyright (C) 2008 Felix Fietkau <nbd@openwrt.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __EAD_H
+#define __EAD_H
+
+#define EAD_DEBUGLEVEL 1
+
+#include <stdint.h>
+#include <stddef.h>
+
+#ifndef MAXSALTLEN
+#define MAXSALTLEN 32
+#endif
+
+#define EAD_PORT       56026UL
+#define EAD_MAGIC      3671771902UL
+#define EAD_CMD_TIMEOUT        10
+
+#define EAD_MAX_IV_INCR        128
+
+/* request/response types */
+/* response id == request id + 1 */
+enum ead_type {
+       EAD_TYPE_PING,
+       EAD_TYPE_PONG,
+
+       EAD_TYPE_SET_USERNAME,
+       EAD_TYPE_ACK_USERNAME,
+
+       EAD_TYPE_GET_PRIME,
+       EAD_TYPE_PRIME,
+
+       EAD_TYPE_SEND_A,
+       EAD_TYPE_SEND_B,
+
+       EAD_TYPE_SEND_AUTH,
+       EAD_TYPE_DONE_AUTH,
+
+       EAD_TYPE_SEND_CMD,
+       EAD_TYPE_RESULT_CMD,
+
+       EAD_TYPE_LAST
+};
+
+enum ead_auth_type {
+       EAD_AUTH_DEFAULT,
+       EAD_AUTH_MD5
+};
+
+enum ead_cmd_type {
+       EAD_CMD_NORMAL,
+       EAD_CMD_BACKGROUND,
+       EAD_CMD_LAST
+};
+
+struct ead_msg_pong {
+       uint16_t auth_type;
+       char name[];
+} __attribute__((packed));
+
+struct ead_msg_number {
+       uint8_t id;
+       unsigned char data[];
+} __attribute__((packed));
+
+struct ead_msg_salt {
+       uint8_t prime;
+       uint8_t len;
+       unsigned char salt[MAXSALTLEN];
+       unsigned char ext_salt[MAXSALTLEN];
+} __attribute__((packed));
+
+struct ead_msg_user {
+       char username[32];
+} __attribute__((packed));
+
+struct ead_msg_auth {
+       unsigned char data[20];
+} __attribute__((packed));
+
+struct ead_msg_cmd {
+       uint8_t type;
+       uint16_t timeout;
+       unsigned char data[];
+} __attribute__((packed));
+
+struct ead_msg_cmd_data {
+       uint8_t done;
+       unsigned char data[];
+} __attribute__((packed));
+
+struct ead_msg_encrypted {
+       uint32_t hash[5];
+       uint32_t iv;
+       uint8_t pad;
+       union {
+               struct ead_msg_cmd cmd;
+               struct ead_msg_cmd_data cmd_data;
+       } data[];
+} __attribute__((packed));
+
+
+#define EAD_DATA(_msg, _type) (&((_msg)->data[0]._type))
+#define EAD_ENC_DATA(_msg, _type) (&((_msg)->data[0].enc.data[0]._type))
+
+struct ead_msg {
+       uint32_t magic;
+       uint32_t len;
+       uint32_t type;
+       uint16_t nid; /* node id */
+       uint16_t tid; /* transaction id */
+       union {
+               struct ead_msg_pong pong;
+               struct ead_msg_user user;
+               struct ead_msg_number number;
+               struct ead_msg_auth auth;
+               struct ead_msg_salt salt;
+               struct ead_msg_encrypted enc;
+       } data[];
+} __attribute__((packed));
+
+
+#endif
diff --git a/package/ead/src/filter.c b/package/ead/src/filter.c
new file mode 100644 (file)
index 0000000..ffa69f1
--- /dev/null
@@ -0,0 +1,23 @@
+/* precompiled expression: udp and dst host 255.255.255.255 and dst port 56026 */
+
+static struct bpf_insn pktfilter_insns[] = {
+       { .code = 0x0028, .jt = 0x00, .jf = 0x00, .k = 0x0000000c },
+       { .code = 0x0015, .jt = 0x0b, .jf = 0x00, .k = 0x000086dd },
+       { .code = 0x0015, .jt = 0x00, .jf = 0x0a, .k = 0x00000800 },
+       { .code = 0x0030, .jt = 0x00, .jf = 0x00, .k = 0x00000017 },
+       { .code = 0x0015, .jt = 0x00, .jf = 0x08, .k = 0x00000011 },
+       { .code = 0x0020, .jt = 0x00, .jf = 0x00, .k = 0x0000001e },
+       { .code = 0x0015, .jt = 0x00, .jf = 0x06, .k = 0xffffffff },
+       { .code = 0x0028, .jt = 0x00, .jf = 0x00, .k = 0x00000014 },
+       { .code = 0x0045, .jt = 0x04, .jf = 0x00, .k = 0x00001fff },
+       { .code = 0x00b1, .jt = 0x00, .jf = 0x00, .k = 0x0000000e },
+       { .code = 0x0048, .jt = 0x00, .jf = 0x00, .k = 0x00000010 },
+       { .code = 0x0015, .jt = 0x00, .jf = 0x01, .k = 0x0000dada },
+       { .code = 0x0006, .jt = 0x00, .jf = 0x00, .k = 0x000005dc },
+       { .code = 0x0006, .jt = 0x00, .jf = 0x00, .k = 0x00000000 },
+};
+
+static struct bpf_program pktfilter = {
+       .bf_len = 14,
+       .bf_insns = pktfilter_insns,
+};
diff --git a/package/ead/src/libbridge.h b/package/ead/src/libbridge.h
new file mode 100644 (file)
index 0000000..6b70e46
--- /dev/null
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2000 Lennert Buytenhek
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef _LIBBRIDGE_H
+#define _LIBBRIDGE_H
+
+#include <sys/socket.h>
+#include <linux/if.h>
+#include <linux/if_bridge.h>
+
+/* defined in net/if.h but that conflicts with linux/if.h... */
+extern unsigned int if_nametoindex (const char *__ifname);
+extern char *if_indextoname (unsigned int __ifindex, char *__ifname);
+
+struct bridge_id
+{
+       unsigned char prio[2];
+       unsigned char addr[6];
+};
+
+struct bridge_info
+{
+       struct bridge_id designated_root;
+       struct bridge_id bridge_id;
+       unsigned root_path_cost;
+       struct timeval max_age;
+       struct timeval hello_time;
+       struct timeval forward_delay;
+       struct timeval bridge_max_age;
+       struct timeval bridge_hello_time;
+       struct timeval bridge_forward_delay;
+       u_int16_t root_port;
+       unsigned char stp_enabled;
+       unsigned char topology_change;
+       unsigned char topology_change_detected;
+       struct timeval ageing_time;
+       struct timeval hello_timer_value;
+       struct timeval tcn_timer_value;
+       struct timeval topology_change_timer_value;
+       struct timeval gc_timer_value;
+};
+
+struct fdb_entry
+{
+       u_int8_t mac_addr[6];
+       u_int16_t port_no;
+       unsigned char is_local;
+       struct timeval ageing_timer_value;
+};
+
+struct port_info
+{
+       unsigned port_no;
+       struct bridge_id designated_root;
+       struct bridge_id designated_bridge;
+       u_int16_t port_id;
+       u_int16_t designated_port;
+       u_int8_t priority;
+       unsigned char top_change_ack;
+       unsigned char config_pending;
+       unsigned char state;
+       unsigned path_cost;
+       unsigned designated_cost;
+       struct timeval message_age_timer_value;
+       struct timeval forward_delay_timer_value;
+       struct timeval hold_timer_value;
+};
+
+#endif
diff --git a/package/ead/src/libbridge_init.c b/package/ead/src/libbridge_init.c
new file mode 100644 (file)
index 0000000..36d0eb9
--- /dev/null
@@ -0,0 +1,208 @@
+/*
+ * Copyright (C) 2000 Lennert Buytenhek
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+#include <string.h>
+#include <dirent.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include "libbridge.h"
+#include "libbridge_private.h"
+
+int br_socket_fd = -1;
+
+static int br_init(void)
+{
+       if ((br_socket_fd = socket(AF_LOCAL, SOCK_STREAM, 0)) < 0)
+               return errno;
+       return 0;
+}
+
+static void br_shutdown(void)
+{
+       close(br_socket_fd);
+       br_socket_fd = -1;
+}
+
+/* If /sys/class/net/XXX/bridge exists then it must be a bridge */
+static int isbridge(const struct dirent *entry)
+{
+       char path[SYSFS_PATH_MAX];
+       struct stat st;
+
+       snprintf(path, SYSFS_PATH_MAX, SYSFS_CLASS_NET "%s/bridge", entry->d_name);
+       return stat(path, &st) == 0 && S_ISDIR(st.st_mode);
+}
+
+/*
+ * New interface uses sysfs to find bridges
+ */
+static int new_foreach_bridge(int (*iterator)(const char *name, void *),
+                             void *arg)
+{
+       struct dirent **namelist;
+       int i, count = 0;
+
+       count = scandir(SYSFS_CLASS_NET, &namelist, isbridge, alphasort);
+       if (count < 0)
+               return -1;
+
+       for (i = 0; i < count; i++) {
+               if (iterator(namelist[i]->d_name, arg))
+                       break;
+       }
+
+       for (i = 0; i < count; i++)
+               free(namelist[i]);
+       free(namelist);
+
+       return count;
+}
+
+/*
+ * Old interface uses ioctl
+ */
+static int old_foreach_bridge(int (*iterator)(const char *, void *), 
+                             void *iarg)
+{
+       int i, ret=0, num;
+       char ifname[IFNAMSIZ];
+       int ifindices[MAX_BRIDGES];
+       unsigned long args[3] = { BRCTL_GET_BRIDGES, 
+                                (unsigned long)ifindices, MAX_BRIDGES };
+
+       num = ioctl(br_socket_fd, SIOCGIFBR, args);
+       if (num < 0) {
+               dprintf("Get bridge indices failed: %s\n",
+                       strerror(errno));
+               return -errno;
+       }
+
+       for (i = 0; i < num; i++) {
+               if (!if_indextoname(ifindices[i], ifname)) {
+                       dprintf("get find name for ifindex %d\n",
+                               ifindices[i]);
+                       return -errno;
+               }
+
+               ++ret;
+               if(iterator(ifname, iarg)) 
+                       break;
+       }
+
+       return ret;
+
+}
+
+/*
+ * Go over all bridges and call iterator function.
+ * if iterator returns non-zero then stop.
+ */
+static int br_foreach_bridge(int (*iterator)(const char *, void *), 
+                    void *arg)
+{
+       int ret;
+
+       ret = new_foreach_bridge(iterator, arg);
+       if (ret <= 0)
+               ret = old_foreach_bridge(iterator, arg);
+
+       return ret;
+}
+
+/* 
+ * Only used if sysfs is not available.
+ */
+static int old_foreach_port(const char *brname,
+                           int (*iterator)(const char *br, const char *port, 
+                                           void *arg),
+                           void *arg)
+{
+       int i, err, count;
+       struct ifreq ifr;
+       char ifname[IFNAMSIZ];
+       int ifindices[MAX_PORTS];
+       unsigned long args[4] = { BRCTL_GET_PORT_LIST,
+                                 (unsigned long)ifindices, MAX_PORTS, 0 };
+
+       memset(ifindices, 0, sizeof(ifindices));
+       strncpy(ifr.ifr_name, brname, IFNAMSIZ);
+       ifr.ifr_data = (char *) &args;
+
+       err = ioctl(br_socket_fd, SIOCDEVPRIVATE, &ifr);
+       if (err < 0) {
+               dprintf("list ports for bridge:'%s' failed: %s\n",
+                       brname, strerror(errno));
+               return -errno;
+       }
+
+       count = 0;
+       for (i = 0; i < MAX_PORTS; i++) {
+               if (!ifindices[i])
+                       continue;
+
+               if (!if_indextoname(ifindices[i], ifname)) {
+                       dprintf("can't find name for ifindex:%d\n",
+                               ifindices[i]);
+                       continue;
+               }
+
+               ++count;
+               if (iterator(brname, ifname, arg))
+                       break;
+       }
+
+       return count;
+}
+
+/*
+ * Iterate over all ports in bridge (using sysfs).
+ */
+static int br_foreach_port(const char *brname,
+                   int (*iterator)(const char *br, const char *port, void *arg),
+                   void *arg)
+{
+       int i, count;
+       struct dirent **namelist;
+       char path[SYSFS_PATH_MAX];
+
+       snprintf(path, SYSFS_PATH_MAX, SYSFS_CLASS_NET "%s/brif", brname);
+       count = scandir(path, &namelist, 0, alphasort);
+       if (count < 0)
+               return old_foreach_port(brname, iterator, arg);
+
+       for (i = 0; i < count; i++) {
+               if (namelist[i]->d_name[0] == '.'
+                   && (namelist[i]->d_name[1] == '\0'
+                       || (namelist[i]->d_name[1] == '.'
+                           && namelist[i]->d_name[2] == '\0')))
+                       continue;
+
+               if (iterator(brname, namelist[i]->d_name, arg))
+                       break;
+       }
+       for (i = 0; i < count; i++)
+               free(namelist[i]);
+       free(namelist);
+
+       return count;
+}
diff --git a/package/ead/src/libbridge_private.h b/package/ead/src/libbridge_private.h
new file mode 100644 (file)
index 0000000..38fd60e
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2000 Lennert Buytenhek
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef _LIBBRIDGE_PRIVATE_H
+#define _LIBBRIDGE_PRIVATE_H
+
+#include <linux/sockios.h>
+#include <sys/time.h>
+#include <sys/ioctl.h>
+#include <linux/if_bridge.h>
+
+#define MAX_BRIDGES    1024
+#define MAX_PORTS      1024
+
+#define SYSFS_CLASS_NET "/sys/class/net/"
+#define SYSFS_PATH_MAX 256
+
+#define dprintf(fmt,arg...)
+
+#endif
diff --git a/package/ead/src/list.h b/package/ead/src/list.h
new file mode 100644 (file)
index 0000000..ac429c8
--- /dev/null
@@ -0,0 +1,602 @@
+/* GPL v2, adapted from the Linux kernel */
+#ifndef _LINUX_LIST_H
+#define _LINUX_LIST_H
+
+#include <stddef.h>
+/**
+ * container_of - cast a member of a structure out to the containing structure
+ * @ptr:       the pointer to the member.
+ * @type:      the type of the container struct this is embedded in.
+ * @member:    the name of the member within the struct.
+ *
+ */
+#ifndef container_of
+#define container_of(ptr, type, member) (                      \
+       (type *)( (char *)ptr - offsetof(type,member) ))
+#endif
+
+
+/*
+ * Simple doubly linked list implementation.
+ *
+ * Some of the internal functions ("__xxx") are useful when
+ * manipulating whole lists rather than single entries, as
+ * sometimes we already know the next/prev entries and we can
+ * generate better code by using them directly rather than
+ * using the generic single-entry routines.
+ */
+
+struct list_head {
+       struct list_head *next, *prev;
+};
+
+#define LIST_HEAD_INIT(name) { &(name), &(name) }
+
+#define LIST_HEAD(name) \
+       struct list_head name = LIST_HEAD_INIT(name)
+
+static inline void INIT_LIST_HEAD(struct list_head *list)
+{
+       list->next = list;
+       list->prev = list;
+}
+
+/*
+ * Insert a new entry between two known consecutive entries.
+ *
+ * This is only for internal list manipulation where we know
+ * the prev/next entries already!
+ */
+static inline void __list_add(struct list_head *new,
+                             struct list_head *prev,
+                             struct list_head *next)
+{
+       next->prev = new;
+       new->next = next;
+       new->prev = prev;
+       prev->next = new;
+}
+
+/**
+ * list_add - add a new entry
+ * @new: new entry to be added
+ * @head: list head to add it after
+ *
+ * Insert a new entry after the specified head.
+ * This is good for implementing stacks.
+ */
+static inline void list_add(struct list_head *new, struct list_head *head)
+{
+       __list_add(new, head, head->next);
+}
+
+
+/**
+ * list_add_tail - add a new entry
+ * @new: new entry to be added
+ * @head: list head to add it before
+ *
+ * Insert a new entry before the specified head.
+ * This is useful for implementing queues.
+ */
+static inline void list_add_tail(struct list_head *new, struct list_head *head)
+{
+       __list_add(new, head->prev, head);
+}
+
+
+/*
+ * Delete a list entry by making the prev/next entries
+ * point to each other.
+ *
+ * This is only for internal list manipulation where we know
+ * the prev/next entries already!
+ */
+static inline void __list_del(struct list_head * prev, struct list_head * next)
+{
+       next->prev = prev;
+       prev->next = next;
+}
+
+/**
+ * list_del - deletes entry from list.
+ * @entry: the element to delete from the list.
+ * Note: list_empty() on entry does not return true after this, the entry is
+ * in an undefined state.
+ */
+static inline void list_del(struct list_head *entry)
+{
+       __list_del(entry->prev, entry->next);
+       entry->next = NULL;
+       entry->prev = NULL;
+}
+
+/**
+ * list_replace - replace old entry by new one
+ * @old : the element to be replaced
+ * @new : the new element to insert
+ *
+ * If @old was empty, it will be overwritten.
+ */
+static inline void list_replace(struct list_head *old,
+                               struct list_head *new)
+{
+       new->next = old->next;
+       new->next->prev = new;
+       new->prev = old->prev;
+       new->prev->next = new;
+}
+
+static inline void list_replace_init(struct list_head *old,
+                                       struct list_head *new)
+{
+       list_replace(old, new);
+       INIT_LIST_HEAD(old);
+}
+
+/**
+ * list_del_init - deletes entry from list and reinitialize it.
+ * @entry: the element to delete from the list.
+ */
+static inline void list_del_init(struct list_head *entry)
+{
+       __list_del(entry->prev, entry->next);
+       INIT_LIST_HEAD(entry);
+}
+
+/**
+ * list_move - delete from one list and add as another's head
+ * @list: the entry to move
+ * @head: the head that will precede our entry
+ */
+static inline void list_move(struct list_head *list, struct list_head *head)
+{
+       __list_del(list->prev, list->next);
+       list_add(list, head);
+}
+
+/**
+ * list_move_tail - delete from one list and add as another's tail
+ * @list: the entry to move
+ * @head: the head that will follow our entry
+ */
+static inline void list_move_tail(struct list_head *list,
+                                 struct list_head *head)
+{
+       __list_del(list->prev, list->next);
+       list_add_tail(list, head);
+}
+
+/**
+ * list_is_last - tests whether @list is the last entry in list @head
+ * @list: the entry to test
+ * @head: the head of the list
+ */
+static inline int list_is_last(const struct list_head *list,
+                               const struct list_head *head)
+{
+       return list->next == head;
+}
+
+/**
+ * list_empty - tests whether a list is empty
+ * @head: the list to test.
+ */
+static inline int list_empty(const struct list_head *head)
+{
+       return head->next == head;
+}
+
+/**
+ * list_empty_careful - tests whether a list is empty and not being modified
+ * @head: the list to test
+ *
+ * Description:
+ * tests whether a list is empty _and_ checks that no other CPU might be
+ * in the process of modifying either member (next or prev)
+ *
+ * NOTE: using list_empty_careful() without synchronization
+ * can only be safe if the only activity that can happen
+ * to the list entry is list_del_init(). Eg. it cannot be used
+ * if another CPU could re-list_add() it.
+ */
+static inline int list_empty_careful(const struct list_head *head)
+{
+       struct list_head *next = head->next;
+       return (next == head) && (next == head->prev);
+}
+
+static inline void __list_splice(struct list_head *list,
+                                struct list_head *head)
+{
+       struct list_head *first = list->next;
+       struct list_head *last = list->prev;
+       struct list_head *at = head->next;
+
+       first->prev = head;
+       head->next = first;
+
+       last->next = at;
+       at->prev = last;
+}
+
+/**
+ * list_splice - join two lists
+ * @list: the new list to add.
+ * @head: the place to add it in the first list.
+ */
+static inline void list_splice(struct list_head *list, struct list_head *head)
+{
+       if (!list_empty(list))
+               __list_splice(list, head);
+}
+
+/**
+ * list_splice_init - join two lists and reinitialise the emptied list.
+ * @list: the new list to add.
+ * @head: the place to add it in the first list.
+ *
+ * The list at @list is reinitialised
+ */
+static inline void list_splice_init(struct list_head *list,
+                                   struct list_head *head)
+{
+       if (!list_empty(list)) {
+               __list_splice(list, head);
+               INIT_LIST_HEAD(list);
+       }
+}
+
+/**
+ * list_entry - get the struct for this entry
+ * @ptr:       the &struct list_head pointer.
+ * @type:      the type of the struct this is embedded in.
+ * @member:    the name of the list_struct within the struct.
+ */
+#define list_entry(ptr, type, member) \
+       container_of(ptr, type, member)
+
+/**
+ * list_first_entry - get the first element from a list
+ * @ptr:       the list head to take the element from.
+ * @type:      the type of the struct this is embedded in.
+ * @member:    the name of the list_struct within the struct.
+ *
+ * Note, that list is expected to be not empty.
+ */
+#define list_first_entry(ptr, type, member) \
+       list_entry((ptr)->next, type, member)
+
+/**
+ * list_for_each       -       iterate over a list
+ * @pos:       the &struct list_head to use as a loop cursor.
+ * @head:      the head for your list.
+ */
+#define list_for_each(pos, head) \
+       for (pos = (head)->next; pos != (head); \
+               pos = pos->next)
+
+/**
+ * __list_for_each     -       iterate over a list
+ * @pos:       the &struct list_head to use as a loop cursor.
+ * @head:      the head for your list.
+ *
+ * This variant differs from list_for_each() in that it's the
+ * simplest possible list iteration code, no prefetching is done.
+ * Use this for code that knows the list to be very short (empty
+ * or 1 entry) most of the time.
+ */
+#define __list_for_each(pos, head) \
+       for (pos = (head)->next; pos != (head); pos = pos->next)
+
+/**
+ * list_for_each_prev  -       iterate over a list backwards
+ * @pos:       the &struct list_head to use as a loop cursor.
+ * @head:      the head for your list.
+ */
+#define list_for_each_prev(pos, head) \
+       for (pos = (head)->prev; pos != (head); \
+               pos = pos->prev)
+
+/**
+ * list_for_each_safe - iterate over a list safe against removal of list entry
+ * @pos:       the &struct list_head to use as a loop cursor.
+ * @n:         another &struct list_head to use as temporary storage
+ * @head:      the head for your list.
+ */
+#define list_for_each_safe(pos, n, head) \
+       for (pos = (head)->next, n = pos->next; pos != (head); \
+               pos = n, n = pos->next)
+
+/**
+ * list_for_each_prev_safe - iterate over a list backwards safe against removal of list entry
+ * @pos:       the &struct list_head to use as a loop cursor.
+ * @n:         another &struct list_head to use as temporary storage
+ * @head:      the head for your list.
+ */
+#define list_for_each_prev_safe(pos, n, head) \
+       for (pos = (head)->prev, n = pos->prev; \
+            pos != (head); \
+            pos = n, n = pos->prev)
+
+/**
+ * list_for_each_entry -       iterate over list of given type
+ * @pos:       the type * to use as a loop cursor.
+ * @head:      the head for your list.
+ * @member:    the name of the list_struct within the struct.
+ */
+#define list_for_each_entry(pos, head, member)                         \
+       for (pos = list_entry((head)->next, typeof(*pos), member);      \
+            &pos->member != (head);    \
+            pos = list_entry(pos->member.next, typeof(*pos), member))
+
+/**
+ * list_for_each_entry_reverse - iterate backwards over list of given type.
+ * @pos:       the type * to use as a loop cursor.
+ * @head:      the head for your list.
+ * @member:    the name of the list_struct within the struct.
+ */
+#define list_for_each_entry_reverse(pos, head, member)                 \
+       for (pos = list_entry((head)->prev, typeof(*pos), member);      \
+            &pos->member != (head);    \
+            pos = list_entry(pos->member.prev, typeof(*pos), member))
+
+/**
+ * list_prepare_entry - prepare a pos entry for use in list_for_each_entry_continue()
+ * @pos:       the type * to use as a start point
+ * @head:      the head of the list
+ * @member:    the name of the list_struct within the struct.
+ *
+ * Prepares a pos entry for use as a start point in list_for_each_entry_continue().
+ */
+#define list_prepare_entry(pos, head, member) \
+       ((pos) ? : list_entry(head, typeof(*pos), member))
+
+/**
+ * list_for_each_entry_continue - continue iteration over list of given type
+ * @pos:       the type * to use as a loop cursor.
+ * @head:      the head for your list.
+ * @member:    the name of the list_struct within the struct.
+ *
+ * Continue to iterate over list of given type, continuing after
+ * the current position.
+ */
+#define list_for_each_entry_continue(pos, head, member)                \
+       for (pos = list_entry(pos->member.next, typeof(*pos), member);  \
+            &pos->member != (head);    \
+            pos = list_entry(pos->member.next, typeof(*pos), member))
+
+/**
+ * list_for_each_entry_continue_reverse - iterate backwards from the given point
+ * @pos:       the type * to use as a loop cursor.
+ * @head:      the head for your list.
+ * @member:    the name of the list_struct within the struct.
+ *
+ * Start to iterate over list of given type backwards, continuing after
+ * the current position.
+ */
+#define list_for_each_entry_continue_reverse(pos, head, member)                \
+       for (pos = list_entry(pos->member.prev, typeof(*pos), member);  \
+            &pos->member != (head);    \
+            pos = list_entry(pos->member.prev, typeof(*pos), member))
+
+/**
+ * list_for_each_entry_from - iterate over list of given type from the current point
+ * @pos:       the type * to use as a loop cursor.
+ * @head:      the head for your list.
+ * @member:    the name of the list_struct within the struct.
+ *
+ * Iterate over list of given type, continuing from current position.
+ */
+#define list_for_each_entry_from(pos, head, member)                    \
+       for (; &pos->member != (head);  \
+            pos = list_entry(pos->member.next, typeof(*pos), member))
+
+/**
+ * list_for_each_entry_safe - iterate over list of given type safe against removal of list entry
+ * @pos:       the type * to use as a loop cursor.
+ * @n:         another type * to use as temporary storage
+ * @head:      the head for your list.
+ * @member:    the name of the list_struct within the struct.
+ */
+#define list_for_each_entry_safe(pos, n, head, member)                 \
+       for (pos = list_entry((head)->next, typeof(*pos), member),      \
+               n = list_entry(pos->member.next, typeof(*pos), member); \
+            &pos->member != (head);                                    \
+            pos = n, n = list_entry(n->member.next, typeof(*n), member))
+
+/**
+ * list_for_each_entry_safe_continue
+ * @pos:       the type * to use as a loop cursor.
+ * @n:         another type * to use as temporary storage
+ * @head:      the head for your list.
+ * @member:    the name of the list_struct within the struct.
+ *
+ * Iterate over list of given type, continuing after current point,
+ * safe against removal of list entry.
+ */
+#define list_for_each_entry_safe_continue(pos, n, head, member)                \
+       for (pos = list_entry(pos->member.next, typeof(*pos), member),          \
+               n = list_entry(pos->member.next, typeof(*pos), member);         \
+            &pos->member != (head);                                            \
+            pos = n, n = list_entry(n->member.next, typeof(*n), member))
+
+/**
+ * list_for_each_entry_safe_from
+ * @pos:       the type * to use as a loop cursor.
+ * @n:         another type * to use as temporary storage
+ * @head:      the head for your list.
+ * @member:    the name of the list_struct within the struct.
+ *
+ * Iterate over list of given type from current point, safe against
+ * removal of list entry.
+ */
+#define list_for_each_entry_safe_from(pos, n, head, member)                    \
+       for (n = list_entry(pos->member.next, typeof(*pos), member);            \
+            &pos->member != (head);                                            \
+            pos = n, n = list_entry(n->member.next, typeof(*n), member))
+
+/**
+ * list_for_each_entry_safe_reverse
+ * @pos:       the type * to use as a loop cursor.
+ * @n:         another type * to use as temporary storage
+ * @head:      the head for your list.
+ * @member:    the name of the list_struct within the struct.
+ *
+ * Iterate backwards over list of given type, safe against removal
+ * of list entry.
+ */
+#define list_for_each_entry_safe_reverse(pos, n, head, member)         \
+       for (pos = list_entry((head)->prev, typeof(*pos), member),      \
+               n = list_entry(pos->member.prev, typeof(*pos), member); \
+            &pos->member != (head);                                    \
+            pos = n, n = list_entry(n->member.prev, typeof(*n), member))
+
+/*
+ * Double linked lists with a single pointer list head.
+ * Mostly useful for hash tables where the two pointer list head is
+ * too wasteful.
+ * You lose the ability to access the tail in O(1).
+ */
+
+struct hlist_head {
+       struct hlist_node *first;
+};
+
+struct hlist_node {
+       struct hlist_node *next, **pprev;
+};
+
+#define HLIST_HEAD_INIT { .first = NULL }
+#define HLIST_HEAD(name) struct hlist_head name = {  .first = NULL }
+#define INIT_HLIST_HEAD(ptr) ((ptr)->first = NULL)
+static inline void INIT_HLIST_NODE(struct hlist_node *h)
+{
+       h->next = NULL;
+       h->pprev = NULL;
+}
+
+static inline int hlist_unhashed(const struct hlist_node *h)
+{
+       return !h->pprev;
+}
+
+static inline int hlist_empty(const struct hlist_head *h)
+{
+       return !h->first;
+}
+
+static inline void __hlist_del(struct hlist_node *n)
+{
+       struct hlist_node *next = n->next;
+       struct hlist_node **pprev = n->pprev;
+       *pprev = next;
+       if (next)
+               next->pprev = pprev;
+}
+
+static inline void hlist_del(struct hlist_node *n)
+{
+       __hlist_del(n);
+       n->next = NULL;
+       n->pprev = NULL;
+}
+
+static inline void hlist_del_init(struct hlist_node *n)
+{
+       if (!hlist_unhashed(n)) {
+               __hlist_del(n);
+               INIT_HLIST_NODE(n);
+       }
+}
+
+
+static inline void hlist_add_head(struct hlist_node *n, struct hlist_head *h)
+{
+       struct hlist_node *first = h->first;
+       n->next = first;
+       if (first)
+               first->pprev = &n->next;
+       h->first = n;
+       n->pprev = &h->first;
+}
+
+
+/* next must be != NULL */
+static inline void hlist_add_before(struct hlist_node *n,
+                                       struct hlist_node *next)
+{
+       n->pprev = next->pprev;
+       n->next = next;
+       next->pprev = &n->next;
+       *(n->pprev) = n;
+}
+
+static inline void hlist_add_after(struct hlist_node *n,
+                                       struct hlist_node *next)
+{
+       next->next = n->next;
+       n->next = next;
+       next->pprev = &n->next;
+
+       if(next->next)
+               next->next->pprev  = &next->next;
+}
+
+#define hlist_entry(ptr, type, member) container_of(ptr,type,member)
+
+#define hlist_for_each(pos, head) \
+       for (pos = (head)->first; pos; pos = pos->next)
+
+#define hlist_for_each_safe(pos, n, head) \
+       for (pos = (head)->first; pos; pos = n)
+
+/**
+ * hlist_for_each_entry        - iterate over list of given type
+ * @tpos:      the type * to use as a loop cursor.
+ * @pos:       the &struct hlist_node to use as a loop cursor.
+ * @head:      the head for your list.
+ * @member:    the name of the hlist_node within the struct.
+ */
+#define hlist_for_each_entry(tpos, pos, head, member)                   \
+       for (pos = (head)->first; pos &&                                 \
+               ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \
+            pos = pos->next)
+
+/**
+ * hlist_for_each_entry_continue - iterate over a hlist continuing after current point
+ * @tpos:      the type * to use as a loop cursor.
+ * @pos:       the &struct hlist_node to use as a loop cursor.
+ * @member:    the name of the hlist_node within the struct.
+ */
+#define hlist_for_each_entry_continue(tpos, pos, member)               \
+       for (pos = (pos)->next; pos &&                                  \
+            ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;});   \
+            pos = pos->next)
+
+/**
+ * hlist_for_each_entry_from - iterate over a hlist continuing from current point
+ * @tpos:      the type * to use as a loop cursor.
+ * @pos:       the &struct hlist_node to use as a loop cursor.
+ * @member:    the name of the hlist_node within the struct.
+ */
+#define hlist_for_each_entry_from(tpos, pos, member)                    \
+       for (; pos &&                    \
+               ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \
+            pos = pos->next)
+
+/**
+ * hlist_for_each_entry_safe - iterate over list of given type safe against removal of list entry
+ * @tpos:      the type * to use as a loop cursor.
+ * @pos:       the &struct hlist_node to use as a loop cursor.
+ * @n:         another &struct hlist_node to use as temporary storage
+ * @head:      the head for your list.
+ * @member:    the name of the hlist_node within the struct.
+ */
+#define hlist_for_each_entry_safe(tpos, pos, n, head, member)           \
+       for (pos = (head)->first;                                        \
+            pos && ({ n = pos->next; 1; }) &&                           \
+               ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \
+            pos = n)
+
+#endif
diff --git a/package/ead/src/passwd b/package/ead/src/passwd
new file mode 100644 (file)
index 0000000..eee7a89
--- /dev/null
@@ -0,0 +1,3 @@
+root:$1$MCGAgYw.$Ip1GcyeUliId3wzVcKR/e/:0:0:root:/root:/bin/ash
+nobody:*:65534:65534:nobody:/var:/bin/false
+daemon:*:65534:65534:daemon:/var:/bin/false
diff --git a/package/ead/src/pfc.c b/package/ead/src/pfc.c
new file mode 100644 (file)
index 0000000..402e37f
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ * Small pcap precompiler
+ * Copyright (C) 2008 Felix Fietkau <nbd@openwrt.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <sys/types.h>
+#include <sys/time.h>
+#include <string.h>
+#include <stdlib.h>
+#include <pcap.h>
+
+int main (int argc, char ** argv)
+{
+       struct bpf_program filter;
+       pcap_t *pc;
+       int i;
+
+       if (argc != 2)
+       {
+               printf ("Usage: %s <expression>\n", argv[0]);
+               return 1;
+       }
+
+       pc = pcap_open_dead(DLT_EN10MB, 1500);
+       if (pcap_compile(pc, &filter, argv[1], 1, 0) != 0) {
+               printf("error in active-filter expression: %s\n", pcap_geterr(pc));
+               return 1;
+       }
+
+       printf("/* precompiled expression: %s */\n\n"
+               "static struct bpf_insn pktfilter_insns[] = {\n",
+               argv[1]);
+
+       for (i = 0; i < filter.bf_len; i++) {
+               struct bpf_insn *in = &filter.bf_insns[i];
+               printf("\t{ .code = 0x%04x, .jt = 0x%02x, .jf = 0x%02x, .k = 0x%08x },\n", in->code, in->jt, in->jf, in->k);
+       }
+       printf("};\n\n"
+               "static struct bpf_program pktfilter = {\n"
+               "\t.bf_len = %d,\n"
+               "\t.bf_insns = pktfilter_insns,\n"
+               "};\n", filter.bf_len);
+       return 0;
+
+}
diff --git a/package/ead/src/pw_encrypt_md5.c b/package/ead/src/pw_encrypt_md5.c
new file mode 100644 (file)
index 0000000..bc9f249
--- /dev/null
@@ -0,0 +1,646 @@
+/*
+ * MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm
+ *
+ * Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
+ * rights reserved.
+ *
+ * License to copy and use this software is granted provided that it
+ * is identified as the "RSA Data Security, Inc. MD5 Message-Digest
+ * Algorithm" in all material mentioning or referencing this software
+ * or this function.
+ *
+ * License is also granted to make and use derivative works provided
+ * that such works are identified as "derived from the RSA Data
+ * Security, Inc. MD5 Message-Digest Algorithm" in all material
+ * mentioning or referencing the derived work.
+ *
+ * RSA Data Security, Inc. makes no representations concerning either
+ * the merchantability of this software or the suitability of this
+ * software for any particular purpose. It is provided "as is"
+ * without express or implied warranty of any kind.
+ *
+ * These notices must be retained in any copies of any part of this
+ * documentation and/or software.
+ *
+ * $FreeBSD: src/lib/libmd/md5c.c,v 1.9.2.1 1999/08/29 14:57:12 peter Exp $
+ *
+ * This code is the same as the code published by RSA Inc.  It has been
+ * edited for clarity and style only.
+ *
+ * ----------------------------------------------------------------------------
+ * The md5_crypt() function was taken from freeBSD's libcrypt and contains
+ * this license:
+ *    "THE BEER-WARE LICENSE" (Revision 42):
+ *     <phk@login.dknet.dk> wrote this file.  As long as you retain this notice you
+ *     can do whatever you want with this stuff. If we meet some day, and you think
+ *     this stuff is worth it, you can buy me a beer in return.   Poul-Henning Kamp
+ *
+ * $FreeBSD: src/lib/libcrypt/crypt.c,v 1.7.2.1 1999/08/29 14:56:33 peter Exp $
+ *
+ * ----------------------------------------------------------------------------
+ * On April 19th, 2001 md5_crypt() was modified to make it reentrant
+ * by Erik Andersen <andersen@uclibc.org>
+ *
+ *
+ * June 28, 2001             Manuel Novoa III
+ *
+ * "Un-inlined" code using loops and static const tables in order to
+ * reduce generated code size (on i386 from approx 4k to approx 2.5k).
+ *
+ * June 29, 2001             Manuel Novoa III
+ *
+ * Completely removed static PADDING array.
+ *
+ * Reintroduced the loop unrolling in MD5_Transform and added the
+ * MD5_SIZE_OVER_SPEED option for configurability.  Define below as:
+ *       0    fully unrolled loops
+ *       1    partially unrolled (4 ops per loop)
+ *       2    no unrolling -- introduces the need to swap 4 variables (slow)
+ *       3    no unrolling and all 4 loops merged into one with switch
+ *               in each loop (glacial)
+ * On i386, sizes are roughly (-Os -fno-builtin):
+ *     0: 3k     1: 2.5k     2: 2.2k     3: 2k
+ *
+ *
+ * Since SuSv3 does not require crypt_r, modified again August 7, 2002
+ * by Erik Andersen to remove reentrance stuff...
+ */
+
+static const uint8_t ascii64[] = "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
+
+/*
+ * Valid values are  1 (fastest/largest) to 3 (smallest/slowest).
+ */
+#define MD5_SIZE_OVER_SPEED 3
+
+/**********************************************************************/
+
+/* MD5 context. */
+struct MD5Context {
+       uint32_t state[4];      /* state (ABCD) */
+       uint32_t count[2];      /* number of bits, modulo 2^64 (lsb first) */
+       unsigned char buffer[64];       /* input buffer */
+};
+
+static void __md5_Init(struct MD5Context *);
+static void __md5_Update(struct MD5Context *, const unsigned char *, unsigned int);
+static void __md5_Pad(struct MD5Context *);
+static void __md5_Final(unsigned char [16], struct MD5Context *);
+static void __md5_Transform(uint32_t [4], const unsigned char [64]);
+
+
+#define MD5_MAGIC_STR "$1$"
+#define MD5_MAGIC_LEN (sizeof(MD5_MAGIC_STR) - 1)
+static const unsigned char __md5__magic[] = MD5_MAGIC_STR;
+
+
+#ifdef i386
+#define __md5_Encode memcpy
+#define __md5_Decode memcpy
+#else /* i386 */
+
+/*
+ * __md5_Encodes input (uint32_t) into output (unsigned char). Assumes len is
+ * a multiple of 4.
+ */
+static void
+__md5_Encode(unsigned char *output, uint32_t *input, unsigned int len)
+{
+       unsigned int i, j;
+
+       for (i = 0, j = 0; j < len; i++, j += 4) {
+               output[j] = input[i];
+               output[j+1] = (input[i] >> 8);
+               output[j+2] = (input[i] >> 16);
+               output[j+3] = (input[i] >> 24);
+       }
+}
+
+/*
+ * __md5_Decodes input (unsigned char) into output (uint32_t). Assumes len is
+ * a multiple of 4.
+ */
+static void
+__md5_Decode(uint32_t *output, const unsigned char *input, unsigned int len)
+{
+       unsigned int i, j;
+
+       for (i = 0, j = 0; j < len; i++, j += 4)
+               output[i] = ((uint32_t)input[j]) | (((uint32_t)input[j+1]) << 8) |
+                   (((uint32_t)input[j+2]) << 16) | (((uint32_t)input[j+3]) << 24);
+}
+#endif /* i386 */
+
+/* F, G, H and I are basic MD5 functions. */
+#define F(x, y, z) (((x) & (y)) | (~(x) & (z)))
+#define G(x, y, z) (((x) & (z)) | ((y) & ~(z)))
+#define H(x, y, z) ((x) ^ (y) ^ (z))
+#define I(x, y, z) ((y) ^ ((x) | ~(z)))
+
+/* ROTATE_LEFT rotates x left n bits. */
+#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
+
+/*
+ * FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
+ * Rotation is separate from addition to prevent recomputation.
+ */
+#define FF(a, b, c, d, x, s, ac) { \
+       (a) += F ((b), (c), (d)) + (x) + (uint32_t)(ac); \
+       (a) = ROTATE_LEFT((a), (s)); \
+       (a) += (b); \
+       }
+#define GG(a, b, c, d, x, s, ac) { \
+       (a) += G ((b), (c), (d)) + (x) + (uint32_t)(ac); \
+       (a) = ROTATE_LEFT((a), (s)); \
+       (a) += (b); \
+       }
+#define HH(a, b, c, d, x, s, ac) { \
+       (a) += H ((b), (c), (d)) + (x) + (uint32_t)(ac); \
+       (a) = ROTATE_LEFT((a), (s)); \
+       (a) += (b); \
+       }
+#define II(a, b, c, d, x, s, ac) { \
+       (a) += I ((b), (c), (d)) + (x) + (uint32_t)(ac); \
+       (a) = ROTATE_LEFT((a), (s)); \
+       (a) += (b); \
+       }
+
+/* MD5 initialization. Begins an MD5 operation, writing a new context. */
+static void __md5_Init(struct MD5Context *context)
+{
+       context->count[0] = context->count[1] = 0;
+
+       /* Load magic initialization constants.  */
+       context->state[0] = 0x67452301;
+       context->state[1] = 0xefcdab89;
+       context->state[2] = 0x98badcfe;
+       context->state[3] = 0x10325476;
+}
+
+/*
+ * MD5 block update operation. Continues an MD5 message-digest
+ * operation, processing another message block, and updating the
+ * context.
+ */
+static void __md5_Update(struct MD5Context *context, const unsigned char *input, unsigned int inputLen)
+{
+       unsigned int i, idx, partLen;
+
+       /* Compute number of bytes mod 64 */
+       idx = (context->count[0] >> 3) & 0x3F;
+
+       /* Update number of bits */
+       context->count[0] += (inputLen << 3);
+       if (context->count[0] < (inputLen << 3))
+               context->count[1]++;
+       context->count[1] += (inputLen >> 29);
+
+       partLen = 64 - idx;
+
+       /* Transform as many times as possible. */
+       if (inputLen >= partLen) {
+               memcpy(&context->buffer[idx], input, partLen);
+               __md5_Transform(context->state, context->buffer);
+
+               for (i = partLen; i + 63 < inputLen; i += 64)
+                       __md5_Transform(context->state, &input[i]);
+
+               idx = 0;
+       } else
+               i = 0;
+
+       /* Buffer remaining input */
+       memcpy(&context->buffer[idx], &input[i], inputLen - i);
+}
+
+/*
+ * MD5 padding. Adds padding followed by original length.
+ */
+static void __md5_Pad(struct MD5Context *context)
+{
+       unsigned char bits[8];
+       unsigned int idx, padLen;
+       unsigned char PADDING[64];
+
+       memset(PADDING, 0, sizeof(PADDING));
+       PADDING[0] = 0x80;
+
+       /* Save number of bits */
+       __md5_Encode(bits, context->count, 8);
+
+       /* Pad out to 56 mod 64. */
+       idx = (context->count[0] >> 3) & 0x3f;
+       padLen = (idx < 56) ? (56 - idx) : (120 - idx);
+       __md5_Update(context, PADDING, padLen);
+
+       /* Append length (before padding) */
+       __md5_Update(context, bits, 8);
+}
+
+/*
+ * MD5 finalization. Ends an MD5 message-digest operation, writing the
+ * the message digest and zeroizing the context.
+ */
+static void __md5_Final(unsigned char digest[16], struct MD5Context *context)
+{
+       /* Do padding. */
+       __md5_Pad(context);
+
+       /* Store state in digest */
+       __md5_Encode(digest, context->state, 16);
+
+       /* Zeroize sensitive information. */
+       memset(context, 0, sizeof(*context));
+}
+
+/* MD5 basic transformation. Transforms state based on block. */
+static void __md5_Transform(uint32_t state[4], const unsigned char block[64])
+{
+       uint32_t a, b, c, d, x[16];
+#if MD5_SIZE_OVER_SPEED > 1
+       uint32_t temp;
+       const unsigned char *ps;
+
+       static const unsigned char S[] = {
+               7, 12, 17, 22,
+               5, 9, 14, 20,
+               4, 11, 16, 23,
+               6, 10, 15, 21
+       };
+#endif /* MD5_SIZE_OVER_SPEED > 1 */
+
+#if MD5_SIZE_OVER_SPEED > 0
+       const uint32_t *pc;
+       const unsigned char *pp;
+       int i;
+
+       static const uint32_t C[] = {
+                                                               /* round 1 */
+               0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee,
+               0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501,
+               0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be,
+               0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821,
+                                                               /* round 2 */
+               0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa,
+               0xd62f105d, 0x2441453,  0xd8a1e681, 0xe7d3fbc8,
+               0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed,
+               0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a,
+                                                               /* round 3 */
+               0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c,
+               0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70,
+               0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x4881d05,
+               0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665,
+                                                               /* round 4 */
+               0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039,
+               0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1,
+               0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1,
+               0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391
+       };
+
+       static const unsigned char P[] = {
+               0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, /* 1 */
+               1, 6, 11, 0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12, /* 2 */
+               5, 8, 11, 14, 1, 4, 7, 10, 13, 0, 3, 6, 9, 12, 15, 2, /* 3 */
+               0, 7, 14, 5, 12, 3, 10, 1, 8, 15, 6, 13, 4, 11, 2, 9  /* 4 */
+       };
+
+#endif /* MD5_SIZE_OVER_SPEED > 0 */
+
+       __md5_Decode(x, block, 64);
+
+       a = state[0]; b = state[1]; c = state[2]; d = state[3];
+
+#if MD5_SIZE_OVER_SPEED > 2
+       pc = C; pp = P; ps = S - 4;
+
+       for (i = 0; i < 64; i++) {
+               if ((i & 0x0f) == 0) ps += 4;
+               temp = a;
+               switch (i>>4) {
+                       case 0:
+                               temp += F(b, c, d);
+                               break;
+                       case 1:
+                               temp += G(b, c, d);
+                               break;
+                       case 2:
+                               temp += H(b, c, d);
+                               break;
+                       case 3:
+                               temp += I(b, c, d);
+                               break;
+               }
+               temp += x[*pp++] + *pc++;
+               temp = ROTATE_LEFT(temp, ps[i & 3]);
+               temp += b;
+               a = d; d = c; c = b; b = temp;
+       }
+#elif MD5_SIZE_OVER_SPEED > 1
+       pc = C; pp = P; ps = S;
+
+       /* Round 1 */
+       for (i = 0; i < 16; i++) {
+               FF(a, b, c, d, x[*pp], ps[i & 0x3], *pc); pp++; pc++;
+               temp = d; d = c; c = b; b = a; a = temp;
+       }
+
+       /* Round 2 */
+       ps += 4;
+       for (; i < 32; i++) {
+               GG(a, b, c, d, x[*pp], ps[i & 0x3], *pc); pp++; pc++;
+               temp = d; d = c; c = b; b = a; a = temp;
+       }
+       /* Round 3 */
+       ps += 4;
+       for (; i < 48; i++) {
+               HH(a, b, c, d, x[*pp], ps[i & 0x3], *pc); pp++; pc++;
+               temp = d; d = c; c = b; b = a; a = temp;
+       }
+
+       /* Round 4 */
+       ps += 4;
+       for (; i < 64; i++) {
+               II(a, b, c, d, x[*pp], ps[i & 0x3], *pc); pp++; pc++;
+               temp = d; d = c; c = b; b = a; a = temp;
+       }
+#elif MD5_SIZE_OVER_SPEED > 0
+       pc = C; pp = P;
+
+       /* Round 1 */
+       for (i = 0; i < 4; i++) {
+               FF(a, b, c, d, x[*pp],  7, *pc); pp++; pc++;
+               FF(d, a, b, c, x[*pp], 12, *pc); pp++; pc++;
+               FF(c, d, a, b, x[*pp], 17, *pc); pp++; pc++;
+               FF(b, c, d, a, x[*pp], 22, *pc); pp++; pc++;
+       }
+
+       /* Round 2 */
+       for (i = 0; i < 4; i++) {
+               GG(a, b, c, d, x[*pp],  5, *pc); pp++; pc++;
+               GG(d, a, b, c, x[*pp],  9, *pc); pp++; pc++;
+               GG(c, d, a, b, x[*pp], 14, *pc); pp++; pc++;
+               GG(b, c, d, a, x[*pp], 20, *pc); pp++; pc++;
+       }
+       /* Round 3 */
+       for (i = 0; i < 4; i++) {
+               HH(a, b, c, d, x[*pp],  4, *pc); pp++; pc++;
+               HH(d, a, b, c, x[*pp], 11, *pc); pp++; pc++;
+               HH(c, d, a, b, x[*pp], 16, *pc); pp++; pc++;
+               HH(b, c, d, a, x[*pp], 23, *pc); pp++; pc++;
+       }
+
+       /* Round 4 */
+       for (i = 0; i < 4; i++) {
+               II(a, b, c, d, x[*pp],  6, *pc); pp++; pc++;
+               II(d, a, b, c, x[*pp], 10, *pc); pp++; pc++;
+               II(c, d, a, b, x[*pp], 15, *pc); pp++; pc++;
+               II(b, c, d, a, x[*pp], 21, *pc); pp++; pc++;
+       }
+#else
+       /* Round 1 */
+#define S11 7
+#define S12 12
+#define S13 17
+#define S14 22
+       FF(a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
+       FF(d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
+       FF(c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
+       FF(b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
+       FF(a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
+       FF(d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
+       FF(c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
+       FF(b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
+       FF(a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
+       FF(d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
+       FF(c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
+       FF(b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
+       FF(a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
+       FF(d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
+       FF(c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
+       FF(b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
+
+       /* Round 2 */
+#define S21 5
+#define S22 9
+#define S23 14
+#define S24 20
+       GG(a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
+       GG(d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
+       GG(c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
+       GG(b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
+       GG(a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
+       GG(d, a, b, c, x[10], S22,  0x2441453); /* 22 */
+       GG(c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
+       GG(b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
+       GG(a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
+       GG(d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
+       GG(c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
+       GG(b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
+       GG(a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
+       GG(d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
+       GG(c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
+       GG(b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
+
+       /* Round 3 */
+#define S31 4
+#define S32 11
+#define S33 16
+#define S34 23
+       HH(a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
+       HH(d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
+       HH(c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
+       HH(b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
+       HH(a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
+       HH(d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
+       HH(c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
+       HH(b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
+       HH(a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
+       HH(d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
+       HH(c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
+       HH(b, c, d, a, x[ 6], S34,  0x4881d05); /* 44 */
+       HH(a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
+       HH(d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
+       HH(c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
+       HH(b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
+
+       /* Round 4 */
+#define S41 6
+#define S42 10
+#define S43 15
+#define S44 21
+       II(a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
+       II(d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
+       II(c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
+       II(b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
+       II(a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
+       II(d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
+       II(c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
+       II(b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
+       II(a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
+       II(d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
+       II(c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
+       II(b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
+       II(a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
+       II(d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
+       II(c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
+       II(b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
+#endif
+
+       state[0] += a;
+       state[1] += b;
+       state[2] += c;
+       state[3] += d;
+
+       /* Zeroize sensitive information. */
+       memset(x, 0, sizeof(x));
+}
+
+
+static char*
+__md5_to64(char *s, unsigned v, int n)
+{
+       while (--n >= 0) {
+               *s++ = ascii64[v & 0x3f];
+               v >>= 6;
+       }
+       return s;
+}
+
+/*
+ * UNIX password
+ *
+ * Use MD5 for what it is best at...
+ */
+#define MD5_OUT_BUFSIZE 36
+static char *
+md5_crypt(char passwd[MD5_OUT_BUFSIZE], const unsigned char *pw, const unsigned char *salt)
+{
+       const unsigned char *sp, *ep;
+       char *p;
+       unsigned char final[17];        /* final[16] exists only to aid in looping */
+       int sl, pl, i, pw_len;
+       struct MD5Context ctx, ctx1;
+
+       /* Refine the Salt first */
+       sp = salt;
+
+       sp += MD5_MAGIC_LEN;
+
+       /* It stops at the first '$', max 8 chars */
+       for (ep = sp; *ep && *ep != '$' && ep < (sp+8); ep++)
+               continue;
+
+       /* get the length of the true salt */
+       sl = ep - sp;
+
+       __md5_Init(&ctx);
+
+       /* The password first, since that is what is most unknown */
+       pw_len = strlen((char*)pw);
+       __md5_Update(&ctx, pw, pw_len);
+
+       /* Then our magic string */
+       __md5_Update(&ctx, __md5__magic, MD5_MAGIC_LEN);
+
+       /* Then the raw salt */
+       __md5_Update(&ctx, sp, sl);
+
+       /* Then just as many characters of the MD5(pw, salt, pw) */
+       __md5_Init(&ctx1);
+       __md5_Update(&ctx1, pw, pw_len);
+       __md5_Update(&ctx1, sp, sl);
+       __md5_Update(&ctx1, pw, pw_len);
+       __md5_Final(final, &ctx1);
+       for (pl = pw_len; pl > 0; pl -= 16)
+               __md5_Update(&ctx, final, pl > 16 ? 16 : pl);
+
+       /* Don't leave anything around in vm they could use. */
+//TODO: the above comment seems to be wrong. final is used later.
+       memset(final, 0, sizeof(final));
+
+       /* Then something really weird... */
+       for (i = pw_len; i; i >>= 1) {
+               __md5_Update(&ctx, ((i & 1) ? final : (const unsigned char *) pw), 1);
+       }
+
+       /* Now make the output string */
+       passwd[0] = '$';
+       passwd[1] = '1';
+       passwd[2] = '$';
+       strncpy(passwd + 3, (char*)sp, sl);
+       passwd[sl + 3] = '$';
+
+       __md5_Final(final, &ctx);
+
+       /*
+        * and now, just to make sure things don't run too fast
+        * On a 60 Mhz Pentium this takes 34 msec, so you would
+        * need 30 seconds to build a 1000 entry dictionary...
+        */
+       for (i = 0; i < 1000; i++) {
+               __md5_Init(&ctx1);
+               if (i & 1)
+                       __md5_Update(&ctx1, pw, pw_len);
+               else
+                       __md5_Update(&ctx1, final, 16);
+
+               if (i % 3)
+                       __md5_Update(&ctx1, sp, sl);
+
+               if (i % 7)
+                       __md5_Update(&ctx1, pw, pw_len);
+
+               if (i & 1)
+                       __md5_Update(&ctx1, final, 16);
+               else
+                       __md5_Update(&ctx1, pw, pw_len);
+               __md5_Final(final, &ctx1);
+       }
+
+       p = passwd + sl + 4; /* 12 bytes max (sl is up to 8 bytes) */
+
+       /* Add 5*4+2 = 22 bytes of hash, + NUL byte. */
+       final[16] = final[5];
+       for (i = 0; i < 5; i++) {
+               unsigned l = (final[i] << 16) | (final[i+6] << 8) | final[i+12];
+               p = __md5_to64(p, l, 4);
+       }
+       p = __md5_to64(p, final[11], 2);
+       *p = '\0';
+
+       /* Don't leave anything around in vm they could use. */
+       memset(final, 0, sizeof(final));
+
+       return passwd;
+}
+
+#undef MD5_SIZE_OVER_SPEED
+#undef MD5_MAGIC_STR
+#undef MD5_MAGIC_LEN
+#undef __md5_Encode
+#undef __md5_Decode
+#undef F
+#undef G
+#undef H
+#undef I
+#undef ROTATE_LEFT
+#undef FF
+#undef GG
+#undef HH
+#undef II
+#undef S11
+#undef S12
+#undef S13
+#undef S14
+#undef S21
+#undef S22
+#undef S23
+#undef S24
+#undef S31
+#undef S32
+#undef S33
+#undef S34
+#undef S41
+#undef S42
+#undef S43
+#undef S44
diff --git a/package/ead/src/sha1.c b/package/ead/src/sha1.c
new file mode 100644 (file)
index 0000000..3683a7d
--- /dev/null
@@ -0,0 +1,104 @@
+/*
+ * SHA transform algorithm, originally taken from code written by
+ * Peter Gutmann, and placed in the public domain.
+ */
+
+static  uint32_t
+rol32(uint32_t word, int shift)
+{
+       return (word << shift) | (word >> (32 - shift));
+}
+
+/* The SHA f()-functions.  */
+
+#define f1(x,y,z)   (z ^ (x & (y ^ z)))                /* x ? y : z */
+#define f2(x,y,z)   (x ^ y ^ z)                        /* XOR */
+#define f3(x,y,z)   ((x & y) + (z & (x ^ y)))  /* majority */
+
+/* The SHA Mysterious Constants */
+
+#define K1  0x5A827999L                        /* Rounds  0-19: sqrt(2) * 2^30 */
+#define K2  0x6ED9EBA1L                        /* Rounds 20-39: sqrt(3) * 2^30 */
+#define K3  0x8F1BBCDCL                        /* Rounds 40-59: sqrt(5) * 2^30 */
+#define K4  0xCA62C1D6L                        /* Rounds 60-79: sqrt(10) * 2^30 */
+
+/**
+ * sha_transform - single block SHA1 transform
+ *
+ * @digest: 160 bit digest to update
+ * @data:   512 bits of data to hash
+ * @W:      80 words of workspace (see note)
+ *
+ * This function generates a SHA1 digest for a single 512-bit block.
+ * Be warned, it does not handle padding and message digest, do not
+ * confuse it with the full FIPS 180-1 digest algorithm for variable
+ * length messages.
+ *
+ * Note: If the hash is security sensitive, the caller should be sure
+ * to clear the workspace. This is left to the caller to avoid
+ * unnecessary clears between chained hashing operations.
+ */
+static void sha_transform(uint32_t *digest, const unsigned char *in, uint32_t *W)
+{
+       uint32_t a, b, c, d, e, t, i;
+
+       for (i = 0; i < 16; i++) {
+               int ofs = 4 * i;
+
+               /* word load/store may be unaligned here, so use bytes instead */
+               W[i] =
+                       (in[ofs+0] << 24) |
+                       (in[ofs+1] << 16) |
+                       (in[ofs+2] << 8) |
+                        in[ofs+3];
+       }
+
+       for (i = 0; i < 64; i++)
+               W[i+16] = rol32(W[i+13] ^ W[i+8] ^ W[i+2] ^ W[i], 1);
+
+       a = digest[0];
+       b = digest[1];
+       c = digest[2];
+       d = digest[3];
+       e = digest[4];
+
+       for (i = 0; i < 20; i++) {
+               t = f1(b, c, d) + K1 + rol32(a, 5) + e + W[i];
+               e = d; d = c; c = rol32(b, 30); b = a; a = t;
+       }
+
+       for (; i < 40; i ++) {
+               t = f2(b, c, d) + K2 + rol32(a, 5) + e + W[i];
+               e = d; d = c; c = rol32(b, 30); b = a; a = t;
+       }
+
+       for (; i < 60; i ++) {
+               t = f3(b, c, d) + K3 + rol32(a, 5) + e + W[i];
+               e = d; d = c; c = rol32(b, 30); b = a; a = t;
+       }
+
+       for (; i < 80; i ++) {
+               t = f2(b, c, d) + K4 + rol32(a, 5) + e + W[i];
+               e = d; d = c; c = rol32(b, 30); b = a; a = t;
+       }
+
+       digest[0] += a;
+       digest[1] += b;
+       digest[2] += c;
+       digest[3] += d;
+       digest[4] += e;
+}
+
+/**
+ * sha_init - initialize the vectors for a SHA1 digest
+ * @buf: vector to initialize
+ */
+static void sha_init(uint32_t *buf)
+{
+       buf[0] = 0x67452301;
+       buf[1] = 0xefcdab89;
+       buf[2] = 0x98badcfe;
+       buf[3] = 0x10325476;
+       buf[4] = 0xc3d2e1f0;
+}
+
diff --git a/package/ead/src/tinysrp/Makefile.am b/package/ead/src/tinysrp/Makefile.am
new file mode 100644 (file)
index 0000000..a8f899f
--- /dev/null
@@ -0,0 +1,28 @@
+AUTOMAKE_OPTIONS = foreign no-dependencies
+
+noinst_HEADERS = t_client.h t_pwd.h t_server.h t_sha.h \
+  bn.h bn_lcl.h bn_prime.h t_defines.h t_read.h
+
+include_HEADERS = tinysrp.h
+
+lib_LIBRARIES = libtinysrp.a
+
+CFLAGS = -O2 @signed@
+
+libtinysrp_a_SOURCES = \
+  tinysrp.c t_client.c t_getconf.c t_conv.c t_getpass.c t_sha.c t_math.c \
+  t_misc.c t_pw.c t_read.c t_server.c t_truerand.c \
+  bn_add.c bn_ctx.c bn_div.c bn_exp.c bn_mul.c bn_word.c bn_asm.c bn_lib.c \
+  bn_shift.c bn_sqr.c
+
+noinst_PROGRAMS = srvtest clitest
+srvtest_SOURCES = srvtest.c
+clitest_SOURCES = clitest.c
+
+bin_PROGRAMS = tconf tphrase
+tconf_SOURCES = tconf.c t_conf.c
+tphrase_SOURCES = tphrase.c
+
+LDADD = libtinysrp.a
+
+EXTRA_DIST = tpasswd Notes
diff --git a/package/ead/src/tinysrp/Makefile.in b/package/ead/src/tinysrp/Makefile.in
new file mode 100644 (file)
index 0000000..26042b4
--- /dev/null
@@ -0,0 +1,481 @@
+# Makefile.in generated automatically by automake 1.4a from Makefile.am
+
+# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+
+SHELL = @SHELL@
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+
+bindir = @bindir@
+sbindir = @sbindir@
+libexecdir = @libexecdir@
+datadir = @datadir@
+sysconfdir = @sysconfdir@
+sharedstatedir = @sharedstatedir@
+localstatedir = @localstatedir@
+libdir = @libdir@
+infodir = @infodir@
+mandir = @mandir@
+includedir = @includedir@
+oldincludedir = /usr/include
+
+DESTDIR =
+
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+
+top_builddir = .
+
+ACLOCAL = @ACLOCAL@
+AUTOCONF = @AUTOCONF@
+AUTOMAKE = @AUTOMAKE@
+AUTOHEADER = @AUTOHEADER@
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_FLAG =
+transform = @program_transform_name@
+
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+CC = @CC@
+LN_S = @LN_S@
+MAKEINFO = @MAKEINFO@
+PACKAGE = @PACKAGE@
+RANLIB = @RANLIB@
+VERSION = @VERSION@
+signed = @signed@
+
+AUTOMAKE_OPTIONS = foreign no-dependencies
+
+noinst_HEADERS = t_client.h t_pwd.h t_server.h t_sha.h   bn.h bn_lcl.h bn_prime.h t_defines.h t_read.h
+
+
+include_HEADERS = tinysrp.h
+
+lib_LIBRARIES = libtinysrp.a
+
+CFLAGS = -O2 @signed@
+
+libtinysrp_a_SOURCES =    tinysrp.c t_client.c t_getconf.c t_conv.c t_getpass.c t_sha.c t_math.c   t_misc.c t_pw.c t_read.c t_server.c t_truerand.c   bn_add.c bn_ctx.c bn_div.c bn_exp.c bn_mul.c bn_word.c bn_asm.c bn_lib.c   bn_shift.c bn_sqr.c
+
+
+noinst_PROGRAMS = srvtest clitest
+srvtest_SOURCES = srvtest.c
+clitest_SOURCES = clitest.c
+
+bin_PROGRAMS = tconf tphrase
+tconf_SOURCES = tconf.c t_conf.c
+tphrase_SOURCES = tphrase.c
+
+LDADD = libtinysrp.a
+
+EXTRA_DIST = tpasswd Notes
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_HEADER = config.h
+CONFIG_CLEAN_FILES = 
+LIBRARIES =  $(lib_LIBRARIES)
+
+
+DEFS = @DEFS@ -I. -I$(srcdir) -I.
+CPPFLAGS = @CPPFLAGS@
+LDFLAGS = @LDFLAGS@
+LIBS = @LIBS@
+libtinysrp_a_LIBADD = 
+libtinysrp_a_OBJECTS =  tinysrp.o t_client.o t_getconf.o t_conv.o \
+t_getpass.o t_sha.o t_math.o t_misc.o t_pw.o t_read.o t_server.o \
+t_truerand.o bn_add.o bn_ctx.o bn_div.o bn_exp.o bn_mul.o bn_word.o \
+bn_asm.o bn_lib.o bn_shift.o bn_sqr.o
+AR = ar
+PROGRAMS =  $(bin_PROGRAMS) $(noinst_PROGRAMS)
+
+tconf_OBJECTS =  tconf.o t_conf.o
+tconf_LDADD = $(LDADD)
+tconf_DEPENDENCIES =  libtinysrp.a
+tconf_LDFLAGS = 
+tphrase_OBJECTS =  tphrase.o
+tphrase_LDADD = $(LDADD)
+tphrase_DEPENDENCIES =  libtinysrp.a
+tphrase_LDFLAGS = 
+srvtest_OBJECTS =  srvtest.o
+srvtest_LDADD = $(LDADD)
+srvtest_DEPENDENCIES =  libtinysrp.a
+srvtest_LDFLAGS = 
+clitest_OBJECTS =  clitest.o
+clitest_LDADD = $(LDADD)
+clitest_DEPENDENCIES =  libtinysrp.a
+clitest_LDFLAGS = 
+COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@
+HEADERS =  $(include_HEADERS) $(noinst_HEADERS)
+
+DIST_COMMON =  ./stamp-h.in Makefile.am Makefile.in acconfig.h \
+acinclude.m4 aclocal.m4 config.h.in configure configure.in install-sh \
+missing mkinstalldirs
+
+
+DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
+
+TAR = gtar
+GZIP_ENV = --best
+SOURCES = $(libtinysrp_a_SOURCES) $(tconf_SOURCES) $(tphrase_SOURCES) $(srvtest_SOURCES) $(clitest_SOURCES)
+OBJECTS = $(libtinysrp_a_OBJECTS) $(tconf_OBJECTS) $(tphrase_OBJECTS) $(srvtest_OBJECTS) $(clitest_OBJECTS)
+
+all: all-redirect
+.SUFFIXES:
+.SUFFIXES: .S .c .o .s
+$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) 
+       cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile
+
+Makefile: $(srcdir)/Makefile.in  $(top_builddir)/config.status
+       cd $(top_builddir) \
+         && CONFIG_FILES=$@ CONFIG_HEADERS= $(SHELL) ./config.status
+
+$(ACLOCAL_M4):  configure.in  acinclude.m4
+       cd $(srcdir) && $(ACLOCAL)
+
+config.status: $(srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+       $(SHELL) ./config.status --recheck
+$(srcdir)/configure: $(srcdir)/configure.in $(ACLOCAL_M4) $(CONFIGURE_DEPENDENCIES)
+       cd $(srcdir) && $(AUTOCONF)
+
+config.h: stamp-h
+       @if test ! -f $@; then \
+               rm -f stamp-h; \
+               $(MAKE) stamp-h; \
+       else :; fi
+stamp-h: $(srcdir)/config.h.in $(top_builddir)/config.status
+       cd $(top_builddir) \
+         && CONFIG_FILES= CONFIG_HEADERS=config.h \
+            $(SHELL) ./config.status
+       @echo timestamp > stamp-h 2> /dev/null
+$(srcdir)/config.h.in: $(srcdir)/stamp-h.in
+       @if test ! -f $@; then \
+               rm -f $(srcdir)/stamp-h.in; \
+               $(MAKE) $(srcdir)/stamp-h.in; \
+       else :; fi
+$(srcdir)/stamp-h.in: $(top_srcdir)/configure.in $(ACLOCAL_M4) acconfig.h
+       cd $(top_srcdir) && $(AUTOHEADER)
+       @echo timestamp > $(srcdir)/stamp-h.in 2> /dev/null
+
+mostlyclean-hdr:
+
+clean-hdr:
+
+distclean-hdr:
+       -rm -f config.h
+
+maintainer-clean-hdr:
+
+mostlyclean-libLIBRARIES:
+
+clean-libLIBRARIES:
+       -test -z "$(lib_LIBRARIES)" || rm -f $(lib_LIBRARIES)
+
+distclean-libLIBRARIES:
+
+maintainer-clean-libLIBRARIES:
+
+install-libLIBRARIES: $(lib_LIBRARIES)
+       @$(NORMAL_INSTALL)
+       $(mkinstalldirs) $(DESTDIR)$(libdir)
+       @list='$(lib_LIBRARIES)'; for p in $$list; do \
+         if test -f $$p; then \
+           echo " $(INSTALL_DATA) $$p $(DESTDIR)$(libdir)/$$p"; \
+           $(INSTALL_DATA) $$p $(DESTDIR)$(libdir)/$$p; \
+         else :; fi; \
+       done
+       @$(POST_INSTALL)
+       @list='$(lib_LIBRARIES)'; for p in $$list; do \
+         if test -f $$p; then \
+           echo " $(RANLIB) $(DESTDIR)$(libdir)/$$p"; \
+           $(RANLIB) $(DESTDIR)$(libdir)/$$p; \
+         else :; fi; \
+       done
+
+uninstall-libLIBRARIES:
+       @$(NORMAL_UNINSTALL)
+       list='$(lib_LIBRARIES)'; for p in $$list; do \
+         rm -f $(DESTDIR)$(libdir)/$$p; \
+       done
+
+.c.o:
+       $(COMPILE) -c $<
+
+.s.o:
+       $(COMPILE) -c $<
+
+.S.o:
+       $(COMPILE) -c $<
+
+mostlyclean-compile:
+       -rm -f *.o core *.core
+
+clean-compile:
+
+distclean-compile:
+       -rm -f *.tab.c
+
+maintainer-clean-compile:
+
+libtinysrp.a: $(libtinysrp_a_OBJECTS) $(libtinysrp_a_DEPENDENCIES)
+       -rm -f libtinysrp.a
+       $(AR) cru libtinysrp.a $(libtinysrp_a_OBJECTS) $(libtinysrp_a_LIBADD)
+       $(RANLIB) libtinysrp.a
+
+mostlyclean-binPROGRAMS:
+
+clean-binPROGRAMS:
+       -test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS)
+
+distclean-binPROGRAMS:
+
+maintainer-clean-binPROGRAMS:
+
+install-binPROGRAMS: $(bin_PROGRAMS)
+       @$(NORMAL_INSTALL)
+       $(mkinstalldirs) $(DESTDIR)$(bindir)
+       @list='$(bin_PROGRAMS)'; for p in $$list; do \
+         if test -f $$p; then \
+           echo "  $(INSTALL_PROGRAM) $(INSTALL_STRIP_FLAG) $$p $(DESTDIR)$(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`"; \
+            $(INSTALL_PROGRAM) $(INSTALL_STRIP_FLAG) $$p $(DESTDIR)$(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \
+         else :; fi; \
+       done
+
+uninstall-binPROGRAMS:
+       @$(NORMAL_UNINSTALL)
+       list='$(bin_PROGRAMS)'; for p in $$list; do \
+         rm -f $(DESTDIR)$(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \
+       done
+
+mostlyclean-noinstPROGRAMS:
+
+clean-noinstPROGRAMS:
+       -test -z "$(noinst_PROGRAMS)" || rm -f $(noinst_PROGRAMS)
+
+distclean-noinstPROGRAMS:
+
+maintainer-clean-noinstPROGRAMS:
+
+tconf: $(tconf_OBJECTS) $(tconf_DEPENDENCIES)
+       @rm -f tconf
+       $(LINK) $(tconf_LDFLAGS) $(tconf_OBJECTS) $(tconf_LDADD) $(LIBS)
+
+tphrase: $(tphrase_OBJECTS) $(tphrase_DEPENDENCIES)
+       @rm -f tphrase
+       $(LINK) $(tphrase_LDFLAGS) $(tphrase_OBJECTS) $(tphrase_LDADD) $(LIBS)
+
+srvtest: $(srvtest_OBJECTS) $(srvtest_DEPENDENCIES)
+       @rm -f srvtest
+       $(LINK) $(srvtest_LDFLAGS) $(srvtest_OBJECTS) $(srvtest_LDADD) $(LIBS)
+
+clitest: $(clitest_OBJECTS) $(clitest_DEPENDENCIES)
+       @rm -f clitest
+       $(LINK) $(clitest_LDFLAGS) $(clitest_OBJECTS) $(clitest_LDADD) $(LIBS)
+
+install-includeHEADERS: $(include_HEADERS)
+       @$(NORMAL_INSTALL)
+       $(mkinstalldirs) $(DESTDIR)$(includedir)
+       @list='$(include_HEADERS)'; for p in $$list; do \
+         if test -f "$$p"; then d= ; else d="$(srcdir)/"; fi; \
+         echo " $(INSTALL_DATA) $$d$$p $(DESTDIR)$(includedir)/$$p"; \
+         $(INSTALL_DATA) $$d$$p $(DESTDIR)$(includedir)/$$p; \
+       done
+
+uninstall-includeHEADERS:
+       @$(NORMAL_UNINSTALL)
+       list='$(include_HEADERS)'; for p in $$list; do \
+         rm -f $(DESTDIR)$(includedir)/$$p; \
+       done
+
+tags: TAGS
+
+ID: $(HEADERS) $(SOURCES) $(LISP)
+       list='$(SOURCES) $(HEADERS)'; \
+       unique=`for i in $$list; do echo $$i; done | \
+         awk '    { files[$$0] = 1; } \
+              END { for (i in files) print i; }'`; \
+       here=`pwd` && cd $(srcdir) \
+         && mkid -f$$here/ID $$unique $(LISP)
+
+TAGS:  $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) $(LISP)
+       tags=; \
+       here=`pwd`; \
+       list='$(SOURCES) $(HEADERS)'; \
+       unique=`for i in $$list; do echo $$i; done | \
+         awk '    { files[$$0] = 1; } \
+              END { for (i in files) print i; }'`; \
+       test -z "$(ETAGS_ARGS)config.h.in$$unique$(LISP)$$tags" \
+         || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags config.h.in $$unique $(LISP) -o $$here/TAGS)
+
+mostlyclean-tags:
+
+clean-tags:
+
+distclean-tags:
+       -rm -f TAGS ID
+
+maintainer-clean-tags:
+
+distdir = $(PACKAGE)-$(VERSION)
+top_distdir = $(distdir)
+
+# This target untars the dist file and tries a VPATH configuration.  Then
+# it guarantees that the distribution is self-contained by making another
+# tarfile.
+distcheck: dist
+       -rm -rf $(distdir)
+       GZIP=$(GZIP_ENV) $(TAR) zxf $(distdir).tar.gz
+       mkdir $(distdir)/=build
+       mkdir $(distdir)/=inst
+       dc_install_base=`cd $(distdir)/=inst && pwd`; \
+       cd $(distdir)/=build \
+         && ../configure --srcdir=.. --prefix=$$dc_install_base \
+         && $(MAKE) $(AM_MAKEFLAGS) \
+         && $(MAKE) $(AM_MAKEFLAGS) dvi \
+         && $(MAKE) $(AM_MAKEFLAGS) check \
+         && $(MAKE) $(AM_MAKEFLAGS) install \
+         && $(MAKE) $(AM_MAKEFLAGS) installcheck \
+         && $(MAKE) $(AM_MAKEFLAGS) dist
+       -rm -rf $(distdir)
+       @banner="$(distdir).tar.gz is ready for distribution"; \
+       dashes=`echo "$$banner" | sed s/./=/g`; \
+       echo "$$dashes"; \
+       echo "$$banner"; \
+       echo "$$dashes"
+dist: distdir
+       -chmod -R a+r $(distdir)
+       GZIP=$(GZIP_ENV) $(TAR) chozf $(distdir).tar.gz $(distdir)
+       -rm -rf $(distdir)
+dist-all: distdir
+       -chmod -R a+r $(distdir)
+       GZIP=$(GZIP_ENV) $(TAR) chozf $(distdir).tar.gz $(distdir)
+       -rm -rf $(distdir)
+distdir: $(DISTFILES)
+       -rm -rf $(distdir)
+       mkdir $(distdir)
+       -chmod 777 $(distdir)
+       @for file in $(DISTFILES); do \
+         d=$(srcdir); \
+         if test -d $$d/$$file; then \
+           cp -pr $$d/$$file $(distdir)/$$file; \
+         else \
+           test -f $(distdir)/$$file \
+           || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
+           || cp -p $$d/$$file $(distdir)/$$file || :; \
+         fi; \
+       done
+info-am:
+info: info-am
+dvi-am:
+dvi: dvi-am
+check-am: all-am
+check: check-am
+installcheck-am:
+installcheck: installcheck-am
+all-recursive-am: config.h
+       $(MAKE) $(AM_MAKEFLAGS) all-recursive
+
+install-exec-am: install-libLIBRARIES install-binPROGRAMS
+install-exec: install-exec-am
+
+install-data-am: install-includeHEADERS
+install-data: install-data-am
+
+install-am: all-am
+       @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+install: install-am
+uninstall-am: uninstall-libLIBRARIES uninstall-binPROGRAMS \
+               uninstall-includeHEADERS
+uninstall: uninstall-am
+all-am: Makefile $(LIBRARIES) $(PROGRAMS) $(HEADERS) config.h
+all-redirect: all-am
+install-strip:
+       $(MAKE) $(AM_MAKEFLAGS) INSTALL_STRIP_FLAG=-s install
+installdirs:
+       $(mkinstalldirs)  $(DESTDIR)$(libdir) $(DESTDIR)$(bindir) \
+               $(DESTDIR)$(includedir)
+
+
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+       -rm -f Makefile $(CONFIG_CLEAN_FILES)
+       -rm -f config.cache config.log stamp-h stamp-h[0-9]*
+
+maintainer-clean-generic:
+mostlyclean-am:  mostlyclean-hdr mostlyclean-libLIBRARIES \
+               mostlyclean-compile mostlyclean-binPROGRAMS \
+               mostlyclean-noinstPROGRAMS mostlyclean-tags \
+               mostlyclean-generic
+
+mostlyclean: mostlyclean-am
+
+clean-am:  clean-hdr clean-libLIBRARIES clean-compile clean-binPROGRAMS \
+               clean-noinstPROGRAMS clean-tags clean-generic \
+               mostlyclean-am
+
+clean: clean-am
+
+distclean-am:  distclean-hdr distclean-libLIBRARIES distclean-compile \
+               distclean-binPROGRAMS distclean-noinstPROGRAMS \
+               distclean-tags distclean-generic clean-am
+
+distclean: distclean-am
+       -rm -f config.status
+
+maintainer-clean-am:  maintainer-clean-hdr maintainer-clean-libLIBRARIES \
+               maintainer-clean-compile maintainer-clean-binPROGRAMS \
+               maintainer-clean-noinstPROGRAMS maintainer-clean-tags \
+               maintainer-clean-generic distclean-am
+       @echo "This command is intended for maintainers to use;"
+       @echo "it deletes files that may require special tools to rebuild."
+
+maintainer-clean: maintainer-clean-am
+       -rm -f config.status
+
+.PHONY: mostlyclean-hdr distclean-hdr clean-hdr maintainer-clean-hdr \
+mostlyclean-libLIBRARIES distclean-libLIBRARIES clean-libLIBRARIES \
+maintainer-clean-libLIBRARIES uninstall-libLIBRARIES \
+install-libLIBRARIES mostlyclean-compile distclean-compile \
+clean-compile maintainer-clean-compile mostlyclean-binPROGRAMS \
+distclean-binPROGRAMS clean-binPROGRAMS maintainer-clean-binPROGRAMS \
+uninstall-binPROGRAMS install-binPROGRAMS mostlyclean-noinstPROGRAMS \
+distclean-noinstPROGRAMS clean-noinstPROGRAMS \
+maintainer-clean-noinstPROGRAMS uninstall-includeHEADERS \
+install-includeHEADERS tags mostlyclean-tags distclean-tags clean-tags \
+maintainer-clean-tags distdir info-am info dvi-am dvi check check-am \
+installcheck-am installcheck all-recursive-am install-exec-am \
+install-exec install-data-am install-data install-am install \
+uninstall-am uninstall all-redirect all-am all installdirs \
+mostlyclean-generic distclean-generic clean-generic \
+maintainer-clean-generic clean mostlyclean distclean maintainer-clean
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/package/ead/src/tinysrp/Notes b/package/ead/src/tinysrp/Notes
new file mode 100644 (file)
index 0000000..a8620aa
--- /dev/null
@@ -0,0 +1,110 @@
+t_* stuff is from the srp 1.7.1 dist
+bn_* stuff is from openssl 0.9.6
+
+(The 7 in libtinysrp's version number reflects the srp version.)
+
+Licensing and copyright for srp and openssl are as indicated in the relevant
+source files.  Everything else here is GPL, including the tinysrp protocol.
+
+Changelog since initial release:
+
+0.7.4   more robust terminal modes in t_getpass
+       a potential buffer overflow in tinysrp
+0.7.5   uninitialized pointer bug in tconf
+
+Changes from the base srp and openssl distributions:
+
+I've removed everything that's not needed for client/server operations, and
+all the bn_* stuff that's only used for prime generation has been moved to
+t_conf.c, which isn't part of the library anymore.  Also, all the routines
+used for passphrase file maintenance have been moved to tphrase.c.
+
+The library has been optimized (a bit) for space instead of speed.  Since
+authentication is usually only done once, this isn't a big problem.  Modern
+CPUs are plenty fast for this task, and even 100 MHz CPUs are fine.  If you
+really need the speed, get the regular distributions.
+
+Note that if the server sends the client a prime that the client doesn't
+know about, the client MUST test for primality.  Since this is pretty
+expensive, and takes 30 seconds on a 100 MHz machine, and uses lots of code,
+I've removed that ability from the client.  So only KNOWN primes can be
+used.  You can still generate new ones with tconf, but you have to install
+them in the table of known primes (pre_params) in t_getconf.c that's common
+to the client and server, and recompile.  The configuration file is gone.
+
+The default prime (the last entry in the table) is 1024 bits; there are
+others with more bits but they will be correspondingly slower.
+
+The default tpasswd file (which is an ascii file that may be editted with a
+regular text editor) contains two users: moo (passphrase "glub glub") and
+"new user" (passphrase "this is a test").  Passphrases may be added or
+changed with tphrase; you can also change the user's prime.  To delete a
+user, edit the tpasswd file and remove that line.  The tpasswd file's
+default name is DEFAULT_PASSWD in t_pwd.h.  Note that you can't change a
+user's username by editting the file: the username is encoded in the
+verifier.  If you change a username you must set a new passphrase with
+tphrase.
+
+Here is an example session, using the supplied srvtest and clitest.  First,
+start both programs in different windows, and enter the user names.  Normally,
+the client would send the username to the server.  Server lines are marked
+with S>, client lines with C>.
+
+S> % srvtest
+S> Enter username: moo
+S> index (to client): 5
+S> salt (to client): 19AI0Hc9jEkdFc
+
+C> % clitest
+C> Enter username: moo
+C> Enter index (from server): 5
+C> Enter salt (from server): 19AI0Hc9jEkdFc
+
+The server reports the index and salt values used for that user.  They
+are sent over the network to the client.  (Simulate this by cutting and
+pasting from one window to the other.)
+
+C> A (to server): 5wCDXRxLIv/zLazYfKupV/OY3BlhTZuJ71wVgI0HcL1kSJEpkMuWF.xEz/BV2wlJl7vk5Eoz9KMS1ccnaatsVP5D6CBm7UA.yVB59EQFN0dNBirvX29NAFdtdMsMppo5tHRy987XjJWrWSLpeibq6emr.gP8nYyX75GQqSiMY1j
+C> Enter password:
+
+S> Enter A (from client): 5wCDXRxLIv/zLazYfKupV/OY3BlhTZuJ71wVgI0HcL1kSJEpkMuWF.xEz/BV2wlJl7vk5Eoz9KMS1ccnaatsVP5D6CBm7UA.yVB59EQFN0dNBirvX29NAFdtdMsMppo5tHRy987XjJWrWSLpeibq6emr.gP8nYyX75GQqSiMY1j
+
+Now the client calculates A and sends it to the server, and while the
+server is munching on that, the client gets the password from the user.
+
+S> B (to client): 9dcCpulxQAbaDXI0NHWY6B.QH6B9fsoXs/x/5SCNBNJm/6H6bYfbVrwNmdquhLZjYMvpcgGc2mBYqL77RNfw1kVQo17//GfsByECBIjRnrAn02ffX9Y/llJcfscAQiii0hyZhJf9PT5wE7pC7WUjIgSqckIZ0JLNDbSr7fJcrgw
+S> Session key: ebbcf3a45c968defdcfff6e144ad8d4f5412167c9716e79cbf7cacfe18257947ad46fa5d6418a1fd
+
+The server now calculates B and sends it to the client.  The session key
+is not sent -- it is a shared secret that can be used for encryption.
+
+C> Enter B (from server): 9dcCpulxQAbaDXI0NHWY6B.QH6B9fsoXs/x/5SCNBNJm/6H6bYfbVrwNmdquhLZjYMvpcgGc2mBYqL77RNfw1kVQo17//GfsByECBIjRnrAn02ffX9Y/llJcfscAQiii0hyZhJf9PT5wE7pC7WUjIgSqckIZ0JLNDbSr7fJcrgw
+C> Session key: ebbcf3a45c968defdcfff6e144ad8d4f5412167c9716e79cbf7cacfe18257947ad46fa5d6418a1fd
+C> Response (to server): b9ea99094a176c4be28eb469982066cc7146d180
+
+The client uses the B value to calculate its own copy of the shared secret
+session key, and sends a response to the server proving that it does know
+the correct key.
+
+S> Enter response (from client): b9ea99094a176c4be28eb469982066cc7146d180
+S> Authentication successful.
+S> Response (to client): cd46c839ccad2d0c76f3ca1905ae8ceda8d1c1dc
+
+The server authenticates the client.  (You're in!)
+
+C> Enter server response: cd46c839ccad2d0c76f3ca1905ae8ceda8d1c1dc
+C> Server authentication successful.
+
+The client authenticates the server (prevents server spoofing in the case
+where the session key isn't used to encrypt the channel -- a spoofed server
+might just respond with random values and _pretend_ to authenticate the
+client; but the spoofed server won't know the session key and this check
+catches that).
+
+Final note:
+
+Remember that many breaches of security involve buggy software, such as
+servers susceptible to buffer overflow exploits that totally bypass any
+passphrase, secure or not.  If an attacker roots your client, or the server,
+no form of authentication will work.  Consider MAC-based schemes if this
+worries you.
diff --git a/package/ead/src/tinysrp/acconfig.h b/package/ead/src/tinysrp/acconfig.h
new file mode 100644 (file)
index 0000000..b74aed0
--- /dev/null
@@ -0,0 +1,9 @@
+#undef SHA1HANDSOFF
+
+#undef POSIX_TERMIOS
+
+#undef POSIX_SIGTYPE
+
+#undef VERSION
+
+#undef volatile
diff --git a/package/ead/src/tinysrp/acinclude.m4 b/package/ead/src/tinysrp/acinclude.m4
new file mode 100644 (file)
index 0000000..696fffc
--- /dev/null
@@ -0,0 +1,26 @@
+dnl
+dnl check for signal type
+dnl
+dnl AC_RETSIGTYPE isn't quite right, but almost.
+dnl
+define(TYPE_SIGNAL,[
+AC_MSG_CHECKING([POSIX signal handlers])
+AC_CACHE_VAL(cv_has_posix_signals,
+[AC_TRY_COMPILE(
+[#include <sys/types.h>
+#include <signal.h>
+#ifdef signal
+#undef signal
+#endif
+extern void (*signal ()) ();], [],
+cv_has_posix_signals=yes, cv_has_posix_signals=no)])
+AC_MSG_RESULT($cv_has_posix_signals)
+if test $cv_has_posix_signals = yes; then
+   AC_DEFINE(RETSIGTYPE, void) AC_DEFINE(POSIX_SIGTYPE)
+else
+  if test $ac_cv_type_signal = void; then
+     AC_DEFINE(RETSIGTYPE, void)
+  else
+     AC_DEFINE(RETSIGTYPE, int)
+  fi
+fi])dnl
diff --git a/package/ead/src/tinysrp/aclocal.m4 b/package/ead/src/tinysrp/aclocal.m4
new file mode 100644 (file)
index 0000000..7fb09ae
--- /dev/null
@@ -0,0 +1,156 @@
+dnl aclocal.m4 generated automatically by aclocal 1.4a
+
+dnl Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+dnl This program is distributed in the hope that it will be useful,
+dnl but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+dnl even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+dnl PARTICULAR PURPOSE.
+
+dnl
+dnl check for signal type
+dnl
+dnl AC_RETSIGTYPE isn't quite right, but almost.
+dnl
+define(TYPE_SIGNAL,[
+AC_MSG_CHECKING([POSIX signal handlers])
+AC_CACHE_VAL(cv_has_posix_signals,
+[AC_TRY_COMPILE(
+[#include <sys/types.h>
+#include <signal.h>
+#ifdef signal
+#undef signal
+#endif
+extern void (*signal ()) ();], [],
+cv_has_posix_signals=yes, cv_has_posix_signals=no)])
+AC_MSG_RESULT($cv_has_posix_signals)
+if test $cv_has_posix_signals = yes; then
+   AC_DEFINE(RETSIGTYPE, void) AC_DEFINE(POSIX_SIGTYPE)
+else
+  if test $ac_cv_type_signal = void; then
+     AC_DEFINE(RETSIGTYPE, void)
+  else
+     AC_DEFINE(RETSIGTYPE, int)
+  fi
+fi])dnl
+
+# Like AC_CONFIG_HEADER, but automatically create stamp file.
+
+AC_DEFUN(AM_CONFIG_HEADER,
+[AC_PREREQ([2.12])
+AC_CONFIG_HEADER([$1])
+dnl When config.status generates a header, we must update the stamp-h file.
+dnl This file resides in the same directory as the config header
+dnl that is generated.  We must strip everything past the first ":",
+dnl and everything past the last "/".
+AC_OUTPUT_COMMANDS(changequote(<<,>>)dnl
+ifelse(patsubst(<<$1>>, <<[^ ]>>, <<>>), <<>>,
+<<test -z "<<$>>CONFIG_HEADERS" || echo timestamp > patsubst(<<$1>>, <<^\([^:]*/\)?.*>>, <<\1>>)stamp-h<<>>dnl>>,
+<<am_indx=1
+for am_file in <<$1>>; do
+  case " <<$>>CONFIG_HEADERS " in
+  *" <<$>>am_file "*<<)>>
+    echo timestamp > `echo <<$>>am_file | sed -e 's%:.*%%' -e 's%[^/]*$%%'`stamp-h$am_indx
+    ;;
+  esac
+  am_indx=`expr "<<$>>am_indx" + 1`
+done<<>>dnl>>)
+changequote([,]))])
+
+# Do all the work for Automake.  This macro actually does too much --
+# some checks are only needed if your package does certain things.
+# But this isn't really a big deal.
+
+# serial 1
+
+dnl Usage:
+dnl AM_INIT_AUTOMAKE(package,version, [no-define])
+
+AC_DEFUN(AM_INIT_AUTOMAKE,
+[AC_REQUIRE([AC_PROG_INSTALL])
+dnl We require 2.13 because we rely on SHELL being computed by configure.
+AC_PREREQ([2.13])
+PACKAGE=[$1]
+AC_SUBST(PACKAGE)
+VERSION=[$2]
+AC_SUBST(VERSION)
+dnl test to see if srcdir already configured
+if test "`cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then
+  AC_MSG_ERROR([source directory already configured; run "make distclean" there first])
+fi
+ifelse([$3],,
+AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package])
+AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package]))
+AC_REQUIRE([AM_SANITY_CHECK])
+AC_REQUIRE([AC_ARG_PROGRAM])
+dnl FIXME This is truly gross.
+missing_dir=`cd $ac_aux_dir && pwd`
+AM_MISSING_PROG(ACLOCAL, aclocal, $missing_dir)
+AM_MISSING_PROG(AUTOCONF, autoconf, $missing_dir)
+AM_MISSING_PROG(AUTOMAKE, automake, $missing_dir)
+AM_MISSING_PROG(AUTOHEADER, autoheader, $missing_dir)
+AM_MISSING_PROG(MAKEINFO, makeinfo, $missing_dir)
+AC_REQUIRE([AC_PROG_MAKE_SET])])
+
+#
+# Check to make sure that the build environment is sane.
+#
+
+AC_DEFUN(AM_SANITY_CHECK,
+[AC_MSG_CHECKING([whether build environment is sane])
+# Just in case
+sleep 1
+echo timestamp > conftestfile
+# Do `set' in a subshell so we don't clobber the current shell's
+# arguments.  Must try -L first in case configure is actually a
+# symlink; some systems play weird games with the mod time of symlinks
+# (eg FreeBSD returns the mod time of the symlink's containing
+# directory).
+if (
+   set X `ls -Lt $srcdir/configure conftestfile 2> /dev/null`
+   if test "[$]*" = "X"; then
+      # -L didn't work.
+      set X `ls -t $srcdir/configure conftestfile`
+   fi
+   if test "[$]*" != "X $srcdir/configure conftestfile" \
+      && test "[$]*" != "X conftestfile $srcdir/configure"; then
+
+      # If neither matched, then we have a broken ls.  This can happen
+      # if, for instance, CONFIG_SHELL is bash and it inherits a
+      # broken ls alias from the environment.  This has actually
+      # happened.  Such a system could not be considered "sane".
+      AC_MSG_ERROR([ls -t appears to fail.  Make sure there is not a broken
+alias in your environment])
+   fi
+
+   test "[$]2" = conftestfile
+   )
+then
+   # Ok.
+   :
+else
+   AC_MSG_ERROR([newly created file is older than distributed files!
+Check your system clock])
+fi
+rm -f conftest*
+AC_MSG_RESULT(yes)])
+
+dnl AM_MISSING_PROG(NAME, PROGRAM, DIRECTORY)
+dnl The program must properly implement --version.
+AC_DEFUN(AM_MISSING_PROG,
+[AC_MSG_CHECKING(for working $2)
+# Run test in a subshell; some versions of sh will print an error if
+# an executable is not found, even if stderr is redirected.
+# Redirect stdin to placate older versions of autoconf.  Sigh.
+if ($2 --version) < /dev/null > /dev/null 2>&1; then
+   $1=$2
+   AC_MSG_RESULT(found)
+else
+   $1="$3/missing $2"
+   AC_MSG_RESULT(missing)
+fi
+AC_SUBST($1)])
+
diff --git a/package/ead/src/tinysrp/bn.h b/package/ead/src/tinysrp/bn.h
new file mode 100644 (file)
index 0000000..0144dd9
--- /dev/null
@@ -0,0 +1,471 @@
+/* crypto/bn/bn.h */
+/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``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.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef HEADER_BN_H
+#define HEADER_BN_H
+
+#include <stdio.h> /* FILE */
+#include "config.h"
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+#ifdef VMS
+#undef BN_LLONG /* experimental, so far... */
+#endif
+
+#undef BN_MUL_COMBA
+#undef BN_SQR_COMBA
+#undef BN_RECURSION
+#undef RECP_MUL_MOD
+#undef MONT_MUL_MOD
+
+#if defined(SIZEOF_LONG_LONG) && SIZEOF_LONG_LONG == 8
+# if SIZEOF_LONG == 4
+#  define THIRTY_TWO_BIT
+# else
+#  define SIXTY_FOUR_BIT_LONG
+# endif
+#else
+# if SIZEOF_LONG == 4
+#  define THIRTY_TWO_BIT
+# endif
+#endif
+
+#undef BN_LLONG
+
+/* assuming long is 64bit - this is the DEC Alpha
+ * unsigned long long is only 64 bits :-(, don't define
+ * BN_LLONG for the DEC Alpha */
+#ifdef SIXTY_FOUR_BIT_LONG
+#define BN_ULLONG       unsigned long long
+#define BN_ULONG        unsigned long
+#define BN_LONG         long
+#define BN_BITS         128
+#define BN_BYTES        8
+#define BN_BITS2        64
+#define BN_BITS4        32
+#define BN_MASK         (0xffffffffffffffffffffffffffffffffLL)
+#define BN_MASK2        (0xffffffffffffffffL)
+#define BN_MASK2l       (0xffffffffL)
+#define BN_MASK2h       (0xffffffff00000000L)
+#define BN_MASK2h1      (0xffffffff80000000L)
+#define BN_TBIT         (0x8000000000000000L)
+#define BN_DEC_CONV     (10000000000000000000UL)
+#define BN_DEC_FMT1     "%lu"
+#define BN_DEC_FMT2     "%019lu"
+#define BN_DEC_NUM      19
+#endif
+
+/* This is where the long long data type is 64 bits, but long is 32.
+ * For machines where there are 64bit registers, this is the mode to use.
+ * IRIX, on R4000 and above should use this mode, along with the relevant
+ * assembler code :-).  Do NOT define BN_LLONG.
+ */
+#ifdef SIXTY_FOUR_BIT
+#undef BN_LLONG
+#undef BN_ULLONG
+#define BN_ULONG        unsigned long long
+#define BN_LONG         long long
+#define BN_BITS         128
+#define BN_BYTES        8
+#define BN_BITS2        64
+#define BN_BITS4        32
+#define BN_MASK2        (0xffffffffffffffffLL)
+#define BN_MASK2l       (0xffffffffL)
+#define BN_MASK2h       (0xffffffff00000000LL)
+#define BN_MASK2h1      (0xffffffff80000000LL)
+#define BN_TBIT         (0x8000000000000000LL)
+#define BN_DEC_CONV     (10000000000000000000LL)
+#define BN_DEC_FMT1     "%llu"
+#define BN_DEC_FMT2     "%019llu"
+#define BN_DEC_NUM      19
+#endif
+
+#ifdef THIRTY_TWO_BIT
+#if defined(WIN32) && !defined(__GNUC__)
+#define BN_ULLONG       unsigned _int64
+#else
+#define BN_ULLONG       unsigned long long
+#endif
+#define BN_ULONG        unsigned long
+#define BN_LONG         long
+#define BN_BITS         64
+#define BN_BYTES        4
+#define BN_BITS2        32
+#define BN_BITS4        16
+#ifdef WIN32
+/* VC++ doesn't like the LL suffix */
+#define BN_MASK         (0xffffffffffffffffL)
+#else
+#define BN_MASK         (0xffffffffffffffffLL)
+#endif
+#define BN_MASK2        (0xffffffffL)
+#define BN_MASK2l       (0xffff)
+#define BN_MASK2h1      (0xffff8000L)
+#define BN_MASK2h       (0xffff0000L)
+#define BN_TBIT         (0x80000000L)
+#define BN_DEC_CONV     (1000000000L)
+#define BN_DEC_FMT1     "%lu"
+#define BN_DEC_FMT2     "%09lu"
+#define BN_DEC_NUM      9
+#endif
+
+#ifdef SIXTEEN_BIT
+#ifndef BN_DIV2W
+#define BN_DIV2W
+#endif
+#define BN_ULLONG       unsigned long
+#define BN_ULONG        unsigned short
+#define BN_LONG         short
+#define BN_BITS         32
+#define BN_BYTES        2
+#define BN_BITS2        16
+#define BN_BITS4        8
+#define BN_MASK         (0xffffffff)
+#define BN_MASK2        (0xffff)
+#define BN_MASK2l       (0xff)
+#define BN_MASK2h1      (0xff80)
+#define BN_MASK2h       (0xff00)
+#define BN_TBIT         (0x8000)
+#define BN_DEC_CONV     (100000)
+#define BN_DEC_FMT1     "%u"
+#define BN_DEC_FMT2     "%05u"
+#define BN_DEC_NUM      5
+#endif
+
+#ifdef EIGHT_BIT
+#ifndef BN_DIV2W
+#define BN_DIV2W
+#endif
+#define BN_ULLONG       unsigned short
+#define BN_ULONG        unsigned char
+#define BN_LONG         char
+#define BN_BITS         16
+#define BN_BYTES        1
+#define BN_BITS2        8
+#define BN_BITS4        4
+#define BN_MASK         (0xffff)
+#define BN_MASK2        (0xff)
+#define BN_MASK2l       (0xf)
+#define BN_MASK2h1      (0xf8)
+#define BN_MASK2h       (0xf0)
+#define BN_TBIT         (0x80)
+#define BN_DEC_CONV     (100)
+#define BN_DEC_FMT1     "%u"
+#define BN_DEC_FMT2     "%02u"
+#define BN_DEC_NUM      2
+#endif
+
+#define BN_DEFAULT_BITS 1280
+
+#ifdef BIGNUM
+#undef BIGNUM
+#endif
+
+#define BN_FLG_MALLOCED         0x01
+#define BN_FLG_STATIC_DATA      0x02
+#define BN_FLG_FREE             0x8000  /* used for debuging */
+#define BN_set_flags(b,n)       ((b)->flags|=(n))
+#define BN_get_flags(b,n)       ((b)->flags&(n))
+
+typedef struct bignum_st
+       {
+       BN_ULONG *d;    /* Pointer to an array of 'BN_BITS2' bit chunks. */
+       int top;        /* Index of last used d +1. */
+       /* The next are internal book keeping for bn_expand. */
+       int dmax;       /* Size of the d array. */
+       int neg;        /* one if the number is negative */
+       int flags;
+       } BIGNUM;
+
+/* Used for temp variables */
+#define BN_CTX_NUM      12
+#define BN_CTX_NUM_POS  12
+typedef struct bignum_ctx
+       {
+       int tos;
+       BIGNUM bn[BN_CTX_NUM];
+       int flags;
+       int depth;
+       int pos[BN_CTX_NUM_POS];
+       int too_many;
+       } BN_CTX;
+
+/* Used for montgomery multiplication */
+typedef struct bn_mont_ctx_st
+       {
+       int ri;        /* number of bits in R */
+       BIGNUM RR;     /* used to convert to montgomery form */
+       BIGNUM N;      /* The modulus */
+       BIGNUM Ni;     /* R*(1/R mod N) - N*Ni = 1
+                       * (Ni is only stored for bignum algorithm) */
+       BN_ULONG n0;   /* least significant word of Ni */
+       int flags;
+       } BN_MONT_CTX;
+
+/* Used for reciprocal division/mod functions
+ * It cannot be shared between threads
+ */
+typedef struct bn_recp_ctx_st
+       {
+       BIGNUM N;       /* the divisor */
+       BIGNUM Nr;      /* the reciprocal */
+       int num_bits;
+       int shift;
+       int flags;
+       } BN_RECP_CTX;
+
+#define BN_to_montgomery(r,a,mont,ctx)  BN_mod_mul_montgomery(\
+       r,a,&((mont)->RR),(mont),ctx)
+
+#define BN_prime_checks 0 /* default: select number of iterations
+                            based on the size of the number */
+
+/* number of Miller-Rabin iterations for an error rate  of less than 2^-80
+ * for random 'b'-bit input, b >= 100 (taken from table 4.4 in the Handbook
+ * of Applied Cryptography [Menezes, van Oorschot, Vanstone; CRC Press 1996];
+ * original paper: Damgaard, Landrock, Pomerance: Average case error estimates
+ * for the strong probable prime test. -- Math. Comp. 61 (1993) 177-194) */
+#define BN_prime_checks_for_size(b) ((b) >= 1300 ?  2 : \
+                               (b) >=  850 ?  3 : \
+                               (b) >=  650 ?  4 : \
+                               (b) >=  550 ?  5 : \
+                               (b) >=  450 ?  6 : \
+                               (b) >=  400 ?  7 : \
+                               (b) >=  350 ?  8 : \
+                               (b) >=  300 ?  9 : \
+                               (b) >=  250 ? 12 : \
+                               (b) >=  200 ? 15 : \
+                               (b) >=  150 ? 18 : \
+                               /* b >= 100 */ 27)
+
+#define BN_num_bytes(a) ((BN_num_bits(a)+7)/8)
+#define BN_is_word(a,w) (((a)->top == 1) && ((a)->d[0] == (BN_ULONG)(w)))
+#define BN_is_zero(a)   (((a)->top == 0) || BN_is_word(a,0))
+#define BN_is_one(a)    (BN_is_word((a),1))
+#define BN_is_odd(a)    (((a)->top > 0) && ((a)->d[0] & 1))
+#define BN_one(a)       (BN_set_word((a),1))
+#define BN_zero(a)      (BN_set_word((a),0))
+
+BIGNUM *BN_value_one(void);
+char *  BN_options(void);
+BN_CTX *BN_CTX_new(void);
+void    BN_CTX_init(BN_CTX *c);
+void    BN_CTX_free(BN_CTX *c);
+void    BN_CTX_start(BN_CTX *ctx);
+BIGNUM *BN_CTX_get(BN_CTX *ctx);
+void    BN_CTX_end(BN_CTX *ctx);
+int     BN_rand(BIGNUM *rnd, int bits, int top,int bottom);
+int     BN_pseudo_rand(BIGNUM *rnd, int bits, int top,int bottom);
+int     BN_num_bits(const BIGNUM *a);
+int     BN_num_bits_word(BN_ULONG);
+BIGNUM *BN_new(void);
+void    BN_init(BIGNUM *);
+void    BN_clear_free(BIGNUM *a);
+BIGNUM *BN_copy(BIGNUM *a, const BIGNUM *b);
+BIGNUM *BN_bin2bn(const unsigned char *s,int len,BIGNUM *ret);
+int     BN_bn2bin(const BIGNUM *a, unsigned char *to);
+int     BN_sub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b);
+int     BN_usub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b);
+int     BN_uadd(BIGNUM *r, const BIGNUM *a, const BIGNUM *b);
+int     BN_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b);
+int     BN_mod(BIGNUM *rem, const BIGNUM *m, const BIGNUM *d, BN_CTX *ctx);
+int     BN_div(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m, const BIGNUM *d,
+              BN_CTX *ctx);
+int     BN_mul(BIGNUM *r, BIGNUM *a, BIGNUM *b, BN_CTX *ctx);
+int     BN_sqr(BIGNUM *r, BIGNUM *a,BN_CTX *ctx);
+BN_ULONG BN_mod_word(const BIGNUM *a, BN_ULONG w);
+BN_ULONG BN_div_word(BIGNUM *a, BN_ULONG w);
+int     BN_mul_word(BIGNUM *a, BN_ULONG w);
+int     BN_add_word(BIGNUM *a, BN_ULONG w);
+int     BN_sub_word(BIGNUM *a, BN_ULONG w);
+int     BN_set_word(BIGNUM *a, BN_ULONG w);
+BN_ULONG BN_get_word(BIGNUM *a);
+int     BN_cmp(const BIGNUM *a, const BIGNUM *b);
+void    BN_free(BIGNUM *a);
+int     BN_is_bit_set(const BIGNUM *a, int n);
+int     BN_lshift(BIGNUM *r, const BIGNUM *a, int n);
+int     BN_lshift1(BIGNUM *r, BIGNUM *a);
+int     BN_exp(BIGNUM *r, BIGNUM *a, BIGNUM *p,BN_CTX *ctx);
+int     BN_mod_exp(BIGNUM *r, BIGNUM *a, const BIGNUM *p,
+                  const BIGNUM *m,BN_CTX *ctx);
+int     BN_mod_exp_mont(BIGNUM *r, BIGNUM *a, const BIGNUM *p,
+                       const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
+int     BN_mod_exp_mont_word(BIGNUM *r, BN_ULONG a, const BIGNUM *p,
+                       const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
+int     BN_mod_exp_simple(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+       const BIGNUM *m,BN_CTX *ctx);
+int     BN_mask_bits(BIGNUM *a,int n);
+int     BN_mod_mul(BIGNUM *ret, BIGNUM *a, BIGNUM *b, const BIGNUM *m, BN_CTX *ctx);
+int     BN_reciprocal(BIGNUM *r, BIGNUM *m, int len, BN_CTX *ctx);
+int     BN_rshift(BIGNUM *r, BIGNUM *a, int n);
+int     BN_rshift1(BIGNUM *r, BIGNUM *a);
+void    BN_clear(BIGNUM *a);
+BIGNUM *BN_dup(const BIGNUM *a);
+int     BN_ucmp(const BIGNUM *a, const BIGNUM *b);
+int     BN_set_bit(BIGNUM *a, int n);
+int     BN_clear_bit(BIGNUM *a, int n);
+int     BN_gcd(BIGNUM *r,BIGNUM *in_a,BIGNUM *in_b,BN_CTX *ctx);
+BIGNUM *BN_mod_inverse(BIGNUM *ret,BIGNUM *a, const BIGNUM *n,BN_CTX *ctx);
+BIGNUM *BN_generate_prime(BIGNUM *ret,int bits,int safe,BIGNUM *add,
+               BIGNUM *rem,void (*callback)(int,int,void *),void *cb_arg);
+int     BN_is_prime(const BIGNUM *p,int nchecks,
+               void (*callback)(int,int,void *),
+               BN_CTX *ctx,void *cb_arg);
+int     BN_is_prime_fasttest(const BIGNUM *p,int nchecks,
+               void (*callback)(int,int,void *),BN_CTX *ctx,void *cb_arg,
+               int do_trial_division);
+
+BN_MONT_CTX *BN_MONT_CTX_new(void );
+void BN_MONT_CTX_init(BN_MONT_CTX *ctx);
+int BN_mod_mul_montgomery(BIGNUM *r,BIGNUM *a,BIGNUM *b,BN_MONT_CTX *mont,
+                         BN_CTX *ctx);
+int BN_from_montgomery(BIGNUM *r,BIGNUM *a,BN_MONT_CTX *mont,BN_CTX *ctx);
+void BN_MONT_CTX_free(BN_MONT_CTX *mont);
+int BN_MONT_CTX_set(BN_MONT_CTX *mont,const BIGNUM *modulus,BN_CTX *ctx);
+BN_MONT_CTX *BN_MONT_CTX_copy(BN_MONT_CTX *to,BN_MONT_CTX *from);
+
+void BN_set_params(int mul,int high,int low,int mont);
+int BN_get_params(int which); /* 0, mul, 1 high, 2 low, 3 mont */
+
+void    BN_RECP_CTX_init(BN_RECP_CTX *recp);
+BN_RECP_CTX *BN_RECP_CTX_new(void);
+void    BN_RECP_CTX_free(BN_RECP_CTX *recp);
+int     BN_RECP_CTX_set(BN_RECP_CTX *recp,const BIGNUM *rdiv,BN_CTX *ctx);
+int     BN_mod_mul_reciprocal(BIGNUM *r, BIGNUM *x, BIGNUM *y,
+               BN_RECP_CTX *recp,BN_CTX *ctx);
+int     BN_mod_exp_recp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+                       const BIGNUM *m, BN_CTX *ctx);
+int     BN_div_recp(BIGNUM *dv, BIGNUM *rem, BIGNUM *m,
+               BN_RECP_CTX *recp, BN_CTX *ctx);
+
+/* library internal functions */
+
+#define bn_expand(a,bits) ((((((bits+BN_BITS2-1))/BN_BITS2)) <= (a)->dmax)?\
+       (a):bn_expand2((a),(bits)/BN_BITS2+1))
+#define bn_wexpand(a,words) (((words) <= (a)->dmax)?(a):bn_expand2((a),(words)))
+BIGNUM *bn_expand2(BIGNUM *a, int words);
+
+#define bn_fix_top(a) \
+       { \
+       BN_ULONG *ftl; \
+       if ((a)->top > 0) \
+               { \
+               for (ftl= &((a)->d[(a)->top-1]); (a)->top > 0; (a)->top--) \
+               if (*(ftl--)) break; \
+               } \
+       }
+
+BN_ULONG bn_mul_add_words(BN_ULONG *rp, BN_ULONG *ap, int num, BN_ULONG w);
+BN_ULONG bn_mul_words(BN_ULONG *rp, BN_ULONG *ap, int num, BN_ULONG w);
+void     bn_sqr_words(BN_ULONG *rp, BN_ULONG *ap, int num);
+BN_ULONG bn_div_words(BN_ULONG h, BN_ULONG l, BN_ULONG d);
+BN_ULONG bn_add_words(BN_ULONG *rp, BN_ULONG *ap, BN_ULONG *bp,int num);
+BN_ULONG bn_sub_words(BN_ULONG *rp, BN_ULONG *ap, BN_ULONG *bp,int num);
+
+#ifdef BN_DEBUG
+  void bn_dump1(FILE *o, const char *a, BN_ULONG *b,int n);
+# define bn_print(a) {fprintf(stderr, #a "="); BN_print_fp(stderr,a); \
+   fprintf(stderr,"\n");}
+# define bn_dump(a,n) bn_dump1(stderr,#a,a,n);
+#else
+# define bn_print(a)
+# define bn_dump(a,b)
+#endif
+
+/* BEGIN ERROR CODES */
+/* The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+
+/* Error codes for the BN functions. */
+
+/* Function codes. */
+#define BN_F_BN_CTX_GET                                  116
+#define BN_F_BN_CTX_NEW                                  106
+#define BN_F_BN_DIV                                      107
+#define BN_F_BN_EXPAND2                                  108
+#define BN_F_BN_MOD_EXP2_MONT                            118
+#define BN_F_BN_MOD_EXP_MONT                             109
+#define BN_F_BN_MOD_EXP_MONT_WORD                        117
+#define BN_F_BN_MOD_INVERSE                              110
+#define BN_F_BN_MOD_MUL_RECIPROCAL                       111
+#define BN_F_BN_MPI2BN                                   112
+#define BN_F_BN_NEW                                      113
+#define BN_F_BN_RAND                                     114
+#define BN_F_BN_USUB                                     115
+
+/* Reason codes. */
+#define BN_R_ARG2_LT_ARG3                                100
+#define BN_R_BAD_RECIPROCAL                              101
+#define BN_R_CALLED_WITH_EVEN_MODULUS                    102
+#define BN_R_DIV_BY_ZERO                                 103
+#define BN_R_ENCODING_ERROR                              104
+#define BN_R_EXPAND_ON_STATIC_BIGNUM_DATA                105
+#define BN_R_INVALID_LENGTH                              106
+#define BN_R_NOT_INITIALIZED                             107
+#define BN_R_NO_INVERSE                                  108
+#define BN_R_TOO_MANY_TEMPORARY_VARIABLES                109
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
+
diff --git a/package/ead/src/tinysrp/bn_add.c b/package/ead/src/tinysrp/bn_add.c
new file mode 100644 (file)
index 0000000..aae4f2b
--- /dev/null
@@ -0,0 +1,305 @@
+/* crypto/bn/bn_add.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``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.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "bn_lcl.h"
+
+/* r can == a or b */
+int BN_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b)
+       {
+       const BIGNUM *tmp;
+
+       bn_check_top(a);
+       bn_check_top(b);
+
+       /*  a +  b      a+b
+        *  a + -b      a-b
+        * -a +  b      b-a
+        * -a + -b      -(a+b)
+        */
+       if (a->neg ^ b->neg)
+               {
+               /* only one is negative */
+               if (a->neg)
+                       { tmp=a; a=b; b=tmp; }
+
+               /* we are now a - b */
+
+               if (BN_ucmp(a,b) < 0)
+                       {
+                       if (!BN_usub(r,b,a)) return(0);
+                       r->neg=1;
+                       }
+               else
+                       {
+                       if (!BN_usub(r,a,b)) return(0);
+                       r->neg=0;
+                       }
+               return(1);
+               }
+
+       if (a->neg) /* both are neg */
+               r->neg=1;
+       else
+               r->neg=0;
+
+       if (!BN_uadd(r,a,b)) return(0);
+       return(1);
+       }
+
+/* unsigned add of b to a, r must be large enough */
+int BN_uadd(BIGNUM *r, const BIGNUM *a, const BIGNUM *b)
+       {
+       register int i;
+       int max,min;
+       BN_ULONG *ap,*bp,*rp,carry,t1;
+       const BIGNUM *tmp;
+
+       bn_check_top(a);
+       bn_check_top(b);
+
+       if (a->top < b->top)
+               { tmp=a; a=b; b=tmp; }
+       max=a->top;
+       min=b->top;
+
+       if (bn_wexpand(r,max+1) == NULL)
+               return(0);
+
+       r->top=max;
+
+
+       ap=a->d;
+       bp=b->d;
+       rp=r->d;
+       carry=0;
+
+       carry=bn_add_words(rp,ap,bp,min);
+       rp+=min;
+       ap+=min;
+       bp+=min;
+       i=min;
+
+       if (carry)
+               {
+               while (i < max)
+                       {
+                       i++;
+                       t1= *(ap++);
+                       if ((*(rp++)=(t1+1)&BN_MASK2) >= t1)
+                               {
+                               carry=0;
+                               break;
+                               }
+                       }
+               if ((i >= max) && carry)
+                       {
+                       *(rp++)=1;
+                       r->top++;
+                       }
+               }
+       if (rp != ap)
+               {
+               for (; i<max; i++)
+                       *(rp++)= *(ap++);
+               }
+       /* memcpy(rp,ap,sizeof(*ap)*(max-i));*/
+       return(1);
+       }
+
+/* unsigned subtraction of b from a, a must be larger than b. */
+int BN_usub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b)
+       {
+       int max,min;
+       register BN_ULONG t1,t2,*ap,*bp,*rp;
+       int i,carry;
+#if defined(IRIX_CC_BUG) && !defined(LINT)
+       int dummy;
+#endif
+
+       bn_check_top(a);
+       bn_check_top(b);
+
+       if (a->top < b->top) /* hmm... should not be happening */
+               {
+               return(0);
+               }
+
+       max=a->top;
+       min=b->top;
+       if (bn_wexpand(r,max) == NULL) return(0);
+
+       ap=a->d;
+       bp=b->d;
+       rp=r->d;
+
+#if 1
+       carry=0;
+       for (i=0; i<min; i++)
+               {
+               t1= *(ap++);
+               t2= *(bp++);
+               if (carry)
+                       {
+                       carry=(t1 <= t2);
+                       t1=(t1-t2-1)&BN_MASK2;
+                       }
+               else
+                       {
+                       carry=(t1 < t2);
+                       t1=(t1-t2)&BN_MASK2;
+                       }
+#if defined(IRIX_CC_BUG) && !defined(LINT)
+               dummy=t1;
+#endif
+               *(rp++)=t1&BN_MASK2;
+               }
+#else
+       carry=bn_sub_words(rp,ap,bp,min);
+       ap+=min;
+       bp+=min;
+       rp+=min;
+       i=min;
+#endif
+       if (carry) /* subtracted */
+               {
+               while (i < max)
+                       {
+                       i++;
+                       t1= *(ap++);
+                       t2=(t1-1)&BN_MASK2;
+                       *(rp++)=t2;
+                       if (t1 > t2) break;
+                       }
+               }
+#if 0
+       memcpy(rp,ap,sizeof(*rp)*(max-i));
+#else
+       if (rp != ap)
+               {
+               for (;;)
+                       {
+                       if (i++ >= max) break;
+                       rp[0]=ap[0];
+                       if (i++ >= max) break;
+                       rp[1]=ap[1];
+                       if (i++ >= max) break;
+                       rp[2]=ap[2];
+                       if (i++ >= max) break;
+                       rp[3]=ap[3];
+                       rp+=4;
+                       ap+=4;
+                       }
+               }
+#endif
+
+       r->top=max;
+       bn_fix_top(r);
+       return(1);
+       }
+
+int BN_sub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b)
+       {
+       int max;
+       int add=0,neg=0;
+       const BIGNUM *tmp;
+
+       bn_check_top(a);
+       bn_check_top(b);
+
+       /*  a -  b      a-b
+        *  a - -b      a+b
+        * -a -  b      -(a+b)
+        * -a - -b      b-a
+        */
+       if (a->neg)
+               {
+               if (b->neg)
+                       { tmp=a; a=b; b=tmp; }
+               else
+                       { add=1; neg=1; }
+               }
+       else
+               {
+               if (b->neg) { add=1; neg=0; }
+               }
+
+       if (add)
+               {
+               if (!BN_uadd(r,a,b)) return(0);
+               r->neg=neg;
+               return(1);
+               }
+
+       /* We are actually doing a - b :-) */
+
+       max=(a->top > b->top)?a->top:b->top;
+       if (bn_wexpand(r,max) == NULL) return(0);
+       if (BN_ucmp(a,b) < 0)
+               {
+               if (!BN_usub(r,b,a)) return(0);
+               r->neg=1;
+               }
+       else
+               {
+               if (!BN_usub(r,a,b)) return(0);
+               r->neg=0;
+               }
+       return(1);
+       }
+
diff --git a/package/ead/src/tinysrp/bn_asm.c b/package/ead/src/tinysrp/bn_asm.c
new file mode 100644 (file)
index 0000000..b24c9af
--- /dev/null
@@ -0,0 +1,382 @@
+/* crypto/bn/bn_asm.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``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.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef BN_DEBUG
+# undef NDEBUG /* avoid conflicting definitions */
+# define NDEBUG
+#endif
+
+#include <stdio.h>
+#include <assert.h>
+#include "bn_lcl.h"
+
+#if defined(BN_LLONG) || defined(BN_UMULT_HIGH)
+
+BN_ULONG bn_mul_add_words(BN_ULONG *rp, BN_ULONG *ap, int num, BN_ULONG w)
+       {
+       BN_ULONG c1=0;
+
+       assert(num >= 0);
+       if (num <= 0) return(c1);
+
+       while (num&~3)
+               {
+               mul_add(rp[0],ap[0],w,c1);
+               mul_add(rp[1],ap[1],w,c1);
+               mul_add(rp[2],ap[2],w,c1);
+               mul_add(rp[3],ap[3],w,c1);
+               ap+=4; rp+=4; num-=4;
+               }
+       if (num)
+               {
+               mul_add(rp[0],ap[0],w,c1); if (--num==0) return c1;
+               mul_add(rp[1],ap[1],w,c1); if (--num==0) return c1;
+               mul_add(rp[2],ap[2],w,c1); return c1;
+               }
+
+       return(c1);
+       }
+
+BN_ULONG bn_mul_words(BN_ULONG *rp, BN_ULONG *ap, int num, BN_ULONG w)
+       {
+       BN_ULONG c1=0;
+
+       assert(num >= 0);
+       if (num <= 0) return(c1);
+
+       while (num&~3)
+               {
+               mul(rp[0],ap[0],w,c1);
+               mul(rp[1],ap[1],w,c1);
+               mul(rp[2],ap[2],w,c1);
+               mul(rp[3],ap[3],w,c1);
+               ap+=4; rp+=4; num-=4;
+               }
+       if (num)
+               {
+               mul(rp[0],ap[0],w,c1); if (--num == 0) return c1;
+               mul(rp[1],ap[1],w,c1); if (--num == 0) return c1;
+               mul(rp[2],ap[2],w,c1);
+               }
+       return(c1);
+       }
+
+void bn_sqr_words(BN_ULONG *r, BN_ULONG *a, int n)
+       {
+       assert(n >= 0);
+       if (n <= 0) return;
+       while (n&~3)
+               {
+               sqr(r[0],r[1],a[0]);
+               sqr(r[2],r[3],a[1]);
+               sqr(r[4],r[5],a[2]);
+               sqr(r[6],r[7],a[3]);
+               a+=4; r+=8; n-=4;
+               }
+       if (n)
+               {
+               sqr(r[0],r[1],a[0]); if (--n == 0) return;
+               sqr(r[2],r[3],a[1]); if (--n == 0) return;
+               sqr(r[4],r[5],a[2]);
+               }
+       }
+
+#else /* !(defined(BN_LLONG) || defined(BN_UMULT_HIGH)) */
+
+BN_ULONG bn_mul_add_words(BN_ULONG *rp, BN_ULONG *ap, int num, BN_ULONG w)
+       {
+       BN_ULONG c=0;
+       BN_ULONG bl,bh;
+
+       assert(num >= 0);
+       if (num <= 0) return((BN_ULONG)0);
+
+       bl=LBITS(w);
+       bh=HBITS(w);
+
+       for (;;)
+               {
+               mul_add(rp[0],ap[0],bl,bh,c);
+               if (--num == 0) break;
+               mul_add(rp[1],ap[1],bl,bh,c);
+               if (--num == 0) break;
+               mul_add(rp[2],ap[2],bl,bh,c);
+               if (--num == 0) break;
+               mul_add(rp[3],ap[3],bl,bh,c);
+               if (--num == 0) break;
+               ap+=4;
+               rp+=4;
+               }
+       return(c);
+       }
+
+BN_ULONG bn_mul_words(BN_ULONG *rp, BN_ULONG *ap, int num, BN_ULONG w)
+       {
+       BN_ULONG carry=0;
+       BN_ULONG bl,bh;
+
+       assert(num >= 0);
+       if (num <= 0) return((BN_ULONG)0);
+
+       bl=LBITS(w);
+       bh=HBITS(w);
+
+       for (;;)
+               {
+               mul(rp[0],ap[0],bl,bh,carry);
+               if (--num == 0) break;
+               mul(rp[1],ap[1],bl,bh,carry);
+               if (--num == 0) break;
+               mul(rp[2],ap[2],bl,bh,carry);
+               if (--num == 0) break;
+               mul(rp[3],ap[3],bl,bh,carry);
+               if (--num == 0) break;
+               ap+=4;
+               rp+=4;
+               }
+       return(carry);
+       }
+
+void bn_sqr_words(BN_ULONG *r, BN_ULONG *a, int n)
+       {
+       assert(n >= 0);
+       if (n <= 0) return;
+       for (;;)
+               {
+               sqr64(r[0],r[1],a[0]);
+               if (--n == 0) break;
+
+               sqr64(r[2],r[3],a[1]);
+               if (--n == 0) break;
+
+               sqr64(r[4],r[5],a[2]);
+               if (--n == 0) break;
+
+               sqr64(r[6],r[7],a[3]);
+               if (--n == 0) break;
+
+               a+=4;
+               r+=8;
+               }
+       }
+
+#endif /* !(defined(BN_LLONG) || defined(BN_UMULT_HIGH)) */
+
+#if defined(BN_LLONG) && defined(BN_DIV2W)
+
+BN_ULONG bn_div_words(BN_ULONG h, BN_ULONG l, BN_ULONG d)
+       {
+       return((BN_ULONG)(((((BN_ULLONG)h)<<BN_BITS2)|l)/(BN_ULLONG)d));
+       }
+
+#else
+
+/* Divide h,l by d and return the result. */
+/* I need to test this some more :-( */
+BN_ULONG bn_div_words(BN_ULONG h, BN_ULONG l, BN_ULONG d)
+       {
+       BN_ULONG dh,dl,q,ret=0,th,tl,t;
+       int i,count=2;
+
+       if (d == 0) return(BN_MASK2);
+
+       i=BN_num_bits_word(d);
+       assert((i == BN_BITS2) || (h > (BN_ULONG)1<<i));
+
+       i=BN_BITS2-i;
+       if (h >= d) h-=d;
+
+       if (i)
+               {
+               d<<=i;
+               h=(h<<i)|(l>>(BN_BITS2-i));
+               l<<=i;
+               }
+       dh=(d&BN_MASK2h)>>BN_BITS4;
+       dl=(d&BN_MASK2l);
+       for (;;)
+               {
+               if ((h>>BN_BITS4) == dh)
+                       q=BN_MASK2l;
+               else
+                       q=h/dh;
+
+               th=q*dh;
+               tl=dl*q;
+               for (;;)
+                       {
+                       t=h-th;
+                       if ((t&BN_MASK2h) ||
+                               ((tl) <= (
+                                       (t<<BN_BITS4)|
+                                       ((l&BN_MASK2h)>>BN_BITS4))))
+                               break;
+                       q--;
+                       th-=dh;
+                       tl-=dl;
+                       }
+               t=(tl>>BN_BITS4);
+               tl=(tl<<BN_BITS4)&BN_MASK2h;
+               th+=t;
+
+               if (l < tl) th++;
+               l-=tl;
+               if (h < th)
+                       {
+                       h+=d;
+                       q--;
+                       }
+               h-=th;
+
+               if (--count == 0) break;
+
+               ret=q<<BN_BITS4;
+               h=((h<<BN_BITS4)|(l>>BN_BITS4))&BN_MASK2;
+               l=(l&BN_MASK2l)<<BN_BITS4;
+               }
+       ret|=q;
+       return(ret);
+       }
+#endif /* !defined(BN_LLONG) && defined(BN_DIV2W) */
+
+#ifdef BN_LLONG
+BN_ULONG bn_add_words(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n)
+       {
+       BN_ULLONG ll=0;
+
+       assert(n >= 0);
+       if (n <= 0) return((BN_ULONG)0);
+
+       for (;;)
+               {
+               ll+=(BN_ULLONG)a[0]+b[0];
+               r[0]=(BN_ULONG)ll&BN_MASK2;
+               ll>>=BN_BITS2;
+               if (--n <= 0) break;
+
+               ll+=(BN_ULLONG)a[1]+b[1];
+               r[1]=(BN_ULONG)ll&BN_MASK2;
+               ll>>=BN_BITS2;
+               if (--n <= 0) break;
+
+               ll+=(BN_ULLONG)a[2]+b[2];
+               r[2]=(BN_ULONG)ll&BN_MASK2;
+               ll>>=BN_BITS2;
+               if (--n <= 0) break;
+
+               ll+=(BN_ULLONG)a[3]+b[3];
+               r[3]=(BN_ULONG)ll&BN_MASK2;
+               ll>>=BN_BITS2;
+               if (--n <= 0) break;
+
+               a+=4;
+               b+=4;
+               r+=4;
+               }
+       return((BN_ULONG)ll);
+       }
+#else /* !BN_LLONG */
+BN_ULONG bn_add_words(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n)
+       {
+       BN_ULONG c,l,t;
+
+       assert(n >= 0);
+       if (n <= 0) return((BN_ULONG)0);
+
+       c=0;
+       for (;;)
+               {
+               t=a[0];
+               t=(t+c)&BN_MASK2;
+               c=(t < c);
+               l=(t+b[0])&BN_MASK2;
+               c+=(l < t);
+               r[0]=l;
+               if (--n <= 0) break;
+
+               t=a[1];
+               t=(t+c)&BN_MASK2;
+               c=(t < c);
+               l=(t+b[1])&BN_MASK2;
+               c+=(l < t);
+               r[1]=l;
+               if (--n <= 0) break;
+
+               t=a[2];
+               t=(t+c)&BN_MASK2;
+               c=(t < c);
+               l=(t+b[2])&BN_MASK2;
+               c+=(l < t);
+               r[2]=l;
+               if (--n <= 0) break;
+
+               t=a[3];
+               t=(t+c)&BN_MASK2;
+               c=(t < c);
+               l=(t+b[3])&BN_MASK2;
+               c+=(l < t);
+               r[3]=l;
+               if (--n <= 0) break;
+
+               a+=4;
+               b+=4;
+               r+=4;
+               }
+       return((BN_ULONG)c);
+       }
+#endif /* !BN_LLONG */
diff --git a/package/ead/src/tinysrp/bn_ctx.c b/package/ead/src/tinysrp/bn_ctx.c
new file mode 100644 (file)
index 0000000..20a6605
--- /dev/null
@@ -0,0 +1,142 @@
+/* crypto/bn/bn_ctx.c */
+/* Written by Ulf Moeller for the OpenSSL project. */
+/* ====================================================================
+ * Copyright (c) 1998-2000 The OpenSSL Project.  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. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS 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.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#ifndef BN_CTX_DEBUG
+# undef NDEBUG /* avoid conflicting definitions */
+# define NDEBUG
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <bn.h>
+
+
+BN_CTX *BN_CTX_new(void)
+       {
+       BN_CTX *ret;
+
+       ret=(BN_CTX *)malloc(sizeof(BN_CTX));
+       if (ret == NULL)
+               {
+               return(NULL);
+               }
+
+       BN_CTX_init(ret);
+       ret->flags=BN_FLG_MALLOCED;
+       return(ret);
+       }
+
+void BN_CTX_init(BN_CTX *ctx)
+       {
+       int i;
+       ctx->tos = 0;
+       ctx->flags = 0;
+       ctx->depth = 0;
+       ctx->too_many = 0;
+       for (i = 0; i < BN_CTX_NUM; i++)
+               BN_init(&(ctx->bn[i]));
+       }
+
+void BN_CTX_free(BN_CTX *ctx)
+       {
+       int i;
+
+       if (ctx == NULL) return;
+       assert(ctx->depth == 0);
+
+       for (i=0; i < BN_CTX_NUM; i++)
+               BN_clear_free(&(ctx->bn[i]));
+       if (ctx->flags & BN_FLG_MALLOCED)
+               free(ctx);
+       }
+
+void BN_CTX_start(BN_CTX *ctx)
+       {
+       if (ctx->depth < BN_CTX_NUM_POS)
+               ctx->pos[ctx->depth] = ctx->tos;
+       ctx->depth++;
+       }
+
+BIGNUM *BN_CTX_get(BN_CTX *ctx)
+       {
+       if (ctx->depth > BN_CTX_NUM_POS || ctx->tos >= BN_CTX_NUM)
+               {
+               if (!ctx->too_many)
+                       {
+                       /* disable error code until BN_CTX_end is called: */
+                       ctx->too_many = 1;
+                       }
+               return NULL;
+               }
+       return (&(ctx->bn[ctx->tos++]));
+       }
+
+void BN_CTX_end(BN_CTX *ctx)
+       {
+       if (ctx == NULL) return;
+       assert(ctx->depth > 0);
+       if (ctx->depth == 0)
+               /* should never happen, but we can tolerate it if not in
+                * debug mode (could be a 'goto err' in the calling function
+                * before BN_CTX_start was reached) */
+               BN_CTX_start(ctx);
+
+       ctx->too_many = 0;
+       ctx->depth--;
+       if (ctx->depth < BN_CTX_NUM_POS)
+               ctx->tos = ctx->pos[ctx->depth];
+       }
diff --git a/package/ead/src/tinysrp/bn_div.c b/package/ead/src/tinysrp/bn_div.c
new file mode 100644 (file)
index 0000000..fd21913
--- /dev/null
@@ -0,0 +1,378 @@
+/* crypto/bn/bn_div.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``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.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "bn_lcl.h"
+
+#define NO_ASM
+
+/* The old slow way */
+#if 0
+int BN_div(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m, const BIGNUM *d,
+          BN_CTX *ctx)
+       {
+       int i,nm,nd;
+       int ret = 0;
+       BIGNUM *D;
+
+       bn_check_top(m);
+       bn_check_top(d);
+       if (BN_is_zero(d))
+               {
+               return(0);
+               }
+
+       if (BN_ucmp(m,d) < 0)
+               {
+               if (rem != NULL)
+                       { if (BN_copy(rem,m) == NULL) return(0); }
+               if (dv != NULL) BN_zero(dv);
+               return(1);
+               }
+
+       BN_CTX_start(ctx);
+       D = BN_CTX_get(ctx);
+       if (dv == NULL) dv = BN_CTX_get(ctx);
+       if (rem == NULL) rem = BN_CTX_get(ctx);
+       if (D == NULL || dv == NULL || rem == NULL)
+               goto end;
+
+       nd=BN_num_bits(d);
+       nm=BN_num_bits(m);
+       if (BN_copy(D,d) == NULL) goto end;
+       if (BN_copy(rem,m) == NULL) goto end;
+
+       /* The next 2 are needed so we can do a dv->d[0]|=1 later
+        * since BN_lshift1 will only work once there is a value :-) */
+       BN_zero(dv);
+       bn_wexpand(dv,1);
+       dv->top=1;
+
+       if (!BN_lshift(D,D,nm-nd)) goto end;
+       for (i=nm-nd; i>=0; i--)
+               {
+               if (!BN_lshift1(dv,dv)) goto end;
+               if (BN_ucmp(rem,D) >= 0)
+                       {
+                       dv->d[0]|=1;
+                       if (!BN_usub(rem,rem,D)) goto end;
+                       }
+/* CAN IMPROVE (and have now :=) */
+               if (!BN_rshift1(D,D)) goto end;
+               }
+       rem->neg=BN_is_zero(rem)?0:m->neg;
+       dv->neg=m->neg^d->neg;
+       ret = 1;
+ end:
+       BN_CTX_end(ctx);
+       return(ret);
+       }
+
+#else
+
+#if !defined(NO_ASM) && !defined(NO_INLINE_ASM) && !defined(PEDANTIC) && !defined(BN_DIV3W)
+# if defined(__GNUC__) && __GNUC__>=2
+#  if defined(__i386)
+   /*
+    * There were two reasons for implementing this template:
+    * - GNU C generates a call to a function (__udivdi3 to be exact)
+    *   in reply to ((((BN_ULLONG)n0)<<BN_BITS2)|n1)/d0 (I fail to
+    *   understand why...);
+    * - divl doesn't only calculate quotient, but also leaves
+    *   remainder in %edx which we can definitely use here:-)
+    *
+    *                                   <appro@fy.chalmers.se>
+    */
+#  define bn_div_words(n0,n1,d0)                \
+       ({  asm volatile (                      \
+               "divl   %4"                     \
+               : "=a"(q), "=d"(rem)            \
+               : "a"(n1), "d"(n0), "g"(d0)     \
+               : "cc");                        \
+           q;                                  \
+       })
+#  define REMAINDER_IS_ALREADY_CALCULATED
+#  endif /* __<cpu> */
+# endif /* __GNUC__ */
+#endif /* NO_ASM */
+
+int BN_div(BIGNUM *dv, BIGNUM *rm, const BIGNUM *num, const BIGNUM *divisor,
+          BN_CTX *ctx)
+       {
+       int norm_shift,i,j,loop;
+       BIGNUM *tmp,wnum,*snum,*sdiv,*res;
+       BN_ULONG *resp,*wnump;
+       BN_ULONG d0,d1;
+       int num_n,div_n;
+
+       bn_check_top(num);
+       bn_check_top(divisor);
+
+       if (BN_is_zero(divisor))
+               {
+               return(0);
+               }
+
+       if (BN_ucmp(num,divisor) < 0)
+               {
+               if (rm != NULL)
+                       { if (BN_copy(rm,num) == NULL) return(0); }
+               if (dv != NULL) BN_zero(dv);
+               return(1);
+               }
+
+       BN_CTX_start(ctx);
+       tmp=BN_CTX_get(ctx);
+       tmp->neg=0;
+       snum=BN_CTX_get(ctx);
+       sdiv=BN_CTX_get(ctx);
+       if (dv == NULL)
+               res=BN_CTX_get(ctx);
+       else    res=dv;
+       if (res == NULL) goto err;
+
+       /* First we normalise the numbers */
+       norm_shift=BN_BITS2-((BN_num_bits(divisor))%BN_BITS2);
+       BN_lshift(sdiv,divisor,norm_shift);
+       sdiv->neg=0;
+       norm_shift+=BN_BITS2;
+       BN_lshift(snum,num,norm_shift);
+       snum->neg=0;
+       div_n=sdiv->top;
+       num_n=snum->top;
+       loop=num_n-div_n;
+
+       /* Lets setup a 'window' into snum
+        * This is the part that corresponds to the current
+        * 'area' being divided */
+       BN_init(&wnum);
+       wnum.d=  &(snum->d[loop]);
+       wnum.top= div_n;
+       wnum.dmax= snum->dmax+1; /* a bit of a lie */
+
+       /* Get the top 2 words of sdiv */
+       /* i=sdiv->top; */
+       d0=sdiv->d[div_n-1];
+       d1=(div_n == 1)?0:sdiv->d[div_n-2];
+
+       /* pointer to the 'top' of snum */
+       wnump= &(snum->d[num_n-1]);
+
+       /* Setup to 'res' */
+       res->neg= (num->neg^divisor->neg);
+       if (!bn_wexpand(res,(loop+1))) goto err;
+       res->top=loop;
+       resp= &(res->d[loop-1]);
+
+       /* space for temp */
+       if (!bn_wexpand(tmp,(div_n+1))) goto err;
+
+       if (BN_ucmp(&wnum,sdiv) >= 0)
+               {
+               if (!BN_usub(&wnum,&wnum,sdiv)) goto err;
+               *resp=1;
+               res->d[res->top-1]=1;
+               }
+       else
+               res->top--;
+       resp--;
+
+       for (i=0; i<loop-1; i++)
+               {
+               BN_ULONG q,l0;
+#ifdef BN_DIV3W
+               q=bn_div_3_words(wnump,d1,d0);
+#else
+               BN_ULONG n0,n1,rem=0;
+
+               n0=wnump[0];
+               n1=wnump[-1];
+               if (n0 == d0)
+                       q=BN_MASK2;
+               else                    /* n0 < d0 */
+                       {
+#ifdef BN_LLONG
+                       BN_ULLONG t2;
+
+#if defined(BN_LLONG) && defined(BN_DIV2W) && !defined(bn_div_words)
+                       q=(BN_ULONG)(((((BN_ULLONG)n0)<<BN_BITS2)|n1)/d0);
+#else
+                       q=bn_div_words(n0,n1,d0);
+#endif
+
+#ifndef REMAINDER_IS_ALREADY_CALCULATED
+                       /*
+                        * rem doesn't have to be BN_ULLONG. The least we
+                        * know it's less that d0, isn't it?
+                        */
+                       rem=(n1-q*d0)&BN_MASK2;
+#endif
+                       t2=(BN_ULLONG)d1*q;
+
+                       for (;;)
+                               {
+                               if (t2 <= ((((BN_ULLONG)rem)<<BN_BITS2)|wnump[-2]))
+                                       break;
+                               q--;
+                               rem += d0;
+                               if (rem < d0) break; /* don't let rem overflow */
+                               t2 -= d1;
+                               }
+#else /* !BN_LLONG */
+                       BN_ULONG t2l,t2h,ql,qh;
+
+                       q=bn_div_words(n0,n1,d0);
+#ifndef REMAINDER_IS_ALREADY_CALCULATED
+                       rem=(n1-q*d0)&BN_MASK2;
+#endif
+
+#ifdef BN_UMULT_HIGH
+                       t2l = d1 * q;
+                       t2h = BN_UMULT_HIGH(d1,q);
+#else
+                       t2l=LBITS(d1); t2h=HBITS(d1);
+                       ql =LBITS(q);  qh =HBITS(q);
+                       mul64(t2l,t2h,ql,qh); /* t2=(BN_ULLONG)d1*q; */
+#endif
+
+                       for (;;)
+                               {
+                               if ((t2h < rem) ||
+                                       ((t2h == rem) && (t2l <= wnump[-2])))
+                                       break;
+                               q--;
+                               rem += d0;
+                               if (rem < d0) break; /* don't let rem overflow */
+                               if (t2l < d1) t2h--; t2l -= d1;
+                               }
+#endif /* !BN_LLONG */
+                       }
+#endif /* !BN_DIV3W */
+
+               l0=bn_mul_words(tmp->d,sdiv->d,div_n,q);
+               wnum.d--; wnum.top++;
+               tmp->d[div_n]=l0;
+               for (j=div_n+1; j>0; j--)
+                       if (tmp->d[j-1]) break;
+               tmp->top=j;
+
+               j=wnum.top;
+               BN_sub(&wnum,&wnum,tmp);
+
+               snum->top=snum->top+wnum.top-j;
+
+               if (wnum.neg)
+                       {
+                       q--;
+                       j=wnum.top;
+                       BN_add(&wnum,&wnum,sdiv);
+                       snum->top+=wnum.top-j;
+                       }
+               *(resp--)=q;
+               wnump--;
+               }
+       if (rm != NULL)
+               {
+               BN_rshift(rm,snum,norm_shift);
+               rm->neg=num->neg;
+               }
+       BN_CTX_end(ctx);
+       return(1);
+err:
+       BN_CTX_end(ctx);
+       return(0);
+       }
+
+#endif
+
+/* rem != m */
+int BN_mod(BIGNUM *rem, const BIGNUM *m, const BIGNUM *d, BN_CTX *ctx)
+       {
+#if 0 /* The old slow way */
+       int i,nm,nd;
+       BIGNUM *dv;
+
+       if (BN_ucmp(m,d) < 0)
+               return((BN_copy(rem,m) == NULL)?0:1);
+
+       BN_CTX_start(ctx);
+       dv=BN_CTX_get(ctx);
+
+       if (!BN_copy(rem,m)) goto err;
+
+       nm=BN_num_bits(rem);
+       nd=BN_num_bits(d);
+       if (!BN_lshift(dv,d,nm-nd)) goto err;
+       for (i=nm-nd; i>=0; i--)
+               {
+               if (BN_cmp(rem,dv) >= 0)
+                       {
+                       if (!BN_sub(rem,rem,dv)) goto err;
+                       }
+               if (!BN_rshift1(dv,dv)) goto err;
+               }
+       BN_CTX_end(ctx);
+       return(1);
+ err:
+       BN_CTX_end(ctx);
+       return(0);
+#else
+       return(BN_div(NULL,rem,m,d,ctx));
+#endif
+       }
+
diff --git a/package/ead/src/tinysrp/bn_exp.c b/package/ead/src/tinysrp/bn_exp.c
new file mode 100644 (file)
index 0000000..09afb79
--- /dev/null
@@ -0,0 +1,395 @@
+/* crypto/bn/bn_exp.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``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.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2000 The OpenSSL Project.  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. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS 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.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+
+#include <stdio.h>
+#include "bn_lcl.h"
+
+#define TABLE_SIZE      32
+
+/* slow but works */
+int BN_mod_mul(BIGNUM *ret, BIGNUM *a, BIGNUM *b, const BIGNUM *m, BN_CTX *ctx)
+       {
+       BIGNUM *t;
+       int r=0;
+
+       bn_check_top(a);
+       bn_check_top(b);
+       bn_check_top(m);
+
+       BN_CTX_start(ctx);
+       if ((t = BN_CTX_get(ctx)) == NULL) goto err;
+       if (a == b)
+               { if (!BN_sqr(t,a,ctx)) goto err; }
+       else
+               { if (!BN_mul(t,a,b,ctx)) goto err; }
+       if (!BN_mod(ret,t,m,ctx)) goto err;
+       r=1;
+err:
+       BN_CTX_end(ctx);
+       return(r);
+       }
+
+int BN_mod_exp(BIGNUM *r, BIGNUM *a, const BIGNUM *p, const BIGNUM *m,
+              BN_CTX *ctx)
+       {
+       int ret;
+
+       bn_check_top(a);
+       bn_check_top(p);
+       bn_check_top(m);
+
+#ifdef MONT_MUL_MOD
+       /* I have finally been able to take out this pre-condition of
+        * the top bit being set.  It was caused by an error in BN_div
+        * with negatives.  There was also another problem when for a^b%m
+        * a >= m.  eay 07-May-97 */
+/*      if ((m->d[m->top-1]&BN_TBIT) && BN_is_odd(m)) */
+
+       if (BN_is_odd(m))
+               {
+               if (a->top == 1)
+                       {
+                       BN_ULONG A = a->d[0];
+                       ret=BN_mod_exp_mont_word(r,A,p,m,ctx,NULL);
+                       }
+               else
+                       ret=BN_mod_exp_mont(r,a,p,m,ctx,NULL);
+               }
+       else
+#endif
+#ifdef RECP_MUL_MOD
+               { ret=BN_mod_exp_recp(r,a,p,m,ctx); }
+#else
+               { ret=BN_mod_exp_simple(r,a,p,m,ctx); }
+#endif
+
+       return(ret);
+       }
+
+
+#ifdef RECP_MUL_MOD
+int BN_mod_exp_recp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+                   const BIGNUM *m, BN_CTX *ctx)
+       {
+       int i,j,bits,ret=0,wstart,wend,window,wvalue;
+       int start=1,ts=0;
+       BIGNUM *aa;
+       BIGNUM val[TABLE_SIZE];
+       BN_RECP_CTX recp;
+
+       bits=BN_num_bits(p);
+
+       if (bits == 0)
+               {
+               BN_one(r);
+               return(1);
+               }
+
+       BN_CTX_start(ctx);
+       if ((aa = BN_CTX_get(ctx)) == NULL) goto err;
+
+       BN_RECP_CTX_init(&recp);
+       if (BN_RECP_CTX_set(&recp,m,ctx) <= 0) goto err;
+
+       BN_init(&(val[0]));
+       ts=1;
+
+       if (!BN_mod(&(val[0]),a,m,ctx)) goto err;               /* 1 */
+
+       window = BN_window_bits_for_exponent_size(bits);
+       if (window > 1)
+               {
+               if (!BN_mod_mul_reciprocal(aa,&(val[0]),&(val[0]),&recp,ctx))
+                       goto err;                               /* 2 */
+               j=1<<(window-1);
+               for (i=1; i<j; i++)
+                       {
+                       BN_init(&val[i]);
+                       if (!BN_mod_mul_reciprocal(&(val[i]),&(val[i-1]),aa,&recp,ctx))
+                               goto err;
+                       }
+               ts=i;
+               }
+
+       start=1;        /* This is used to avoid multiplication etc
+                        * when there is only the value '1' in the
+                        * buffer. */
+       wvalue=0;       /* The 'value' of the window */
+       wstart=bits-1;  /* The top bit of the window */
+       wend=0;         /* The bottom bit of the window */
+
+       if (!BN_one(r)) goto err;
+
+       for (;;)
+               {
+               if (BN_is_bit_set(p,wstart) == 0)
+                       {
+                       if (!start)
+                               if (!BN_mod_mul_reciprocal(r,r,r,&recp,ctx))
+                               goto err;
+                       if (wstart == 0) break;
+                       wstart--;
+                       continue;
+                       }
+               /* We now have wstart on a 'set' bit, we now need to work out
+                * how bit a window to do.  To do this we need to scan
+                * forward until the last set bit before the end of the
+                * window */
+               j=wstart;
+               wvalue=1;
+               wend=0;
+               for (i=1; i<window; i++)
+                       {
+                       if (wstart-i < 0) break;
+                       if (BN_is_bit_set(p,wstart-i))
+                               {
+                               wvalue<<=(i-wend);
+                               wvalue|=1;
+                               wend=i;
+                               }
+                       }
+
+               /* wend is the size of the current window */
+               j=wend+1;
+               /* add the 'bytes above' */
+               if (!start)
+                       for (i=0; i<j; i++)
+                               {
+                               if (!BN_mod_mul_reciprocal(r,r,r,&recp,ctx))
+                                       goto err;
+                               }
+
+               /* wvalue will be an odd number < 2^window */
+               if (!BN_mod_mul_reciprocal(r,r,&(val[wvalue>>1]),&recp,ctx))
+                       goto err;
+
+               /* move the 'window' down further */
+               wstart-=wend+1;
+               wvalue=0;
+               start=0;
+               if (wstart < 0) break;
+               }
+       ret=1;
+err:
+       BN_CTX_end(ctx);
+       for (i=0; i<ts; i++)
+               BN_clear_free(&(val[i]));
+       BN_RECP_CTX_free(&recp);
+       return(ret);
+       }
+#else
+
+/* The old fallback, simple version :-) */
+int BN_mod_exp_simple(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+            const BIGNUM *m, BN_CTX *ctx)
+       {
+       int i,j,bits,ret=0,wstart,wend,window,wvalue,ts=0;
+       int start=1;
+       BIGNUM *d;
+       BIGNUM val[TABLE_SIZE];
+
+       bits=BN_num_bits(p);
+
+       if (bits == 0)
+               {
+               BN_one(r);
+               return(1);
+               }
+
+       BN_CTX_start(ctx);
+       if ((d = BN_CTX_get(ctx)) == NULL) goto err;
+
+       BN_init(&(val[0]));
+       ts=1;
+       if (!BN_mod(&(val[0]),a,m,ctx)) goto err;               /* 1 */
+
+       window = BN_window_bits_for_exponent_size(bits);
+       if (window > 1)
+               {
+               if (!BN_mod_mul(d,&(val[0]),&(val[0]),m,ctx))
+                       goto err;                               /* 2 */
+               j=1<<(window-1);
+               for (i=1; i<j; i++)
+                       {
+                       BN_init(&(val[i]));
+                       if (!BN_mod_mul(&(val[i]),&(val[i-1]),d,m,ctx))
+                               goto err;
+                       }
+               ts=i;
+               }
+
+       start=1;        /* This is used to avoid multiplication etc
+                        * when there is only the value '1' in the
+                        * buffer. */
+       wvalue=0;       /* The 'value' of the window */
+       wstart=bits-1;  /* The top bit of the window */
+       wend=0;         /* The bottom bit of the window */
+
+       if (!BN_one(r)) goto err;
+
+       for (;;)
+               {
+               if (BN_is_bit_set(p,wstart) == 0)
+                       {
+                       if (!start)
+                               if (!BN_mod_mul(r,r,r,m,ctx))
+                               goto err;
+                       if (wstart == 0) break;
+                       wstart--;
+                       continue;
+                       }
+               /* We now have wstart on a 'set' bit, we now need to work out
+                * how bit a window to do.  To do this we need to scan
+                * forward until the last set bit before the end of the
+                * window */
+               j=wstart;
+               wvalue=1;
+               wend=0;
+               for (i=1; i<window; i++)
+                       {
+                       if (wstart-i < 0) break;
+                       if (BN_is_bit_set(p,wstart-i))
+                               {
+                               wvalue<<=(i-wend);
+                               wvalue|=1;
+                               wend=i;
+                               }
+                       }
+
+               /* wend is the size of the current window */
+               j=wend+1;
+               /* add the 'bytes above' */
+               if (!start)
+                       for (i=0; i<j; i++)
+                               {
+                               if (!BN_mod_mul(r,r,r,m,ctx))
+                                       goto err;
+                               }
+
+               /* wvalue will be an odd number < 2^window */
+               if (!BN_mod_mul(r,r,&(val[wvalue>>1]),m,ctx))
+                       goto err;
+
+               /* move the 'window' down further */
+               wstart-=wend+1;
+               wvalue=0;
+               start=0;
+               if (wstart < 0) break;
+               }
+       ret=1;
+err:
+       BN_CTX_end(ctx);
+       for (i=0; i<ts; i++)
+               BN_clear_free(&(val[i]));
+       return(ret);
+       }
+#endif
diff --git a/package/ead/src/tinysrp/bn_lcl.h b/package/ead/src/tinysrp/bn_lcl.h
new file mode 100644 (file)
index 0000000..129ad65
--- /dev/null
@@ -0,0 +1,419 @@
+/* crypto/bn/bn_lcl.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``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.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2000 The OpenSSL Project.  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. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS 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.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#ifndef HEADER_BN_LCL_H
+#define HEADER_BN_LCL_H
+
+#include <bn.h>
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+
+/*
+ * BN_window_bits_for_exponent_size -- macro for sliding window mod_exp functions
+ *
+ *
+ * For window size 'w' (w >= 2) and a random 'b' bits exponent,
+ * the number of multiplications is a constant plus on average
+ *
+ *    2^(w-1) + (b-w)/(w+1);
+ *
+ * here  2^(w-1)  is for precomputing the table (we actually need
+ * entries only for windows that have the lowest bit set), and
+ * (b-w)/(w+1)  is an approximation for the expected number of
+ * w-bit windows, not counting the first one.
+ *
+ * Thus we should use
+ *
+ *    w >= 6  if        b > 671
+ *     w = 5  if  671 > b > 239
+ *     w = 4  if  239 > b >  79
+ *     w = 3  if   79 > b >  23
+ *    w <= 2  if   23 > b
+ *
+ * (with draws in between).  Very small exponents are often selected
+ * with low Hamming weight, so we use  w = 1  for b <= 23.
+ */
+#if 1
+#define BN_window_bits_for_exponent_size(b) \
+               ((b) > 671 ? 6 : \
+                (b) > 239 ? 5 : \
+                (b) >  79 ? 4 : \
+                (b) >  23 ? 3 : 1)
+#else
+/* Old SSLeay/OpenSSL table.
+ * Maximum window size was 5, so this table differs for b==1024;
+ * but it coincides for other interesting values (b==160, b==512).
+ */
+#define BN_window_bits_for_exponent_size(b) \
+               ((b) > 255 ? 5 : \
+                (b) > 127 ? 4 : \
+                (b) >  17 ? 3 : 1)
+#endif
+
+
+
+/* Pentium pro 16,16,16,32,64 */
+/* Alpha       16,16,16,16.64 */
+#define BN_MULL_SIZE_NORMAL                     (16) /* 32 */
+#define BN_MUL_RECURSIVE_SIZE_NORMAL            (16) /* 32 less than */
+#define BN_SQR_RECURSIVE_SIZE_NORMAL            (16) /* 32 */
+#define BN_MUL_LOW_RECURSIVE_SIZE_NORMAL        (32) /* 32 */
+#define BN_MONT_CTX_SET_SIZE_WORD               (64) /* 32 */
+
+#if !defined(NO_ASM) && !defined(NO_INLINE_ASM) && !defined(PEDANTIC)
+/*
+ * BN_UMULT_HIGH section.
+ *
+ * No, I'm not trying to overwhelm you when stating that the
+ * product of N-bit numbers is 2*N bits wide:-) No, I don't expect
+ * you to be impressed when I say that if the compiler doesn't
+ * support 2*N integer type, then you have to replace every N*N
+ * multiplication with 4 (N/2)*(N/2) accompanied by some shifts
+ * and additions which unavoidably results in severe performance
+ * penalties. Of course provided that the hardware is capable of
+ * producing 2*N result... That's when you normally start
+ * considering assembler implementation. However! It should be
+ * pointed out that some CPUs (most notably Alpha, PowerPC and
+ * upcoming IA-64 family:-) provide *separate* instruction
+ * calculating the upper half of the product placing the result
+ * into a general purpose register. Now *if* the compiler supports
+ * inline assembler, then it's not impossible to implement the
+ * "bignum" routines (and have the compiler optimize 'em)
+ * exhibiting "native" performance in C. That's what BN_UMULT_HIGH
+ * macro is about:-)
+ *
+ *                                      <appro@fy.chalmers.se>
+ */
+# if defined(__alpha) && (defined(SIXTY_FOUR_BIT_LONG) || defined(SIXTY_FOUR_BIT))
+#  if defined(__DECC)
+#   include <c_asm.h>
+#   define BN_UMULT_HIGH(a,b)   (BN_ULONG)asm("umulh %a0,%a1,%v0",(a),(b))
+#  elif defined(__GNUC__)
+#   define BN_UMULT_HIGH(a,b)   ({      \
+       register BN_ULONG ret;          \
+       asm ("umulh     %1,%2,%0"       \
+            : "=r"(ret)                \
+            : "r"(a), "r"(b));         \
+       ret;                    })
+#  endif        /* compiler */
+# elif defined(_ARCH_PPC) && defined(__64BIT__) && defined(SIXTY_FOUR_BIT_LONG)
+#  if defined(__GNUC__)
+#   define BN_UMULT_HIGH(a,b)   ({      \
+       register BN_ULONG ret;          \
+       asm ("mulhdu    %0,%1,%2"       \
+            : "=r"(ret)                \
+            : "r"(a), "r"(b));         \
+       ret;                    })
+#  endif        /* compiler */
+# endif         /* cpu */
+#endif          /* NO_ASM */
+
+/*************************************************************
+ * Using the long long type
+ */
+#define Lw(t)    (((BN_ULONG)(t))&BN_MASK2)
+#define Hw(t)    (((BN_ULONG)((t)>>BN_BITS2))&BN_MASK2)
+
+/* This is used for internal error checking and is not normally used */
+#ifdef BN_DEBUG
+# include <assert.h>
+# define bn_check_top(a) assert ((a)->top >= 0 && (a)->top <= (a)->dmax);
+#else
+# define bn_check_top(a)
+#endif
+
+/* This macro is to add extra stuff for development checking */
+#ifdef BN_DEBUG
+#define bn_set_max(r) ((r)->max=(r)->top,BN_set_flags((r),BN_FLG_STATIC_DATA))
+#else
+#define bn_set_max(r)
+#endif
+
+/* These macros are used to 'take' a section of a bignum for read only use */
+#define bn_set_low(r,a,n) \
+       { \
+       (r)->top=((a)->top > (n))?(n):(a)->top; \
+       (r)->d=(a)->d; \
+       (r)->neg=(a)->neg; \
+       (r)->flags|=BN_FLG_STATIC_DATA; \
+       bn_set_max(r); \
+       }
+
+#define bn_set_high(r,a,n) \
+       { \
+       if ((a)->top > (n)) \
+               { \
+               (r)->top=(a)->top-n; \
+               (r)->d= &((a)->d[n]); \
+               } \
+       else \
+               (r)->top=0; \
+       (r)->neg=(a)->neg; \
+       (r)->flags|=BN_FLG_STATIC_DATA; \
+       bn_set_max(r); \
+       }
+
+#ifdef BN_LLONG
+#define mul_add(r,a,w,c) { \
+       BN_ULLONG t; \
+       t=(BN_ULLONG)w * (a) + (r) + (c); \
+       (r)= Lw(t); \
+       (c)= Hw(t); \
+       }
+
+#define mul(r,a,w,c) { \
+       BN_ULLONG t; \
+       t=(BN_ULLONG)w * (a) + (c); \
+       (r)= Lw(t); \
+       (c)= Hw(t); \
+       }
+
+#define sqr(r0,r1,a) { \
+       BN_ULLONG t; \
+       t=(BN_ULLONG)(a)*(a); \
+       (r0)=Lw(t); \
+       (r1)=Hw(t); \
+       }
+
+#elif defined(BN_UMULT_HIGH)
+#define mul_add(r,a,w,c) {              \
+       BN_ULONG high,low,ret,tmp=(a);  \
+       ret =  (r);                     \
+       high=  BN_UMULT_HIGH(w,tmp);    \
+       ret += (c);                     \
+       low =  (w) * tmp;               \
+       (c) =  (ret<(c))?1:0;           \
+       (c) += high;                    \
+       ret += low;                     \
+       (c) += (ret<low)?1:0;           \
+       (r) =  ret;                     \
+       }
+
+#define mul(r,a,w,c)    {               \
+       BN_ULONG high,low,ret,ta=(a);   \
+       low =  (w) * ta;                \
+       high=  BN_UMULT_HIGH(w,ta);     \
+       ret =  low + (c);               \
+       (c) =  high;                    \
+       (c) += (ret<low)?1:0;           \
+       (r) =  ret;                     \
+       }
+
+#define sqr(r0,r1,a)    {               \
+       BN_ULONG tmp=(a);               \
+       (r0) = tmp * tmp;               \
+       (r1) = BN_UMULT_HIGH(tmp,tmp);  \
+       }
+
+#else
+/*************************************************************
+ * No long long type
+ */
+
+#define LBITS(a)        ((a)&BN_MASK2l)
+#define HBITS(a)        (((a)>>BN_BITS4)&BN_MASK2l)
+#define L2HBITS(a)      ((BN_ULONG)((a)&BN_MASK2l)<<BN_BITS4)
+
+#define LLBITS(a)       ((a)&BN_MASKl)
+#define LHBITS(a)       (((a)>>BN_BITS2)&BN_MASKl)
+#define LL2HBITS(a)     ((BN_ULLONG)((a)&BN_MASKl)<<BN_BITS2)
+
+#define mul64(l,h,bl,bh) \
+       { \
+       BN_ULONG m,m1,lt,ht; \
+ \
+       lt=l; \
+       ht=h; \
+       m =(bh)*(lt); \
+       lt=(bl)*(lt); \
+       m1=(bl)*(ht); \
+       ht =(bh)*(ht); \
+       m=(m+m1)&BN_MASK2; if (m < m1) ht+=L2HBITS(1L); \
+       ht+=HBITS(m); \
+       m1=L2HBITS(m); \
+       lt=(lt+m1)&BN_MASK2; if (lt < m1) ht++; \
+       (l)=lt; \
+       (h)=ht; \
+       }
+
+#define sqr64(lo,ho,in) \
+       { \
+       BN_ULONG l,h,m; \
+ \
+       h=(in); \
+       l=LBITS(h); \
+       h=HBITS(h); \
+       m =(l)*(h); \
+       l*=l; \
+       h*=h; \
+       h+=(m&BN_MASK2h1)>>(BN_BITS4-1); \
+       m =(m&BN_MASK2l)<<(BN_BITS4+1); \
+       l=(l+m)&BN_MASK2; if (l < m) h++; \
+       (lo)=l; \
+       (ho)=h; \
+       }
+
+#define mul_add(r,a,bl,bh,c) { \
+       BN_ULONG l,h; \
+ \
+       h= (a); \
+       l=LBITS(h); \
+       h=HBITS(h); \
+       mul64(l,h,(bl),(bh)); \
+ \
+       /* non-multiply part */ \
+       l=(l+(c))&BN_MASK2; if (l < (c)) h++; \
+       (c)=(r); \
+       l=(l+(c))&BN_MASK2; if (l < (c)) h++; \
+       (c)=h&BN_MASK2; \
+       (r)=l; \
+       }
+
+#define mul(r,a,bl,bh,c) { \
+       BN_ULONG l,h; \
+ \
+       h= (a); \
+       l=LBITS(h); \
+       h=HBITS(h); \
+       mul64(l,h,(bl),(bh)); \
+ \
+       /* non-multiply part */ \
+       l+=(c); if ((l&BN_MASK2) < (c)) h++; \
+       (c)=h&BN_MASK2; \
+       (r)=l&BN_MASK2; \
+       }
+#endif /* !BN_LLONG */
+
+void bn_mul_normal(BN_ULONG *r,BN_ULONG *a,int na,BN_ULONG *b,int nb);
+void bn_mul_comba8(BN_ULONG *r,BN_ULONG *a,BN_ULONG *b);
+void bn_mul_comba4(BN_ULONG *r,BN_ULONG *a,BN_ULONG *b);
+void bn_sqr_normal(BN_ULONG *r, BN_ULONG *a, int n, BN_ULONG *tmp);
+void bn_sqr_comba8(BN_ULONG *r,BN_ULONG *a);
+void bn_sqr_comba4(BN_ULONG *r,BN_ULONG *a);
+int bn_cmp_words(BN_ULONG *a,BN_ULONG *b,int n);
+void bn_mul_recursive(BN_ULONG *r,BN_ULONG *a,BN_ULONG *b,int n2,BN_ULONG *t);
+void bn_mul_part_recursive(BN_ULONG *r,BN_ULONG *a,BN_ULONG *b,
+       int tn, int n,BN_ULONG *t);
+void bn_sqr_recursive(BN_ULONG *r,BN_ULONG *a, int n2, BN_ULONG *t);
+void bn_mul_low_normal(BN_ULONG *r,BN_ULONG *a,BN_ULONG *b, int n);
+void bn_mul_low_recursive(BN_ULONG *r,BN_ULONG *a,BN_ULONG *b,int n2,
+       BN_ULONG *t);
+void bn_mul_high(BN_ULONG *r,BN_ULONG *a,BN_ULONG *b,BN_ULONG *l,int n2,
+       BN_ULONG *t);
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif
diff --git a/package/ead/src/tinysrp/bn_lib.c b/package/ead/src/tinysrp/bn_lib.c
new file mode 100644 (file)
index 0000000..cfa0d75
--- /dev/null
@@ -0,0 +1,576 @@
+/* crypto/bn/bn_lib.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``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.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef BN_DEBUG
+# undef NDEBUG /* avoid conflicting definitions */
+# define NDEBUG
+#endif
+
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "bn_lcl.h"
+
+const char *BN_version="Big Number";
+
+/* For a 32 bit machine
+ * 2 -   4 ==  128
+ * 3 -   8 ==  256
+ * 4 -  16 ==  512
+ * 5 -  32 == 1024
+ * 6 -  64 == 2048
+ * 7 - 128 == 4096
+ * 8 - 256 == 8192
+ */
+static int bn_limit_bits=0;
+static int bn_limit_num=8;        /* (1<<bn_limit_bits) */
+static int bn_limit_bits_low=0;
+static int bn_limit_num_low=8;    /* (1<<bn_limit_bits_low) */
+static int bn_limit_bits_high=0;
+static int bn_limit_num_high=8;   /* (1<<bn_limit_bits_high) */
+static int bn_limit_bits_mont=0;
+static int bn_limit_num_mont=8;   /* (1<<bn_limit_bits_mont) */
+
+int BN_num_bits_word(BN_ULONG l)
+       {
+       static const char bits[256]={
+               0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,
+               5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+               6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
+               6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
+               7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
+               7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
+               7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
+               7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
+               8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
+               8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
+               8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
+               8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
+               8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
+               8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
+               8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
+               8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
+               };
+
+#if defined(SIXTY_FOUR_BIT_LONG)
+       if (l & 0xffffffff00000000L)
+               {
+               if (l & 0xffff000000000000L)
+                       {
+                       if (l & 0xff00000000000000L)
+                               {
+                               return(bits[(int)(l>>56)]+56);
+                               }
+                       else    return(bits[(int)(l>>48)]+48);
+                       }
+               else
+                       {
+                       if (l & 0x0000ff0000000000L)
+                               {
+                               return(bits[(int)(l>>40)]+40);
+                               }
+                       else    return(bits[(int)(l>>32)]+32);
+                       }
+               }
+       else
+#else
+#ifdef SIXTY_FOUR_BIT
+       if (l & 0xffffffff00000000LL)
+               {
+               if (l & 0xffff000000000000LL)
+                       {
+                       if (l & 0xff00000000000000LL)
+                               {
+                               return(bits[(int)(l>>56)]+56);
+                               }
+                       else    return(bits[(int)(l>>48)]+48);
+                       }
+               else
+                       {
+                       if (l & 0x0000ff0000000000LL)
+                               {
+                               return(bits[(int)(l>>40)]+40);
+                               }
+                       else    return(bits[(int)(l>>32)]+32);
+                       }
+               }
+       else
+#endif
+#endif
+               {
+#if defined(THIRTY_TWO_BIT) || defined(SIXTY_FOUR_BIT) || defined(SIXTY_FOUR_BIT_LONG)
+               if (l & 0xffff0000L)
+                       {
+                       if (l & 0xff000000L)
+                               return(bits[(int)(l>>24L)]+24);
+                       else    return(bits[(int)(l>>16L)]+16);
+                       }
+               else
+#endif
+                       {
+#if defined(SIXTEEN_BIT) || defined(THIRTY_TWO_BIT) || defined(SIXTY_FOUR_BIT) || defined(SIXTY_FOUR_BIT_LONG)
+                       if (l & 0xff00L)
+                               return(bits[(int)(l>>8)]+8);
+                       else
+#endif
+                               return(bits[(int)(l   )]  );
+                       }
+               }
+       }
+
+int BN_num_bits(const BIGNUM *a)
+       {
+       BN_ULONG l;
+       int i;
+
+       bn_check_top(a);
+
+       if (a->top == 0) return(0);
+       l=a->d[a->top-1];
+       assert(l != 0);
+       i=(a->top-1)*BN_BITS2;
+       return(i+BN_num_bits_word(l));
+       }
+
+void BN_clear_free(BIGNUM *a)
+       {
+       int i;
+
+       if (a == NULL) return;
+       if (a->d != NULL)
+               {
+               memset(a->d,0,a->dmax*sizeof(a->d[0]));
+               if (!(BN_get_flags(a,BN_FLG_STATIC_DATA)))
+                       free(a->d);
+               }
+       i=BN_get_flags(a,BN_FLG_MALLOCED);
+       memset(a,0,sizeof(BIGNUM));
+       if (i)
+               free(a);
+       }
+
+void BN_free(BIGNUM *a)
+       {
+       if (a == NULL) return;
+       if ((a->d != NULL) && !(BN_get_flags(a,BN_FLG_STATIC_DATA)))
+               free(a->d);
+       a->flags|=BN_FLG_FREE; /* REMOVE? */
+       if (a->flags & BN_FLG_MALLOCED)
+               free(a);
+       }
+
+void BN_init(BIGNUM *a)
+       {
+       memset(a,0,sizeof(BIGNUM));
+       }
+
+BIGNUM *BN_new(void)
+       {
+       BIGNUM *ret;
+
+       if ((ret=(BIGNUM *)malloc(sizeof(BIGNUM))) == NULL)
+               {
+               return(NULL);
+               }
+       ret->flags=BN_FLG_MALLOCED;
+       ret->top=0;
+       ret->neg=0;
+       ret->dmax=0;
+       ret->d=NULL;
+       return(ret);
+       }
+
+/* This is an internal function that should not be used in applications.
+ * It ensures that 'b' has enough room for a 'words' word number number.
+ * It is mostly used by the various BIGNUM routines. If there is an error,
+ * NULL is returned. If not, 'b' is returned. */
+
+BIGNUM *bn_expand2(BIGNUM *b, int words)
+       {
+       BN_ULONG *A,*a;
+       const BN_ULONG *B;
+       int i;
+
+       bn_check_top(b);
+
+       if (words > b->dmax)
+               {
+               bn_check_top(b);
+               if (BN_get_flags(b,BN_FLG_STATIC_DATA))
+                       {
+                       return(NULL);
+                       }
+               a=A=(BN_ULONG *)malloc(sizeof(BN_ULONG)*(words+1));
+               if (A == NULL)
+                       {
+                       return(NULL);
+                       }
+#if 1
+               B=b->d;
+               /* Check if the previous number needs to be copied */
+               if (B != NULL)
+                       {
+#if 0
+                       /* This lot is an unrolled loop to copy b->top
+                        * BN_ULONGs from B to A
+                        */
+/*
+ * I have nothing against unrolling but it's usually done for
+ * several reasons, namely:
+ * - minimize percentage of decision making code, i.e. branches;
+ * - avoid cache trashing;
+ * - make it possible to schedule loads earlier;
+ * Now let's examine the code below. The cornerstone of C is
+ * "programmer is always right" and that's what we love it for:-)
+ * For this very reason C compilers have to be paranoid when it
+ * comes to data aliasing and assume the worst. Yeah, but what
+ * does it mean in real life? This means that loop body below will
+ * be compiled to sequence of loads immediately followed by stores
+ * as compiler assumes the worst, something in A==B+1 style. As a
+ * result CPU pipeline is going to starve for incoming data. Secondly
+ * if A and B happen to share same cache line such code is going to
+ * cause severe cache trashing. Both factors have severe impact on
+ * performance of modern CPUs and this is the reason why this
+ * particular piece of code is #ifdefed away and replaced by more
+ * "friendly" version found in #else section below. This comment
+ * also applies to BN_copy function.
+ *
+ *                                      <appro@fy.chalmers.se>
+ */
+                       for (i=b->top&(~7); i>0; i-=8)
+                               {
+                               A[0]=B[0]; A[1]=B[1]; A[2]=B[2]; A[3]=B[3];
+                               A[4]=B[4]; A[5]=B[5]; A[6]=B[6]; A[7]=B[7];
+                               A+=8;
+                               B+=8;
+                               }
+                       switch (b->top&7)
+                               {
+                       case 7:
+                               A[6]=B[6];
+                       case 6:
+                               A[5]=B[5];
+                       case 5:
+                               A[4]=B[4];
+                       case 4:
+                               A[3]=B[3];
+                       case 3:
+                               A[2]=B[2];
+                       case 2:
+                               A[1]=B[1];
+                       case 1:
+                               A[0]=B[0];
+                       case 0:
+                               /* I need the 'case 0' entry for utrix cc.
+                                * If the optimizer is turned on, it does the
+                                * switch table by doing
+                                * a=top&7
+                                * a--;
+                                * goto jump_table[a];
+                                * If top is 0, this makes us jump to 0xffffffc
+                                * which is rather bad :-(.
+                                * eric 23-Apr-1998
+                                */
+                               ;
+                               }
+#else
+                       for (i=b->top>>2; i>0; i--,A+=4,B+=4)
+                               {
+                               /*
+                                * The fact that the loop is unrolled
+                                * 4-wise is a tribute to Intel. It's
+                                * the one that doesn't have enough
+                                * registers to accomodate more data.
+                                * I'd unroll it 8-wise otherwise:-)
+                                *
+                                *              <appro@fy.chalmers.se>
+                                */
+                               BN_ULONG a0,a1,a2,a3;
+                               a0=B[0]; a1=B[1]; a2=B[2]; a3=B[3];
+                               A[0]=a0; A[1]=a1; A[2]=a2; A[3]=a3;
+                               }
+                       switch (b->top&3)
+                               {
+                               case 3: A[2]=B[2];
+                               case 2: A[1]=B[1];
+                               case 1: A[0]=B[0];
+                               case 0: ; /* ultrix cc workaround, see above */
+                               }
+#endif
+                       free(b->d);
+                       }
+
+               b->d=a;
+               b->dmax=words;
+
+               /* Now need to zero any data between b->top and b->max */
+
+               A= &(b->d[b->top]);
+               for (i=(b->dmax - b->top)>>3; i>0; i--,A+=8)
+                       {
+                       A[0]=0; A[1]=0; A[2]=0; A[3]=0;
+                       A[4]=0; A[5]=0; A[6]=0; A[7]=0;
+                       }
+               for (i=(b->dmax - b->top)&7; i>0; i--,A++)
+                       A[0]=0;
+#else
+                       memset(A,0,sizeof(BN_ULONG)*(words+1));
+                       memcpy(A,b->d,sizeof(b->d[0])*b->top);
+                       b->d=a;
+                       b->max=words;
+#endif
+
+/*              memset(&(p[b->max]),0,((words+1)-b->max)*sizeof(BN_ULONG)); */
+/*      { int i; for (i=b->max; i<words+1; i++) p[i]=i;} */
+
+               }
+       return(b);
+       }
+
+BIGNUM *BN_copy(BIGNUM *a, const BIGNUM *b)
+       {
+       int i;
+       BN_ULONG *A;
+       const BN_ULONG *B;
+
+       bn_check_top(b);
+
+       if (a == b) return(a);
+       if (bn_wexpand(a,b->top) == NULL) return(NULL);
+
+#if 1
+       A=a->d;
+       B=b->d;
+       for (i=b->top>>2; i>0; i--,A+=4,B+=4)
+               {
+               BN_ULONG a0,a1,a2,a3;
+               a0=B[0]; a1=B[1]; a2=B[2]; a3=B[3];
+               A[0]=a0; A[1]=a1; A[2]=a2; A[3]=a3;
+               }
+       switch (b->top&3)
+               {
+               case 3: A[2]=B[2];
+               case 2: A[1]=B[1];
+               case 1: A[0]=B[0];
+               case 0: ; /* ultrix cc workaround, see comments in bn_expand2 */
+               }
+#else
+       memcpy(a->d,b->d,sizeof(b->d[0])*b->top);
+#endif
+
+/*      memset(&(a->d[b->top]),0,sizeof(a->d[0])*(a->max-b->top));*/
+       a->top=b->top;
+       if ((a->top == 0) && (a->d != NULL))
+               a->d[0]=0;
+       a->neg=b->neg;
+       return(a);
+       }
+
+int BN_set_word(BIGNUM *a, BN_ULONG w)
+       {
+       int i,n;
+       if (bn_expand(a,sizeof(BN_ULONG)*8) == NULL) return(0);
+
+       n=sizeof(BN_ULONG)/BN_BYTES;
+       a->neg=0;
+       a->top=0;
+       a->d[0]=(BN_ULONG)w&BN_MASK2;
+       if (a->d[0] != 0) a->top=1;
+       for (i=1; i<n; i++)
+               {
+               /* the following is done instead of
+                * w>>=BN_BITS2 so compilers don't complain
+                * on builds where sizeof(long) == BN_TYPES */
+#ifndef SIXTY_FOUR_BIT /* the data item > unsigned long */
+               w>>=BN_BITS4;
+               w>>=BN_BITS4;
+#else
+               w=0;
+#endif
+               a->d[i]=(BN_ULONG)w&BN_MASK2;
+               if (a->d[i] != 0) a->top=i+1;
+               }
+       return(1);
+       }
+
+/* ignore negative */
+BIGNUM *BN_bin2bn(const unsigned char *s, int len, BIGNUM *ret)
+       {
+       unsigned int i,m;
+       unsigned int n;
+       BN_ULONG l;
+
+       if (ret == NULL) ret=BN_new();
+       if (ret == NULL) return(NULL);
+       l=0;
+       n=len;
+       if (n == 0)
+               {
+               ret->top=0;
+               return(ret);
+               }
+       if (bn_expand(ret,(int)(n+2)*8) == NULL)
+               return(NULL);
+       i=((n-1)/BN_BYTES)+1;
+       m=((n-1)%(BN_BYTES));
+       ret->top=i;
+       while (n-- > 0)
+               {
+               l=(l<<8L)| *(s++);
+               if (m-- == 0)
+                       {
+                       ret->d[--i]=l;
+                       l=0;
+                       m=BN_BYTES-1;
+                       }
+               }
+       /* need to call this due to clear byte at top if avoiding
+        * having the top bit set (-ve number) */
+       bn_fix_top(ret);
+       return(ret);
+       }
+
+/* ignore negative */
+int BN_bn2bin(const BIGNUM *a, unsigned char *to)
+       {
+       int n,i;
+       BN_ULONG l;
+
+       n=i=BN_num_bytes(a);
+       while (i-- > 0)
+               {
+               l=a->d[i/BN_BYTES];
+               *(to++)=(unsigned char)(l>>(8*(i%BN_BYTES)))&0xff;
+               }
+       return(n);
+       }
+
+int BN_ucmp(const BIGNUM *a, const BIGNUM *b)
+       {
+       int i;
+       BN_ULONG t1,t2,*ap,*bp;
+
+       bn_check_top(a);
+       bn_check_top(b);
+
+       i=a->top-b->top;
+       if (i != 0) return(i);
+       ap=a->d;
+       bp=b->d;
+       for (i=a->top-1; i>=0; i--)
+               {
+               t1= ap[i];
+               t2= bp[i];
+               if (t1 != t2)
+                       return(t1 > t2?1:-1);
+               }
+       return(0);
+       }
+
+int BN_cmp(const BIGNUM *a, const BIGNUM *b)
+       {
+       int i;
+       int gt,lt;
+       BN_ULONG t1,t2;
+
+       if ((a == NULL) || (b == NULL))
+               {
+               if (a != NULL)
+                       return(-1);
+               else if (b != NULL)
+                       return(1);
+               else
+                       return(0);
+               }
+
+       bn_check_top(a);
+       bn_check_top(b);
+
+       if (a->neg != b->neg)
+               {
+               if (a->neg)
+                       return(-1);
+               else    return(1);
+               }
+       if (a->neg == 0)
+               { gt=1; lt= -1; }
+       else    { gt= -1; lt=1; }
+
+       if (a->top > b->top) return(gt);
+       if (a->top < b->top) return(lt);
+       for (i=a->top-1; i>=0; i--)
+               {
+               t1=a->d[i];
+               t2=b->d[i];
+               if (t1 > t2) return(gt);
+               if (t1 < t2) return(lt);
+               }
+       return(0);
+       }
+
+int BN_is_bit_set(const BIGNUM *a, int n)
+       {
+       int i,j;
+
+       if (n < 0) return(0);
+       i=n/BN_BITS2;
+       j=n%BN_BITS2;
+       if (a->top <= i) return(0);
+       return((a->d[i]&(((BN_ULONG)1)<<j))?1:0);
+       }
diff --git a/package/ead/src/tinysrp/bn_mul.c b/package/ead/src/tinysrp/bn_mul.c
new file mode 100644 (file)
index 0000000..d2d9fc5
--- /dev/null
@@ -0,0 +1,176 @@
+/* crypto/bn/bn_mul.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``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.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include "bn_lcl.h"
+
+int BN_mul(BIGNUM *r, BIGNUM *a, BIGNUM *b, BN_CTX *ctx)
+       {
+       int top,al,bl;
+       BIGNUM *rr;
+       int ret = 0;
+#if defined(BN_MUL_COMBA) || defined(BN_RECURSION)
+       int i;
+#endif
+#ifdef BN_RECURSION
+       BIGNUM *t;
+       int j,k;
+#endif
+
+#ifdef BN_COUNT
+       printf("BN_mul %d * %d\n",a->top,b->top);
+#endif
+
+       bn_check_top(a);
+       bn_check_top(b);
+       bn_check_top(r);
+
+       al=a->top;
+       bl=b->top;
+
+       if ((al == 0) || (bl == 0))
+               {
+               BN_zero(r);
+               return(1);
+               }
+       top=al+bl;
+
+       BN_CTX_start(ctx);
+       if ((r == a) || (r == b))
+               {
+               if ((rr = BN_CTX_get(ctx)) == NULL) goto err;
+               }
+       else
+               rr = r;
+       rr->neg=a->neg^b->neg;
+
+#if defined(BN_MUL_COMBA) || defined(BN_RECURSION)
+       i = al-bl;
+#endif
+#ifdef BN_MUL_COMBA
+       if (i == 0)
+               {
+# if 0
+               if (al == 4)
+                       {
+                       if (bn_wexpand(rr,8) == NULL) goto err;
+                       rr->top=8;
+                       bn_mul_comba4(rr->d,a->d,b->d);
+                       goto end;
+                       }
+# endif
+               if (al == 8)
+                       {
+                       if (bn_wexpand(rr,16) == NULL) goto err;
+                       rr->top=16;
+                       bn_mul_comba8(rr->d,a->d,b->d);
+                       goto end;
+                       }
+               }
+#endif /* BN_MUL_COMBA */
+       if (bn_wexpand(rr,top) == NULL) goto err;
+       rr->top=top;
+       bn_mul_normal(rr->d,a->d,al,b->d,bl);
+
+#if defined(BN_MUL_COMBA) || defined(BN_RECURSION)
+end:
+#endif
+       bn_fix_top(rr);
+       if (r != rr) BN_copy(r,rr);
+       ret=1;
+err:
+       BN_CTX_end(ctx);
+       return(ret);
+       }
+
+void bn_mul_normal(BN_ULONG *r, BN_ULONG *a, int na, BN_ULONG *b, int nb)
+       {
+       BN_ULONG *rr;
+
+#ifdef BN_COUNT
+       printf(" bn_mul_normal %d * %d\n",na,nb);
+#endif
+
+       if (na < nb)
+               {
+               int itmp;
+               BN_ULONG *ltmp;
+
+               itmp=na; na=nb; nb=itmp;
+               ltmp=a;   a=b;   b=ltmp;
+
+               }
+       rr= &(r[na]);
+       rr[0]=bn_mul_words(r,a,na,b[0]);
+
+       for (;;)
+               {
+               if (--nb <= 0) return;
+               rr[1]=bn_mul_add_words(&(r[1]),a,na,b[1]);
+               if (--nb <= 0) return;
+               rr[2]=bn_mul_add_words(&(r[2]),a,na,b[2]);
+               if (--nb <= 0) return;
+               rr[3]=bn_mul_add_words(&(r[3]),a,na,b[3]);
+               if (--nb <= 0) return;
+               rr[4]=bn_mul_add_words(&(r[4]),a,na,b[4]);
+               rr+=4;
+               r+=4;
+               b+=4;
+               }
+       }
diff --git a/package/ead/src/tinysrp/bn_prime.h b/package/ead/src/tinysrp/bn_prime.h
new file mode 100644 (file)
index 0000000..b7cf9a9
--- /dev/null
@@ -0,0 +1,325 @@
+/* Auto generated by bn_prime.pl */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * 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 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. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``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.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef EIGHT_BIT
+#define NUMPRIMES 2048
+#else
+#define NUMPRIMES 54