add the 'ead' package (emergency access daemon), which can provide remote access...
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)
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
+#endif
+static const unsigned int primes[NUMPRIMES]=
+       {
+          2,   3,   5,   7,  11,  13,  17,  19,
+         23,  29,  31,  37,  41,  43,  47,  53,
+         59,  61,  67,  71,  73,  79,  83,  89,
+         97, 101, 103, 107, 109, 113, 127, 131,
+        137, 139, 149, 151, 157, 163, 167, 173,
+        179, 181, 191, 193, 197, 199, 211, 223,
+        227, 229, 233, 239, 241, 251,
+#ifndef EIGHT_BIT
+        257, 263,
+        269, 271, 277, 281, 283, 293, 307, 311,
+        313, 317, 331, 337, 347, 349, 353, 359,
+        367, 373, 379, 383, 389, 397, 401, 409,
+        419, 421, 431, 433, 439, 443, 449, 457,
+        461, 463, 467, 479, 487, 491, 499, 503,
+        509, 521, 523, 541, 547, 557, 563, 569,
+        571, 577, 587, 593, 599, 601, 607, 613,
+        617, 619, 631, 641, 643, 647, 653, 659,
+        661, 673, 677, 683, 691, 701, 709, 719,
+        727, 733, 739, 743, 751, 757, 761, 769,
+        773, 787, 797, 809, 811, 821, 823, 827,
+        829, 839, 853, 857, 859, 863, 877, 881,
+        883, 887, 907, 911, 919, 929, 937, 941,
+        947, 953, 967, 971, 977, 983, 991, 997,
+       1009,1013,1019,1021,1031,1033,1039,1049,
+       1051,1061,1063,1069,1087,1091,1093,1097,
+       1103,1109,1117,1123,1129,1151,1153,1163,
+       1171,1181,1187,1193,1201,1213,1217,1223,
+       1229,1231,1237,1249,1259,1277,1279,1283,
+       1289,1291,1297,1301,1303,1307,1319,1321,
+       1327,1361,1367,1373,1381,1399,1409,1423,
+       1427,1429,1433,1439,1447,1451,1453,1459,
+       1471,1481,1483,1487,1489,1493,1499,1511,
+       1523,1531,1543,1549,1553,1559,1567,1571,
+       1579,1583,1597,1601,1607,1609,1613,1619,
+       1621,1627,1637,1657,1663,1667,1669,1693,
+       1697,1699,1709,1721,1723,1733,1741,1747,
+       1753,1759,1777,1783,1787,1789,1801,1811,
+       1823,1831,1847,1861,1867,1871,1873,1877,
+       1879,1889,1901,1907,1913,1931,1933,1949,
+       1951,1973,1979,1987,1993,1997,1999,2003,
+       2011,2017,2027,2029,2039,2053,2063,2069,
+       2081,2083,2087,2089,2099,2111,2113,2129,
+       2131,2137,2141,2143,2153,2161,2179,2203,
+       2207,2213,2221,2237,2239,2243,2251,2267,
+       2269,2273,2281,2287,2293,2297,2309,2311,
+       2333,2339,2341,2347,2351,2357,2371,2377,
+       2381,2383,2389,2393,2399,2411,2417,2423,
+       2437,2441,2447,2459,2467,2473,2477,2503,
+       2521,2531,2539,2543,2549,2551,2557,2579,
+       2591,2593,2609,2617,2621,2633,2647,2657,
+       2659,2663,2671,2677,2683,2687,2689,2693,
+       2699,2707,2711,2713,2719,2729,2731,2741,
+       2749,2753,2767,2777,2789,2791,2797,2801,
+       2803,2819,2833,2837,2843,2851,2857,2861,
+       2879,2887,2897,2903,2909,2917,2927,2939,
+       2953,2957,2963,2969,2971,2999,3001,3011,
+       3019,3023,3037,3041,3049,3061,3067,3079,
+       3083,3089,3109,3119,3121,3137,3163,3167,
+       3169,3181,3187,3191,3203,3209,3217,3221,
+       3229,3251,3253,3257,3259,3271,3299,3301,
+       3307,3313,3319,3323,3329,3331,3343,3347,
+       3359,3361,3371,3373,3389,3391,3407,3413,
+       3433,3449,3457,3461,3463,3467,3469,3491,
+       3499,3511,3517,3527,3529,3533,3539,3541,
+       3547,3557,3559,3571,3581,3583,3593,3607,
+       3613,3617,3623,3631,3637,3643,3659,3671,
+       3673,3677,3691,3697,3701,3709,3719,3727,
+       3733,3739,3761,3767,3769,3779,3793,3797,
+       3803,3821,3823,3833,3847,3851,3853,3863,
+       3877,3881,3889,3907,3911,3917,3919,3923,
+       3929,3931,3943,3947,3967,3989,4001,4003,
+       4007,4013,4019,4021,4027,4049,4051,4057,
+       4073,4079,4091,4093,4099,4111,4127,4129,
+       4133,4139,4153,4157,4159,4177,4201,4211,
+       4217,4219,4229,4231,4241,4243,4253,4259,
+       4261,4271,4273,4283,4289,4297,4327,4337,
+       4339,4349,4357,4363,4373,4391,4397,4409,
+       4421,4423,4441,4447,4451,4457,4463,4481,
+       4483,4493,4507,4513,4517,4519,4523,4547,
+       4549,4561,4567,4583,4591,4597,4603,4621,
+       4637,4639,4643,4649,4651,4657,4663,4673,
+       4679,4691,4703,4721,4723,4729,4733,4751,
+       4759,4783,4787,4789,4793,4799,4801,4813,
+       4817,4831,4861,4871,4877,4889,4903,4909,
+       4919,4931,4933,4937,4943,4951,4957,4967,
+       4969,4973,4987,4993,4999,5003,5009,5011,
+       5021,5023,5039,5051,5059,5077,5081,5087,
+       5099,5101,5107,5113,5119,5147,5153,5167,
+       5171,5179,5189,5197,5209,5227,5231,5233,
+       5237,5261,5273,5279,5281,5297,5303,5309,
+       5323,5333,5347,5351,5381,5387,5393,5399,
+       5407,5413,5417,5419,5431,5437,5441,5443,
+       5449,5471,5477,5479,5483,5501,5503,5507,
+       5519,5521,5527,5531,5557,5563,5569,5573,
+       5581,5591,5623,5639,5641,5647,5651,5653,
+       5657,5659,5669,5683,5689,5693,5701,5711,
+       5717,5737,5741,5743,5749,5779,5783,5791,
+       5801,5807,5813,5821,5827,5839,5843,5849,
+       5851,5857,5861,5867,5869,5879,5881,5897,
+       5903,5923,5927,5939,5953,5981,5987,6007,
+       6011,6029,6037,6043,6047,6053,6067,6073,
+       6079,6089,6091,6101,6113,6121,6131,6133,
+       6143,6151,6163,6173,6197,6199,6203,6211,
+       6217,6221,6229,6247,6257,6263,6269,6271,
+       6277,6287,6299,6301,6311,6317,6323,6329,
+       6337,6343,6353,6359,6361,6367,6373,6379,
+       6389,6397,6421,6427,6449,6451,6469,6473,
+       6481,6491,6521,6529,6547,6551,6553,6563,
+       6569,6571,6577,6581,6599,6607,6619,6637,
+       6653,6659,6661,6673,6679,6689,6691,6701,
+       6703,6709,6719,6733,6737,6761,6763,6779,
+       6781,6791,6793,6803,6823,6827,6829,6833,
+       6841,6857,6863,6869,6871,6883,6899,6907,
+       6911,6917,6947,6949,6959,6961,6967,6971,
+       6977,6983,6991,6997,7001,7013,7019,7027,
+       7039,7043,7057,7069,7079,7103,7109,7121,
+       7127,7129,7151,7159,7177,7187,7193,7207,
+       7211,7213,7219,7229,7237,7243,7247,7253,
+       7283,7297,7307,7309,7321,7331,7333,7349,
+       7351,7369,7393,7411,7417,7433,7451,7457,
+       7459,7477,7481,7487,7489,7499,7507,7517,
+       7523,7529,7537,7541,7547,7549,7559,7561,
+       7573,7577,7583,7589,7591,7603,7607,7621,
+       7639,7643,7649,7669,7673,7681,7687,7691,
+       7699,7703,7717,7723,7727,7741,7753,7757,
+       7759,7789,7793,7817,7823,7829,7841,7853,
+       7867,7873,7877,7879,7883,7901,7907,7919,
+       7927,7933,7937,7949,7951,7963,7993,8009,
+       8011,8017,8039,8053,8059,8069,8081,8087,
+       8089,8093,8101,8111,8117,8123,8147,8161,
+       8167,8171,8179,8191,8209,8219,8221,8231,
+       8233,8237,8243,8263,8269,8273,8287,8291,
+       8293,8297,8311,8317,8329,8353,8363,8369,
+       8377,8387,8389,8419,8423,8429,8431,8443,
+       8447,8461,8467,8501,8513,8521,8527,8537,
+       8539,8543,8563,8573,8581,8597,8599,8609,
+       8623,8627,8629,8641,8647,8663,8669,8677,
+       8681,8689,8693,8699,8707,8713,8719,8731,
+       8737,8741,8747,8753,8761,8779,8783,8803,
+       8807,8819,8821,8831,8837,8839,8849,8861,
+       8863,8867,8887,8893,8923,8929,8933,8941,
+       8951,8963,8969,8971,8999,9001,9007,9011,
+       9013,9029,9041,9043,9049,9059,9067,9091,
+       9103,9109,9127,9133,9137,9151,9157,9161,
+       9173,9181,9187,9199,9203,9209,9221,9227,
+       9239,9241,9257,9277,9281,9283,9293,9311,
+       9319,9323,9337,9341,9343,9349,9371,9377,
+       9391,9397,9403,9413,9419,9421,9431,9433,
+       9437,9439,9461,9463,9467,9473,9479,9491,
+       9497,9511,9521,9533,9539,9547,9551,9587,
+       9601,9613,9619,9623,9629,9631,9643,9649,
+       9661,9677,9679,9689,9697,9719,9721,9733,
+       9739,9743,9749,9767,9769,9781,9787,9791,
+       9803,9811,9817,9829,9833,9839,9851,9857,
+       9859,9871,9883,9887,9901,9907,9923,9929,
+       9931,9941,9949,9967,9973,10007,10009,10037,
+       10039,10061,10067,10069,10079,10091,10093,10099,
+       10103,10111,10133,10139,10141,10151,10159,10163,
+       10169,10177,10181,10193,10211,10223,10243,10247,
+       10253,10259,10267,10271,10273,10289,10301,10303,
+       10313,10321,10331,10333,10337,10343,10357,10369,
+       10391,10399,10427,10429,10433,10453,10457,10459,
+       10463,10477,10487,10499,10501,10513,10529,10531,
+       10559,10567,10589,10597,10601,10607,10613,10627,
+       10631,10639,10651,10657,10663,10667,10687,10691,
+       10709,10711,10723,10729,10733,10739,10753,10771,
+       10781,10789,10799,10831,10837,10847,10853,10859,
+       10861,10867,10883,10889,10891,10903,10909,10937,
+       10939,10949,10957,10973,10979,10987,10993,11003,
+       11027,11047,11057,11059,11069,11071,11083,11087,
+       11093,11113,11117,11119,11131,11149,11159,11161,
+       11171,11173,11177,11197,11213,11239,11243,11251,
+       11257,11261,11273,11279,11287,11299,11311,11317,
+       11321,11329,11351,11353,11369,11383,11393,11399,
+       11411,11423,11437,11443,11447,11467,11471,11483,
+       11489,11491,11497,11503,11519,11527,11549,11551,
+       11579,11587,11593,11597,11617,11621,11633,11657,
+       11677,11681,11689,11699,11701,11717,11719,11731,
+       11743,11777,11779,11783,11789,11801,11807,11813,
+       11821,11827,11831,11833,11839,11863,11867,11887,
+       11897,11903,11909,11923,11927,11933,11939,11941,
+       11953,11959,11969,11971,11981,11987,12007,12011,
+       12037,12041,12043,12049,12071,12073,12097,12101,
+       12107,12109,12113,12119,12143,12149,12157,12161,
+       12163,12197,12203,12211,12227,12239,12241,12251,
+       12253,12263,12269,12277,12281,12289,12301,12323,
+       12329,12343,12347,12373,12377,12379,12391,12401,
+       12409,12413,12421,12433,12437,12451,12457,12473,
+       12479,12487,12491,12497,12503,12511,12517,12527,
+       12539,12541,12547,12553,12569,12577,12583,12589,
+       12601,12611,12613,12619,12637,12641,12647,12653,
+       12659,12671,12689,12697,12703,12713,12721,12739,
+       12743,12757,12763,12781,12791,12799,12809,12821,
+       12823,12829,12841,12853,12889,12893,12899,12907,
+       12911,12917,12919,12923,12941,12953,12959,12967,
+       12973,12979,12983,13001,13003,13007,13009,13033,
+       13037,13043,13049,13063,13093,13099,13103,13109,
+       13121,13127,13147,13151,13159,13163,13171,13177,
+       13183,13187,13217,13219,13229,13241,13249,13259,
+       13267,13291,13297,13309,13313,13327,13331,13337,
+       13339,13367,13381,13397,13399,13411,13417,13421,
+       13441,13451,13457,13463,13469,13477,13487,13499,
+       13513,13523,13537,13553,13567,13577,13591,13597,
+       13613,13619,13627,13633,13649,13669,13679,13681,
+       13687,13691,13693,13697,13709,13711,13721,13723,
+       13729,13751,13757,13759,13763,13781,13789,13799,
+       13807,13829,13831,13841,13859,13873,13877,13879,
+       13883,13901,13903,13907,13913,13921,13931,13933,
+       13963,13967,13997,13999,14009,14011,14029,14033,
+       14051,14057,14071,14081,14083,14087,14107,14143,
+       14149,14153,14159,14173,14177,14197,14207,14221,
+       14243,14249,14251,14281,14293,14303,14321,14323,
+       14327,14341,14347,14369,14387,14389,14401,14407,
+       14411,14419,14423,14431,14437,14447,14449,14461,
+       14479,14489,14503,14519,14533,14537,14543,14549,
+       14551,14557,14561,14563,14591,14593,14621,14627,
+       14629,14633,14639,14653,14657,14669,14683,14699,
+       14713,14717,14723,14731,14737,14741,14747,14753,
+       14759,14767,14771,14779,14783,14797,14813,14821,
+       14827,14831,14843,14851,14867,14869,14879,14887,
+       14891,14897,14923,14929,14939,14947,14951,14957,
+       14969,14983,15013,15017,15031,15053,15061,15073,
+       15077,15083,15091,15101,15107,15121,15131,15137,
+       15139,15149,15161,15173,15187,15193,15199,15217,
+       15227,15233,15241,15259,15263,15269,15271,15277,
+       15287,15289,15299,15307,15313,15319,15329,15331,
+       15349,15359,15361,15373,15377,15383,15391,15401,
+       15413,15427,15439,15443,15451,15461,15467,15473,
+       15493,15497,15511,15527,15541,15551,15559,15569,
+       15581,15583,15601,15607,15619,15629,15641,15643,
+       15647,15649,15661,15667,15671,15679,15683,15727,
+       15731,15733,15737,15739,15749,15761,15767,15773,
+       15787,15791,15797,15803,15809,15817,15823,15859,
+       15877,15881,15887,15889,15901,15907,15913,15919,
+       15923,15937,15959,15971,15973,15991,16001,16007,
+       16033,16057,16061,16063,16067,16069,16073,16087,
+       16091,16097,16103,16111,16127,16139,16141,16183,
+       16187,16189,16193,16217,16223,16229,16231,16249,
+       16253,16267,16273,16301,16319,16333,16339,16349,
+       16361,16363,16369,16381,16411,16417,16421,16427,
+       16433,16447,16451,16453,16477,16481,16487,16493,
+       16519,16529,16547,16553,16561,16567,16573,16603,
+       16607,16619,16631,16633,16649,16651,16657,16661,
+       16673,16691,16693,16699,16703,16729,16741,16747,
+       16759,16763,16787,16811,16823,16829,16831,16843,
+       16871,16879,16883,16889,16901,16903,16921,16927,
+       16931,16937,16943,16963,16979,16981,16987,16993,
+       17011,17021,17027,17029,17033,17041,17047,17053,
+       17077,17093,17099,17107,17117,17123,17137,17159,
+       17167,17183,17189,17191,17203,17207,17209,17231,
+       17239,17257,17291,17293,17299,17317,17321,17327,
+       17333,17341,17351,17359,17377,17383,17387,17389,
+       17393,17401,17417,17419,17431,17443,17449,17467,
+       17471,17477,17483,17489,17491,17497,17509,17519,
+       17539,17551,17569,17573,17579,17581,17597,17599,
+       17609,17623,17627,17657,17659,17669,17681,17683,
+       17707,17713,17729,17737,17747,17749,17761,17783,
+       17789,17791,17807,17827,17837,17839,17851,17863,
+#endif
+       };
diff --git a/package/ead/src/tinysrp/bn_shift.c b/package/ead/src/tinysrp/bn_shift.c
new file mode 100644 (file)
index 0000000..f403720
--- /dev/null
@@ -0,0 +1,139 @@
+/* crypto/bn/bn_shift.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_lshift(BIGNUM *r, const BIGNUM *a, int n)
+       {
+       int i,nw,lb,rb;
+       BN_ULONG *t,*f;
+       BN_ULONG l;
+
+       r->neg=a->neg;
+       if (bn_wexpand(r,a->top+(n/BN_BITS2)+1) == NULL) return(0);
+       nw=n/BN_BITS2;
+       lb=n%BN_BITS2;
+       rb=BN_BITS2-lb;
+       f=a->d;
+       t=r->d;
+       t[a->top+nw]=0;
+       if (lb == 0)
+               for (i=a->top-1; i>=0; i--)
+                       t[nw+i]=f[i];
+       else
+               for (i=a->top-1; i>=0; i--)
+                       {
+                       l=f[i];
+                       t[nw+i+1]|=(l>>rb)&BN_MASK2;
+                       t[nw+i]=(l<<lb)&BN_MASK2;
+                       }
+       memset(t,0,nw*sizeof(t[0]));
+/*      for (i=0; i<nw; i++)
+               t[i]=0;*/
+       r->top=a->top+nw+1;
+       bn_fix_top(r);
+       return(1);
+       }
+
+int BN_rshift(BIGNUM *r, BIGNUM *a, int n)
+       {
+       int i,j,nw,lb,rb;
+       BN_ULONG *t,*f;
+       BN_ULONG l,tmp;
+
+       nw=n/BN_BITS2;
+       rb=n%BN_BITS2;
+       lb=BN_BITS2-rb;
+       if (nw > a->top || a->top == 0)
+               {
+               BN_zero(r);
+               return(1);
+               }
+       if (r != a)
+               {
+               r->neg=a->neg;
+               if (bn_wexpand(r,a->top-nw+1) == NULL) return(0);
+               }
+
+       f= &(a->d[nw]);
+       t=r->d;
+       j=a->top-nw;
+       r->top=j;
+
+       if (rb == 0)
+               {
+               for (i=j+1; i > 0; i--)
+                       *(t++)= *(f++);
+               }
+       else
+               {
+               l= *(f++);
+               for (i=1; i<j; i++)
+                       {
+                       tmp =(l>>rb)&BN_MASK2;
+                       l= *(f++);
+                       *(t++) =(tmp|(l<<lb))&BN_MASK2;
+                       }
+               *(t++) =(l>>rb)&BN_MASK2;
+               }
+       *t=0;
+       bn_fix_top(r);
+       return(1);
+       }
diff --git a/package/ead/src/tinysrp/bn_sqr.c b/package/ead/src/tinysrp/bn_sqr.c
new file mode 100644 (file)
index 0000000..2d3db70
--- /dev/null
@@ -0,0 +1,160 @@
+/* crypto/bn/bn_sqr.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"
+
+/* r must not be a */
+/* I've just gone over this and it is now %20 faster on x86 - eay - 27 Jun 96 */
+int BN_sqr(BIGNUM *r, BIGNUM *a, BN_CTX *ctx)
+       {
+       int max,al;
+       int ret = 0;
+       BIGNUM *tmp,*rr;
+
+#ifdef BN_COUNT
+printf("BN_sqr %d * %d\n",a->top,a->top);
+#endif
+       bn_check_top(a);
+
+       al=a->top;
+       if (al <= 0)
+               {
+               r->top=0;
+               return(1);
+               }
+
+       BN_CTX_start(ctx);
+       rr=(a != r) ? r : BN_CTX_get(ctx);
+       tmp=BN_CTX_get(ctx);
+       if (tmp == NULL) goto err;
+
+       max=(al+al);
+       if (bn_wexpand(rr,max+1) == NULL) goto err;
+
+       r->neg=0;
+       if (al == 4)
+               {
+#ifndef BN_SQR_COMBA
+               BN_ULONG t[8];
+               bn_sqr_normal(rr->d,a->d,4,t);
+#else
+               bn_sqr_comba4(rr->d,a->d);
+#endif
+               }
+       else if (al == 8)
+               {
+#ifndef BN_SQR_COMBA
+               BN_ULONG t[16];
+               bn_sqr_normal(rr->d,a->d,8,t);
+#else
+               bn_sqr_comba8(rr->d,a->d);
+#endif
+               }
+       else
+               {
+               if (bn_wexpand(tmp,max) == NULL) goto err;
+               bn_sqr_normal(rr->d,a->d,al,tmp->d);
+               }
+
+       rr->top=max;
+       if ((max > 0) && (rr->d[max-1] == 0)) rr->top--;
+       if (rr != r) BN_copy(r,rr);
+       ret = 1;
+ err:
+       BN_CTX_end(ctx);
+       return(ret);
+       }
+
+/* tmp must have 2*n words */
+void bn_sqr_normal(BN_ULONG *r, BN_ULONG *a, int n, BN_ULONG *tmp)
+       {
+       int i,j,max;
+       BN_ULONG *ap,*rp;
+
+       max=n*2;
+       ap=a;
+       rp=r;
+       rp[0]=rp[max-1]=0;
+       rp++;
+       j=n;
+
+       if (--j > 0)
+               {
+               ap++;
+               rp[j]=bn_mul_words(rp,ap,j,ap[-1]);
+               rp+=2;
+               }
+
+       for (i=n-2; i>0; i--)
+               {
+               j--;
+               ap++;
+               rp[j]=bn_mul_add_words(rp,ap,j,ap[-1]);
+               rp+=2;
+               }
+
+       bn_add_words(r,r,r,max);
+
+       /* There will not be a carry */
+
+       bn_sqr_words(tmp,a,n);
+
+       bn_add_words(r,r,tmp,max);
+       }
diff --git a/package/ead/src/tinysrp/bn_word.c b/package/ead/src/tinysrp/bn_word.c
new file mode 100644 (file)
index 0000000..7820e08
--- /dev/null
@@ -0,0 +1,130 @@
+/* crypto/bn/bn_word.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"
+
+int BN_add_word(BIGNUM *a, BN_ULONG w)
+       {
+       BN_ULONG l;
+       int i;
+
+       if (a->neg)
+               {
+               a->neg=0;
+               i=BN_sub_word(a,w);
+               if (!BN_is_zero(a))
+                       a->neg=!(a->neg);
+               return(i);
+               }
+       w&=BN_MASK2;
+       if (bn_wexpand(a,a->top+1) == NULL) return(0);
+       i=0;
+       for (;;)
+               {
+               l=(a->d[i]+(BN_ULONG)w)&BN_MASK2;
+               a->d[i]=l;
+               if (w > l)
+                       w=1;
+               else
+                       break;
+               i++;
+               }
+       if (i >= a->top)
+               a->top++;
+       return(1);
+       }
+
+int BN_sub_word(BIGNUM *a, BN_ULONG w)
+       {
+       int i;
+
+       if (BN_is_zero(a) || a->neg)
+               {
+               a->neg=0;
+               i=BN_add_word(a,w);
+               a->neg=1;
+               return(i);
+               }
+
+       w&=BN_MASK2;
+       if ((a->top == 1) && (a->d[0] < w))
+               {
+               a->d[0]=w-a->d[0];
+               a->neg=1;
+               return(1);
+               }
+       i=0;
+       for (;;)
+               {
+               if (a->d[i] >= w)
+                       {
+                       a->d[i]-=w;
+                       break;
+                       }
+               else
+                       {
+                       a->d[i]=(a->d[i]-w)&BN_MASK2;
+                       i++;
+                       w=1;
+                       }
+               }
+       if ((a->d[i] == 0) && (i == (a->top-1)))
+               a->top--;
+       return(1);
+       }
diff --git a/package/ead/src/tinysrp/clitest.c b/package/ead/src/tinysrp/clitest.c
new file mode 100644 (file)
index 0000000..faaa5dd
--- /dev/null
@@ -0,0 +1,112 @@
+/*
+ * Copyright (c) 1997-1999  The Stanford SRP Authentication Project
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL STANFORD BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF
+ * THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * In addition, the following conditions apply:
+ *
+ * 1. Any software that incorporates the SRP authentication technology
+ *    must display the following acknowlegment:
+ *    "This product uses the 'Secure Remote Password' cryptographic
+ *     authentication system developed by Tom Wu (tjw@CS.Stanford.EDU)."
+ *
+ * 2. Any software that incorporates all or part of the SRP distribution
+ *    itself must also display the following acknowledgment:
+ *    "This product includes software developed by Tom Wu and Eugene
+ *     Jhong for the SRP Distribution (http://srp.stanford.edu/srp/)."
+ *
+ * 3. Redistributions in source or binary form must retain an intact copy
+ *    of this copyright notice and list of conditions.
+ */
+
+#include <stdio.h>
+#include "t_defines.h"
+#include "t_pwd.h"
+#include "t_client.h"
+
+int
+main()
+{
+  int index;
+  struct t_client * tc;
+  struct t_preconf *tcp;
+  struct t_num n;
+  struct t_num g;
+  struct t_num s;
+  struct t_num B;
+  char username[MAXUSERLEN];
+  char hexbuf[MAXHEXPARAMLEN];
+  char buf1[MAXPARAMLEN], buf2[MAXPARAMLEN], buf3[MAXSALTLEN];
+  unsigned char cbuf[20];
+  struct t_num * A;
+  unsigned char * skey;
+  char pass[128];
+
+  printf("Enter username: ");
+  fgets(username, sizeof(username), stdin);
+  username[strlen(username) - 1] = '\0';
+  printf("Enter index (from server): ");
+  fgets(hexbuf, sizeof(hexbuf), stdin);
+  index = atoi(hexbuf);
+  tcp = t_getpreparam(index - 1);
+  printf("Enter salt (from server): ");
+  fgets(hexbuf, sizeof(hexbuf), stdin);
+  s.data = buf3;
+  s.len = t_fromb64(s.data, hexbuf);
+
+  tc = t_clientopen(username, &tcp->modulus, &tcp->generator, &s);
+  if (tc == 0) {
+    printf("invalid n, g\n");
+    exit(1);
+  }
+
+  A = t_clientgenexp(tc);
+  printf("A (to server): %s\n", t_tob64(hexbuf, A->data, A->len));
+
+  t_getpass(pass, 128, "Enter password:");
+  t_clientpasswd(tc, pass);
+
+  printf("Enter B (from server): ");
+  fgets(hexbuf, sizeof(hexbuf), stdin);
+  B.data = buf1;
+  B.len = t_fromb64(B.data, hexbuf);
+
+  skey = t_clientgetkey(tc, &B);
+  printf("Session key: %s\n", t_tohex(hexbuf, skey, 40));
+  printf("Response (to server): %s\n",
+    t_tohex(hexbuf, t_clientresponse(tc), RESPONSE_LEN));
+
+  printf("Enter server response: ");
+  fgets(hexbuf, sizeof(hexbuf), stdin);
+  hexbuf[strlen(hexbuf) - 1] = '\0';
+  t_fromhex(cbuf, hexbuf);
+
+  if (t_clientverify(tc, cbuf) == 0)
+    printf("Server authentication successful.\n");
+  else
+    printf("Server authentication failed.\n");
+
+  t_clientclose(tc);
+
+  return 0;
+}
diff --git a/package/ead/src/tinysrp/config.h.in b/package/ead/src/tinysrp/config.h.in
new file mode 100644 (file)
index 0000000..a4b50c7
--- /dev/null
@@ -0,0 +1,79 @@
+/* config.h.in.  Generated automatically from configure.in by autoheader.  */
+
+/* Define if type char is unsigned and you are not using gcc.  */
+#ifndef __CHAR_UNSIGNED__
+#undef __CHAR_UNSIGNED__
+#endif
+
+/* Define to empty if the keyword does not work.  */
+#undef const
+
+/* Define as __inline if that's what the C compiler calls it.  */
+#undef inline
+
+/* Define as the return type of signal handlers (int or void).  */
+#undef RETSIGTYPE
+
+/* Define if you have the ANSI C header files.  */
+#undef STDC_HEADERS
+
+/* Define if you can safely include both <sys/time.h> and <time.h>.  */
+#undef TIME_WITH_SYS_TIME
+
+/* Define if your processor stores words with the most significant
+   byte first (like Motorola and SPARC, unlike Intel and VAX).  */
+#undef WORDS_BIGENDIAN
+
+#undef SHA1HANDSOFF
+
+#undef POSIX_TERMIOS
+
+#undef POSIX_SIGTYPE
+
+#undef volatile
+
+/* The number of bytes in a int.  */
+#undef SIZEOF_INT
+
+/* The number of bytes in a long.  */
+#undef SIZEOF_LONG
+
+/* The number of bytes in a long long.  */
+#undef SIZEOF_LONG_LONG
+
+/* The number of bytes in a short.  */
+#undef SIZEOF_SHORT
+
+/* Define if you have the memcpy function.  */
+#undef HAVE_MEMCPY
+
+/* Define if you have the sigaction function.  */
+#undef HAVE_SIGACTION
+
+/* Define if you have the strchr function.  */
+#undef HAVE_STRCHR
+
+/* Define if you have the <sgtty.h> header file.  */
+#undef HAVE_SGTTY_H
+
+/* Define if you have the <sys/ioctl.h> header file.  */
+#undef HAVE_SYS_IOCTL_H
+
+/* Define if you have the <sys/time.h> header file.  */
+#undef HAVE_SYS_TIME_H
+
+/* Define if you have the <termio.h> header file.  */
+#undef HAVE_TERMIO_H
+
+/* Define if you have the <termios.h> header file.  */
+#undef HAVE_TERMIOS_H
+
+/* Define if you have the <unistd.h> header file.  */
+#undef HAVE_UNISTD_H
+
+/* Name of package */
+#undef PACKAGE
+
+/* Version number of package */
+#undef VERSION
+
diff --git a/package/ead/src/tinysrp/configure b/package/ead/src/tinysrp/configure
new file mode 100755 (executable)
index 0000000..6ee76bf
--- /dev/null
@@ -0,0 +1,2421 @@
+#! /bin/sh
+
+# Guess values for system-dependent variables and create Makefiles.
+# Generated automatically using autoconf version 2.13 
+# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc.
+#
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+
+# Defaults:
+ac_help=
+ac_default_prefix=/usr/local
+# Any additions from configure.in:
+
+# Initialize some variables set by options.
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+build=NONE
+cache_file=./config.cache
+exec_prefix=NONE
+host=NONE
+no_create=
+nonopt=NONE
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+target=NONE
+verbose=
+x_includes=NONE
+x_libraries=NONE
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datadir='${prefix}/share'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+libdir='${exec_prefix}/lib'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+infodir='${prefix}/info'
+mandir='${prefix}/man'
+
+# Initialize some other variables.
+subdirs=
+MFLAGS= MAKEFLAGS=
+SHELL=${CONFIG_SHELL-/bin/sh}
+# Maximum number of lines to put in a shell here document.
+ac_max_here_lines=12
+
+ac_prev=
+for ac_option
+do
+
+  # If the previous option needs an argument, assign it.
+  if test -n "$ac_prev"; then
+    eval "$ac_prev=\$ac_option"
+    ac_prev=
+    continue
+  fi
+
+  case "$ac_option" in
+  -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
+  *) ac_optarg= ;;
+  esac
+
+  # Accept the important Cygnus configure options, so we can diagnose typos.
+
+  case "$ac_option" in
+
+  -bindir | --bindir | --bindi | --bind | --bin | --bi)
+    ac_prev=bindir ;;
+  -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
+    bindir="$ac_optarg" ;;
+
+  -build | --build | --buil | --bui | --bu)
+    ac_prev=build ;;
+  -build=* | --build=* | --buil=* | --bui=* | --bu=*)
+    build="$ac_optarg" ;;
+
+  -cache-file | --cache-file | --cache-fil | --cache-fi \
+  | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+    ac_prev=cache_file ;;
+  -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+  | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+    cache_file="$ac_optarg" ;;
+
+  -datadir | --datadir | --datadi | --datad | --data | --dat | --da)
+    ac_prev=datadir ;;
+  -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \
+  | --da=*)
+    datadir="$ac_optarg" ;;
+
+  -disable-* | --disable-*)
+    ac_feature=`echo $ac_option|sed -e 's/-*disable-//'`
+    # Reject names that are not valid shell variable names.
+    if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then
+      { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+    fi
+    ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+    eval "enable_${ac_feature}=no" ;;
+
+  -enable-* | --enable-*)
+    ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'`
+    # Reject names that are not valid shell variable names.
+    if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then
+      { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+    fi
+    ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+    case "$ac_option" in
+      *=*) ;;
+      *) ac_optarg=yes ;;
+    esac
+    eval "enable_${ac_feature}='$ac_optarg'" ;;
+
+  -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+  | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+  | --exec | --exe | --ex)
+    ac_prev=exec_prefix ;;
+  -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+  | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+  | --exec=* | --exe=* | --ex=*)
+    exec_prefix="$ac_optarg" ;;
+
+  -gas | --gas | --ga | --g)
+    # Obsolete; use --with-gas.
+    with_gas=yes ;;
+
+  -help | --help | --hel | --he)
+    # Omit some internal or obsolete options to make the list less imposing.
+    # This message is too long to be a string in the A/UX 3.1 sh.
+    cat << EOF
+Usage: configure [options] [host]
+Options: [defaults in brackets after descriptions]
+Configuration:
+  --cache-file=FILE       cache test results in FILE
+  --help                  print this message
+  --no-create             do not create output files
+  --quiet, --silent       do not print \`checking...' messages
+  --version               print the version of autoconf that created configure
+Directory and file names:
+  --prefix=PREFIX         install architecture-independent files in PREFIX
+                          [$ac_default_prefix]
+  --exec-prefix=EPREFIX   install architecture-dependent files in EPREFIX
+                          [same as prefix]
+  --bindir=DIR            user executables in DIR [EPREFIX/bin]
+  --sbindir=DIR           system admin executables in DIR [EPREFIX/sbin]
+  --libexecdir=DIR        program executables in DIR [EPREFIX/libexec]
+  --datadir=DIR           read-only architecture-independent data in DIR
+                          [PREFIX/share]
+  --sysconfdir=DIR        read-only single-machine data in DIR [PREFIX/etc]
+  --sharedstatedir=DIR    modifiable architecture-independent data in DIR
+                          [PREFIX/com]
+  --localstatedir=DIR     modifiable single-machine data in DIR [PREFIX/var]
+  --libdir=DIR            object code libraries in DIR [EPREFIX/lib]
+  --includedir=DIR        C header files in DIR [PREFIX/include]
+  --oldincludedir=DIR     C header files for non-gcc in DIR [/usr/include]
+  --infodir=DIR           info documentation in DIR [PREFIX/info]
+  --mandir=DIR            man documentation in DIR [PREFIX/man]
+  --srcdir=DIR            find the sources in DIR [configure dir or ..]
+  --program-prefix=PREFIX prepend PREFIX to installed program names
+  --program-suffix=SUFFIX append SUFFIX to installed program names
+  --program-transform-name=PROGRAM
+                          run sed PROGRAM on installed program names
+EOF
+    cat << EOF
+Host type:
+  --build=BUILD           configure for building on BUILD [BUILD=HOST]
+  --host=HOST             configure for HOST [guessed]
+  --target=TARGET         configure for TARGET [TARGET=HOST]
+Features and packages:
+  --disable-FEATURE       do not include FEATURE (same as --enable-FEATURE=no)
+  --enable-FEATURE[=ARG]  include FEATURE [ARG=yes]
+  --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
+  --without-PACKAGE       do not use PACKAGE (same as --with-PACKAGE=no)
+  --x-includes=DIR        X include files are in DIR
+  --x-libraries=DIR       X library files are in DIR
+EOF
+    if test -n "$ac_help"; then
+      echo "--enable and --with options recognized:$ac_help"
+    fi
+    exit 0 ;;
+
+  -host | --host | --hos | --ho)
+    ac_prev=host ;;
+  -host=* | --host=* | --hos=* | --ho=*)
+    host="$ac_optarg" ;;
+
+  -includedir | --includedir | --includedi | --included | --include \
+  | --includ | --inclu | --incl | --inc)
+    ac_prev=includedir ;;
+  -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
+  | --includ=* | --inclu=* | --incl=* | --inc=*)
+    includedir="$ac_optarg" ;;
+
+  -infodir | --infodir | --infodi | --infod | --info | --inf)
+    ac_prev=infodir ;;
+  -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
+    infodir="$ac_optarg" ;;
+
+  -libdir | --libdir | --libdi | --libd)
+    ac_prev=libdir ;;
+  -libdir=* | --libdir=* | --libdi=* | --libd=*)
+    libdir="$ac_optarg" ;;
+
+  -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
+  | --libexe | --libex | --libe)
+    ac_prev=libexecdir ;;
+  -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
+  | --libexe=* | --libex=* | --libe=*)
+    libexecdir="$ac_optarg" ;;
+
+  -localstatedir | --localstatedir | --localstatedi | --localstated \
+  | --localstate | --localstat | --localsta | --localst \
+  | --locals | --local | --loca | --loc | --lo)
+    ac_prev=localstatedir ;;
+  -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+  | --localstate=* | --localstat=* | --localsta=* | --localst=* \
+  | --locals=* | --local=* | --loca=* | --loc=* | --lo=*)
+    localstatedir="$ac_optarg" ;;
+
+  -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
+    ac_prev=mandir ;;
+  -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
+    mandir="$ac_optarg" ;;
+
+  -nfp | --nfp | --nf)
+    # Obsolete; use --without-fp.
+    with_fp=no ;;
+
+  -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+  | --no-cr | --no-c)
+    no_create=yes ;;
+
+  -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+  | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
+    no_recursion=yes ;;
+
+  -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
+  | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
+  | --oldin | --oldi | --old | --ol | --o)
+    ac_prev=oldincludedir ;;
+  -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
+  | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
+  | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
+    oldincludedir="$ac_optarg" ;;
+
+  -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+    ac_prev=prefix ;;
+  -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+    prefix="$ac_optarg" ;;
+
+  -program-prefix | --program-prefix | --program-prefi | --program-pref \
+  | --program-pre | --program-pr | --program-p)
+    ac_prev=program_prefix ;;
+  -program-prefix=* | --program-prefix=* | --program-prefi=* \
+  | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+    program_prefix="$ac_optarg" ;;
+
+  -program-suffix | --program-suffix | --program-suffi | --program-suff \
+  | --program-suf | --program-su | --program-s)
+    ac_prev=program_suffix ;;
+  -program-suffix=* | --program-suffix=* | --program-suffi=* \
+  | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+    program_suffix="$ac_optarg" ;;
+
+  -program-transform-name | --program-transform-name \
+  | --program-transform-nam | --program-transform-na \
+  | --program-transform-n | --program-transform- \
+  | --program-transform | --program-transfor \
+  | --program-transfo | --program-transf \
+  | --program-trans | --program-tran \
+  | --progr-tra | --program-tr | --program-t)
+    ac_prev=program_transform_name ;;
+  -program-transform-name=* | --program-transform-name=* \
+  | --program-transform-nam=* | --program-transform-na=* \
+  | --program-transform-n=* | --program-transform-=* \
+  | --program-transform=* | --program-transfor=* \
+  | --program-transfo=* | --program-transf=* \
+  | --program-trans=* | --program-tran=* \
+  | --progr-tra=* | --program-tr=* | --program-t=*)
+    program_transform_name="$ac_optarg" ;;
+
+  -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+  | -silent | --silent | --silen | --sile | --sil)
+    silent=yes ;;
+
+  -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
+    ac_prev=sbindir ;;
+  -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
+  | --sbi=* | --sb=*)
+    sbindir="$ac_optarg" ;;
+
+  -sharedstatedir | --sharedstatedir | --sharedstatedi \
+  | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
+  | --sharedst | --shareds | --shared | --share | --shar \
+  | --sha | --sh)
+    ac_prev=sharedstatedir ;;
+  -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
+  | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
+  | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
+  | --sha=* | --sh=*)
+    sharedstatedir="$ac_optarg" ;;
+
+  -site | --site | --sit)
+    ac_prev=site ;;
+  -site=* | --site=* | --sit=*)
+    site="$ac_optarg" ;;
+
+  -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+    ac_prev=srcdir ;;
+  -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+    srcdir="$ac_optarg" ;;
+
+  -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
+  | --syscon | --sysco | --sysc | --sys | --sy)
+    ac_prev=sysconfdir ;;
+  -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
+  | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
+    sysconfdir="$ac_optarg" ;;
+
+  -target | --target | --targe | --targ | --tar | --ta | --t)
+    ac_prev=target ;;
+  -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
+    target="$ac_optarg" ;;
+
+  -v | -verbose | --verbose | --verbos | --verbo | --verb)
+    verbose=yes ;;
+
+  -version | --version | --versio | --versi | --vers)
+    echo "configure generated by autoconf version 2.13"
+    exit 0 ;;
+
+  -with-* | --with-*)
+    ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'`
+    # Reject names that are not valid shell variable names.
+    if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then
+      { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+    fi
+    ac_package=`echo $ac_package| sed 's/-/_/g'`
+    case "$ac_option" in
+      *=*) ;;
+      *) ac_optarg=yes ;;
+    esac
+    eval "with_${ac_package}='$ac_optarg'" ;;
+
+  -without-* | --without-*)
+    ac_package=`echo $ac_option|sed -e 's/-*without-//'`
+    # Reject names that are not valid shell variable names.
+    if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then
+      { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+    fi
+    ac_package=`echo $ac_package| sed 's/-/_/g'`
+    eval "with_${ac_package}=no" ;;
+
+  --x)
+    # Obsolete; use --with-x.
+    with_x=yes ;;
+
+  -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+  | --x-incl | --x-inc | --x-in | --x-i)
+    ac_prev=x_includes ;;
+  -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+  | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+    x_includes="$ac_optarg" ;;
+
+  -x-libraries | --x-libraries | --x-librarie | --x-librari \
+  | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+    ac_prev=x_libraries ;;
+  -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+  | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+    x_libraries="$ac_optarg" ;;
+
+  -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; }
+    ;;
+
+  *)
+    if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then
+      echo "configure: warning: $ac_option: invalid host type" 1>&2
+    fi
+    if test "x$nonopt" != xNONE; then
+      { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; }
+    fi
+    nonopt="$ac_option"
+    ;;
+
+  esac
+done
+
+if test -n "$ac_prev"; then
+  { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; }
+fi
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+# File descriptor usage:
+# 0 standard input
+# 1 file creation
+# 2 errors and warnings
+# 3 some systems may open it to /dev/tty
+# 4 used on the Kubota Titan
+# 6 checking for... messages and results
+# 5 compiler messages saved in config.log
+if test "$silent" = yes; then
+  exec 6>/dev/null
+else
+  exec 6>&1
+fi
+exec 5>./config.log
+
+echo "\
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+" 1>&5
+
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Also quote any args containing shell metacharacters.
+ac_configure_args=
+for ac_arg
+do
+  case "$ac_arg" in
+  -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+  | --no-cr | --no-c) ;;
+  -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+  | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;;
+  *" "*|*"     "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*)
+  ac_configure_args="$ac_configure_args '$ac_arg'" ;;
+  *) ac_configure_args="$ac_configure_args $ac_arg" ;;
+  esac
+done
+
+# NLS nuisances.
+# Only set these to C if already set.  These must not be set unconditionally
+# because not all systems understand e.g. LANG=C (notably SCO).
+# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'!
+# Non-C LC_CTYPE values break the ctype check.
+if test "${LANG+set}"   = set; then LANG=C;   export LANG;   fi
+if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi
+if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi
+if test "${LC_CTYPE+set}"    = set; then LC_CTYPE=C;    export LC_CTYPE;    fi
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -rf conftest* confdefs.h
+# AIX cpp loses on an empty file, so make sure it contains at least a newline.
+echo > confdefs.h
+
+# A filename unique to this package, relative to the directory that
+# configure is in, which we can look for to find out if srcdir is correct.
+ac_unique_file=t_pwd.h
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+  ac_srcdir_defaulted=yes
+  # Try the directory containing this script, then its parent.
+  ac_prog=$0
+  ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'`
+  test "x$ac_confdir" = "x$ac_prog" && ac_confdir=.
+  srcdir=$ac_confdir
+  if test ! -r $srcdir/$ac_unique_file; then
+    srcdir=..
+  fi
+else
+  ac_srcdir_defaulted=no
+fi
+if test ! -r $srcdir/$ac_unique_file; then
+  if test "$ac_srcdir_defaulted" = yes; then
+    { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; }
+  else
+    { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; }
+  fi
+fi
+srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'`
+
+# Prefer explicitly selected file to automatically selected ones.
+if test -z "$CONFIG_SITE"; then
+  if test "x$prefix" != xNONE; then
+    CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
+  else
+    CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
+  fi
+fi
+for ac_site_file in $CONFIG_SITE; do
+  if test -r "$ac_site_file"; then
+    echo "loading site script $ac_site_file"
+    . "$ac_site_file"
+  fi
+done
+
+if test -r "$cache_file"; then
+  echo "loading cache $cache_file"
+  . $cache_file
+else
+  echo "creating cache $cache_file"
+  > $cache_file
+fi
+
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+ac_exeext=
+ac_objext=o
+if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then
+  # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu.
+  if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then
+    ac_n= ac_c='
+' ac_t='       '
+  else
+    ac_n=-n ac_c= ac_t=
+  fi
+else
+  ac_n= ac_c='\c' ac_t=
+fi
+
+
+
+
+
+ac_aux_dir=
+for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do
+  if test -f $ac_dir/install-sh; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/install-sh -c"
+    break
+  elif test -f $ac_dir/install.sh; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/install.sh -c"
+    break
+  fi
+done
+if test -z "$ac_aux_dir"; then
+  { echo "configure: error: can not find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." 1>&2; exit 1; }
+fi
+ac_config_guess=$ac_aux_dir/config.guess
+ac_config_sub=$ac_aux_dir/config.sub
+ac_configure=$ac_aux_dir/configure # This should be Cygnus configure.
+
+# Find a good install program.  We prefer a C program (faster),
+# so one script is as good as another.  But avoid the broken or
+# incompatible versions:
+# SysV /etc/install, /usr/sbin/install
+# SunOS /usr/etc/install
+# IRIX /sbin/install
+# AIX /bin/install
+# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
+# AFS /usr/afsws/bin/install, which mishandles nonexistent args
+# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
+# ./install, which can be erroneously created by make from ./install.sh.
+echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6
+echo "configure:559: checking for a BSD compatible install" >&5
+if test -z "$INSTALL"; then
+if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+    IFS="${IFS=        }"; ac_save_IFS="$IFS"; IFS=":"
+  for ac_dir in $PATH; do
+    # Account for people who put trailing slashes in PATH elements.
+    case "$ac_dir/" in
+    /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;;
+    *)
+      # OSF1 and SCO ODT 3.0 have their own names for install.
+      # Don't use installbsd from OSF since it installs stuff as root
+      # by default.
+      for ac_prog in ginstall scoinst install; do
+        if test -f $ac_dir/$ac_prog; then
+         if test $ac_prog = install &&
+            grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then
+           # AIX install.  It has an incompatible calling convention.
+           :
+         else
+           ac_cv_path_install="$ac_dir/$ac_prog -c"
+           break 2
+         fi
+       fi
+      done
+      ;;
+    esac
+  done
+  IFS="$ac_save_IFS"
+
+fi
+  if test "${ac_cv_path_install+set}" = set; then
+    INSTALL="$ac_cv_path_install"
+  else
+    # As a last resort, use the slow shell script.  We don't cache a
+    # path for INSTALL within a source directory, because that will
+    # break other packages using the cache if that directory is
+    # removed, or if the path is relative.
+    INSTALL="$ac_install_sh"
+  fi
+fi
+echo "$ac_t""$INSTALL" 1>&6
+
+# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
+# It thinks the first close brace ends the variable substitution.
+test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
+
+test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}'
+
+test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
+
+echo $ac_n "checking whether build environment is sane""... $ac_c" 1>&6
+echo "configure:612: checking whether build environment is sane" >&5
+# 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".
+      { echo "configure: error: ls -t appears to fail.  Make sure there is not a broken
+alias in your environment" 1>&2; exit 1; }
+   fi
+
+   test "$2" = conftestfile
+   )
+then
+   # Ok.
+   :
+else
+   { echo "configure: error: newly created file is older than distributed files!
+Check your system clock" 1>&2; exit 1; }
+fi
+rm -f conftest*
+echo "$ac_t""yes" 1>&6
+if test "$program_transform_name" = s,x,x,; then
+  program_transform_name=
+else
+  # Double any \ or $.  echo might interpret backslashes.
+  cat <<\EOF_SED > conftestsed
+s,\\,\\\\,g; s,\$,$$,g
+EOF_SED
+  program_transform_name="`echo $program_transform_name|sed -f conftestsed`"
+  rm -f conftestsed
+fi
+test "$program_prefix" != NONE &&
+  program_transform_name="s,^,${program_prefix},; $program_transform_name"
+# Use a double $ so make ignores it.
+test "$program_suffix" != NONE &&
+  program_transform_name="s,\$\$,${program_suffix},; $program_transform_name"
+
+# sed with no file args requires a program.
+test "$program_transform_name" = "" && program_transform_name="s,x,x,"
+
+echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6
+echo "configure:669: checking whether ${MAKE-make} sets \${MAKE}" >&5
+set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_prog_make_${ac_make}_set'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftestmake <<\EOF
+all:
+       @echo 'ac_maketemp="${MAKE}"'
+EOF
+# GNU make sometimes prints "make[1]: Entering...", which would confuse us.
+eval `${MAKE-make} -f conftestmake 2>/dev/null | grep temp=`
+if test -n "$ac_maketemp"; then
+  eval ac_cv_prog_make_${ac_make}_set=yes
+else
+  eval ac_cv_prog_make_${ac_make}_set=no
+fi
+rm -f conftestmake
+fi
+if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  SET_MAKE=
+else
+  echo "$ac_t""no" 1>&6
+  SET_MAKE="MAKE=${MAKE-make}"
+fi
+
+
+
+PACKAGE=libtinysrp
+
+VERSION=0.7.5
+
+if test "`cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then
+  { echo "configure: error: source directory already configured; run "make distclean" there first" 1>&2; exit 1; }
+fi
+cat >> confdefs.h <<EOF
+#define PACKAGE "$PACKAGE"
+EOF
+
+cat >> confdefs.h <<EOF
+#define VERSION "$VERSION"
+EOF
+
+
+
+missing_dir=`cd $ac_aux_dir && pwd`
+echo $ac_n "checking for working aclocal""... $ac_c" 1>&6
+echo "configure:716: checking for working aclocal" >&5
+# 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 (aclocal --version) < /dev/null > /dev/null 2>&1; then
+   ACLOCAL=aclocal
+   echo "$ac_t""found" 1>&6
+else
+   ACLOCAL="$missing_dir/missing aclocal"
+   echo "$ac_t""missing" 1>&6
+fi
+
+echo $ac_n "checking for working autoconf""... $ac_c" 1>&6
+echo "configure:729: checking for working autoconf" >&5
+# 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 (autoconf --version) < /dev/null > /dev/null 2>&1; then
+   AUTOCONF=autoconf
+   echo "$ac_t""found" 1>&6
+else
+   AUTOCONF="$missing_dir/missing autoconf"
+   echo "$ac_t""missing" 1>&6
+fi
+
+echo $ac_n "checking for working automake""... $ac_c" 1>&6
+echo "configure:742: checking for working automake" >&5
+# 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 (automake --version) < /dev/null > /dev/null 2>&1; then
+   AUTOMAKE=automake
+   echo "$ac_t""found" 1>&6
+else
+   AUTOMAKE="$missing_dir/missing automake"
+   echo "$ac_t""missing" 1>&6
+fi
+
+echo $ac_n "checking for working autoheader""... $ac_c" 1>&6
+echo "configure:755: checking for working autoheader" >&5
+# 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 (autoheader --version) < /dev/null > /dev/null 2>&1; then
+   AUTOHEADER=autoheader
+   echo "$ac_t""found" 1>&6
+else
+   AUTOHEADER="$missing_dir/missing autoheader"
+   echo "$ac_t""missing" 1>&6
+fi
+
+echo $ac_n "checking for working makeinfo""... $ac_c" 1>&6
+echo "configure:768: checking for working makeinfo" >&5
+# 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 (makeinfo --version) < /dev/null > /dev/null 2>&1; then
+   MAKEINFO=makeinfo
+   echo "$ac_t""found" 1>&6
+else
+   MAKEINFO="$missing_dir/missing makeinfo"
+   echo "$ac_t""missing" 1>&6
+fi
+
+
+
+test "$CFLAGS" = "" && CFLAGS="-O2"
+
+
+# Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:788: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+  IFS="${IFS=  }"; ac_save_ifs="$IFS"; IFS=":"
+  ac_dummy="$PATH"
+  for ac_dir in $ac_dummy; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      ac_cv_prog_CC="gcc"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+  echo "$ac_t""$CC" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+if test -z "$CC"; then
+  # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:818: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+  IFS="${IFS=  }"; ac_save_ifs="$IFS"; IFS=":"
+  ac_prog_rejected=no
+  ac_dummy="$PATH"
+  for ac_dir in $ac_dummy; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then
+        ac_prog_rejected=yes
+       continue
+      fi
+      ac_cv_prog_CC="cc"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+if test $ac_prog_rejected = yes; then
+  # We found a bogon in the path, so make sure we never use it.
+  set dummy $ac_cv_prog_CC
+  shift
+  if test $# -gt 0; then
+    # We chose a different compiler from the bogus one.
+    # However, it has the same basename, so the bogon will be chosen
+    # first if we set CC to just the basename; use the full file name.
+    shift
+    set dummy "$ac_dir/$ac_word" "$@"
+    shift
+    ac_cv_prog_CC="$@"
+  fi
+fi
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+  echo "$ac_t""$CC" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+  if test -z "$CC"; then
+    case "`uname -s`" in
+    *win32* | *WIN32*)
+      # Extract the first word of "cl", so it can be a program name with args.
+set dummy cl; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:869: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+  IFS="${IFS=  }"; ac_save_ifs="$IFS"; IFS=":"
+  ac_dummy="$PATH"
+  for ac_dir in $ac_dummy; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      ac_cv_prog_CC="cl"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+  echo "$ac_t""$CC" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+ ;;
+    esac
+  fi
+  test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; }
+fi
+
+echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6
+echo "configure:901: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
+
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+cat > conftest.$ac_ext << EOF
+
+#line 912 "configure"
+#include "confdefs.h"
+
+main(){return(0);}
+EOF
+if { (eval echo configure:917: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  ac_cv_prog_cc_works=yes
+  # If we can't run a trivial program, we are probably using a cross compiler.
+  if (./conftest; exit) 2>/dev/null; then
+    ac_cv_prog_cc_cross=no
+  else
+    ac_cv_prog_cc_cross=yes
+  fi
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  ac_cv_prog_cc_works=no
+fi
+rm -fr conftest*
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+echo "$ac_t""$ac_cv_prog_cc_works" 1>&6
+if test $ac_cv_prog_cc_works = no; then
+  { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; }
+fi
+echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6
+echo "configure:943: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
+echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6
+cross_compiling=$ac_cv_prog_cc_cross
+
+echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6
+echo "configure:948: checking whether we are using GNU C" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.c <<EOF
+#ifdef __GNUC__
+  yes;
+#endif
+EOF
+if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:957: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
+  ac_cv_prog_gcc=yes
+else
+  ac_cv_prog_gcc=no
+fi
+fi
+
+echo "$ac_t""$ac_cv_prog_gcc" 1>&6
+
+if test $ac_cv_prog_gcc = yes; then
+  GCC=yes
+else
+  GCC=
+fi
+
+ac_test_CFLAGS="${CFLAGS+set}"
+ac_save_CFLAGS="$CFLAGS"
+CFLAGS=
+echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6
+echo "configure:976: checking whether ${CC-cc} accepts -g" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  echo 'void f(){}' > conftest.c
+if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then
+  ac_cv_prog_cc_g=yes
+else
+  ac_cv_prog_cc_g=no
+fi
+rm -f conftest*
+
+fi
+
+echo "$ac_t""$ac_cv_prog_cc_g" 1>&6
+if test "$ac_test_CFLAGS" = set; then
+  CFLAGS="$ac_save_CFLAGS"
+elif test $ac_cv_prog_cc_g = yes; then
+  if test "$GCC" = yes; then
+    CFLAGS="-g -O2"
+  else
+    CFLAGS="-g"
+  fi
+else
+  if test "$GCC" = yes; then
+    CFLAGS="-O2"
+  else
+    CFLAGS=
+  fi
+fi
+
+# Find a good install program.  We prefer a C program (faster),
+# so one script is as good as another.  But avoid the broken or
+# incompatible versions:
+# SysV /etc/install, /usr/sbin/install
+# SunOS /usr/etc/install
+# IRIX /sbin/install
+# AIX /bin/install
+# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
+# AFS /usr/afsws/bin/install, which mishandles nonexistent args
+# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
+# ./install, which can be erroneously created by make from ./install.sh.
+echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6
+echo "configure:1019: checking for a BSD compatible install" >&5
+if test -z "$INSTALL"; then
+if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+    IFS="${IFS=        }"; ac_save_IFS="$IFS"; IFS=":"
+  for ac_dir in $PATH; do
+    # Account for people who put trailing slashes in PATH elements.
+    case "$ac_dir/" in
+    /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;;
+    *)
+      # OSF1 and SCO ODT 3.0 have their own names for install.
+      # Don't use installbsd from OSF since it installs stuff as root
+      # by default.
+      for ac_prog in ginstall scoinst install; do
+        if test -f $ac_dir/$ac_prog; then
+         if test $ac_prog = install &&
+            grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then
+           # AIX install.  It has an incompatible calling convention.
+           :
+         else
+           ac_cv_path_install="$ac_dir/$ac_prog -c"
+           break 2
+         fi
+       fi
+      done
+      ;;
+    esac
+  done
+  IFS="$ac_save_IFS"
+
+fi
+  if test "${ac_cv_path_install+set}" = set; then
+    INSTALL="$ac_cv_path_install"
+  else
+    # As a last resort, use the slow shell script.  We don't cache a
+    # path for INSTALL within a source directory, because that will
+    # break other packages using the cache if that directory is
+    # removed, or if the path is relative.
+    INSTALL="$ac_install_sh"
+  fi
+fi
+echo "$ac_t""$INSTALL" 1>&6
+
+# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
+# It thinks the first close brace ends the variable substitution.
+test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
+
+test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}'
+
+test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
+
+echo $ac_n "checking whether ln -s works""... $ac_c" 1>&6
+echo "configure:1072: checking whether ln -s works" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_LN_S'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  rm -f conftestdata
+if ln -s X conftestdata 2>/dev/null
+then
+  rm -f conftestdata
+  ac_cv_prog_LN_S="ln -s"
+else
+  ac_cv_prog_LN_S=ln
+fi
+fi
+LN_S="$ac_cv_prog_LN_S"
+if test "$ac_cv_prog_LN_S" = "ln -s"; then
+  echo "$ac_t""yes" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+# Extract the first word of "ranlib", so it can be a program name with args.
+set dummy ranlib; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1095: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test -n "$RANLIB"; then
+  ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
+else
+  IFS="${IFS=  }"; ac_save_ifs="$IFS"; IFS=":"
+  ac_dummy="$PATH"
+  for ac_dir in $ac_dummy; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      ac_cv_prog_RANLIB="ranlib"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+  test -z "$ac_cv_prog_RANLIB" && ac_cv_prog_RANLIB=":"
+fi
+fi
+RANLIB="$ac_cv_prog_RANLIB"
+if test -n "$RANLIB"; then
+  echo "$ac_t""$RANLIB" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+if test "$program_transform_name" = s,x,x,; then
+  program_transform_name=
+else
+  # Double any \ or $.  echo might interpret backslashes.
+  cat <<\EOF_SED > conftestsed
+s,\\,\\\\,g; s,\$,$$,g
+EOF_SED
+  program_transform_name="`echo $program_transform_name|sed -f conftestsed`"
+  rm -f conftestsed
+fi
+test "$program_prefix" != NONE &&
+  program_transform_name="s,^,${program_prefix},; $program_transform_name"
+# Use a double $ so make ignores it.
+test "$program_suffix" != NONE &&
+  program_transform_name="s,\$\$,${program_suffix},; $program_transform_name"
+
+# sed with no file args requires a program.
+test "$program_transform_name" = "" && program_transform_name="s,x,x,"
+
+
+
+echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6
+echo "configure:1144: checking how to run the C preprocessor" >&5
+# On Suns, sometimes $CPP names a directory.
+if test -n "$CPP" && test -d "$CPP"; then
+  CPP=
+fi
+if test -z "$CPP"; then
+if eval "test \"`echo '$''{'ac_cv_prog_CPP'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+    # This must be in double quotes, not single quotes, because CPP may get
+  # substituted into the Makefile and "${CC-cc}" will confuse make.
+  CPP="${CC-cc} -E"
+  # On the NeXT, cc -E runs the code through the compiler's parser,
+  # not just through cpp.
+  cat > conftest.$ac_ext <<EOF
+#line 1159 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1165: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+  :
+else
+  echo "$ac_err" >&5
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  CPP="${CC-cc} -E -traditional-cpp"
+  cat > conftest.$ac_ext <<EOF
+#line 1176 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1182: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+  :
+else
+  echo "$ac_err" >&5
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  CPP="${CC-cc} -nologo -E"
+  cat > conftest.$ac_ext <<EOF
+#line 1193 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1199: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+  :
+else
+  echo "$ac_err" >&5
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  CPP=/lib/cpp
+fi
+rm -f conftest*
+fi
+rm -f conftest*
+fi
+rm -f conftest*
+  ac_cv_prog_CPP="$CPP"
+fi
+  CPP="$ac_cv_prog_CPP"
+else
+  ac_cv_prog_CPP="$CPP"
+fi
+echo "$ac_t""$CPP" 1>&6
+
+echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6
+echo "configure:1224: checking for ANSI C header files" >&5
+if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 1229 "configure"
+#include "confdefs.h"
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1237: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+  rm -rf conftest*
+  ac_cv_header_stdc=yes
+else
+  echo "$ac_err" >&5
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+if test $ac_cv_header_stdc = yes; then
+  # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+cat > conftest.$ac_ext <<EOF
+#line 1254 "configure"
+#include "confdefs.h"
+#include <string.h>
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  egrep "memchr" >/dev/null 2>&1; then
+  :
+else
+  rm -rf conftest*
+  ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+  # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+cat > conftest.$ac_ext <<EOF
+#line 1272 "configure"
+#include "confdefs.h"
+#include <stdlib.h>
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  egrep "free" >/dev/null 2>&1; then
+  :
+else
+  rm -rf conftest*
+  ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+  # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+if test "$cross_compiling" = yes; then
+  :
+else
+  cat > conftest.$ac_ext <<EOF
+#line 1293 "configure"
+#include "confdefs.h"
+#include <ctype.h>
+#define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+#define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int main () { int i; for (i = 0; i < 256; i++)
+if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2);
+exit (0); }
+
+EOF
+if { (eval echo configure:1304: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+  :
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -fr conftest*
+  ac_cv_header_stdc=no
+fi
+rm -fr conftest*
+fi
+
+fi
+fi
+
+echo "$ac_t""$ac_cv_header_stdc" 1>&6
+if test $ac_cv_header_stdc = yes; then
+  cat >> confdefs.h <<\EOF
+#define STDC_HEADERS 1
+EOF
+
+fi
+
+for ac_hdr in sgtty.h sys/ioctl.h sys/time.h termio.h termios.h unistd.h
+do
+ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
+echo "configure:1331: checking for $ac_hdr" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 1336 "configure"
+#include "confdefs.h"
+#include <$ac_hdr>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1341: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+  rm -rf conftest*
+  eval "ac_cv_header_$ac_safe=yes"
+else
+  echo "$ac_err" >&5
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+    ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
+  cat >> confdefs.h <<EOF
+#define $ac_tr_hdr 1
+EOF
+else
+  echo "$ac_t""no" 1>&6
+fi
+done
+
+
+
+echo $ac_n "checking for working const""... $ac_c" 1>&6
+echo "configure:1370: checking for working const" >&5
+if eval "test \"`echo '$''{'ac_cv_c_const'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 1375 "configure"
+#include "confdefs.h"
+
+int main() {
+
+/* Ultrix mips cc rejects this.  */
+typedef int charset[2]; const charset x;
+/* SunOS 4.1.1 cc rejects this.  */
+char const *const *ccp;
+char **p;
+/* NEC SVR4.0.2 mips cc rejects this.  */
+struct point {int x, y;};
+static struct point const zero = {0,0};
+/* AIX XL C 1.02.0.0 rejects this.
+   It does not let you subtract one const X* pointer from another in an arm
+   of an if-expression whose if-part is not a constant expression */
+const char *g = "string";
+ccp = &g + (g ? g-g : 0);
+/* HPUX 7.0 cc rejects these. */
+++ccp;
+p = (char**) ccp;
+ccp = (char const *const *) p;
+{ /* SCO 3.2v4 cc rejects this.  */
+  char *t;
+  char const *s = 0 ? (char *) 0 : (char const *) 0;
+
+  *t++ = 0;
+}
+{ /* Someone thinks the Sun supposedly-ANSI compiler will reject this.  */
+  int x[] = {25, 17};
+  const int *foo = &x[0];
+  ++foo;
+}
+{ /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */
+  typedef const int *iptr;
+  iptr p = 0;
+  ++p;
+}
+{ /* AIX XL C 1.02.0.0 rejects this saying
+     "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */
+  struct s { int j; const int *ap[3]; };
+  struct s *b; b->j = 5;
+}
+{ /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */
+  const int foo = 10;
+}
+
+; return 0; }
+EOF
+if { (eval echo configure:1424: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+  rm -rf conftest*
+  ac_cv_c_const=yes
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  ac_cv_c_const=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_c_const" 1>&6
+if test $ac_cv_c_const = no; then
+  cat >> confdefs.h <<\EOF
+#define const 
+EOF
+
+fi
+
+echo $ac_n "checking for inline""... $ac_c" 1>&6
+echo "configure:1445: checking for inline" >&5
+if eval "test \"`echo '$''{'ac_cv_c_inline'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  ac_cv_c_inline=no
+for ac_kw in inline __inline__ __inline; do
+  cat > conftest.$ac_ext <<EOF
+#line 1452 "configure"
+#include "confdefs.h"
+
+int main() {
+} $ac_kw foo() {
+; return 0; }
+EOF
+if { (eval echo configure:1459: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+  rm -rf conftest*
+  ac_cv_c_inline=$ac_kw; break
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+fi
+rm -f conftest*
+done
+
+fi
+
+echo "$ac_t""$ac_cv_c_inline" 1>&6
+case "$ac_cv_c_inline" in
+  inline | yes) ;;
+  no) cat >> confdefs.h <<\EOF
+#define inline 
+EOF
+ ;;
+  *)  cat >> confdefs.h <<EOF
+#define inline $ac_cv_c_inline
+EOF
+ ;;
+esac
+
+echo $ac_n "checking whether time.h and sys/time.h may both be included""... $ac_c" 1>&6
+echo "configure:1485: checking whether time.h and sys/time.h may both be included" >&5
+if eval "test \"`echo '$''{'ac_cv_header_time'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 1490 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#include <sys/time.h>
+#include <time.h>
+int main() {
+struct tm *tp;
+; return 0; }
+EOF
+if { (eval echo configure:1499: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+  rm -rf conftest*
+  ac_cv_header_time=yes
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  ac_cv_header_time=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_header_time" 1>&6
+if test $ac_cv_header_time = yes; then
+  cat >> confdefs.h <<\EOF
+#define TIME_WITH_SYS_TIME 1
+EOF
+
+fi
+
+echo $ac_n "checking whether byte ordering is bigendian""... $ac_c" 1>&6
+echo "configure:1520: checking whether byte ordering is bigendian" >&5
+if eval "test \"`echo '$''{'ac_cv_c_bigendian'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  ac_cv_c_bigendian=unknown
+# See if sys/param.h defines the BYTE_ORDER macro.
+cat > conftest.$ac_ext <<EOF
+#line 1527 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#include <sys/param.h>
+int main() {
+
+#if !BYTE_ORDER || !BIG_ENDIAN || !LITTLE_ENDIAN
+ bogus endian macros
+#endif
+; return 0; }
+EOF
+if { (eval echo configure:1538: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+  rm -rf conftest*
+  # It does; now see whether it defined to BIG_ENDIAN or not.
+cat > conftest.$ac_ext <<EOF
+#line 1542 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#include <sys/param.h>
+int main() {
+
+#if BYTE_ORDER != BIG_ENDIAN
+ not big endian
+#endif
+; return 0; }
+EOF
+if { (eval echo configure:1553: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+  rm -rf conftest*
+  ac_cv_c_bigendian=yes
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  ac_cv_c_bigendian=no
+fi
+rm -f conftest*
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+fi
+rm -f conftest*
+if test $ac_cv_c_bigendian = unknown; then
+if test "$cross_compiling" = yes; then
+    { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
+else
+  cat > conftest.$ac_ext <<EOF
+#line 1573 "configure"
+#include "confdefs.h"
+main () {
+  /* Are we little or big endian?  From Harbison&Steele.  */
+  union
+  {
+    long l;
+    char c[sizeof (long)];
+  } u;
+  u.l = 1;
+  exit (u.c[sizeof (long) - 1] == 1);
+}
+EOF
+if { (eval echo configure:1586: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+  ac_cv_c_bigendian=no
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -fr conftest*
+  ac_cv_c_bigendian=yes
+fi
+rm -fr conftest*
+fi
+
+fi
+fi
+
+echo "$ac_t""$ac_cv_c_bigendian" 1>&6
+if test $ac_cv_c_bigendian = yes; then
+  cat >> confdefs.h <<\EOF
+#define WORDS_BIGENDIAN 1
+EOF
+
+fi
+
+echo $ac_n "checking size of short""... $ac_c" 1>&6
+echo "configure:1610: checking size of short" >&5
+if eval "test \"`echo '$''{'ac_cv_sizeof_short'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test "$cross_compiling" = yes; then
+    { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
+else
+  cat > conftest.$ac_ext <<EOF
+#line 1618 "configure"
+#include "confdefs.h"
+#include <stdio.h>
+main()
+{
+  FILE *f=fopen("conftestval", "w");
+  if (!f) exit(1);
+  fprintf(f, "%d\n", sizeof(short));
+  exit(0);
+}
+EOF
+if { (eval echo configure:1629: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+  ac_cv_sizeof_short=`cat conftestval`
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -fr conftest*
+  ac_cv_sizeof_short=0
+fi
+rm -fr conftest*
+fi
+
+fi
+echo "$ac_t""$ac_cv_sizeof_short" 1>&6
+cat >> confdefs.h <<EOF
+#define SIZEOF_SHORT $ac_cv_sizeof_short
+EOF
+
+
+echo $ac_n "checking size of int""... $ac_c" 1>&6
+echo "configure:1649: checking size of int" >&5
+if eval "test \"`echo '$''{'ac_cv_sizeof_int'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test "$cross_compiling" = yes; then
+    { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
+else
+  cat > conftest.$ac_ext <<EOF
+#line 1657 "configure"
+#include "confdefs.h"
+#include <stdio.h>
+main()
+{
+  FILE *f=fopen("conftestval", "w");
+  if (!f) exit(1);
+  fprintf(f, "%d\n", sizeof(int));
+  exit(0);
+}
+EOF
+if { (eval echo configure:1668: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+  ac_cv_sizeof_int=`cat conftestval`
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -fr conftest*
+  ac_cv_sizeof_int=0
+fi
+rm -fr conftest*
+fi
+
+fi
+echo "$ac_t""$ac_cv_sizeof_int" 1>&6
+cat >> confdefs.h <<EOF
+#define SIZEOF_INT $ac_cv_sizeof_int
+EOF
+
+
+echo $ac_n "checking size of long""... $ac_c" 1>&6
+echo "configure:1688: checking size of long" >&5
+if eval "test \"`echo '$''{'ac_cv_sizeof_long'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test "$cross_compiling" = yes; then
+    { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
+else
+  cat > conftest.$ac_ext <<EOF
+#line 1696 "configure"
+#include "confdefs.h"
+#include <stdio.h>
+main()
+{
+  FILE *f=fopen("conftestval", "w");
+  if (!f) exit(1);
+  fprintf(f, "%d\n", sizeof(long));
+  exit(0);
+}
+EOF
+if { (eval echo configure:1707: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+  ac_cv_sizeof_long=`cat conftestval`
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -fr conftest*
+  ac_cv_sizeof_long=0
+fi
+rm -fr conftest*
+fi
+
+fi
+echo "$ac_t""$ac_cv_sizeof_long" 1>&6
+cat >> confdefs.h <<EOF
+#define SIZEOF_LONG $ac_cv_sizeof_long
+EOF
+
+
+echo $ac_n "checking size of long long""... $ac_c" 1>&6
+echo "configure:1727: checking size of long long" >&5
+if eval "test \"`echo '$''{'ac_cv_sizeof_long_long'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test "$cross_compiling" = yes; then
+    { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
+else
+  cat > conftest.$ac_ext <<EOF
+#line 1735 "configure"
+#include "confdefs.h"
+#include <stdio.h>
+main()
+{
+  FILE *f=fopen("conftestval", "w");
+  if (!f) exit(1);
+  fprintf(f, "%d\n", sizeof(long long));
+  exit(0);
+}
+EOF
+if { (eval echo configure:1746: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+  ac_cv_sizeof_long_long=`cat conftestval`
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -fr conftest*
+  ac_cv_sizeof_long_long=0
+fi
+rm -fr conftest*
+fi
+
+fi
+echo "$ac_t""$ac_cv_sizeof_long_long" 1>&6
+cat >> confdefs.h <<EOF
+#define SIZEOF_LONG_LONG $ac_cv_sizeof_long_long
+EOF
+
+
+cat > conftest.$ac_ext <<EOF
+#line 1766 "configure"
+#include "confdefs.h"
+
+int main() {
+volatile int i;
+; return 0; }
+EOF
+if { (eval echo configure:1773: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+  :
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  cat >> confdefs.h <<\EOF
+#define volatile 
+EOF
+
+fi
+rm -f conftest*
+echo $ac_n "checking whether char is unsigned""... $ac_c" 1>&6
+echo "configure:1786: checking whether char is unsigned" >&5
+if eval "test \"`echo '$''{'ac_cv_c_char_unsigned'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test "$GCC" = yes; then
+  # GCC predefines this symbol on systems where it applies.
+cat > conftest.$ac_ext <<EOF
+#line 1793 "configure"
+#include "confdefs.h"
+#ifdef __CHAR_UNSIGNED__
+  yes
+#endif
+
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  egrep "yes" >/dev/null 2>&1; then
+  rm -rf conftest*
+  ac_cv_c_char_unsigned=yes
+else
+  rm -rf conftest*
+  ac_cv_c_char_unsigned=no
+fi
+rm -f conftest*
+
+else
+if test "$cross_compiling" = yes; then
+    { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
+else
+  cat > conftest.$ac_ext <<EOF
+#line 1815 "configure"
+#include "confdefs.h"
+/* volatile prevents gcc2 from optimizing the test away on sparcs.  */
+#if !defined(__STDC__) || __STDC__ != 1
+#define volatile
+#endif
+main() {
+  volatile char c = 255; exit(c < 0);
+}
+EOF
+if { (eval echo configure:1825: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+  ac_cv_c_char_unsigned=yes
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -fr conftest*
+  ac_cv_c_char_unsigned=no
+fi
+rm -fr conftest*
+fi
+
+fi
+fi
+
+echo "$ac_t""$ac_cv_c_char_unsigned" 1>&6
+if test $ac_cv_c_char_unsigned = yes && test "$GCC" != yes; then
+  cat >> confdefs.h <<\EOF
+#define __CHAR_UNSIGNED__ 1
+EOF
+
+fi
+
+
+if test "$ac_cv_c_char_unsigned" = "yes"; then
+  signed=-signed
+fi
+
+
+for ac_func in sigaction strchr memcpy
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:1857: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 1862 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $ac_func(); below.  */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:1885: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_func_$ac_func=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+    ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+  cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+else
+  echo "$ac_t""no" 1>&6
+fi
+done
+
+
+echo $ac_n "checking POSIX signal handlers""... $ac_c" 1>&6
+echo "configure:1911: checking POSIX signal handlers" >&5
+if eval "test \"`echo '$''{'ac_cv_has_posix_signals'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 1916 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#include <signal.h>
+#ifdef signal
+#undef signal
+#endif
+extern void (*signal ()) ();
+int main() {
+
+; return 0; }
+EOF
+if { (eval echo configure:1928: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+  rm -rf conftest*
+  ac_cv_has_posix_signals=yes
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  ac_cv_has_posix_signals=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_has_posix_signals" 1>&6
+if test $ac_cv_has_posix_signals = yes; then
+   cat >> confdefs.h <<\EOF
+#define RETSIGTYPE void
+EOF
+ cat >> confdefs.h <<\EOF
+#define POSIX_SIGTYPE 1
+EOF
+
+else
+  if test $ac_cv_type_signal = void; then
+     cat >> confdefs.h <<\EOF
+#define RETSIGTYPE void
+EOF
+
+  else
+     cat >> confdefs.h <<\EOF
+#define RETSIGTYPE int
+EOF
+
+  fi
+fi
+ac_safe=`echo "termios.h" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for termios.h""... $ac_c" 1>&6
+echo "configure:1964: checking for termios.h" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 1969 "configure"
+#include "confdefs.h"
+#include <termios.h>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1974: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+  rm -rf conftest*
+  eval "ac_cv_header_$ac_safe=yes"
+else
+  echo "$ac_err" >&5
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  echo $ac_n "checking for cfsetispeed""... $ac_c" 1>&6
+echo "configure:1991: checking for cfsetispeed" >&5
+if eval "test \"`echo '$''{'ac_cv_func_cfsetispeed'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 1996 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char cfsetispeed(); below.  */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char cfsetispeed();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_cfsetispeed) || defined (__stub___cfsetispeed)
+choke me
+#else
+cfsetispeed();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:2019: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_func_cfsetispeed=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_func_cfsetispeed=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'cfsetispeed`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  cat >> confdefs.h <<\EOF
+#define POSIX_TERMIOS 1
+EOF
+
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+
+
+
+cat >> confdefs.h <<\EOF
+#define SHA1HANDSOFF 1
+EOF
+
+
+trap '' 1 2 15
+cat > confcache <<\EOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs.  It is not useful on other systems.
+# If it contains results you don't want to keep, you may remove or edit it.
+#
+# By default, configure uses ./config.cache as the cache file,
+# creating it if it does not exist already.  You can give configure
+# the --cache-file=FILE option to use a different cache file; that is
+# what configure does when it calls configure scripts in
+# subdirectories, so they share the cache.
+# Giving --cache-file=/dev/null disables caching, for debugging configure.
+# config.status only pays attention to the cache file if you give it the
+# --recheck option to rerun configure.
+#
+EOF
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, don't put newlines in cache variables' values.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+(set) 2>&1 |
+  case `(ac_space=' '; set | grep ac_space) 2>&1` in
+  *ac_space=\ *)
+    # `set' does not quote correctly, so add quotes (double-quote substitution
+    # turns \\\\ into \\, and sed turns \\ into \).
+    sed -n \
+      -e "s/'/'\\\\''/g" \
+      -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p"
+    ;;
+  *)
+    # `set' quotes correctly as required by POSIX, so do not add quotes.
+    sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p'
+    ;;
+  esac >> confcache
+if cmp -s $cache_file confcache; then
+  :
+else
+  if test -w $cache_file; then
+    echo "updating cache $cache_file"
+    cat confcache > $cache_file
+  else
+    echo "not updating unwritable cache $cache_file"
+  fi
+fi
+rm -f confcache
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+# Any assignment to VPATH causes Sun make to only execute
+# the first set of double-colon rules, so remove it if not needed.
+# If there is a colon in the path, we need to keep it.
+if test "x$srcdir" = x.; then
+  ac_vpsub='/^[        ]*VPATH[        ]*=[^:]*$/d'
+fi
+
+trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15
+
+DEFS=-DHAVE_CONFIG_H
+
+# Without the "./", some shells look in PATH for config.status.
+: ${CONFIG_STATUS=./config.status}
+
+echo creating $CONFIG_STATUS
+rm -f $CONFIG_STATUS
+cat > $CONFIG_STATUS <<EOF
+#! /bin/sh
+# Generated automatically by configure.
+# Run this file to recreate the current configuration.
+# This directory was configured as follows,
+# on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+#
+# $0 $ac_configure_args
+#
+# Compiler output produced by configure, useful for debugging
+# configure, is in ./config.log if it exists.
+
+ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]"
+for ac_option
+do
+  case "\$ac_option" in
+  -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+    echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion"
+    exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;;
+  -version | --version | --versio | --versi | --vers | --ver | --ve | --v)
+    echo "$CONFIG_STATUS generated by autoconf version 2.13"
+    exit 0 ;;
+  -help | --help | --hel | --he | --h)
+    echo "\$ac_cs_usage"; exit 0 ;;
+  *) echo "\$ac_cs_usage"; exit 1 ;;
+  esac
+done
+
+ac_given_srcdir=$srcdir
+ac_given_INSTALL="$INSTALL"
+
+trap 'rm -fr `echo "Makefile config.h" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+# Protect against being on the right side of a sed subst in config.status.
+sed 's/%@/@@/; s/@%/@@/; s/%g\$/@g/; /@g\$/s/[\\\\&%]/\\\\&/g;
+ s/@@/%@/; s/@@/@%/; s/@g\$/%g/' > conftest.subs <<\\CEOF
+$ac_vpsub
+$extrasub
+s%@SHELL@%$SHELL%g
+s%@CFLAGS@%$CFLAGS%g
+s%@CPPFLAGS@%$CPPFLAGS%g
+s%@CXXFLAGS@%$CXXFLAGS%g
+s%@FFLAGS@%$FFLAGS%g
+s%@DEFS@%$DEFS%g
+s%@LDFLAGS@%$LDFLAGS%g
+s%@LIBS@%$LIBS%g
+s%@exec_prefix@%$exec_prefix%g
+s%@prefix@%$prefix%g
+s%@program_transform_name@%$program_transform_name%g
+s%@bindir@%$bindir%g
+s%@sbindir@%$sbindir%g
+s%@libexecdir@%$libexecdir%g
+s%@datadir@%$datadir%g
+s%@sysconfdir@%$sysconfdir%g
+s%@sharedstatedir@%$sharedstatedir%g
+s%@localstatedir@%$localstatedir%g
+s%@libdir@%$libdir%g
+s%@includedir@%$includedir%g
+s%@oldincludedir@%$oldincludedir%g
+s%@infodir@%$infodir%g
+s%@mandir@%$mandir%g
+s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g
+s%@INSTALL_SCRIPT@%$INSTALL_SCRIPT%g
+s%@INSTALL_DATA@%$INSTALL_DATA%g
+s%@PACKAGE@%$PACKAGE%g
+s%@VERSION@%$VERSION%g
+s%@ACLOCAL@%$ACLOCAL%g
+s%@AUTOCONF@%$AUTOCONF%g
+s%@AUTOMAKE@%$AUTOMAKE%g
+s%@AUTOHEADER@%$AUTOHEADER%g
+s%@MAKEINFO@%$MAKEINFO%g
+s%@SET_MAKE@%$SET_MAKE%g
+s%@CC@%$CC%g
+s%@LN_S@%$LN_S%g
+s%@RANLIB@%$RANLIB%g
+s%@CPP@%$CPP%g
+s%@signed@%$signed%g
+
+CEOF
+EOF
+
+cat >> $CONFIG_STATUS <<\EOF
+
+# Split the substitutions into bite-sized pieces for seds with
+# small command number limits, like on Digital OSF/1 and HP-UX.
+ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script.
+ac_file=1 # Number of current file.
+ac_beg=1 # First line for current file.
+ac_end=$ac_max_sed_cmds # Line after last line for current file.
+ac_more_lines=:
+ac_sed_cmds=""
+while $ac_more_lines; do
+  if test $ac_beg -gt 1; then
+    sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file
+  else
+    sed "${ac_end}q" conftest.subs > conftest.s$ac_file
+  fi
+  if test ! -s conftest.s$ac_file; then
+    ac_more_lines=false
+    rm -f conftest.s$ac_file
+  else
+    if test -z "$ac_sed_cmds"; then
+      ac_sed_cmds="sed -f conftest.s$ac_file"
+    else
+      ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file"
+    fi
+    ac_file=`expr $ac_file + 1`
+    ac_beg=$ac_end
+    ac_end=`expr $ac_end + $ac_max_sed_cmds`
+  fi
+done
+if test -z "$ac_sed_cmds"; then
+  ac_sed_cmds=cat
+fi
+EOF
+
+cat >> $CONFIG_STATUS <<EOF
+
+CONFIG_FILES=\${CONFIG_FILES-"Makefile"}
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then
+  # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+  case "$ac_file" in
+  *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
+       ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
+  *) ac_file_in="${ac_file}.in" ;;
+  esac
+
+  # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories.
+
+  # Remove last slash and all that follows it.  Not all systems have dirname.
+  ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
+  if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
+    # The file is in a subdirectory.
+    test ! -d "$ac_dir" && mkdir "$ac_dir"
+    ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`"
+    # A "../" for each directory in $ac_dir_suffix.
+    ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'`
+  else
+    ac_dir_suffix= ac_dots=
+  fi
+
+  case "$ac_given_srcdir" in
+  .)  srcdir=.
+      if test -z "$ac_dots"; then top_srcdir=.
+      else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;;
+  /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;;
+  *) # Relative path.
+    srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix"
+    top_srcdir="$ac_dots$ac_given_srcdir" ;;
+  esac
+
+  case "$ac_given_INSTALL" in
+  [/$]*) INSTALL="$ac_given_INSTALL" ;;
+  *) INSTALL="$ac_dots$ac_given_INSTALL" ;;
+  esac
+
+  echo creating "$ac_file"
+  rm -f "$ac_file"
+  configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure."
+  case "$ac_file" in
+  *Makefile*) ac_comsub="1i\\
+# $configure_input" ;;
+  *) ac_comsub= ;;
+  esac
+
+  ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
+  sed -e "$ac_comsub
+s%@configure_input@%$configure_input%g
+s%@srcdir@%$srcdir%g
+s%@top_srcdir@%$top_srcdir%g
+s%@INSTALL@%$INSTALL%g
+" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file
+fi; done
+rm -f conftest.s*
+
+# These sed commands are passed to sed as "A NAME B NAME C VALUE D", where
+# NAME is the cpp macro being defined and VALUE is the value it is being given.
+#
+# ac_d sets the value in "#define NAME VALUE" lines.
+ac_dA='s%^\([  ]*\)#\([        ]*define[       ][      ]*\)'
+ac_dB='\([     ][      ]*\)[^  ]*%\1#\2'
+ac_dC='\3'
+ac_dD='%g'
+# ac_u turns "#undef NAME" with trailing blanks into "#define NAME VALUE".
+ac_uA='s%^\([  ]*\)#\([        ]*\)undef\([    ][      ]*\)'
+ac_uB='\([     ]\)%\1#\2define\3'
+ac_uC=' '
+ac_uD='\4%g'
+# ac_e turns "#undef NAME" without trailing blanks into "#define NAME VALUE".
+ac_eA='s%^\([  ]*\)#\([        ]*\)undef\([    ][      ]*\)'
+ac_eB='$%\1#\2define\3'
+ac_eC=' '
+ac_eD='%g'
+
+if test "${CONFIG_HEADERS+set}" != set; then
+EOF
+cat >> $CONFIG_STATUS <<EOF
+  CONFIG_HEADERS="config.h"
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+fi
+for ac_file in .. $CONFIG_HEADERS; do if test "x$ac_file" != x..; then
+  # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+  case "$ac_file" in
+  *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
+       ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
+  *) ac_file_in="${ac_file}.in" ;;
+  esac
+
+  echo creating $ac_file
+
+  rm -f conftest.frag conftest.in conftest.out
+  ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
+  cat $ac_file_inputs > conftest.in
+
+EOF
+
+# Transform confdefs.h into a sed script conftest.vals that substitutes
+# the proper values into config.h.in to produce config.h.  And first:
+# Protect against being on the right side of a sed subst in config.status.
+# Protect against being in an unquoted here document in config.status.
+rm -f conftest.vals
+cat > conftest.hdr <<\EOF
+s/[\\&%]/\\&/g
+s%[\\$`]%\\&%g
+s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD}%gp
+s%ac_d%ac_u%gp
+s%ac_u%ac_e%gp
+EOF
+sed -n -f conftest.hdr confdefs.h > conftest.vals
+rm -f conftest.hdr
+
+# This sed command replaces #undef with comments.  This is necessary, for
+# example, in the case of _POSIX_SOURCE, which is predefined and required
+# on some systems where configure will not decide to define it.
+cat >> conftest.vals <<\EOF
+s%^[   ]*#[    ]*undef[        ][      ]*[a-zA-Z_][a-zA-Z_0-9]*%/* & */%
+EOF
+
+# Break up conftest.vals because some shells have a limit on
+# the size of here documents, and old seds have small limits too.
+
+rm -f conftest.tail
+while :
+do
+  ac_lines=`grep -c . conftest.vals`
+  # grep -c gives empty output for an empty file on some AIX systems.
+  if test -z "$ac_lines" || test "$ac_lines" -eq 0; then break; fi
+  # Write a limited-size here document to conftest.frag.
+  echo '  cat > conftest.frag <<CEOF' >> $CONFIG_STATUS
+  sed ${ac_max_here_lines}q conftest.vals >> $CONFIG_STATUS
+  echo 'CEOF
+  sed -f conftest.frag conftest.in > conftest.out
+  rm -f conftest.in
+  mv conftest.out conftest.in
+' >> $CONFIG_STATUS
+  sed 1,${ac_max_here_lines}d conftest.vals > conftest.tail
+  rm -f conftest.vals
+  mv conftest.tail conftest.vals
+done
+rm -f conftest.vals
+
+cat >> $CONFIG_STATUS <<\EOF
+  rm -f conftest.frag conftest.h
+  echo "/* $ac_file.  Generated automatically by configure.  */" > conftest.h
+  cat conftest.in >> conftest.h
+  rm -f conftest.in
+  if cmp -s $ac_file conftest.h 2>/dev/null; then
+    echo "$ac_file is unchanged"
+    rm -f conftest.h
+  else
+    # Remove last slash and all that follows it.  Not all systems have dirname.
+      ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
+      if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
+      # The file is in a subdirectory.
+      test ! -d "$ac_dir" && mkdir "$ac_dir"
+    fi
+    rm -f $ac_file
+    mv conftest.h $ac_file
+  fi
+fi; done
+
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+test -z "$CONFIG_HEADERS" || echo timestamp > stamp-h
+
+exit 0
+EOF
+chmod +x $CONFIG_STATUS
+rm -fr confdefs* $ac_clean_files
+test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1
+
diff --git a/package/ead/src/tinysrp/configure.in b/package/ead/src/tinysrp/configure.in
new file mode 100644 (file)
index 0000000..627d15a
--- /dev/null
@@ -0,0 +1,52 @@
+dnl Process this file with autoconf to produce a configure script.
+
+AC_INIT(t_pwd.h)
+AM_CONFIG_HEADER(config.h)
+AM_INIT_AUTOMAKE(libtinysrp, 0.7.5)
+
+test "$CFLAGS" = "" && CFLAGS="-O2"
+
+dnl Checks for programs.
+
+AC_PROG_CC
+AC_PROG_INSTALL
+AC_PROG_LN_S
+AC_PROG_RANLIB
+AC_ARG_PROGRAM
+
+dnl Checks for header files.
+
+AC_HEADER_STDC
+AC_CHECK_HEADERS(sgtty.h sys/ioctl.h sys/time.h termio.h termios.h unistd.h)
+
+dnl Checks for typedefs, structures, and compiler characteristics.
+
+AC_C_CONST
+AC_C_INLINE
+AC_HEADER_TIME
+AC_C_BIGENDIAN
+AC_CHECK_SIZEOF(short)
+AC_CHECK_SIZEOF(int)
+AC_CHECK_SIZEOF(long)
+AC_CHECK_SIZEOF(long long)
+AC_TRY_COMPILE(, [volatile int i;], , AC_DEFINE(volatile, ))
+AC_C_CHAR_UNSIGNED
+
+AC_SUBST(signed)dnl
+if test "$ac_cv_c_char_unsigned" = "yes"; then
+  signed=-signed
+fi
+
+dnl Checks for library functions.
+
+AC_CHECK_FUNCS(sigaction strchr memcpy)
+TYPE_SIGNAL
+AC_HEADER_CHECK(termios.h,AC_FUNC_CHECK(cfsetispeed,AC_DEFINE(POSIX_TERMIOS)))
+
+dnl User options
+
+dnl Some defines for now.
+
+AC_DEFINE(SHA1HANDSOFF)
+
+AC_OUTPUT(Makefile)
diff --git a/package/ead/src/tinysrp/install-sh b/package/ead/src/tinysrp/install-sh
new file mode 100755 (executable)
index 0000000..e843669
--- /dev/null
@@ -0,0 +1,250 @@
+#!/bin/sh
+#
+# install - install a program, script, or datafile
+# This comes from X11R5 (mit/util/scripts/install.sh).
+#
+# Copyright 1991 by the Massachusetts Institute of Technology
+#
+# Permission to use, copy, modify, distribute, and sell this software and its
+# documentation for any purpose is hereby granted without fee, provided that
+# the above copyright notice appear in all copies and that both that
+# copyright notice and this permission notice appear in supporting
+# documentation, and that the name of M.I.T. not be used in advertising or
+# publicity pertaining to distribution of the software without specific,
+# written prior permission.  M.I.T. makes no representations about the
+# suitability of this software for any purpose.  It is provided "as is"
+# without express or implied warranty.
+#
+# Calling this script install-sh is preferred over install.sh, to prevent
+# `make' implicit rules from creating a file called install from it
+# when there is no Makefile.
+#
+# This script is compatible with the BSD install script, but was written
+# from scratch.  It can only install one file at a time, a restriction
+# shared with many OS's install programs.
+
+
+# set DOITPROG to echo to test this script
+
+# Don't use :- since 4.3BSD and earlier shells don't like it.
+doit="${DOITPROG-}"
+
+
+# put in absolute paths if you don't have them in your path; or use env. vars.
+
+mvprog="${MVPROG-mv}"
+cpprog="${CPPROG-cp}"
+chmodprog="${CHMODPROG-chmod}"
+chownprog="${CHOWNPROG-chown}"
+chgrpprog="${CHGRPPROG-chgrp}"
+stripprog="${STRIPPROG-strip}"
+rmprog="${RMPROG-rm}"
+mkdirprog="${MKDIRPROG-mkdir}"
+
+transformbasename=""
+transform_arg=""
+instcmd="$mvprog"
+chmodcmd="$chmodprog 0755"
+chowncmd=""
+chgrpcmd=""
+stripcmd=""
+rmcmd="$rmprog -f"
+mvcmd="$mvprog"
+src=""
+dst=""
+dir_arg=""
+
+while [ x"$1" != x ]; do
+    case $1 in
+       -c) instcmd="$cpprog"
+           shift
+           continue;;
+
+       -d) dir_arg=true
+           shift
+           continue;;
+
+       -m) chmodcmd="$chmodprog $2"
+           shift
+           shift
+           continue;;
+
+       -o) chowncmd="$chownprog $2"
+           shift
+           shift
+           continue;;
+
+       -g) chgrpcmd="$chgrpprog $2"
+           shift
+           shift
+           continue;;
+
+       -s) stripcmd="$stripprog"
+           shift
+           continue;;
+
+       -t=*) transformarg=`echo $1 | sed 's/-t=//'`
+           shift
+           continue;;
+
+       -b=*) transformbasename=`echo $1 | sed 's/-b=//'`
+           shift
+           continue;;
+
+       *)  if [ x"$src" = x ]
+           then
+               src=$1
+           else
+               # this colon is to work around a 386BSD /bin/sh bug
+               :
+               dst=$1
+           fi
+           shift
+           continue;;
+    esac
+done
+
+if [ x"$src" = x ]
+then
+       echo "install:  no input file specified"
+       exit 1
+else
+       true
+fi
+
+if [ x"$dir_arg" != x ]; then
+       dst=$src
+       src=""
+       
+       if [ -d $dst ]; then
+               instcmd=:
+       else
+               instcmd=mkdir
+       fi
+else
+
+# Waiting for this to be detected by the "$instcmd $src $dsttmp" command
+# might cause directories to be created, which would be especially bad 
+# if $src (and thus $dsttmp) contains '*'.
+
+       if [ -f $src -o -d $src ]
+       then
+               true
+       else
+               echo "install:  $src does not exist"
+               exit 1
+       fi
+       
+       if [ x"$dst" = x ]
+       then
+               echo "install:  no destination specified"
+               exit 1
+       else
+               true
+       fi
+
+# If destination is a directory, append the input filename; if your system
+# does not like double slashes in filenames, you may need to add some logic
+
+       if [ -d $dst ]
+       then
+               dst="$dst"/`basename $src`
+       else
+               true
+       fi
+fi
+
+## this sed command emulates the dirname command
+dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
+
+# Make sure that the destination directory exists.
+#  this part is taken from Noah Friedman's mkinstalldirs script
+
+# Skip lots of stat calls in the usual case.
+if [ ! -d "$dstdir" ]; then
+defaultIFS='   
+'
+IFS="${IFS-${defaultIFS}}"
+
+oIFS="${IFS}"
+# Some sh's can't handle IFS=/ for some reason.
+IFS='%'
+set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'`
+IFS="${oIFS}"
+
+pathcomp=''
+
+while [ $# -ne 0 ] ; do
+       pathcomp="${pathcomp}${1}"
+       shift
+
+       if [ ! -d "${pathcomp}" ] ;
+        then
+               $mkdirprog "${pathcomp}"
+       else
+               true
+       fi
+
+       pathcomp="${pathcomp}/"
+done
+fi
+
+if [ x"$dir_arg" != x ]
+then
+       $doit $instcmd $dst &&
+
+       if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi &&
+       if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi &&
+       if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi &&
+       if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi
+else
+
+# If we're going to rename the final executable, determine the name now.
+
+       if [ x"$transformarg" = x ] 
+       then
+               dstfile=`basename $dst`
+       else
+               dstfile=`basename $dst $transformbasename | 
+                       sed $transformarg`$transformbasename
+       fi
+
+# don't allow the sed command to completely eliminate the filename
+
+       if [ x"$dstfile" = x ] 
+       then
+               dstfile=`basename $dst`
+       else
+               true
+       fi
+
+# Make a temp file name in the proper directory.
+
+       dsttmp=$dstdir/#inst.$$#
+
+# Move or copy the file name to the temp name
+
+       $doit $instcmd $src $dsttmp &&
+
+       trap "rm -f ${dsttmp}" 0 &&
+
+# and set any options; do chmod last to preserve setuid bits
+
+# If any of these fail, we abort the whole thing.  If we want to
+# ignore errors from any of these, just make sure not to ignore
+# errors from the above "$doit $instcmd $src $dsttmp" command.
+
+       if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi &&
+       if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi &&
+       if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi &&
+       if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi &&
+
+# Now rename the file to the real destination.
+
+       $doit $rmcmd -f $dstdir/$dstfile &&
+       $doit $mvcmd $dsttmp $dstdir/$dstfile 
+
+fi &&
+
+
+exit 0
diff --git a/package/ead/src/tinysrp/missing b/package/ead/src/tinysrp/missing
new file mode 100755 (executable)
index 0000000..a6abd06
--- /dev/null
@@ -0,0 +1,134 @@
+#! /bin/sh
+# Common stub for a few missing GNU programs while installing.
+# Copyright (C) 1996, 1997 Free Software Foundation, Inc.
+# Franc,ois Pinard <pinard@iro.umontreal.ca>, 1996.
+
+# 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, 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., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+if test $# -eq 0; then
+  echo 1>&2 "Try \`$0 --help' for more information"
+  exit 1
+fi
+
+case "$1" in
+
+  -h|--h|--he|--hel|--help)
+    echo "\
+$0 [OPTION]... PROGRAM [ARGUMENT]...
+
+Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an
+error status if there is no known handling for PROGRAM.
+
+Options:
+  -h, --help      display this help and exit
+  -v, --version   output version information and exit
+
+Supported PROGRAM values:
+  aclocal      touch file \`aclocal.m4'
+  autoconf     touch file \`configure'
+  autoheader   touch file \`config.h.in'
+  automake     touch all \`Makefile.in' files
+  bison        touch file \`y.tab.c'
+  makeinfo     touch the output file
+  yacc         touch file \`y.tab.c'"
+    ;;
+
+  -v|--v|--ve|--ver|--vers|--versi|--versio|--version)
+    echo "missing - GNU libit 0.0"
+    ;;
+
+  -*)
+    echo 1>&2 "$0: Unknown \`$1' option"
+    echo 1>&2 "Try \`$0 --help' for more information"
+    exit 1
+    ;;
+
+  aclocal)
+    echo 1>&2 "\
+WARNING: \`$1' is missing on your system.  You should only need it if
+         you modified \`acinclude.m4' or \`configure.in'.  You might want
+         to install the \`Automake' and \`Perl' packages.  Grab them from
+         any GNU archive site."
+    touch aclocal.m4
+    ;;
+
+  autoconf)
+    echo 1>&2 "\
+WARNING: \`$1' is missing on your system.  You should only need it if
+         you modified \`configure.in'.  You might want to install the
+         \`Autoconf' and \`GNU m4' packages.  Grab them from any GNU
+         archive site."
+    touch configure
+    ;;
+
+  autoheader)
+    echo 1>&2 "\
+WARNING: \`$1' is missing on your system.  You should only need it if
+         you modified \`acconfig.h' or \`configure.in'.  You might want
+         to install the \`Autoconf' and \`GNU m4' packages.  Grab them
+         from any GNU archive site."
+    touch config.h.in
+    ;;
+
+  automake)
+    echo 1>&2 "\
+WARNING: \`$1' is missing on your system.  You should only need it if
+         you modified \`Makefile.am', \`acinclude.m4' or \`configure.in'.
+         You might want to install the \`Automake' and \`Perl' packages.
+         Grab them from any GNU archive site."
+    find . -type f -name Makefile.am -print \
+      | sed 's/^\(.*\).am$/touch \1.in/' \
+      | sh
+    ;;
+
+  bison|yacc)
+    echo 1>&2 "\
+WARNING: \`$1' is missing on your system.  You should only need it if
+         you modified a \`.y' file.  You may need the \`Bison' package
+         in order for those modifications to take effect.  You can get
+         \`Bison' from any GNU archive site."
+    touch y.tab.c
+    ;;
+
+  makeinfo)
+    echo 1>&2 "\
+WARNING: \`$1' is missing on your system.  You should only need it if
+         you modified a \`.texi' or \`.texinfo' file, or any other file
+         indirectly affecting the aspect of the manual.  The spurious
+         call might also be the consequence of using a buggy \`make' (AIX,
+         DU, IRIX).  You might want to install the \`Texinfo' package or
+         the \`GNU make' package.  Grab either from any GNU archive site."
+    file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'`
+    if test -z "$file"; then
+      file=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'`
+      file=`sed -n '/^@setfilename/ { s/.* \([^ ]*\) *$/\1/; p; q; }' $file`
+    fi
+    touch $file
+    ;;
+
+  *)
+    echo 1>&2 "\
+WARNING: \`$1' is needed, and you do not seem to have it handy on your
+         system.  You might have modified some files without having the
+         proper tools for further handling them.  Check the \`README' file,
+         it often tells you about the needed prerequirements for installing
+         this package.  You may also peek at any GNU archive site, in case
+         some other package would contain this missing \`$1' program."
+    exit 1
+    ;;
+esac
+
+exit 0
diff --git a/package/ead/src/tinysrp/mkinstalldirs b/package/ead/src/tinysrp/mkinstalldirs
new file mode 100755 (executable)
index 0000000..a01481b
--- /dev/null
@@ -0,0 +1,40 @@
+#! /bin/sh
+# mkinstalldirs --- make directory hierarchy
+# Author: Noah Friedman <friedman@prep.ai.mit.edu>
+# Created: 1993-05-16
+# Public domain
+
+# $Id: mkinstalldirs,v 1.10 1996/05/03 07:37:52 friedman Exp $
+
+errstatus=0
+
+for file
+do
+   set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'`
+   shift
+
+   pathcomp=
+   for d
+   do
+     pathcomp="$pathcomp$d"
+     case "$pathcomp" in
+       -* ) pathcomp=./$pathcomp ;;
+     esac
+
+     if test ! -d "$pathcomp"; then
+        echo "mkdir $pathcomp" 1>&2
+
+        mkdir "$pathcomp" || lasterr=$?
+
+        if test ! -d "$pathcomp"; then
+         errstatus=$lasterr
+        fi
+     fi
+
+     pathcomp="$pathcomp/"
+   done
+done
+
+exit $errstatus
+
+# mkinstalldirs ends here
diff --git a/package/ead/src/tinysrp/srvtest.c b/package/ead/src/tinysrp/srvtest.c
new file mode 100644 (file)
index 0000000..e09d501
--- /dev/null
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 1997-1999  The Stanford SRP Authentication Project
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL STANFORD BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF
+ * THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * In addition, the following conditions apply:
+ *
+ * 1. Any software that incorporates the SRP authentication technology
+ *    must display the following acknowlegment:
+ *    "This product uses the 'Secure Remote Password' cryptographic
+ *     authentication system developed by Tom Wu (tjw@CS.Stanford.EDU)."
+ *
+ * 2. Any software that incorporates all or part of the SRP distribution
+ *    itself must also display the following acknowledgment:
+ *    "This product includes software developed by Tom Wu and Eugene
+ *     Jhong for the SRP Distribution (http://srp.stanford.edu/srp/)."
+ *
+ * 3. Redistributions in source or binary form must retain an intact copy
+ *    of this copyright notice and list of conditions.
+ */
+
+#include <stdio.h>
+#include "t_defines.h"
+#include "t_pwd.h"
+#include "t_server.h"
+
+int
+main(argc, argv)
+     int argc;
+     char * argv[];
+{
+  struct t_server * ts;
+  struct t_pw * tpw;
+  struct t_conf * tcnf;
+  struct t_num * B;
+  char username[MAXUSERLEN];
+  char hexbuf[MAXHEXPARAMLEN];
+  char buf[MAXPARAMLEN];
+  struct t_num A;
+  unsigned char * skey;
+  unsigned char cbuf[20];
+  FILE * fp;
+  FILE * fp2;
+  char confname[256];
+
+  printf("Enter username: ");
+  fgets(username, sizeof(username), stdin);
+  username[strlen(username) - 1] = '\0';
+  ts = t_serveropen(username);
+
+  if(ts == NULL) {
+    fprintf(stderr, "User %s not found\n", username);
+    exit(1);
+  }
+
+#if 0
+  printf("n: %s\n", t_tob64(hexbuf, ts->n.data, ts->n.len));
+  printf("g: %s\n", t_tob64(hexbuf, ts->g.data, ts->g.len));
+#endif
+  printf("index (to client): %d\n", ts->index);
+  printf("salt (to client): %s\n", t_tob64(hexbuf, ts->s.data, ts->s.len));
+
+  B = t_servergenexp(ts);
+  printf("Enter A (from client): ");
+  fgets(hexbuf, sizeof(hexbuf), stdin);
+  A.data = buf;
+  A.len = t_fromb64(A.data, hexbuf);
+
+  printf("B (to client): %s\n", t_tob64(hexbuf, B->data, B->len));
+
+  skey = t_servergetkey(ts, &A);
+  printf("Session key: %s\n", t_tohex(hexbuf, skey, 40));
+
+  /* printf("[Expected response: %s]\n", t_tohex(hexbuf, cbuf, 16)); */
+
+  printf("Enter response (from client): ");
+  fgets(hexbuf, sizeof(hexbuf), stdin);
+  hexbuf[strlen(hexbuf) - 1] = '\0';
+  t_fromhex(cbuf, hexbuf);
+
+  if(t_serververify(ts, cbuf) == 0) {
+    printf("Authentication successful.\n");
+    printf("Response (to client): %s\n",
+      t_tohex(hexbuf, t_serverresponse(ts), RESPONSE_LEN));
+  } else
+    printf("Authentication failed.\n");
+
+  t_serverclose(ts);
+
+  return 0;
+}
diff --git a/package/ead/src/tinysrp/stamp-h.in b/package/ead/src/tinysrp/stamp-h.in
new file mode 100644 (file)
index 0000000..9788f70
--- /dev/null
@@ -0,0 +1 @@
+timestamp
diff --git a/package/ead/src/tinysrp/t_client.c b/package/ead/src/tinysrp/t_client.c
new file mode 100644 (file)
index 0000000..ebdd203
--- /dev/null
@@ -0,0 +1,287 @@
+/*
+ * Copyright (c) 1997-1999  The Stanford SRP Authentication Project
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL STANFORD BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF
+ * THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * In addition, the following conditions apply:
+ *
+ * 1. Any software that incorporates the SRP authentication technology
+ *    must display the following acknowlegment:
+ *    "This product uses the 'Secure Remote Password' cryptographic
+ *     authentication system developed by Tom Wu (tjw@CS.Stanford.EDU)."
+ *
+ * 2. Any software that incorporates all or part of the SRP distribution
+ *    itself must also display the following acknowledgment:
+ *    "This product includes software developed by Tom Wu and Eugene
+ *     Jhong for the SRP Distribution (http://srp.stanford.edu/srp/)."
+ *
+ * 3. Redistributions in source or binary form must retain an intact copy
+ *    of this copyright notice and list of conditions.
+ */
+
+#include <stdio.h>
+#include "t_defines.h"
+#include "t_pwd.h"
+#include "t_client.h"
+#include "t_sha.h"
+
+_TYPE( struct t_client * )
+t_clientopen(u, n, g, s)
+     const char * u;
+     struct t_num * n;
+     struct t_num * g;
+     struct t_num * s;
+{
+  struct t_client * tc;
+  unsigned char buf1[SHA_DIGESTSIZE], buf2[SHA_DIGESTSIZE];
+  SHA1_CTX ctxt;
+  int i, validated;
+  struct t_preconf * tpc;
+
+  BigInteger nn, gg, n12, r;
+
+  validated = 0;
+  if(n->len < MIN_MOD_BYTES)
+    return 0;
+  for(i = 0; i < t_getprecount(); ++i) {
+    tpc = t_getpreparam(i);
+    if(tpc->modulus.len == n->len && tpc->generator.len == g->len &&
+       memcmp(tpc->modulus.data, n->data, n->len) == 0 &&
+       memcmp(tpc->generator.data, g->data, g->len) == 0) {
+      validated = 1;    /* Match found, done */
+      break;
+    }
+  }
+
+  if(validated == 0)
+    return 0;
+
+  if((tc = malloc(sizeof(struct t_client))) == 0)
+    return 0;
+
+  strncpy(tc->username, u, MAXUSERLEN);
+
+  SHA1Init(&tc->hash);
+
+  tc->n.len = n->len;
+  tc->n.data = tc->nbuf;
+  memcpy(tc->n.data, n->data, tc->n.len);
+
+  SHA1Init(&ctxt);
+  SHA1Update(&ctxt, tc->n.data, tc->n.len);
+  SHA1Final(buf1, &ctxt);
+
+  tc->g.len = g->len;
+  tc->g.data = tc->gbuf;
+  memcpy(tc->g.data, g->data, tc->g.len);
+
+  SHA1Init(&ctxt);
+  SHA1Update(&ctxt, tc->g.data, tc->g.len);
+  SHA1Final(buf2, &ctxt);
+
+  for(i = 0; i < sizeof(buf1); ++i)
+    buf1[i] ^= buf2[i];
+
+  SHA1Update(&tc->hash, buf1, sizeof(buf1));
+
+  SHA1Init(&ctxt);
+  SHA1Update(&ctxt, tc->username, strlen(tc->username));
+  SHA1Final(buf1, &ctxt);
+
+  SHA1Update(&tc->hash, buf1, sizeof(buf1));
+
+  tc->s.len = s->len;
+  tc->s.data = tc->sbuf;
+  memcpy(tc->s.data, s->data, tc->s.len);
+
+  SHA1Update(&tc->hash, tc->s.data, tc->s.len);
+
+  tc->a.data = tc->abuf;
+  tc->A.data = tc->Abuf;
+  tc->p.data = tc->pbuf;
+  tc->v.data = tc->vbuf;
+
+  SHA1Init(&tc->ckhash);
+
+  return tc;
+}
+
+_TYPE( struct t_num * )
+t_clientgenexp(tc)
+     struct t_client * tc;
+{
+  BigInteger a, A, n, g;
+
+  if(tc->n.len < ALEN)
+    tc->a.len = tc->n.len;
+  else
+    tc->a.len = ALEN;
+
+  t_random(tc->a.data, tc->a.len);
+  a = BigIntegerFromBytes(tc->a.data, tc->a.len);
+  n = BigIntegerFromBytes(tc->n.data, tc->n.len);
+  g = BigIntegerFromBytes(tc->g.data, tc->g.len);
+  A = BigIntegerFromInt(0);
+  BigIntegerModExp(A, g, a, n);
+  tc->A.len = BigIntegerToBytes(A, tc->A.data);
+
+  BigIntegerFree(A);
+  BigIntegerFree(a);
+  BigIntegerFree(g);
+  BigIntegerFree(n);
+
+  SHA1Update(&tc->hash, tc->A.data, tc->A.len);
+  SHA1Update(&tc->ckhash, tc->A.data, tc->A.len);
+
+  return &tc->A;
+}
+
+_TYPE( void )
+t_clientpasswd(tc, password)
+     struct t_client * tc;
+     char * password;
+{
+  BigInteger n, g, p, v;
+  SHA1_CTX ctxt;
+  unsigned char dig[SHA_DIGESTSIZE];
+
+  n = BigIntegerFromBytes(tc->n.data, tc->n.len);
+  g = BigIntegerFromBytes(tc->g.data, tc->g.len);
+
+  SHA1Init(&ctxt);
+  SHA1Update(&ctxt, tc->username, strlen(tc->username));
+  SHA1Update(&ctxt, ":", 1);
+  SHA1Update(&ctxt, password, strlen(password));
+  SHA1Final(dig, &ctxt);
+
+  SHA1Init(&ctxt);
+  SHA1Update(&ctxt, tc->s.data, tc->s.len);
+  SHA1Update(&ctxt, dig, sizeof(dig));
+  SHA1Final(dig, &ctxt);
+
+  p = BigIntegerFromBytes(dig, sizeof(dig));
+
+  v = BigIntegerFromInt(0);
+  BigIntegerModExp(v, g, p, n);
+
+  tc->p.len = BigIntegerToBytes(p, tc->p.data);
+  BigIntegerFree(p);
+
+  tc->v.len = BigIntegerToBytes(v, tc->v.data);
+  BigIntegerFree(v);
+}
+
+_TYPE( unsigned char * )
+t_clientgetkey(tc, serverval)
+     struct t_client * tc;
+     struct t_num * serverval;
+{
+  BigInteger n, B, v, p, a, sum, S;
+  unsigned char sbuf[MAXPARAMLEN];
+  unsigned char dig[SHA_DIGESTSIZE];
+  unsigned slen;
+  unsigned int u;
+  SHA1_CTX ctxt;
+
+  SHA1Init(&ctxt);
+  SHA1Update(&ctxt, serverval->data, serverval->len);
+  SHA1Final(dig, &ctxt);
+  u = (dig[0] << 24) | (dig[1] << 16) | (dig[2] << 8) | dig[3];
+  if(u == 0)
+    return NULL;
+
+  SHA1Update(&tc->hash, serverval->data, serverval->len);
+
+  B = BigIntegerFromBytes(serverval->data, serverval->len);
+  n = BigIntegerFromBytes(tc->n.data, tc->n.len);
+
+  if(BigIntegerCmp(B, n) >= 0 || BigIntegerCmpInt(B, 0) == 0) {
+    BigIntegerFree(B);
+    BigIntegerFree(n);
+    return NULL;
+  }
+  v = BigIntegerFromBytes(tc->v.data, tc->v.len);
+  if(BigIntegerCmp(B, v) < 0)
+    BigIntegerAdd(B, B, n);
+  BigIntegerSub(B, B, v);
+  BigIntegerFree(v);
+
+  a = BigIntegerFromBytes(tc->a.data, tc->a.len);
+  p = BigIntegerFromBytes(tc->p.data, tc->p.len);
+
+  sum = BigIntegerFromInt(0);
+  BigIntegerMulInt(sum, p, u);
+  BigIntegerAdd(sum, sum, a);
+
+  BigIntegerFree(p);
+  BigIntegerFree(a);
+
+  S = BigIntegerFromInt(0);
+  BigIntegerModExp(S, B, sum, n);
+  slen = BigIntegerToBytes(S, sbuf);
+
+  BigIntegerFree(S);
+  BigIntegerFree(sum);
+  BigIntegerFree(B);
+  BigIntegerFree(n);
+
+  t_sessionkey(tc->session_key, sbuf, slen);
+  memset(sbuf, 0, slen);
+
+  SHA1Update(&tc->hash, tc->session_key, sizeof(tc->session_key));
+
+  SHA1Final(tc->session_response, &tc->hash);
+  SHA1Update(&tc->ckhash, tc->session_response, sizeof(tc->session_response));
+  SHA1Update(&tc->ckhash, tc->session_key, sizeof(tc->session_key));
+
+  return tc->session_key;
+}
+
+_TYPE( int )
+t_clientverify(tc, resp)
+    struct t_client * tc;
+    unsigned char * resp;
+{
+  unsigned char expected[SHA_DIGESTSIZE];
+
+  SHA1Final(expected, &tc->ckhash);
+  return memcmp(expected, resp, sizeof(expected));
+}
+
+_TYPE( unsigned char * )
+t_clientresponse(tc)
+    struct t_client * tc;
+{
+  return tc->session_response;
+}
+
+_TYPE( void )
+t_clientclose(tc)
+     struct t_client * tc;
+{
+  memset(tc->abuf, 0, sizeof(tc->abuf));
+  memset(tc->pbuf, 0, sizeof(tc->pbuf));
+  memset(tc->vbuf, 0, sizeof(tc->vbuf));
+  memset(tc->session_key, 0, sizeof(tc->session_key));
+  free(tc);
+}
diff --git a/package/ead/src/tinysrp/t_client.h b/package/ead/src/tinysrp/t_client.h
new file mode 100644 (file)
index 0000000..42922af
--- /dev/null
@@ -0,0 +1,148 @@
+/*
+ * Copyright (c) 1997-1999  The Stanford SRP Authentication Project
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL STANFORD BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF
+ * THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * In addition, the following conditions apply:
+ *
+ * 1. Any software that incorporates the SRP authentication technology
+ *    must display the following acknowlegment:
+ *    "This product uses the 'Secure Remote Password' cryptographic
+ *     authentication system developed by Tom Wu (tjw@CS.Stanford.EDU)."
+ *
+ * 2. Any software that incorporates all or part of the SRP distribution
+ *    itself must also display the following acknowledgment:
+ *    "This product includes software developed by Tom Wu and Eugene
+ *     Jhong for the SRP Distribution (http://srp.stanford.edu/srp/)."
+ *
+ * 3. Redistributions in source or binary form must retain an intact copy
+ *    of this copyright notice and list of conditions.
+ */
+
+#ifndef T_CLIENT_H
+#define T_CLIENT_H
+
+#include "t_sha.h"
+
+#if     !defined(P)
+#ifdef  __STDC__
+#define P(x)    x
+#else
+#define P(x)    ()
+#endif
+#endif
+
+/*      For building dynamic link libraries under windows, windows NT
+ *      using MSVC1.5 or MSVC2.0
+ */
+
+#ifndef _DLLDECL
+#define _DLLDECL
+
+#ifdef MSVC15   /* MSVC1.5 support for 16 bit apps */
+#define _MSVC15EXPORT _export
+#define _MSVC20EXPORT
+#define _DLLAPI _export _pascal
+#define _TYPE(a) a _MSVC15EXPORT
+#define DLLEXPORT 1
+
+#elif MSVC20
+#define _MSVC15EXPORT
+#define _MSVC20EXPORT _declspec(dllexport)
+#define _DLLAPI
+#define _TYPE(a) _MSVC20EXPORT a
+#define DLLEXPORT 1
+
+#else                   /* Default, non-dll.  Use this for Unix or DOS */
+#define _MSVC15DEXPORT
+#define _MSVC20EXPORT
+#define _DLLAPI
+#define _TYPE(a) a
+#endif
+#endif
+
+#define ALEN 32
+#define MIN_MOD_BYTES 64        /* 512 bits */
+
+struct t_client {
+  struct t_num n;
+  struct t_num g;
+  struct t_num s;
+
+  struct t_num a;
+  struct t_num A;
+
+  struct t_num p;
+  struct t_num v;
+
+  SHA1_CTX hash, ckhash;
+
+  char username[MAXUSERLEN];
+  unsigned char session_key[SESSION_KEY_LEN];
+  unsigned char session_response[RESPONSE_LEN];
+
+  unsigned char nbuf[MAXPARAMLEN], gbuf[MAXPARAMLEN], sbuf[MAXSALTLEN];
+  unsigned char pbuf[MAXPARAMLEN], vbuf[MAXPARAMLEN];
+  unsigned char abuf[ALEN], Abuf[MAXPARAMLEN];
+};
+
+/*
+ * SRP client-side negotiation
+ *
+ * This code negotiates the client side of an SRP exchange.
+ * "t_clientopen" accepts a username, and N, g, and s parameters,
+ *   which are usually sent by the server in the first round.
+ *   The client should then call...
+ * "t_clientgenexp" will generate a random 256-bit exponent and
+ *   raise g to that power, returning the result.  This result
+ *   should be sent to the server as w(p).
+ * "t_clientpasswd" accepts the user's password, which should be
+ *   entered locally and updates the client's state.
+ * "t_clientgetkey" accepts the exponential y(p), which should
+ *   be sent by the server in the next round and computes the
+ *   256-bit session key.  This data should be saved before the
+ *   session is closed.
+ * "t_clientresponse" computes the session key proof as SHA(y(p), K).
+ * "t_clientclose" closes the session and frees its memory.
+ *
+ * Note that authentication is not performed per se; it is up
+ * to either/both sides of the protocol to now verify securely
+ * that their session keys agree in order to establish authenticity.
+ * One possible way is through "oracle hashing"; one side sends
+ * r, the other replies with H(r,K), where H() is a hash function.
+ *
+ * t_clientresponse and t_clientverify now implement a version of
+ * the session-key verification described above.
+ */
+_TYPE( struct t_client * )
+  t_clientopen P((const char *, struct t_num *, struct t_num *,
+                 struct t_num *));
+_TYPE( struct t_num * ) t_clientgenexp P((struct t_client *));
+_TYPE( void ) t_clientpasswd P((struct t_client *, char *));
+_TYPE( unsigned char * )
+  t_clientgetkey P((struct t_client *, struct t_num *));
+_TYPE( int ) t_clientverify P((struct t_client *, unsigned char *));
+_TYPE( unsigned char * ) t_clientresponse P((struct t_client *));
+_TYPE( void ) t_clientclose P((struct t_client *));
+
+#endif
diff --git a/package/ead/src/tinysrp/t_conf.c b/package/ead/src/tinysrp/t_conf.c
new file mode 100644 (file)
index 0000000..fbe6f41
--- /dev/null
@@ -0,0 +1,1080 @@
+/*
+ * Copyright (c) 1997-1999  The Stanford SRP Authentication Project
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL STANFORD BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF
+ * THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * In addition, the following conditions apply:
+ *
+ * 1. Any software that incorporates the SRP authentication technology
+ *    must display the following acknowlegment:
+ *    "This product uses the 'Secure Remote Password' cryptographic
+ *     authentication system developed by Tom Wu (tjw@CS.Stanford.EDU)."
+ *
+ * 2. Any software that incorporates all or part of the SRP distribution
+ *    itself must also display the following acknowledgment:
+ *    "This product includes software developed by Tom Wu and Eugene
+ *     Jhong for the SRP Distribution (http://srp.stanford.edu/srp/)."
+ *
+ * 3. Redistributions in source or binary form must retain an intact copy
+ *    of this copyright notice and list of conditions.
+ */
+
+#include <stdio.h>
+
+#include "t_defines.h"
+#include "t_pwd.h"
+#include "t_read.h"
+#include "bn.h"
+#include "bn_lcl.h"
+#include "bn_prime.h"
+
+#define TABLE_SIZE      32
+
+static int witness(BIGNUM *w, const BIGNUM *a, const BIGNUM *a1,
+       const BIGNUM *a1_odd, int k, BN_CTX *ctx, BN_MONT_CTX *mont);
+
+/*
+ * This is the safe prime generation logic.
+ * To generate a safe prime p (where p = 2q+1 and q is prime), we start
+ * with a random odd q that is one bit shorter than the desired length
+ * of p.  We use a simple 30-element sieve to filter the values of q
+ * and consider only those that are 11, 23, or 29 (mod 30).  (If q were
+ * anything else, either q or p would be divisible by 2, 3, or 5).
+ * For the values of q that are left, we apply the following tests in
+ * this order:
+ *
+ *   trial divide q
+ *   let p = 2q + 1
+ *   trial divide p
+ *   apply Fermat test to q (2^q == 2 (mod q))
+ *   apply Fermat test to p (2^p == 2 (mod p))
+ *   apply real probablistic primality test to q
+ *   apply real probablistic primality test to p
+ *
+ * A number that passes all these tests is considered a safe prime for
+ * our purposes.  The tests are ordered this way for efficiency; the
+ * slower tests are run rarely if ever at all.
+ */
+
+static int
+trialdiv(x)
+     const BigInteger x;
+{
+  static int primes[] = {               /* All odd primes < 256 */
+      3,   5,   7,  11,  13,  17,  19,  23,  29,
+     31,  37,  41,  43,  47,  53,  59,  61,  67,
+     71,  73,  79,  83,  89,  97, 101, 103,
+    107, 109, 113, 127, 131, 137, 139, 149, 151,
+    157, 163, 167, 173, 179, 181, 191, 193, 197,
+    199, 211, 223, 227, 229, 233, 239, 241, 251
+  };
+  static int nprimes = sizeof(primes) / sizeof(int);
+  int i;
+
+  for(i = 0; i < nprimes; ++i) {
+    if(BigIntegerModInt(x, primes[i]) == 0)
+      return primes[i];
+  }
+  return 1;
+}
+
+/* x + sieve30[x%30] == 11, 23, or 29 (mod 30) */
+
+static int sieve30[] =
+{  11, 10,  9,  8,  7,  6,  5,  4,  3,  2,
+    1, 12, 11, 10,  9,  8,  7,  6,  5,  4,
+    3,  2,  1,  6,  5,  4,  3,  2,  1, 12
+};
+
+/* Find a Sophie-Germain prime between "lo" and "hi".  NOTE: this is not
+   a "safe prime", but the smaller prime.  Take 2q+1 to get the safe prime. */
+
+static void
+sophie_germain(q, lo, hi)
+     BigInteger q;              /* assumed initialized */
+     const BigInteger lo;
+     const BigInteger hi;
+{
+  BigInteger m, p, r;
+  char parambuf[MAXPARAMLEN];
+  int foundprime = 0;
+  int i, mod30;
+
+  m = BigIntegerFromInt(0);
+  BigIntegerSub(m, hi, lo);
+  i = (BigIntegerBitLen(m) + 7) / 8;
+  t_random(parambuf, i);
+  r = BigIntegerFromBytes(parambuf, i);
+  BigIntegerMod(r, r, m);
+
+  BigIntegerAdd(q, r, lo);
+  if(BigIntegerModInt(q, 2) == 0)
+    BigIntegerAddInt(q, q, 1);          /* make q odd */
+
+  mod30 = BigIntegerModInt(q, 30);      /* mod30 = q % 30 */
+
+  BigIntegerFree(m);
+  m = BigIntegerFromInt(2);                     /* m = 2 */
+  p = BigIntegerFromInt(0);
+
+  while(BigIntegerCmp(q, hi) < 0) {
+    if(trialdiv(q) < 2) {
+      BigIntegerMulInt(p, q, 2);                        /* p = 2 * q */
+      BigIntegerAddInt(p, p, 1);                /* p += 1 */
+      if(trialdiv(p) < 2) {
+       BigIntegerModExp(r, m, q, q);           /* r = 2^q % q */
+       if(BigIntegerCmpInt(r, 2) == 0) {       /* if(r == 2) */
+         BigIntegerModExp(r, m, p, p);         /* r = 2^p % p */
+         if(BigIntegerCmpInt(r, 2) == 0) {     /* if(r == 2) */
+           if(BigIntegerCheckPrime(q) && BigIntegerCheckPrime(p)) {
+             ++foundprime;
+             break;
+           }
+         }
+       }
+      }
+    }
+
+    i = sieve30[mod30];
+    BigIntegerAddInt(q, q, i);          /* q += i */
+    mod30 = (mod30 + i) % 30;
+  }
+
+  /* should wrap around on failure */
+  if(!foundprime) {
+    fprintf(stderr, "Prime generation failed!\n");
+    exit(1);
+  }
+
+  BigIntegerFree(r);
+  BigIntegerFree(m);
+  BigIntegerFree(p);
+}
+
+_TYPE( struct t_confent * )
+t_makeconfent(tc, nsize)
+     struct t_conf * tc;
+     int nsize;
+{
+  BigInteger n, g, q, t, u;
+
+  t = BigIntegerFromInt(0);
+  u = BigIntegerFromInt(1);             /* u = 1 */
+  BigIntegerLShift(t, u, nsize - 2);    /* t = 2^(nsize-2) */
+  BigIntegerMulInt(u, t, 2);            /* u = 2^(nsize-1) */
+
+  q = BigIntegerFromInt(0);
+  sophie_germain(q, t, u);
+
+  n = BigIntegerFromInt(0);
+  BigIntegerMulInt(n, q, 2);
+  BigIntegerAddInt(n, n, 1);
+
+  /* Look for a generator mod n */
+  g = BigIntegerFromInt(2);
+  while(1) {
+    BigIntegerModExp(t, g, q, n);               /* t = g^q % n */
+    if(BigIntegerCmpInt(t, 1) == 0)             /* if(t == 1) */
+      BigIntegerAddInt(g, g, 1);                /* ++g */
+    else
+      break;
+  }
+  BigIntegerFree(t);
+  BigIntegerFree(u);
+  BigIntegerFree(q);
+
+  tc->tcbuf.modulus.data = tc->modbuf;
+  tc->tcbuf.modulus.len = BigIntegerToBytes(n, tc->tcbuf.modulus.data);
+  BigIntegerFree(n);
+
+  tc->tcbuf.generator.data = tc->genbuf;
+  tc->tcbuf.generator.len = BigIntegerToBytes(g, tc->tcbuf.generator.data);
+  BigIntegerFree(g);
+
+  tc->tcbuf.index = 1;
+  return &tc->tcbuf;
+}
+
+_TYPE( struct t_confent * )
+t_makeconfent_c(tc, nsize)
+     struct t_conf * tc;
+     int nsize;
+{
+  BigInteger g, n, p, q, j, k, t, u;
+  int psize, qsize;
+
+  psize = nsize / 2;
+  qsize = nsize - psize;
+
+  t = BigIntegerFromInt(1);             /* t = 1 */
+  u = BigIntegerFromInt(0);
+  BigIntegerLShift(u, t, psize - 3);    /* u = t*2^(psize-3) = 2^(psize-3) */
+  BigIntegerMulInt(t, u, 3);                    /* t = 3*u = 1.5*2^(psize-2) */
+  BigIntegerAdd(u, u, t);                       /* u += t [u = 2^(psize-1)] */
+  j = BigIntegerFromInt(0);
+  sophie_germain(j, t, u);
+
+  k = BigIntegerFromInt(0);
+  if(qsize != psize) {
+    BigIntegerFree(t);
+    t = BigIntegerFromInt(1);           /* t = 1 */
+    BigIntegerLShift(u, t, qsize - 3);  /* u = t*2^(qsize-3) = 2^(qsize-3) */
+    BigIntegerMulInt(t, u, 3);          /* t = 3*u = 1.5*2^(qsize-2) */
+    BigIntegerAdd(u, u, t);             /* u += t [u = 2^(qsize-1)] */
+  }
+  sophie_germain(k, t, u);
+
+  p = BigIntegerFromInt(0);
+  BigIntegerMulInt(p, j, 2);            /* p = 2 * j */
+  BigIntegerAddInt(p, p, 1);            /* p += 1 */
+
+  q = BigIntegerFromInt(0);
+  BigIntegerMulInt(q, k, 2);            /* q = 2 * k */
+  BigIntegerAddInt(q, q, 1);            /* q += 1 */
+
+  n = BigIntegerFromInt(0);
+  BigIntegerMul(n, p, q);               /* n = p * q */
+  BigIntegerMul(u, j, k);               /* u = j * k */
+
+  BigIntegerFree(p);
+  BigIntegerFree(q);
+  BigIntegerFree(j);
+  BigIntegerFree(k);
+
+  g = BigIntegerFromInt(2);             /* g = 2 */
+
+  /* Look for a generator mod n */
+  while(1) {
+    BigIntegerModExp(t, g, u, n);       /* t = g^u % n */
+    if(BigIntegerCmpInt(t, 1) == 0)
+      BigIntegerAddInt(g, g, 1);        /* ++g */
+    else
+      break;
+  }
+
+  BigIntegerFree(u);
+  BigIntegerFree(t);
+
+  tc->tcbuf.modulus.data = tc->modbuf;
+  tc->tcbuf.modulus.len = BigIntegerToBytes(n, tc->tcbuf.modulus.data);
+  BigIntegerFree(n);
+
+  tc->tcbuf.generator.data = tc->genbuf;
+  tc->tcbuf.generator.len = BigIntegerToBytes(g, tc->tcbuf.generator.data);
+  BigIntegerFree(g);
+
+  tc->tcbuf.index = 1;
+  return &tc->tcbuf;
+}
+
+_TYPE( struct t_confent * )
+t_newconfent(tc)
+    struct t_conf * tc;
+{
+  tc->tcbuf.index = 0;
+  tc->tcbuf.modulus.data = tc->modbuf;
+  tc->tcbuf.modulus.len = 0;
+  tc->tcbuf.generator.data = tc->genbuf;
+  tc->tcbuf.generator.len = 0;
+  return &tc->tcbuf;
+}
+
+_TYPE( void )
+t_putconfent(ent, fp)
+     const struct t_confent * ent;
+     FILE * fp;
+{
+  char strbuf[MAXB64PARAMLEN];
+
+  fprintf(fp, "%d:%s:", ent->index,
+         t_tob64(strbuf, ent->modulus.data, ent->modulus.len));
+  fprintf(fp, "%s\n",
+         t_tob64(strbuf, ent->generator.data, ent->generator.len));
+}
+
+int
+BigIntegerBitLen(b)
+     BigInteger b;
+{
+  return BN_num_bits(b);
+}
+
+int
+BigIntegerCheckPrime(n)
+     BigInteger n;
+{
+  BN_CTX * ctx = BN_CTX_new();
+  int rv = BN_is_prime(n, 25, NULL, ctx, NULL);
+  BN_CTX_free(ctx);
+  return rv;
+}
+
+unsigned int
+BigIntegerModInt(d, m)
+     BigInteger d;
+     unsigned int m;
+{
+  return BN_mod_word(d, m);
+}
+
+void
+BigIntegerMod(result, d, m)
+     BigInteger result, d, m;
+{
+  BN_CTX * ctx = BN_CTX_new();
+  BN_mod(result, d, m, ctx);
+  BN_CTX_free(ctx);
+}
+
+void
+BigIntegerMul(result, m1, m2)
+     BigInteger result, m1, m2;
+{
+  BN_CTX * ctx = BN_CTX_new();
+  BN_mul(result, m1, m2, ctx);
+  BN_CTX_free(ctx);
+}
+
+void
+BigIntegerLShift(result, x, bits)
+     BigInteger result, x;
+     unsigned int bits;
+{
+  BN_lshift(result, x, bits);
+}
+
+int BN_is_prime(const BIGNUM *a, int checks, void (*callback)(int,int,void *),
+       BN_CTX *ctx_passed, void *cb_arg)
+       {
+       return BN_is_prime_fasttest(a, checks, callback, ctx_passed, cb_arg, 0);
+       }
+
+int BN_is_prime_fasttest(const BIGNUM *a, int checks,
+               void (*callback)(int,int,void *),
+               BN_CTX *ctx_passed, void *cb_arg,
+               int do_trial_division)
+       {
+       int i, j, ret = -1;
+       int k;
+       BN_CTX *ctx = NULL;
+       BIGNUM *A1, *A1_odd, *check; /* taken from ctx */
+       BN_MONT_CTX *mont = NULL;
+       const BIGNUM *A = NULL;
+
+       if (checks == BN_prime_checks)
+               checks = BN_prime_checks_for_size(BN_num_bits(a));
+
+       /* first look for small factors */
+       if (!BN_is_odd(a))
+               return(0);
+       if (do_trial_division)
+               {
+               for (i = 1; i < NUMPRIMES; i++)
+                       if (BN_mod_word(a, primes[i]) == 0)
+                               return 0;
+               if (callback != NULL) callback(1, -1, cb_arg);
+               }
+
+       if (ctx_passed != NULL)
+               ctx = ctx_passed;
+       else
+               if ((ctx=BN_CTX_new()) == NULL)
+                       goto err;
+       BN_CTX_start(ctx);
+
+       /* A := abs(a) */
+       if (a->neg)
+               {
+               BIGNUM *t;
+               if ((t = BN_CTX_get(ctx)) == NULL) goto err;
+               BN_copy(t, a);
+               t->neg = 0;
+               A = t;
+               }
+       else
+               A = a;
+       A1 = BN_CTX_get(ctx);
+       A1_odd = BN_CTX_get(ctx);
+       check = BN_CTX_get(ctx);
+       if (check == NULL) goto err;
+
+       /* compute A1 := A - 1 */
+       if (!BN_copy(A1, A))
+               goto err;
+       if (!BN_sub_word(A1, 1))
+               goto err;
+       if (BN_is_zero(A1))
+               {
+               ret = 0;
+               goto err;
+               }
+
+       /* write  A1  as  A1_odd * 2^k */
+       k = 1;
+       while (!BN_is_bit_set(A1, k))
+               k++;
+       if (!BN_rshift(A1_odd, A1, k))
+               goto err;
+
+       /* Montgomery setup for computations mod A */
+       mont = BN_MONT_CTX_new();
+       if (mont == NULL)
+               goto err;
+       if (!BN_MONT_CTX_set(mont, A, ctx))
+               goto err;
+
+       for (i = 0; i < checks; i++)
+               {
+               if (!BN_pseudo_rand(check, BN_num_bits(A1), 0, 0))
+                       goto err;
+               if (BN_cmp(check, A1) >= 0)
+                       if (!BN_sub(check, check, A1))
+                               goto err;
+               if (!BN_add_word(check, 1))
+                       goto err;
+               /* now 1 <= check < A */
+
+               j = witness(check, A, A1, A1_odd, k, ctx, mont);
+               if (j == -1) goto err;
+               if (j)
+                       {
+                       ret=0;
+                       goto err;
+                       }
+               if (callback != NULL) callback(1,i,cb_arg);
+               }
+       ret=1;
+err:
+       if (ctx != NULL)
+               {
+               BN_CTX_end(ctx);
+               if (ctx_passed == NULL)
+                       BN_CTX_free(ctx);
+               }
+       if (mont != NULL)
+               BN_MONT_CTX_free(mont);
+
+       return(ret);
+       }
+
+static int witness(BIGNUM *w, const BIGNUM *a, const BIGNUM *a1,
+       const BIGNUM *a1_odd, int k, BN_CTX *ctx, BN_MONT_CTX *mont)
+       {
+       if (!BN_mod_exp_mont(w, w, a1_odd, a, ctx, mont)) /* w := w^a1_odd mod a */
+               return -1;
+       if (BN_is_one(w))
+               return 0; /* probably prime */
+       if (BN_cmp(w, a1) == 0)
+               return 0; /* w == -1 (mod a),  'a' is probably prime */
+       while (--k)
+               {
+               if (!BN_mod_mul(w, w, w, a, ctx)) /* w := w^2 mod a */
+                       return -1;
+               if (BN_is_one(w))
+                       return 1; /* 'a' is composite, otherwise a previous 'w' would
+                                  * have been == -1 (mod 'a') */
+               if (BN_cmp(w, a1) == 0)
+                       return 0; /* w == -1 (mod a), 'a' is probably prime */
+               }
+       /* If we get here, 'w' is the (a-1)/2-th power of the original 'w',
+        * and it is neither -1 nor +1 -- so 'a' cannot be prime */
+       return 1;
+       }
+
+int BN_mod_exp_mont(BIGNUM *rr, BIGNUM *a, const BIGNUM *p,
+                   const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *in_mont)
+       {
+       int i,j,bits,ret=0,wstart,wend,window,wvalue;
+       int start=1,ts=0;
+       BIGNUM *d,*r;
+       BIGNUM *aa;
+       BIGNUM val[TABLE_SIZE];
+       BN_MONT_CTX *mont=NULL;
+
+       bn_check_top(a);
+       bn_check_top(p);
+       bn_check_top(m);
+
+       if (!(m->d[0] & 1))
+               {
+               return(0);
+               }
+       bits=BN_num_bits(p);
+       if (bits == 0)
+               {
+               BN_one(rr);
+               return(1);
+               }
+       BN_CTX_start(ctx);
+       d = BN_CTX_get(ctx);
+       r = BN_CTX_get(ctx);
+       if (d == NULL || r == NULL) goto err;
+
+       /* If this is not done, things will break in the montgomery
+        * part */
+
+       if (in_mont != NULL)
+               mont=in_mont;
+       else
+               {
+               if ((mont=BN_MONT_CTX_new()) == NULL) goto err;
+               if (!BN_MONT_CTX_set(mont,m,ctx)) goto err;
+               }
+
+       BN_init(&val[0]);
+       ts=1;
+       if (BN_ucmp(a,m) >= 0)
+               {
+               if (!BN_mod(&(val[0]),a,m,ctx))
+                       goto err;
+               aa= &(val[0]);
+               }
+       else
+               aa=a;
+       if (!BN_to_montgomery(&(val[0]),aa,mont,ctx)) goto err; /* 1 */
+
+       window = BN_window_bits_for_exponent_size(bits);
+       if (window > 1)
+               {
+               if (!BN_mod_mul_montgomery(d,&(val[0]),&(val[0]),mont,ctx)) goto err; /* 2 */
+               j=1<<(window-1);
+               for (i=1; i<j; i++)
+                       {
+                       BN_init(&(val[i]));
+                       if (!BN_mod_mul_montgomery(&(val[i]),&(val[i-1]),d,mont,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_to_montgomery(r,BN_value_one(),mont,ctx)) goto err;
+       for (;;)
+               {
+               if (BN_is_bit_set(p,wstart) == 0)
+                       {
+                       if (!start)
+                               {
+                               if (!BN_mod_mul_montgomery(r,r,r,mont,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_montgomery(r,r,r,mont,ctx))
+                                       goto err;
+                               }
+
+               /* wvalue will be an odd number < 2^window */
+               if (!BN_mod_mul_montgomery(r,r,&(val[wvalue>>1]),mont,ctx))
+                       goto err;
+
+               /* move the 'window' down further */
+               wstart-=wend+1;
+               wvalue=0;
+               start=0;
+               if (wstart < 0) break;
+               }
+       if (!BN_from_montgomery(rr,r,mont,ctx)) goto err;
+       ret=1;
+err:
+       if ((in_mont == NULL) && (mont != NULL)) BN_MONT_CTX_free(mont);
+       BN_CTX_end(ctx);
+       for (i=0; i<ts; i++)
+               BN_clear_free(&(val[i]));
+       return(ret);
+       }
+
+BN_ULONG BN_mod_word(const BIGNUM *a, BN_ULONG w)
+       {
+#ifndef BN_LLONG
+       BN_ULONG ret=0;
+#else
+       BN_ULLONG ret=0;
+#endif
+       int i;
+
+       w&=BN_MASK2;
+       for (i=a->top-1; i>=0; i--)
+               {
+#ifndef BN_LLONG
+               ret=((ret<<BN_BITS4)|((a->d[i]>>BN_BITS4)&BN_MASK2l))%w;
+               ret=((ret<<BN_BITS4)|(a->d[i]&BN_MASK2l))%w;
+#else
+               ret=(BN_ULLONG)(((ret<<(BN_ULLONG)BN_BITS2)|a->d[i])%
+                       (BN_ULLONG)w);
+#endif
+               }
+       return((BN_ULONG)ret);
+       }
+
+static int bnrand(int pseudorand, BIGNUM *rnd, int bits, int top, int bottom)
+       {
+       unsigned char *buf=NULL;
+       int ret=0,bit,bytes,mask;
+
+       if (bits == 0)
+               {
+               BN_zero(rnd);
+               return 1;
+               }
+
+       bytes=(bits+7)/8;
+       bit=(bits-1)%8;
+       mask=0xff<<bit;
+
+       buf=(unsigned char *)malloc(bytes);
+       if (buf == NULL)
+               {
+               goto err;
+               }
+
+       /* make a random number and set the top and bottom bits */
+       /* this ignores the pseudorand flag */
+
+       t_random(buf, bytes);
+
+       if (top)
+               {
+               if (bit == 0)
+                       {
+                       buf[0]=1;
+                       buf[1]|=0x80;
+                       }
+               else
+                       {
+                       buf[0]|=(3<<(bit-1));
+                       buf[0]&= ~(mask<<1);
+                       }
+               }
+       else
+               {
+               buf[0]|=(1<<bit);
+               buf[0]&= ~(mask<<1);
+               }
+       if (bottom) /* set bottom bits to whatever odd is */
+               buf[bytes-1]|=1;
+       if (!BN_bin2bn(buf,bytes,rnd)) goto err;
+       ret=1;
+err:
+       if (buf != NULL)
+               {
+               memset(buf,0,bytes);
+               free(buf);
+               }
+       return(ret);
+       }
+
+/* BN_pseudo_rand is the same as BN_rand, now. */
+
+int     BN_pseudo_rand(BIGNUM *rnd, int bits, int top, int bottom)
+       {
+       return bnrand(1, rnd, bits, top, bottom);
+       }
+
+#define MONT_WORD /* use the faster word-based algorithm */
+
+int BN_mod_mul_montgomery(BIGNUM *r, BIGNUM *a, BIGNUM *b,
+                         BN_MONT_CTX *mont, BN_CTX *ctx)
+       {
+       BIGNUM *tmp,*tmp2;
+       int ret=0;
+
+       BN_CTX_start(ctx);
+       tmp = BN_CTX_get(ctx);
+       tmp2 = BN_CTX_get(ctx);
+       if (tmp == NULL || tmp2 == NULL) goto err;
+
+       bn_check_top(tmp);
+       bn_check_top(tmp2);
+
+       if (a == b)
+               {
+               if (!BN_sqr(tmp,a,ctx)) goto err;
+               }
+       else
+               {
+               if (!BN_mul(tmp,a,b,ctx)) goto err;
+               }
+       /* reduce from aRR to aR */
+       if (!BN_from_montgomery(r,tmp,mont,ctx)) goto err;
+       ret=1;
+err:
+       BN_CTX_end(ctx);
+       return(ret);
+       }
+
+int BN_from_montgomery(BIGNUM *ret, BIGNUM *a, BN_MONT_CTX *mont,
+            BN_CTX *ctx)
+       {
+       int retn=0;
+
+#ifdef MONT_WORD
+       BIGNUM *n,*r;
+       BN_ULONG *ap,*np,*rp,n0,v,*nrp;
+       int al,nl,max,i,x,ri;
+
+       BN_CTX_start(ctx);
+       if ((r = BN_CTX_get(ctx)) == NULL) goto err;
+
+       if (!BN_copy(r,a)) goto err;
+       n= &(mont->N);
+
+       ap=a->d;
+       /* mont->ri is the size of mont->N in bits (rounded up
+          to the word size) */
+       al=ri=mont->ri/BN_BITS2;
+
+       nl=n->top;
+       if ((al == 0) || (nl == 0)) { r->top=0; return(1); }
+
+       max=(nl+al+1); /* allow for overflow (no?) XXX */
+       if (bn_wexpand(r,max) == NULL) goto err;
+       if (bn_wexpand(ret,max) == NULL) goto err;
+
+       r->neg=a->neg^n->neg;
+       np=n->d;
+       rp=r->d;
+       nrp= &(r->d[nl]);
+
+       /* clear the top words of T */
+#if 1
+       for (i=r->top; i<max; i++) /* memset? XXX */
+               r->d[i]=0;
+#else
+       memset(&(r->d[r->top]),0,(max-r->top)*sizeof(BN_ULONG));
+#endif
+
+       r->top=max;
+       n0=mont->n0;
+
+#ifdef BN_COUNT
+       printf("word BN_from_montgomery %d * %d\n",nl,nl);
+#endif
+       for (i=0; i<nl; i++)
+               {
+#ifdef __TANDEM
+               {
+                  long long t1;
+                  long long t2;
+                  long long t3;
+                  t1 = rp[0] * (n0 & 0177777);
+                  t2 = 037777600000l;
+                  t2 = n0 & t2;
+                  t3 = rp[0] & 0177777;
+                  t2 = (t3 * t2) & BN_MASK2;
+                  t1 = t1 + t2;
+                  v=bn_mul_add_words(rp,np,nl,(BN_ULONG) t1);
+               }
+#else
+               v=bn_mul_add_words(rp,np,nl,(rp[0]*n0)&BN_MASK2);
+#endif
+               nrp++;
+               rp++;
+               if (((nrp[-1]+=v)&BN_MASK2) >= v)
+                       continue;
+               else
+                       {
+                       if (((++nrp[0])&BN_MASK2) != 0) continue;
+                       if (((++nrp[1])&BN_MASK2) != 0) continue;
+                       for (x=2; (((++nrp[x])&BN_MASK2) == 0); x++) ;
+                       }
+               }
+       bn_fix_top(r);
+
+       /* mont->ri will be a multiple of the word size */
+#if 0
+       BN_rshift(ret,r,mont->ri);
+#else
+       ret->neg = r->neg;
+       x=ri;
+       rp=ret->d;
+       ap= &(r->d[x]);
+       if (r->top < x)
+               al=0;
+       else
+               al=r->top-x;
+       ret->top=al;
+       al-=4;
+       for (i=0; i<al; i+=4)
+               {
+               BN_ULONG t1,t2,t3,t4;
+
+               t1=ap[i+0];
+               t2=ap[i+1];
+               t3=ap[i+2];
+               t4=ap[i+3];
+               rp[i+0]=t1;
+               rp[i+1]=t2;
+               rp[i+2]=t3;
+               rp[i+3]=t4;
+               }
+       al+=4;
+       for (; i<al; i++)
+               rp[i]=ap[i];
+#endif
+#else /* !MONT_WORD */
+       BIGNUM *t1,*t2;
+
+       BN_CTX_start(ctx);
+       t1 = BN_CTX_get(ctx);
+       t2 = BN_CTX_get(ctx);
+       if (t1 == NULL || t2 == NULL) goto err;
+
+       if (!BN_copy(t1,a)) goto err;
+       BN_mask_bits(t1,mont->ri);
+
+       if (!BN_mul(t2,t1,&mont->Ni,ctx)) goto err;
+       BN_mask_bits(t2,mont->ri);
+
+       if (!BN_mul(t1,t2,&mont->N,ctx)) goto err;
+       if (!BN_add(t2,a,t1)) goto err;
+       BN_rshift(ret,t2,mont->ri);
+#endif /* MONT_WORD */
+
+       if (BN_ucmp(ret, &(mont->N)) >= 0)
+               {
+               BN_usub(ret,ret,&(mont->N));
+               }
+       retn=1;
+ err:
+       BN_CTX_end(ctx);
+       return(retn);
+       }
+
+void BN_MONT_CTX_init(BN_MONT_CTX *ctx)
+       {
+       ctx->ri=0;
+       BN_init(&(ctx->RR));
+       BN_init(&(ctx->N));
+       BN_init(&(ctx->Ni));
+       ctx->flags=0;
+       }
+
+BN_MONT_CTX *BN_MONT_CTX_new(void)
+       {
+       BN_MONT_CTX *ret;
+
+       if ((ret=(BN_MONT_CTX *)malloc(sizeof(BN_MONT_CTX))) == NULL)
+               return(NULL);
+
+       BN_MONT_CTX_init(ret);
+       ret->flags=BN_FLG_MALLOCED;
+       return(ret);
+       }
+
+void BN_MONT_CTX_free(BN_MONT_CTX *mont)
+       {
+       if(mont == NULL)
+           return;
+
+       BN_free(&(mont->RR));
+       BN_free(&(mont->N));
+       BN_free(&(mont->Ni));
+       if (mont->flags & BN_FLG_MALLOCED)
+               free(mont);
+       }
+
+int BN_MONT_CTX_set(BN_MONT_CTX *mont, const BIGNUM *mod, BN_CTX *ctx)
+       {
+       BIGNUM Ri,*R;
+
+       BN_init(&Ri);
+       R= &(mont->RR);                                 /* grab RR as a temp */
+       BN_copy(&(mont->N),mod);                        /* Set N */
+
+#ifdef MONT_WORD
+               {
+               BIGNUM tmod;
+               BN_ULONG buf[2];
+
+               mont->ri=(BN_num_bits(mod)+(BN_BITS2-1))/BN_BITS2*BN_BITS2;
+               BN_zero(R);
+               BN_set_bit(R,BN_BITS2);                 /* R */
+
+               buf[0]=mod->d[0]; /* tmod = N mod word size */
+               buf[1]=0;
+               tmod.d=buf;
+               tmod.top=1;
+               tmod.dmax=2;
+               tmod.neg=mod->neg;
+                                                       /* Ri = R^-1 mod N*/
+               if ((BN_mod_inverse(&Ri,R,&tmod,ctx)) == NULL)
+                       goto err;
+               BN_lshift(&Ri,&Ri,BN_BITS2);            /* R*Ri */
+               if (!BN_is_zero(&Ri))
+                       BN_sub_word(&Ri,1);
+               else /* if N mod word size == 1 */
+                       BN_set_word(&Ri,BN_MASK2);  /* Ri-- (mod word size) */
+               BN_div(&Ri,NULL,&Ri,&tmod,ctx); /* Ni = (R*Ri-1)/N,
+                                                * keep only least significant word: */
+               mont->n0=Ri.d[0];
+               BN_free(&Ri);
+               }
+#else /* !MONT_WORD */
+               { /* bignum version */
+               mont->ri=BN_num_bits(mod);
+               BN_zero(R);
+               BN_set_bit(R,mont->ri);                 /* R = 2^ri */
+                                                       /* Ri = R^-1 mod N*/
+               if ((BN_mod_inverse(&Ri,R,mod,ctx)) == NULL)
+                       goto err;
+               BN_lshift(&Ri,&Ri,mont->ri);            /* R*Ri */
+               BN_sub_word(&Ri,1);
+                                                       /* Ni = (R*Ri-1) / N */
+               BN_div(&(mont->Ni),NULL,&Ri,mod,ctx);
+               BN_free(&Ri);
+               }
+#endif
+
+       /* setup RR for conversions */
+       BN_zero(&(mont->RR));
+       BN_set_bit(&(mont->RR),mont->ri*2);
+       BN_mod(&(mont->RR),&(mont->RR),&(mont->N),ctx);
+
+       return(1);
+err:
+       return(0);
+       }
+
+BIGNUM *BN_value_one(void)
+       {
+       static BN_ULONG data_one=1L;
+       static BIGNUM const_one={&data_one,1,1,0};
+
+       return(&const_one);
+       }
+
+/* solves ax == 1 (mod n) */
+BIGNUM *BN_mod_inverse(BIGNUM *in, BIGNUM *a, const BIGNUM *n, BN_CTX *ctx)
+       {
+       BIGNUM *A,*B,*X,*Y,*M,*D,*R=NULL;
+       BIGNUM *T,*ret=NULL;
+       int sign;
+
+       bn_check_top(a);
+       bn_check_top(n);
+
+       BN_CTX_start(ctx);
+       A = BN_CTX_get(ctx);
+       B = BN_CTX_get(ctx);
+       X = BN_CTX_get(ctx);
+       D = BN_CTX_get(ctx);
+       M = BN_CTX_get(ctx);
+       Y = BN_CTX_get(ctx);
+       if (Y == NULL) goto err;
+
+       if (in == NULL)
+               R=BN_new();
+       else
+               R=in;
+       if (R == NULL) goto err;
+
+       BN_zero(X);
+       BN_one(Y);
+       if (BN_copy(A,a) == NULL) goto err;
+       if (BN_copy(B,n) == NULL) goto err;
+       sign=1;
+
+       while (!BN_is_zero(B))
+               {
+               if (!BN_div(D,M,A,B,ctx)) goto err;
+               T=A;
+               A=B;
+               B=M;
+               /* T has a struct, M does not */
+
+               if (!BN_mul(T,D,X,ctx)) goto err;
+               if (!BN_add(T,T,Y)) goto err;
+               M=Y;
+               Y=X;
+               X=T;
+               sign= -sign;
+               }
+       if (sign < 0)
+               {
+               if (!BN_sub(Y,n,Y)) goto err;
+               }
+
+       if (BN_is_one(A))
+               { if (!BN_mod(R,Y,n,ctx)) goto err; }
+       else
+               {
+               goto err;
+               }
+       ret=R;
+err:
+       if ((ret == NULL) && (in == NULL)) BN_free(R);
+       BN_CTX_end(ctx);
+       return(ret);
+       }
+
+int BN_set_bit(BIGNUM *a, int n)
+       {
+       int i,j,k;
+
+       i=n/BN_BITS2;
+       j=n%BN_BITS2;
+       if (a->top <= i)
+               {
+               if (bn_wexpand(a,i+1) == NULL) return(0);
+               for(k=a->top; k<i+1; k++)
+                       a->d[k]=0;
+               a->top=i+1;
+               }
+
+       a->d[i]|=(((BN_ULONG)1)<<j);
+       return(1);
+       }
+
diff --git a/package/ead/src/tinysrp/t_conv.c b/package/ead/src/tinysrp/t_conv.c
new file mode 100644 (file)
index 0000000..d3fe246
--- /dev/null
@@ -0,0 +1,226 @@
+/*
+ * Copyright (c) 1997-1999  The Stanford SRP Authentication Project
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
+ *
+ * IN NO EVENT SHALL STANFORD BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF
+ * THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * In addition, the following conditions apply:
+ *
+ * 1. Any software that incorporates the SRP authentication technology
+ *    must display the following acknowlegment:
+ *    "This product uses the 'Secure Remote Password' cryptographic
+ *     authentication system developed by Tom Wu (tjw@CS.Stanford.EDU)."
+ *
+ * 2. Any software that incorporates all or part of the SRP distribution
+ *    itself must also display the following acknowledgment:
+ *    "This product includes software developed by Tom Wu and Eugene
+ *     Jhong for the SRP Distribution (http://srp.stanford.edu/srp/)."
+ *
+ * 3. Redistributions in source or binary form must retain an intact copy
+ *    of this copyright notice and list of conditions.
+ */
+
+/*#define _POSIX_SOURCE*/
+#include <stdio.h>
+#include "t_defines.h"
+
+static int
+hexDigitToInt(c)
+     char c;
+{
+  if(c >= '0' && c <= '9')
+    return c - '0';
+  else if(c >= 'a' && c <= 'f')
+    return c - 'a' + 10;
+  else if(c >= 'A' && c <= 'F')
+    return c - 'A' + 10;
+  else
+    return 0;
+}
+
+/*
+ * Convert a hex string to a string of bytes; return size of dst
+ */
+_TYPE( int )
+t_fromhex(dst, src)
+     register char *dst, *src;
+{
+  register char *chp = dst;
+  register unsigned size = strlen(src);
+
+  /* FIXME: handle whitespace and non-hex digits by setting size and src
+     appropriately. */
+
+  if(size % 2 == 1) {
+    *chp++ = hexDigitToInt(*src++);
+    --size;
+  }
+  while(size > 0) {
+    *chp++ = (hexDigitToInt(*src) << 4) | hexDigitToInt(*(src + 1));
+    src += 2;
+    size -= 2;
+  }
+  return chp - dst;
+}
+
+/*
+ * Convert a string of bytes to their hex representation
+ */
+_TYPE( char * )
+t_tohex(dst, src, size)
+     register char *dst, *src;
+     register unsigned size;
+{
+   int notleading = 0;
+
+   register char *chp = dst;
+   if (size != 0) do {
+      if(notleading || *src != '\0') {
+       notleading = 1;
+       sprintf(chp, "%.2x", * (unsigned char *) src);
+       chp += 2;
+      }
+      ++src;
+   } while (--size != 0);
+   return dst;
+}
+
+static char b64table[] =
+  "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz./";
+
+/*
+ * Convert a base64 string into raw byte array representation.
+ */
+_TYPE( int )
+t_fromb64(dst, src)
+     register char *dst, *src;
+{
+  unsigned char *a;
+  char *loc;
+  int i, j;
+  unsigned int size;
+
+  while(*src && (*src == ' ' || *src == '\t' || *src == '\n'))
+      ++src;
+  size = strlen(src);
+
+  a = malloc((size + 1) * sizeof(unsigned char));
+  if(a == (unsigned char *) 0)
+    return -1;
+
+  i = 0;
+  while(i < size) {
+    loc = strchr(b64table, src[i]);
+    if(loc == (char *) 0)
+      break;
+    else
+      a[i] = loc - b64table;
+    ++i;
+  }
+  size = i;
+
+  i = size - 1;
+  j = size;
+  while(1) {
+    a[j] = a[i];
+    if(--i < 0)
+      break;
+    a[j] |= (a[i] & 3) << 6;
+    --j;
+    a[j] = (unsigned char) ((a[i] & 0x3c) >> 2);
+    if(--i < 0)
+      break;
+    a[j] |= (a[i] & 0xf) << 4;
+    --j;
+    a[j] = (unsigned char) ((a[i] & 0x30) >> 4);
+    if(--i < 0)
+      break;
+    a[j] |= (a[i] << 2);
+
+    a[--j] = 0;
+    if(--i < 0)
+      break;
+  }
+
+  while(a[j] == 0 && j <= size)
+    ++j;
+
+  memcpy(dst, a + j, size - j + 1);
+  free(a);
+  return size - j + 1;
+}
+
+/*
+ * Convert a raw byte string into a null-terminated base64 ASCII string.
+ */
+_TYPE( char * )
+t_tob64(dst, src, size)
+     register char *dst, *src;
+     register unsigned size;
+{
+  int c, pos = size % 3;
+  unsigned char b0 = 0, b1 = 0, b2 = 0, notleading = 0;
+  char *olddst = dst;
+
+  switch(pos) {
+  case 1:
+    b2 = src[0];
+    break;
+  case 2:
+    b1 = src[0];
+    b2 = src[1];
+    break;
+  }
+
+  while(1) {
+    c = (b0 & 0xfc) >> 2;
+    if(notleading || c != 0) {
+      *dst++ = b64table[c];
+      notleading = 1;
+    }
+    c = ((b0 & 3) << 4) | ((b1 & 0xf0) >> 4);
+    if(notleading || c != 0) {
+      *dst++ = b64table[c];
+      notleading = 1;
+    }
+    c = ((b1 & 0xf) << 2) | ((b2 & 0xc0) >> 6);
+    if(notleading || c != 0) {
+      *dst++ = b64table[c];
+      notleading = 1;
+    }
+    c = b2 & 0x3f;
+    if(notleading || c != 0) {
+      *dst++ = b64table[c];
+      notleading = 1;
+    }
+    if(pos >= size)
+      break;
+    else {
+      b0 = src[pos++];
+      b1 = src[pos++];
+      b2 = src[pos++];
+    }
+  }
+
+  *dst++ = '\0';
+  return olddst;
+}
diff --git a/package/ead/src/tinysrp/t_defines.h b/package/ead/src/tinysrp/t_defines.h
new file mode 100644 (file)
index 0000000..4128093
--- /dev/null
@@ -0,0 +1,169 @@
+/*
+ * Copyright (c) 1997-1999  The Stanford SRP Authentication Project
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL STANFORD BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF
+ * THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * In addition, the following conditions apply:
+ *
+ * 1. Any software that incorporates the SRP authentication technology
+ *    must display the following acknowlegment:
+ *    "This product uses the 'Secure Remote Password' cryptographic
+ *     authentication system developed by Tom Wu (tjw@CS.Stanford.EDU)."
+ *
+ * 2. Any software that incorporates all or part of the SRP distribution
+ *    itself must also display the following acknowledgment:
+ *    "This product includes software developed by Tom Wu and Eugene
+ *     Jhong for the SRP Distribution (http://srp.stanford.edu/srp/)."
+ *
+ * 3. Redistributions in source or binary form must retain an intact copy
+ *    of this copyright notice and list of conditions.
+ */
+
+#ifndef T_DEFINES_H
+#define T_DEFINES_H
+
+#ifndef P
+#if defined(__STDC__) || defined(__cplusplus)
+#define P(x) x
+#else
+#define P(x) ()
+#endif
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif /* HAVE_CONFIG_H */
+
+#ifndef _DLLDECL
+#define _DLLDECL
+
+#ifdef MSVC15   /* MSVC1.5 support for 16 bit apps */
+#define _MSVC15EXPORT _export
+#define _MSVC20EXPORT
+#define _DLLAPI _export _pascal
+#define _TYPE(a) a _MSVC15EXPORT
+#define DLLEXPORT 1
+
+#elif MSVC20
+#define _MSVC15EXPORT
+#define _MSVC20EXPORT _declspec(dllexport)
+#define _DLLAPI
+#define _TYPE(a) _MSVC20EXPORT a
+#define DLLEXPORT 1
+
+#else                   /* Default, non-dll.  Use this for Unix or DOS */
+#define _MSVC15DEXPORT
+#define _MSVC20EXPORT
+#define _DLLAPI
+#define _TYPE(a) a
+#endif
+#endif
+
+#if STDC_HEADERS
+#include <stdlib.h>
+#include <string.h>
+#else /* not STDC_HEADERS */
+#ifndef HAVE_STRCHR
+#define strchr index
+#define strrchr rindex
+#endif
+char *strchr(), *strrchr(), *strtok();
+#ifndef HAVE_MEMCPY
+#define memcpy(d, s, n) bcopy((s), (d), (n))
+#endif
+#endif /* not STDC_HEADERS */
+
+#include <sys/types.h>
+
+#if TIME_WITH_SYS_TIME
+#include <sys/time.h>
+#include <time.h>
+#else  /* not TIME_WITH_SYS_TIME */
+#if HAVE_SYS_TIME_H
+#include <sys/time.h>
+#else
+#include <time.h>
+#endif
+#endif /* not TIME_WITH_SYS_TIME */
+
+#if HAVE_TERMIOS_H
+#include <termios.h>
+#define STTY(fd, termio) tcsetattr(fd, TCSANOW, termio)
+#define GTTY(fd, termio) tcgetattr(fd, termio)
+#define TERMIO struct termios
+#define USE_TERMIOS
+#elif HAVE_TERMIO_H
+#include <sys/ioctl.h>
+#include <termio.h>
+#define STTY(fd, termio) ioctl(fd, TCSETA, termio)
+#define GTTY(fd, termio) ioctl(fd, TCGETA, termio)
+#define TEMRIO struct termio
+#define USE_TERMIO
+#elif HAVE_SGTTY_H
+#include <sgtty.h>
+#define STTY(fd, termio) stty(fd, termio)
+#define GTTY(fd, termio) gtty(fd, termio)
+#define TERMIO struct sgttyb
+#define USE_SGTTY
+#endif
+
+#ifdef USE_FTIME
+#include <sys/timeb.h>
+#endif
+
+#ifndef MATH_PRIV
+typedef void * BigInteger;
+#endif
+
+_TYPE( BigInteger ) BigIntegerFromInt P((unsigned int number));
+_TYPE( BigInteger ) BigIntegerFromBytes P((unsigned char * bytes, int length));
+_TYPE( int ) BigIntegerToBytes P((BigInteger src, unsigned char * dest));
+_TYPE( int ) BigIntegerBitLen P((BigInteger b));
+_TYPE( int ) BigIntegerCmp P((BigInteger c1, BigInteger c2));
+_TYPE( int ) BigIntegerCmpInt P((BigInteger c1, unsigned int c2));
+_TYPE( void ) BigIntegerLShift P((BigInteger result, BigInteger x,
+                               unsigned int bits));
+_TYPE( void ) BigIntegerAdd P((BigInteger result, BigInteger a1, BigInteger a2));
+_TYPE( void ) BigIntegerAddInt P((BigInteger result,
+                               BigInteger a1, unsigned int a2));
+_TYPE( void ) BigIntegerSub P((BigInteger result, BigInteger s1, BigInteger s2));
+_TYPE( void ) BigIntegerSubInt P((BigInteger result,
+                               BigInteger s1, unsigned int s2));
+/* For BigIntegerMul{,Int}: result != m1, m2 */
+_TYPE( void ) BigIntegerMul P((BigInteger result, BigInteger m1, BigInteger m2));
+_TYPE( void ) BigIntegerMulInt P((BigInteger result,
+                               BigInteger m1, unsigned int m2));
+_TYPE( void ) BigIntegerDivInt P((BigInteger result,
+                               BigInteger d, unsigned int m));
+_TYPE( void ) BigIntegerMod P((BigInteger result, BigInteger d, BigInteger m));
+_TYPE( unsigned int ) BigIntegerModInt P((BigInteger d, unsigned int m));
+_TYPE( void ) BigIntegerModMul P((BigInteger result,
+                               BigInteger m1, BigInteger m2, BigInteger m));
+_TYPE( void ) BigIntegerModExp P((BigInteger result, BigInteger base,
+                               BigInteger expt, BigInteger modulus));
+_TYPE( void ) BigIntegerModExpInt P((BigInteger result, BigInteger base,
+                                  unsigned int expt, BigInteger modulus));
+_TYPE( int ) BigIntegerCheckPrime P((BigInteger n));
+_TYPE( void ) BigIntegerFree P((BigInteger b));
+
+#endif
diff --git a/package/ead/src/tinysrp/t_getconf.c b/package/ead/src/tinysrp/t_getconf.c
new file mode 100644 (file)
index 0000000..db6de61
--- /dev/null
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 1997-1999  The Stanford SRP Authentication Project
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL STANFORD BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF
+ * THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * In addition, the following conditions apply:
+ *
+ * 1. Any software that incorporates the SRP authentication technology
+ *    must display the following acknowlegment:
+ *    "This product uses the 'Secure Remote Password' cryptographic
+ *     authentication system developed by Tom Wu (tjw@CS.Stanford.EDU)."
+ *
+ * 2. Any software that incorporates all or part of the SRP distribution
+ *    itself must also display the following acknowledgment:
+ *    "This product includes software developed by Tom Wu and Eugene
+ *     Jhong for the SRP Distribution (http://srp.stanford.edu/srp/)."
+ *
+ * 3. Redistributions in source or binary form must retain an intact copy
+ *    of this copyright notice and list of conditions.
+ */
+
+#include <stdio.h>
+
+#include "t_defines.h"
+#include "t_pwd.h"
+#include "t_read.h"
+
+/* Master builtin parameter storage object.  The default that tphrase
+uses is the last one. */
+
+static struct pre_struct {
+  struct t_preconf preconf;
+  int state;    /* 0 == uninitialized/first time */
+  unsigned char modbuf[MAXPARAMLEN];
+  unsigned char genbuf[MAXPARAMLEN];
+} pre_params[] = {
+  { { "2iQzj1CagQc/5ctbuJYLWlhtAsPHc7xWVyCPAKFRLWKADpASkqe9djWPFWTNTdeJtL8nAhImCn3Sr/IAdQ1FrGw0WvQUstPx3FO9KNcXOwisOQ1VlL.gheAHYfbYyBaxXL.NcJx9TUwgWDT0hRzFzqSrdGGTN3FgSTA1v4QnHtEygNj3eZ.u0MThqWUaDiP87nqha7XnT66bkTCkQ8.7T8L4KZjIImrNrUftedTTBi.WCi.zlrBxDuOM0da0JbUkQlXqvp0yvJAPpC11nxmmZOAbQOywZGmu9nhZNuwTlxjfIro0FOdthaDTuZRL9VL7MRPUDo/DQEyW.d4H.UIlzp",
+      "2",
+      NULL }, 0 },
+  { { "dUyyhxav9tgnyIg65wHxkzkb7VIPh4o0lkwfOKiPp4rVJrzLRYVBtb76gKlaO7ef5LYGEw3G.4E0jbMxcYBetDy2YdpiP/3GWJInoBbvYHIRO9uBuxgsFKTKWu7RnR7yTau/IrFTdQ4LY/q.AvoCzMxV0PKvD9Odso/LFIItn8PbTov3VMn/ZEH2SqhtpBUkWtmcIkEflhX/YY/fkBKfBbe27/zUaKUUZEUYZ2H2nlCL60.JIPeZJSzsu/xHDVcx",
+      "2",
+      NULL }, 0 },
+  { { "3NUKQ2Re4P5BEK0TLg2dX3gETNNNECPoe92h4OVMaDn3Xo/0QdjgG/EvM.hiVV1BdIGklSI14HA38Mpe5k04juR5/EXMU0r1WtsLhNXwKBlf2zEfoOh0zVmDvqInpU695f29Iy7sNW3U5RIogcs740oUp2Kdv5wuITwnIx84cnO.e467/IV1lPnvMCr0pd1dgS0a.RV5eBJr03Q65Xy61R",
+      "2",
+      NULL }, 0 },
+  { { "F//////////oG/QeY5emZJ4ncABWDmSqIa2JWYAPynq0Wk.fZiJco9HIWXvZZG4tU.L6RFDEaCRC2iARV9V53TFuJLjRL72HUI5jNPYNdx6z4n2wQOtxMiB/rosz0QtxUuuQ/jQYP.bhfya4NnB7.P9A6PHxEPJWV//////////",
+      "5",
+      "oakley prime 2" }, 0 },
+  { { "Ewl2hcjiutMd3Fu2lgFnUXWSc67TVyy2vwYCKoS9MLsrdJVT9RgWTCuEqWJrfB6uE3LsE9GkOlaZabS7M29sj5TnzUqOLJMjiwEzArfiLr9WbMRANlF68N5AVLcPWvNx6Zjl3m5Scp0BzJBz9TkgfhzKJZ.WtP3Mv/67I/0wmRZ",
+      "2",
+      NULL }, 0 },
+};
+
+_TYPE( int )
+t_getprecount()
+{
+  return (sizeof(pre_params) / sizeof(struct pre_struct));
+}
+
+static struct t_confent sysconf;
+
+/* id is index origin 1 */
+
+_TYPE( struct t_confent * )
+gettcid
+(id)
+     int id;
+{
+       struct t_preconf *tcp;
+
+       if (id <= 0 || id > t_getprecount()) {
+               return NULL;
+       }
+       tcp = t_getpreparam(id - 1);
+       sysconf.index = id;
+       sysconf.modulus = tcp->modulus;
+       sysconf.generator = tcp->generator;
+
+       return &sysconf;
+}
+
+_TYPE( struct t_preconf * )
+t_getpreparam(idx)
+     int idx;
+{
+  if(pre_params[idx].state == 0) {
+    /* Wire up storage */
+    pre_params[idx].preconf.modulus.data = pre_params[idx].modbuf;
+    pre_params[idx].preconf.generator.data = pre_params[idx].genbuf;
+
+    /* Convert from b64 to t_num */
+    pre_params[idx].preconf.modulus.len = t_fromb64(pre_params[idx].preconf.modulus.data, pre_params[idx].preconf.mod_b64);
+    pre_params[idx].preconf.generator.len = t_fromb64(pre_params[idx].preconf.generator.data, pre_params[idx].preconf.gen_b64);
+
+    pre_params[idx].state = 1;
+  }
+  return &(pre_params[idx].preconf);
+}
diff --git a/package/ead/src/tinysrp/t_getpass.c b/package/ead/src/tinysrp/t_getpass.c
new file mode 100644 (file)
index 0000000..6ae7fca
--- /dev/null
@@ -0,0 +1,191 @@
+/*
+ * Copyright 1990 - 1995, Julianne Frances Haugh
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Julianne F. Haugh nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "t_defines.h"
+#ifdef _WIN32
+#include <windows.h>
+#include <io.h>
+#endif /* _WIN32 */
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif /* HAVE_UNISTD_H */
+#include <signal.h>
+#include <stdio.h>
+
+static  int     sig_caught;
+#ifdef HAVE_SIGACTION
+static  struct  sigaction sigact;
+#endif
+
+/*ARGSUSED*/
+static RETSIGTYPE
+sig_catch (sig)
+int     sig;
+{
+       sig_caught = 1;
+}
+
+_TYPE( int )
+t_getpass (buf, maxlen, prompt)
+       char *buf;
+       unsigned maxlen;
+       const char *prompt;
+{
+       char    *cp;
+#ifdef _WIN32
+    HANDLE handle = (HANDLE) _get_osfhandle(_fileno(stdin));
+    DWORD  mode;
+
+    GetConsoleMode( handle, &mode );
+    SetConsoleMode( handle, mode & ~ENABLE_ECHO_INPUT );
+
+    if(fputs(prompt, stdout) == EOF ||
+       fgets(buf, maxlen, stdin) == NULL) {
+       SetConsoleMode(handle,mode);
+       return -1;
+    }
+    cp = buf + strlen(buf) - 1;
+    if ( *cp == 0x0a )
+       *cp = '\0';
+    printf("\n");
+    SetConsoleMode(handle,mode);
+#else
+       FILE    *fp;
+       int     tty_opened = 0;
+
+#ifdef HAVE_SIGACTION
+       struct  sigaction old_sigact;
+#else
+       RETSIGTYPE      (*old_signal)();
+#endif
+       TERMIO  new_modes;
+       TERMIO  old_modes;
+
+       /*
+        * set a flag so the SIGINT signal can be re-sent if it
+        * is caught
+        */
+
+       sig_caught = 0;
+
+       /*
+        * if /dev/tty can't be opened, getpass() needs to read
+        * from stdin instead.
+        */
+
+       if ((fp = fopen ("/dev/tty", "r")) == 0) {
+               fp = stdin;
+               setbuf (fp, (char *) 0);
+       } else {
+               tty_opened = 1;
+       }
+
+       /*
+        * the current tty modes must be saved so they can be
+        * restored later on.  echo will be turned off, except
+        * for the newline character (BSD has to punt on this)
+        */
+
+       if (GTTY (fileno (fp), &new_modes))
+               return -1;
+
+       old_modes = new_modes;
+
+#ifdef HAVE_SIGACTION
+       sigact.sa_handler = sig_catch;
+       (void) sigaction (SIGINT, &sigact, &old_sigact);
+#else
+       old_signal = signal (SIGINT, sig_catch);
+#endif
+
+#ifdef USE_SGTTY
+       new_modes.sg_flags &= ~ECHO;
+#else
+       new_modes.c_iflag &= ~IGNCR;
+       new_modes.c_iflag |= ICRNL;
+       new_modes.c_oflag |= OPOST|ONLCR;
+       new_modes.c_lflag &= ~(ECHO|ECHOE|ECHOK);
+       new_modes.c_lflag |= ICANON|ECHONL;
+#endif
+
+       if (STTY (fileno (fp), &new_modes))
+               goto out;
+
+       /*
+        * the prompt is output, and the response read without
+        * echoing.  the trailing newline must be removed.  if
+        * the fgets() returns an error, a NULL pointer is
+        * returned.
+        */
+
+       if (fputs (prompt, stdout) == EOF)
+               goto out;
+
+       (void) fflush (stdout);
+
+       if (fgets (buf, maxlen, fp) == buf) {
+               if ((cp = strchr (buf, '\n')))
+                       *cp = '\0';
+               else
+                       buf[maxlen - 1] = '\0';
+
+#ifdef USE_SGTTY
+               putc ('\n', stdout);
+#endif
+       }
+       else buf[0] = '\0';
+out:
+       /*
+        * the old SIGINT handler is restored after the tty
+        * modes.  then /dev/tty is closed if it was opened in
+        * the beginning.  finally, if a signal was caught it
+        * is sent to this process for normal processing.
+        */
+
+       if (STTY (fileno (fp), &old_modes))
+       { memset (buf, 0, maxlen); return -1; }
+
+#ifdef HAVE_SIGACTION
+       (void) sigaction (SIGINT, &old_sigact, NULL);
+#else
+       (void) signal (SIGINT, old_signal);
+#endif
+
+       if (tty_opened)
+               (void) fclose (fp);
+
+       if (sig_caught) {
+               kill (getpid (), SIGINT);
+               memset (buf, 0, maxlen);
+               return -1;
+       }
+#endif
+
+       return 0;
+}
diff --git a/package/ead/src/tinysrp/t_math.c b/package/ead/src/tinysrp/t_math.c
new file mode 100644 (file)
index 0000000..20161a0
--- /dev/null
@@ -0,0 +1,177 @@
+/*
+ * Copyright (c) 1997-1999  The Stanford SRP Authentication Project
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL STANFORD BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF
+ * THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * In addition, the following conditions apply:
+ *
+ * 1. Any software that incorporates the SRP authentication technology
+ *    must display the following acknowlegment:
+ *    "This product uses the 'Secure Remote Password' cryptographic
+ *     authentication system developed by Tom Wu (tjw@CS.Stanford.EDU)."
+ *
+ * 2. Any software that incorporates all or part of the SRP distribution
+ *    itself must also display the following acknowledgment:
+ *    "This product includes software developed by Tom Wu and Eugene
+ *     Jhong for the SRP Distribution (http://srp.stanford.edu/srp/)."
+ *
+ * 3. Redistributions in source or binary form must retain an intact copy
+ *    of this copyright notice and list of conditions.
+ */
+
+#include <stdio.h>
+#include <sys/types.h>
+
+#include "config.h"
+
+#include "bn.h"
+typedef BIGNUM * BigInteger;
+#define MATH_PRIV
+
+#include "t_defines.h"
+#include "t_pwd.h"
+
+/* Math library interface stubs */
+
+BigInteger
+BigIntegerFromInt(n)
+     unsigned int n;
+{
+  BIGNUM * a = BN_new();
+  BN_set_word(a, n);
+  return a;
+}
+
+BigInteger
+BigIntegerFromBytes(bytes, length)
+     unsigned char * bytes;
+     int length;
+{
+  BIGNUM * a = BN_new();
+  BN_bin2bn(bytes, length, a);
+  return a;
+}
+
+int
+BigIntegerToBytes(src, dest)
+     BigInteger src;
+     unsigned char * dest;
+{
+  return BN_bn2bin(src, dest);
+}
+
+int
+BigIntegerCmp(c1, c2)
+     BigInteger c1, c2;
+{
+  return BN_cmp(c1, c2);
+}
+
+int
+BigIntegerCmpInt(c1, c2)
+     BigInteger c1;
+     unsigned int c2;
+{
+  BIGNUM * a = BN_new();
+  int rv;
+  BN_set_word(a, c2);
+  rv = BN_cmp(c1, a);
+  BN_free(a);
+  return rv;
+}
+
+void
+BigIntegerAdd(result, a1, a2)
+     BigInteger result, a1, a2;
+{
+  BN_add(result, a1, a2);
+}
+
+void
+BigIntegerAddInt(result, a1, a2)
+     BigInteger result, a1;
+     unsigned int a2;
+{
+  BIGNUM * a = BN_new();
+  BN_set_word(a, a2);
+  BN_add(result, a1, a);
+  BN_free(a);
+}
+
+void
+BigIntegerSub(result, s1, s2)
+     BigInteger result, s1, s2;
+{
+  BN_sub(result, s1, s2);
+}
+
+void
+BigIntegerMulInt(result, m1, m2)
+     BigInteger result, m1;
+     unsigned int m2;
+{
+  BN_CTX * ctx = BN_CTX_new();
+  BIGNUM * m = BN_new();
+  BN_set_word(m, m2);
+  BN_mul(result, m1, m, ctx);
+  BN_CTX_free(ctx);
+}
+
+void
+BigIntegerModMul(r, m1, m2, modulus)
+     BigInteger r, m1, m2, modulus;
+{
+  BN_CTX * ctx = BN_CTX_new();
+  BN_mod_mul(r, m1, m2, modulus, ctx);
+  BN_CTX_free(ctx);
+}
+
+void
+BigIntegerModExp(r, b, e, m)
+     BigInteger r, b, e, m;
+{
+  BN_CTX * ctx = BN_CTX_new();
+  BN_mod_exp(r, b, e, m, ctx);
+  BN_CTX_free(ctx);
+}
+
+void
+BigIntegerModExpInt(r, b, e, m)
+     BigInteger r, b;
+     unsigned int e;
+     BigInteger m;
+{
+  BN_CTX * ctx = BN_CTX_new();
+  BIGNUM * p = BN_new();
+  BN_set_word(p, e);
+  BN_mod_exp(r, b, p, m, ctx);
+  BN_free(p);
+  BN_CTX_free(ctx);
+}
+
+void
+BigIntegerFree(b)
+     BigInteger b;
+{
+  BN_free(b);
+}
diff --git a/package/ead/src/tinysrp/t_misc.c b/package/ead/src/tinysrp/t_misc.c
new file mode 100644 (file)
index 0000000..a23986f
--- /dev/null
@@ -0,0 +1,338 @@
+/*
+ * Copyright (c) 1997-1999  The Stanford SRP Authentication Project
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL STANFORD BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF
+ * THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * In addition, the following conditions apply:
+ *
+ * 1. Any software that incorporates the SRP authentication technology
+ *    must display the following acknowlegment:
+ *    "This product uses the 'Secure Remote Password' cryptographic
+ *     authentication system developed by Tom Wu (tjw@CS.Stanford.EDU)."
+ *
+ * 2. Any software that incorporates all or part of the SRP distribution
+ *    itself must also display the following acknowledgment:
+ *    "This product includes software developed by Tom Wu and Eugene
+ *     Jhong for the SRP Distribution (http://srp.stanford.edu/srp/)."
+ *
+ * 3. Redistributions in source or binary form must retain an intact copy
+ *    of this copyright notice and list of conditions.
+ */
+
+#include "t_defines.h"
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif /* HAVE_UNISTD_H */
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#include "t_sha.h"
+
+#ifndef NULL
+#define NULL 0
+#endif
+
+static unsigned char randpool[SHA_DIGESTSIZE], randout[SHA_DIGESTSIZE];
+static unsigned long randcnt = 0;
+static unsigned int outpos = 0;
+SHA1_CTX randctxt;
+
+/*
+ * t_envhash - Generate a 160-bit SHA hash of the environment
+ *
+ * This routine performs an SHA hash of all the "name=value" pairs
+ * in the environment concatenated together and dumps them in the
+ * output.  While it is true that anyone on the system can see
+ * your environment, someone not on the system will have a very
+ * difficult time guessing it, especially since some systems play
+ * tricks with variable ordering and sometimes define quirky
+ * environment variables like $WINDOWID or $_.
+ */
+extern char ** environ;
+
+static void
+t_envhash(out)
+     unsigned char * out;
+{
+  char ** ptr;
+  char ebuf[256];
+  SHA1_CTX ctxt;
+
+  SHA1Init(&ctxt);
+  for(ptr = environ; *ptr; ++ptr) {
+    strncpy(ebuf, *ptr, 255);
+    ebuf[255] = '\0';
+    SHA1Update(&ctxt, ebuf, strlen(ebuf));
+  }
+  SHA1Final(out, &ctxt);
+}
+
+/*
+ * t_fshash - Generate a 160-bit SHA hash from the file system
+ *
+ * This routine climbs up the directory tree from the current
+ * directory, running stat() on each directory until it hits the
+ * root directory.  This information is sensitive to the last
+ * access/modification times of all the directories above you,
+ * so someone who lists one of those directories injects some
+ * entropy into the system.  Obviously, this hash is very sensitive
+ * to your current directory when the program is run.
+ *
+ * For good measure, it also performs an fstat on the standard input,
+ * usually your tty, throws that into the buffer, creates a file in
+ * /tmp (the inode is unpredictable on a busy system), and runs stat()
+ * on that before deleting it.
+ *
+ * The entire buffer is run once through SHA to obtain the final result.
+ */
+static void
+t_fshash(out)
+     unsigned char * out;
+{
+  char dotpath[128];
+  struct stat st;
+  SHA1_CTX ctxt;
+  int i, pinode;
+  dev_t pdev;
+
+  SHA1Init(&ctxt);
+  if(stat(".", &st) >= 0) {
+    SHA1Update(&ctxt, (unsigned char *) &st, sizeof(st));
+    pinode = st.st_ino;
+    pdev = st.st_dev;
+    strcpy(dotpath, "..");
+    for(i = 0; i < 40; ++i) {
+      if(stat(dotpath, &st) < 0)
+       break;
+      if(st.st_ino == pinode && st.st_dev == pdev)
+       break;
+      SHA1Update(&ctxt, (unsigned char *) &st, sizeof(st));
+      pinode = st.st_ino;
+      pdev = st.st_dev;
+      strcat(dotpath, "/..");
+    }
+  }
+
+  if(fstat(0, &st) >= 0)
+    SHA1Update(&ctxt, (unsigned char *) &st, sizeof(st));
+
+  sprintf(dotpath, "/tmp/rnd.%d", getpid());
+  if(creat(dotpath, 0600) >= 0 && stat(dotpath, &st) >= 0)
+    SHA1Update(&ctxt, (unsigned char *) &st, sizeof(st));
+  unlink(dotpath);
+
+  SHA1Final(out, &ctxt);
+}
+
+/*
+ * Generate a high-entropy seed for the strong random number generator.
+ * This uses a wide variety of quickly gathered and somewhat unpredictable
+ * system information.  The 'preseed' structure is assembled from:
+ *
+ *   The system time in seconds
+ *   The system time in microseconds
+ *   The current process ID
+ *   The parent process ID
+ *   A hash of the user's environment
+ *   A hash gathered from the file system
+ *   Input from a random device, if available
+ *   Timings of system interrupts
+ *
+ * The entire structure (60 bytes on most systems) is fed to SHA to produce
+ * a 160-bit seed for the strong random number generator.  It is believed
+ * that in the worst case (on a quiet system with no random device versus
+ * an attacker who has access to the system already), the seed contains at
+ * least about 80 bits of entropy.  Versus an attacker who does not have
+ * access to the system, the entropy should be slightly over 128 bits.
+ */
+static char initialized = 0;
+
+static struct {
+  unsigned int trand1;
+  time_t sec;
+  time_t usec;
+  short pid;
+  short ppid;
+  unsigned char envh[SHA_DIGESTSIZE];
+  unsigned char fsh[SHA_DIGESTSIZE];
+  unsigned char devrand[20];
+  unsigned int trand2;
+} preseed;
+
+unsigned long raw_truerand();
+
+void
+t_initrand()
+{
+  SHA1_CTX ctxt;
+#ifdef USE_FTIME
+  struct timeb t;
+#else
+  struct timeval t;
+#endif
+  int i, r=0;
+
+  if(initialized)
+    return;
+
+  initialized = 1;
+
+  i = open("/dev/urandom", O_RDONLY);
+  if(i > 0) {
+    r += read(i, preseed.devrand, sizeof(preseed.devrand));
+    close(i);
+  }
+
+  /* Resort to truerand only if desperate for some Real entropy */
+  if(r == 0)
+    preseed.trand1 = raw_truerand();
+
+#ifdef USE_FTIME
+  ftime(&t);
+#else
+  gettimeofday(&t, NULL);
+#endif
+
+#ifdef USE_FTIME
+  preseed.sec = t.time;
+  preseed.usec = t.millitm;
+#else
+  preseed.sec = t.tv_sec;
+  preseed.usec = t.tv_usec;
+#endif
+  preseed.pid = getpid();
+  preseed.ppid = getppid();
+  t_envhash(preseed.envh);
+  t_fshash(preseed.fsh);
+
+  if(r == 0)
+    preseed.trand2 = raw_truerand();
+
+  SHA1Init(&ctxt);
+  SHA1Update(&ctxt, (unsigned char *) &preseed, sizeof(preseed));
+  SHA1Final(randpool, &ctxt);
+  outpos = 0;
+  memset((unsigned char *) &preseed, 0, sizeof(preseed));
+  memset((unsigned char *) &ctxt, 0, sizeof(ctxt));
+}
+
+#define NUM_RANDOMS 12
+
+/*
+ * The strong random number generator.  This uses a 160-bit seed
+ * and uses SHA-1 in a feedback configuration to generate successive
+ * outputs.  If S[0] is set to the initial seed, then:
+ *
+ *         S[i+1] = SHA-1(i || S[i])
+ *         A[i] = SHA-1(S[i])
+ *
+ * where the A[i] are the output blocks starting with i=0.
+ * Each cycle generates 20 bytes of new output.
+ */
+_TYPE( void )
+t_random(data, size)
+     unsigned char * data;
+     unsigned size;
+{
+  if(!initialized)
+    t_initrand();
+
+  if(size <= 0)         /* t_random(NULL, 0) forces seed initialization */
+    return;
+
+  while(size > outpos) {
+    if(outpos > 0) {
+      memcpy(data, randout + (sizeof(randout) - outpos), outpos);
+      data += outpos;
+      size -= outpos;
+    }
+
+    /* Recycle */
+    SHA1Init(&randctxt);
+    SHA1Update(&randctxt, randpool, sizeof(randpool));
+    SHA1Final(randout, &randctxt);
+    SHA1Init(&randctxt);
+    SHA1Update(&randctxt, (unsigned char *) &randcnt, sizeof(randcnt));
+    SHA1Update(&randctxt, randpool, sizeof(randpool));
+    SHA1Final(randpool, &randctxt);
+    ++randcnt;
+    outpos = sizeof(randout);
+  }
+
+  if(size > 0) {
+    memcpy(data, randout + (sizeof(randout) - outpos), size);
+    outpos -= size;
+  }
+}
+
+/*
+ * The interleaved session-key hash.  This separates the even and the odd
+ * bytes of the input (ignoring the first byte if the input length is odd),
+ * hashes them separately, and re-interleaves the two outputs to form a
+ * single 320-bit value.
+ */
+_TYPE( unsigned char * )
+t_sessionkey(key, sk, sklen)
+     unsigned char * key;
+     unsigned char * sk;
+     unsigned sklen;
+{
+  unsigned i, klen;
+  unsigned char * hbuf;
+  unsigned char hout[SHA_DIGESTSIZE];
+  SHA1_CTX ctxt;
+
+  while(sklen > 0 && *sk == 0) {        /* Skip leading 0's */
+    --sklen;
+    ++sk;
+  }
+
+  klen = sklen / 2;
+  if((hbuf = malloc(klen * sizeof(char))) == 0)
+    return 0;
+
+  for(i = 0; i < klen; ++i)
+    hbuf[i] = sk[sklen - 2 * i - 1];
+  SHA1Init(&ctxt);
+  SHA1Update(&ctxt, hbuf, klen);
+  SHA1Final(hout, &ctxt);
+  for(i = 0; i < sizeof(hout); ++i)
+    key[2 * i] = hout[i];
+
+  for(i = 0; i < klen; ++i)
+    hbuf[i] = sk[sklen - 2 * i - 2];
+  SHA1Init(&ctxt);
+  SHA1Update(&ctxt, hbuf, klen);
+  SHA1Final(hout, &ctxt);
+  for(i = 0; i < sizeof(hout); ++i)
+    key[2 * i + 1] = hout[i];
+
+  memset(hout, 0, sizeof(hout));
+  memset(hbuf, 0, klen);
+  free(hbuf);
+  return key;
+}
diff --git a/package/ead/src/tinysrp/t_pw.c b/package/ead/src/tinysrp/t_pw.c
new file mode 100644 (file)
index 0000000..18e929b
--- /dev/null
@@ -0,0 +1,262 @@
+/*
+ * Copyright (c) 1997-2000  The Stanford SRP Authentication Project
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL STANFORD BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF
+ * THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * In addition, the following conditions apply:
+ *
+ * 1. Any software that incorporates the SRP authentication technology
+ *    must display the following acknowlegment:
+ *    "This product uses the 'Secure Remote Password' cryptographic
+ *     authentication system developed by Tom Wu (tjw@CS.Stanford.EDU)."
+ *
+ * 2. Any software that incorporates all or part of the SRP distribution
+ *    itself must also display the following acknowledgment:
+ *    "This product includes software developed by Tom Wu and Eugene
+ *     Jhong for the SRP Distribution (http://srp.stanford.edu/srp/)."
+ *
+ * 3. Redistributions in source or binary form must retain an intact copy
+ *    of this copyright notice and list of conditions.
+ */
+
+#include "t_defines.h"
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif /* HAVE_UNISTD_H */
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#ifdef USE_HOMEDIR
+#include <pwd.h>
+#endif
+#ifdef WIN32
+#include <io.h>
+#endif
+
+#include "t_pwd.h"
+#include "t_read.h"
+#include "t_sha.h"
+#include "t_server.h"
+
+static struct t_pw * syspw = NULL;
+static struct t_passwd tpass;
+
+_TYPE( struct t_server * )
+t_serveropen(username)
+     const char * username;
+{
+  struct t_passwd * p;
+  p = gettpnam(username);
+  if(p == NULL) {
+    return NULL;
+  } else {
+    return t_serveropenraw(&p->tp, &p->tc);
+  }
+}
+
+
+/* t_openpw(NULL) is deprecated - use settpent()/gettpnam() instead */
+
+_TYPE( struct t_pw * )
+t_openpw(fp)
+     FILE * fp;
+{
+  struct t_pw * tpw;
+  char close_flag = 0;
+
+  if(fp == NULL) { /* Deprecated */
+    if((fp = fopen(DEFAULT_PASSWD, "r")) == NULL)
+      return NULL;
+    close_flag = 1;
+  }
+  else
+    close_flag = 0;
+
+  if((tpw = malloc(sizeof(struct t_pw))) == NULL)
+    return NULL;
+  tpw->instream = fp;
+  tpw->close_on_exit = close_flag;
+  tpw->state = FILE_ONLY;
+
+  return tpw;
+}
+
+_TYPE( struct t_pw * )
+t_openpwbyname(pwname)
+     const char * pwname;
+{
+  FILE * fp;
+  struct t_pw * t;
+
+  if(pwname == NULL)            /* Deprecated */
+    return t_openpw(NULL);
+
+  if((fp = fopen(pwname, "r")) == NULL)
+    return NULL;
+
+  t = t_openpw(fp);
+  t->close_on_exit = 1;
+  return t;
+}
+
+_TYPE( void )
+t_closepw(tpw)
+     struct t_pw * tpw;
+{
+  if(tpw->close_on_exit)
+    fclose(tpw->instream);
+  free(tpw);
+}
+
+_TYPE( void )
+t_rewindpw(tpw)
+     struct t_pw * tpw;
+{
+#ifdef ENABLE_YP
+  if(tpw->state == IN_NIS)
+    tpw->state = FILE_NIS;
+#endif
+  rewind(tpw->instream);
+}
+
+#ifdef ENABLE_YP
+static void
+savepwent(tpw, pwent)
+     struct t_pw * tpw;
+     struct t_pwent *pwent;
+{
+  tpw->pebuf.name = tpw->userbuf;
+  tpw->pebuf.password.data = tpw->pwbuf;
+  tpw->pebuf.salt.data = tpw->saltbuf;
+  strcpy(tpw->pebuf.name, pwent->name);
+  tpw->pebuf.password.len = pwent->password.len;
+  memcpy(tpw->pebuf.password.data, pwent->password.data, pwent->password.len);
+  tpw->pebuf.salt.len = pwent->salt.len;
+  memcpy(tpw->pebuf.salt.data, pwent->salt.data, pwent->salt.len);
+  tpw->pebuf.index = pwent->index;
+}
+#endif /* ENABLE_YP */
+
+_TYPE( struct t_pwent * )
+t_getpwbyname(tpw, user)
+     struct t_pw * tpw;
+     const char * user;
+{
+  char indexbuf[16];
+  char passbuf[MAXB64PARAMLEN];
+  char saltstr[MAXB64SALTLEN];
+  char username[MAXUSERLEN];
+#ifdef ENABLE_YP
+  struct t_passwd * nisent;
+#endif
+
+  t_rewindpw(tpw);
+
+  while(t_nextfield(tpw->instream, username, MAXUSERLEN) > 0) {
+#ifdef ENABLE_YP
+    if(tpw->state == FILE_NIS && *username == '+') {
+      if(strlen(username) == 1 || strcmp(user, username+1) == 0) {
+       nisent = _yp_gettpnam(user);    /* Entry is +username or + */
+       if(nisent != NULL) {
+         savepwent(tpw, &nisent->tp);
+         return &tpw->pebuf;
+       }
+      }
+    }
+#endif
+    if(strcmp(user, username) == 0)
+      if(t_nextfield(tpw->instream, passbuf, MAXB64PARAMLEN) > 0 &&
+        (tpw->pebuf.password.len = t_fromb64(tpw->pwbuf, passbuf)) > 0 &&
+        t_nextfield(tpw->instream, saltstr, MAXB64SALTLEN) > 0 &&
+        (tpw->pebuf.salt.len = t_fromb64(tpw->saltbuf, saltstr)) > 0 &&
+        t_nextfield(tpw->instream, indexbuf, 16) > 0 &&
+        (tpw->pebuf.index = atoi(indexbuf)) > 0) {
+       strcpy(tpw->userbuf, username);
+       tpw->pebuf.name = tpw->userbuf;
+       tpw->pebuf.password.data = tpw->pwbuf;
+       tpw->pebuf.salt.data = tpw->saltbuf;
+       t_nextline(tpw->instream);
+       return &tpw->pebuf;
+      }
+    if(t_nextline(tpw->instream) < 0)
+      return NULL;
+  }
+  return NULL;
+}
+
+/* System password file accessors */
+
+static int
+pwinit()
+{
+  if(syspw == NULL) {
+    if((syspw = t_openpwbyname(DEFAULT_PASSWD)) == NULL)
+      return -1;
+    syspw->state = FILE_NIS;
+  }
+  return 0;
+}
+
+static void
+pwsetup(out, tpwd, tcnf)
+     struct t_passwd * out;
+     struct t_pwent * tpwd;
+     struct t_confent * tcnf;
+{
+  out->tp.name = tpwd->name;
+  out->tp.password.len = tpwd->password.len;
+  out->tp.password.data = tpwd->password.data;
+  out->tp.salt.len = tpwd->salt.len;
+  out->tp.salt.data = tpwd->salt.data;
+  out->tp.index = tpwd->index;
+
+  out->tc.index = tcnf->index;
+  out->tc.modulus.len = tcnf->modulus.len;
+  out->tc.modulus.data = tcnf->modulus.data;
+  out->tc.generator.len = tcnf->generator.len;
+  out->tc.generator.data = tcnf->generator.data;
+}
+
+_TYPE( struct t_passwd * )
+gettpnam
+(user)
+     const char * user;
+{
+  struct t_pwent * tpptr;
+  struct t_confent * tcptr;
+
+  if(pwinit() < 0)
+    return NULL;
+  tpptr = t_getpwbyname(syspw, user);
+  if(tpptr == NULL)
+    return NULL;
+  tcptr =
+    gettcid
+    (tpptr->index);
+  if(tcptr == NULL)
+    return NULL;
+  pwsetup(&tpass, tpptr, tcptr);
+  return &tpass;
+}
diff --git a/package/ead/src/tinysrp/t_pwd.h b/package/ead/src/tinysrp/t_pwd.h
new file mode 100644 (file)
index 0000000..73697be
--- /dev/null
@@ -0,0 +1,310 @@
+/*
+ * Copyright (c) 1997-1999  The Stanford SRP Authentication Project
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL STANFORD BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF
+ * THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * In addition, the following conditions apply:
+ *
+ * 1. Any software that incorporates the SRP authentication technology
+ *    must display the following acknowlegment:
+ *    "This product uses the 'Secure Remote Password' cryptographic
+ *     authentication system developed by Tom Wu (tjw@CS.Stanford.EDU)."
+ *
+ * 2. Any software that incorporates all or part of the SRP distribution
+ *    itself must also display the following acknowledgment:
+ *    "This product includes software developed by Tom Wu and Eugene
+ *     Jhong for the SRP Distribution (http://srp.stanford.edu/srp/)."
+ *
+ * 3. Redistributions in source or binary form must retain an intact copy
+ *    of this copyright notice and list of conditions.
+ */
+
+#ifndef T_PWD_H
+#define T_PWD_H
+
+#ifndef P
+#if defined (__STDC__) || defined (__cplusplus)
+#define P(x) x
+#else
+#define P(x) ()
+#endif
+#endif
+
+/*      For building dynamic link libraries under windows, windows NT
+ *      using MSVC1.5 or MSVC2.0
+ */
+
+#ifndef _DLLDECL
+#define _DLLDECL
+
+#ifdef MSVC15   /* MSVC1.5 support for 16 bit apps */
+#define _MSVC15EXPORT _export
+#define _MSVC20EXPORT
+#define _DLLAPI _export _pascal
+#define _TYPE(a) a _MSVC15EXPORT
+#define DLLEXPORT 1
+
+#elif MSVC20
+#define _MSVC15EXPORT
+#define _MSVC20EXPORT _declspec(dllexport)
+#define _DLLAPI
+#define _TYPE(a) _MSVC20EXPORT a
+#define DLLEXPORT 1
+
+#else                   /* Default, non-dll.  Use this for Unix or DOS */
+#define _MSVC15DEXPORT
+#define _MSVC20EXPORT
+#define _DLLAPI
+#define _TYPE(a) a
+#endif
+#endif
+
+#define MAXPARAMBITS    2048
+#define MAXPARAMLEN     ((MAXPARAMBITS + 7) / 8)
+#define MAXB64PARAMLEN  ((MAXPARAMBITS + 5) / 6 + 1)
+#define MAXHEXPARAMLEN  ((MAXPARAMBITS + 3) / 4 + 1)
+#define MAXOCTPARAMLEN  ((MAXPARAMBITS + 2) / 3 + 1)
+
+#define MAXUSERLEN      32
+#define MAXSALTLEN      32
+#define MAXB64SALTLEN   44      /* 256 bits in b64 + null */
+#define SALTLEN         10      /* Normally 80 bits */
+
+#define RESPONSE_LEN    20      /* 160-bit proof hashes */
+#define SESSION_KEY_LEN (2 * RESPONSE_LEN)      /* 320-bit session key */
+
+#define DEFAULT_PASSWD  "tpasswd"
+
+struct t_num {  /* Standard byte-oriented integer representation */
+  int len;
+  unsigned char * data;
+};
+
+struct t_preconf {      /* Structure returned by t_getpreparam() */
+  char * mod_b64;
+  char * gen_b64;
+  char * comment;
+
+  struct t_num modulus;
+  struct t_num generator;
+};
+
+/*
+ * The built-in (known good) parameters access routines
+ *
+ * "t_getprecount" returns the number of precompiled parameter sets.
+ * "t_getpreparam" returns the indicated parameter set.
+ * Memory is statically allocated - callers need not perform any memory mgmt.
+ */
+_TYPE( int ) t_getprecount();
+_TYPE( struct t_preconf * ) t_getpreparam P((int));
+
+struct t_confent {      /* One configuration file entry (index, N, g) */
+  int index;
+  struct t_num modulus;
+  struct t_num generator;
+};
+
+struct t_conf {         /* An open configuration file */
+  FILE * instream;
+  char close_on_exit;
+  unsigned char modbuf[MAXPARAMLEN];
+  unsigned char genbuf[MAXPARAMLEN];
+  struct t_confent tcbuf;
+};
+
+/*
+ * The configuration file routines are designed along the lines of the
+ * "getpw" functions in the standard C library.
+ *
+ * "t_openconf" accepts a stdio stream and interprets it as a config file.
+ * "t_openconfbyname" accepts a filename and does the same thing.
+ * "t_closeconf" closes the config file.
+ * "t_getconfent" fetches the next sequential configuration entry.
+ * "t_getconfbyindex" fetches the configuration entry whose index
+ *   matches the one supplied, or NULL if one can't be found.
+ * "t_getconflast" fetches the last configuration entry in the file.
+ * "t_makeconfent" generates a set of configuration entry parameters
+ *   randomly.
+ * "t_newconfent" returns an empty configuration entry.
+ * "t_cmpconfent" compares two configuration entries a la strcmp.
+ * "t_checkconfent" verifies that a set of configuration parameters
+ *   are suitable.  N must be prime and should be a safe prime.
+ * "t_putconfent" writes a configuration entry to a stream.
+ */
+_TYPE( struct t_conf * ) t_openconf P((FILE *));
+_TYPE( struct t_conf * ) t_openconfbyname P((const char *));
+_TYPE( void ) t_closeconf P((struct t_conf *));
+_TYPE( void ) t_rewindconf P((struct t_conf *));
+_TYPE( struct t_confent * ) t_getconfent P((struct t_conf *));
+_TYPE( struct t_confent * ) t_getconfbyindex P((struct t_conf *, int));
+_TYPE( struct t_confent * ) t_getconflast P((struct t_conf *));
+_TYPE( struct t_confent * ) t_makeconfent P((struct t_conf *, int));
+_TYPE( struct t_confent * ) t_makeconfent_c P((struct t_conf *, int));
+_TYPE( struct t_confent * ) t_newconfent P((struct t_conf *));
+_TYPE( int ) t_cmpconfent P((const struct t_confent *, const struct t_confent *));
+_TYPE( int ) t_checkconfent P((const struct t_confent *));
+_TYPE( void ) t_putconfent P((const struct t_confent *, FILE *));
+
+/* libc-style system conf file access */
+_TYPE( struct t_confent *) gettcent();
+_TYPE( struct t_confent *) gettcid P((int));
+_TYPE( void ) settcent();
+_TYPE( void ) endtcent();
+
+#ifdef ENABLE_NSW
+extern struct t_confent * _gettcent();
+extern struct t_confent * _gettcid P((int));
+extern void _settcent();
+extern void _endtcent();
+#endif
+
+/* A hack to support '+'-style entries in the passwd file */
+
+typedef enum fstate {
+  FILE_ONLY,    /* Ordinary file, don't consult NIS ever */
+  FILE_NIS,     /* Currently accessing file, use NIS if encountered */
+  IN_NIS,       /* Currently in a '+' entry; use NIS for getXXent */
+} FILE_STATE;
+
+struct t_pwent {        /* A single password file entry */
+  char * name;
+  struct t_num password;
+  struct t_num salt;
+  int index;
+};
+
+struct t_pw {           /* An open password file */
+  FILE * instream;
+  char close_on_exit;
+  FILE_STATE state;
+  char userbuf[MAXUSERLEN];
+  unsigned char pwbuf[MAXPARAMLEN];
+  unsigned char saltbuf[SALTLEN];
+  struct t_pwent pebuf;
+};
+
+/*
+ * The password manipulation routines are patterned after the getpw*
+ * standard C library function calls.
+ *
+ * "t_openpw" reads a stream as if it were a password file.
+ * "t_openpwbyname" opens the named file as a password file.
+ * "t_closepw" closes an open password file.
+ * "t_rewindpw" starts the internal file pointer from the beginning
+ *   of the password file.
+ * "t_getpwent" retrieves the next sequential password entry.
+ * "t_getpwbyname" looks up the password entry corresponding to the
+ *   specified user.
+ * "t_makepwent" constructs a password entry from a username, password,
+ *   numeric salt, and configuration entry.
+ * "t_putpwent" writes a password entry to a stream.
+ */
+_TYPE( struct t_pw * ) t_openpw P((FILE *));
+_TYPE( struct t_pw * ) t_openpwbyname P((const char *));
+_TYPE( void ) t_closepw P((struct t_pw *));
+_TYPE( void ) t_rewindpw P((struct t_pw *));
+_TYPE( struct t_pwent * ) t_getpwent P((struct t_pw *));
+_TYPE( struct t_pwent * ) t_getpwbyname P((struct t_pw *, const char *));
+_TYPE( struct t_pwent * ) t_makepwent P((struct t_pw *, const char *,
+                                        const char *, const struct t_num *,
+                                        const struct t_confent *));
+_TYPE( void ) t_putpwent P((const struct t_pwent *, FILE *));
+
+struct t_passwd {
+  struct t_pwent tp;
+  struct t_confent tc;
+};
+
+/* libc-style system password file access */
+_TYPE( struct t_passwd * ) gettpent();
+_TYPE( struct t_passwd * ) gettpnam P((const char *));
+_TYPE( void ) settpent();
+_TYPE( void ) endtpent();
+
+#ifdef ENABLE_NSW
+extern struct t_passwd * _gettpent();
+extern struct t_passwd * _gettpnam P((const char *));
+extern void _settpent();
+extern void _endtpent();
+#endif
+
+/*
+ * Utility functions
+ *
+ * "t_verifypw" accepts a username and password, and checks against the
+ *   system password file to see if the password for that user is correct.
+ *   Returns > 0 if it is correct, 0 if not, and -1 if some error occurred
+ *   (i.e. the user doesn't exist on the system).  This is intended ONLY
+ *   for local authentication; for remote authentication, look at the
+ *   t_client and t_server source.  (That's the whole point of SRP!)
+ * "t_changepw" modifies the specified file, substituting the given password
+ *   entry for the one already in the file.  If no matching entry is found,
+ *   the new entry is simply appended to the file.
+ * "t_deletepw" removes the specified user from the specified file.
+ */
+_TYPE( int ) t_verifypw P((const char *, const char *));
+_TYPE( int ) t_changepw P((const char *, const struct t_pwent *));
+_TYPE( int ) t_deletepw P((const char *, const char *));
+
+/* Conversion utilities */
+
+/*
+ * All these calls accept output as the first parameter.  In the case of
+ * t_tohex and t_tob64, the last argument is the length of the byte-string
+ * input.
+ */
+_TYPE( char * t_tohex ) P((char *, char *, unsigned));
+_TYPE( int ) t_fromhex P((char *, char *));
+_TYPE( char * ) t_tob64 P((char *, char *, unsigned));
+_TYPE( int ) t_fromb64 P((char *, char *));
+
+/* Miscellaneous utilities */
+
+/*
+ * "t_random" is a cryptographic random number generator, which is seeded
+ *   from various high-entropy sources and uses a one-way hash function
+ *   in a feedback configuration.
+ * "t_sessionkey" is the interleaved hash used to generate session keys
+ *   from a large integer.
+ * "t_getpass" reads a password from the terminal without echoing.
+ */
+_TYPE( void ) t_random P((unsigned char *, unsigned));
+_TYPE( void ) t_stronginitrand();
+_TYPE( unsigned char * )
+  t_sessionkey P((unsigned char *, unsigned char *, unsigned));
+_TYPE( int ) t_getpass P((char *, unsigned, const char *));
+
+/*
+ * Return value of t_checkprime:
+ *   < 0 : not prime
+ *   = 0 : prime, but not safe
+ *   > 0 : safe
+ */
+#define NUM_NOTPRIME    -1
+#define NUM_NOTSAFE     0
+#define NUM_SAFE        1
+
+_TYPE( int ) t_checkprime P((const struct t_num *));
+
+#endif
diff --git a/package/ead/src/tinysrp/t_read.c b/package/ead/src/tinysrp/t_read.c
new file mode 100644 (file)
index 0000000..087b7d5
--- /dev/null
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 1997-1999  The Stanford SRP Authentication Project
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
+ *
+ * IN NO EVENT SHALL STANFORD BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF
+ * THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * In addition, the following conditions apply:
+ *
+ * 1. Any software that incorporates the SRP authentication technology
+ *    must display the following acknowlegment:
+ *    "This product uses the 'Secure Remote Password' cryptographic
+ *     authentication system developed by Tom Wu (tjw@CS.Stanford.EDU)."
+ *
+ * 2. Any software that incorporates all or part of the SRP distribution
+ *    itself must also display the following acknowledgment:
+ *    "This product includes software developed by Tom Wu and Eugene
+ *     Jhong for the SRP Distribution (http://srp.stanford.edu/srp/)."
+ *
+ * 3. Redistributions in source or binary form must retain an intact copy
+ *    of this copyright notice and list of conditions.
+ */
+
+#include <stdio.h>
+#include "config.h"
+
+#define FSEPARATOR     ':'
+
+int
+t_nextfield(fp, s, max)
+FILE * fp;
+char * s;
+unsigned max;
+{
+  int c, count = 0;
+
+  while((c = getc(fp)) != EOF) {
+    if(c == '\n') {
+      ungetc(c, fp);
+      break;
+    }
+    else if(c == FSEPARATOR)
+      break;
+    if(count < max - 1) {
+      *s++ = c;
+      ++count;
+    }
+  }
+  *s++ = '\0';
+  return count;
+}
+
+int
+t_nextline(fp)
+FILE * fp;
+{
+  int c;
+
+  while((c = getc(fp)) != '\n')
+    if(c == EOF)
+      return -1;
+  return 0;
+}
diff --git a/package/ead/src/tinysrp/t_read.h b/package/ead/src/tinysrp/t_read.h
new file mode 100644 (file)
index 0000000..e621f79
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 1997-1999  The Stanford SRP Authentication Project
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
+ *
+ * IN NO EVENT SHALL STANFORD BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF
+ * THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * In addition, the following conditions apply:
+ *
+ * 1. Any software that incorporates the SRP authentication technology
+ *    must display the following acknowlegment:
+ *    "This product uses the 'Secure Remote Password' cryptographic
+ *     authentication system developed by Tom Wu (tjw@CS.Stanford.EDU)."
+ *
+ * 2. Any software that incorporates all or part of the SRP distribution
+ *    itself must also display the following acknowledgment:
+ *    "This product includes software developed by Tom Wu and Eugene
+ *     Jhong for the SRP Distribution (http://srp.stanford.edu/srp/)."
+ *
+ * 3. Redistributions in source or binary form must retain an intact copy
+ *    of this copyright notice and list of conditions.
+ */
+
+#ifndef _T_READ_H_
+#define _T_READ_H_
+
+#if     !defined(P)
+#ifdef  __STDC__
+#define P(x)    x
+#else
+#define P(x)    ()
+#endif
+#endif
+
+extern int t_nextfield P((FILE *, char *, unsigned));
+extern int t_nextline P((FILE *));
+#endif
diff --git a/package/ead/src/tinysrp/t_server.c b/package/ead/src/tinysrp/t_server.c
new file mode 100644 (file)
index 0000000..6ab501b
--- /dev/null
@@ -0,0 +1,259 @@
+/*
+ * Copyright (c) 1997-1999  The Stanford SRP Authentication Project
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL STANFORD BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF
+ * THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * In addition, the following conditions apply:
+ *
+ * 1. Any software that incorporates the SRP authentication technology
+ *    must display the following acknowlegment:
+ *    "This product uses the 'Secure Remote Password' cryptographic
+ *     authentication system developed by Tom Wu (tjw@CS.Stanford.EDU)."
+ *
+ * 2. Any software that incorporates all or part of the SRP distribution
+ *    itself must also display the following acknowledgment:
+ *    "This product includes software developed by Tom Wu and Eugene
+ *     Jhong for the SRP Distribution (http://srp.stanford.edu/srp/)."
+ *
+ * 3. Redistributions in source or binary form must retain an intact copy
+ *    of this copyright notice and list of conditions.
+ */
+
+#include <stdio.h>
+#include "t_defines.h"
+#include "t_pwd.h"
+#include "t_server.h"
+
+_TYPE( struct t_server * )
+t_serveropenraw(ent, tce)
+     struct t_pwent * ent;
+     struct t_confent * tce;
+{
+  struct t_server * ts;
+  unsigned char buf1[SHA_DIGESTSIZE], buf2[SHA_DIGESTSIZE];
+  SHA1_CTX ctxt;
+  int i;
+
+  if((ts = malloc(sizeof(struct t_server))) == 0)
+    return 0;
+
+  SHA1Init(&ts->ckhash);
+
+  ts->index = ent->index;
+  ts->n.len = tce->modulus.len;
+  ts->n.data = ts->nbuf;
+  memcpy(ts->n.data, tce->modulus.data, ts->n.len);
+
+  SHA1Init(&ctxt);
+  SHA1Update(&ctxt, ts->n.data, ts->n.len);
+  SHA1Final(buf1, &ctxt);
+
+  ts->g.len = tce->generator.len;
+  ts->g.data = ts->gbuf;
+  memcpy(ts->g.data, tce->generator.data, ts->g.len);
+
+  SHA1Init(&ctxt);
+  SHA1Update(&ctxt, ts->g.data, ts->g.len);
+  SHA1Final(buf2, &ctxt);
+
+  for(i = 0; i < sizeof(buf1); ++i)
+    buf1[i] ^= buf2[i];
+
+  SHA1Update(&ts->ckhash, buf1, sizeof(buf1));
+
+  SHA1Init(&ctxt);
+  SHA1Update(&ctxt, ent->name, strlen(ent->name));
+  SHA1Final(buf1, &ctxt);
+
+  SHA1Update(&ts->ckhash, buf1, sizeof(buf1));
+
+  ts->v.len = ent->password.len;
+  ts->v.data = ts->vbuf;
+  memcpy(ts->v.data, ent->password.data, ts->v.len);
+
+  ts->s.len = ent->salt.len;
+  ts->s.data = ts->saltbuf;
+  memcpy(ts->s.data, ent->salt.data, ts->s.len);
+
+  SHA1Update(&ts->ckhash, ts->s.data, ts->s.len);
+
+  ts->b.data = ts->bbuf;
+  ts->B.data = ts->Bbuf;
+
+  SHA1Init(&ts->hash);
+  SHA1Init(&ts->oldhash);
+  SHA1Init(&ts->oldckhash);
+
+  return ts;
+}
+
+_TYPE( struct t_num * )
+t_servergenexp(ts)
+     struct t_server * ts;
+{
+  BigInteger b, B, v, n, g;
+
+  if(ts->n.len < BLEN)
+    ts->b.len = ts->n.len;
+  else
+    ts->b.len = BLEN;
+
+  t_random(ts->b.data, ts->b.len);
+  b = BigIntegerFromBytes(ts->b.data, ts->b.len);
+  n = BigIntegerFromBytes(ts->n.data, ts->n.len);
+  g = BigIntegerFromBytes(ts->g.data, ts->g.len);
+  B = BigIntegerFromInt(0);
+  BigIntegerModExp(B, g, b, n);
+
+  v = BigIntegerFromBytes(ts->v.data, ts->v.len);
+  BigIntegerAdd(B, B, v);
+  if(BigIntegerCmp(B, n) > 0)
+    BigIntegerSub(B, B, n);
+
+  ts->B.len = BigIntegerToBytes(B, ts->B.data);
+
+  BigIntegerFree(v);
+  BigIntegerFree(B);
+  BigIntegerFree(b);
+  BigIntegerFree(g);
+  BigIntegerFree(n);
+
+  SHA1Update(&ts->oldckhash, ts->B.data, ts->B.len);
+
+  return &ts->B;
+}
+
+_TYPE( unsigned char * )
+t_servergetkey(ts, clientval)
+     struct t_server * ts;
+     struct t_num * clientval;
+{
+  BigInteger n, v, A, b, prod, res, S;
+  SHA1_CTX ctxt;
+  unsigned char sbuf[MAXPARAMLEN];
+  unsigned char dig[SHA_DIGESTSIZE];
+  unsigned slen;
+  unsigned int u;
+
+  SHA1Update(&ts->ckhash, clientval->data, clientval->len);
+  SHA1Update(&ts->ckhash, ts->B.data, ts->B.len);
+
+  SHA1Init(&ctxt);
+  SHA1Update(&ctxt, ts->B.data, ts->B.len);
+  SHA1Final(dig, &ctxt);
+  u = (dig[0] << 24) | (dig[1] << 16) | (dig[2] << 8) | dig[3];
+
+  SHA1Update(&ts->oldhash, clientval->data, clientval->len);
+  SHA1Update(&ts->hash, clientval->data, clientval->len);
+
+  n = BigIntegerFromBytes(ts->n.data, ts->n.len);
+  b = BigIntegerFromBytes(ts->b.data, ts->b.len);
+  v = BigIntegerFromBytes(ts->v.data, ts->v.len);
+  A = BigIntegerFromBytes(clientval->data, clientval->len);
+
+  prod = BigIntegerFromInt(0);
+  BigIntegerModExpInt(prod, v, u, n);
+  res = BigIntegerFromInt(0);
+  BigIntegerModMul(res, prod, A, n);
+
+  BigIntegerFree(A);
+  BigIntegerFree(v);
+  BigIntegerFree(prod);
+
+  if(BigIntegerCmpInt(res, 1) <= 0) {   /* Check for Av^u == 1 (mod n) */
+    BigIntegerFree(res);
+    BigIntegerFree(b);
+    BigIntegerFree(n);
+    return NULL;
+  }
+
+  S = BigIntegerFromInt(0);
+
+  BigIntegerAddInt(S, res, 1);
+  if(BigIntegerCmp(S, n) == 0) {        /* Check for Av^u == -1 (mod n) */
+    BigIntegerFree(res);
+    BigIntegerFree(b);
+    BigIntegerFree(n);
+    BigIntegerFree(S);
+    return NULL;
+  }
+
+  BigIntegerModExp(S, res, b, n);
+  slen = BigIntegerToBytes(S, sbuf);
+
+  BigIntegerFree(S);
+  BigIntegerFree(res);
+  BigIntegerFree(b);
+  BigIntegerFree(n);
+
+  t_sessionkey(ts->session_key, sbuf, slen);
+  memset(sbuf, 0, slen);
+
+  SHA1Update(&ts->oldhash, ts->session_key, sizeof(ts->session_key));
+  SHA1Update(&ts->oldckhash, ts->session_key, sizeof(ts->session_key));
+  SHA1Update(&ts->ckhash, ts->session_key, sizeof(ts->session_key));
+
+  return ts->session_key;
+}
+
+_TYPE( int )
+t_serververify(ts, resp)
+    struct t_server * ts;
+    unsigned char * resp;
+{
+  unsigned char expected[SHA_DIGESTSIZE];
+  int i;
+
+  SHA1Final(expected, &ts->oldckhash);
+  i = memcmp(expected, resp, sizeof(expected));
+  if(i == 0) {
+    SHA1Final(ts->session_response, &ts->oldhash);
+    return 0;
+  }
+  SHA1Final(expected, &ts->ckhash);
+  i = memcmp(expected, resp, sizeof(expected));
+  if(i == 0) {
+    SHA1Update(&ts->hash, expected, sizeof(expected));
+    SHA1Update(&ts->hash, ts->session_key, sizeof(ts->session_key));
+    SHA1Final(ts->session_response, &ts->hash);
+  }
+  return i;
+}
+
+_TYPE( unsigned char * )
+t_serverresponse(ts)
+    struct t_server * ts;
+{
+  return ts->session_response;
+}
+
+_TYPE( void )
+t_serverclose(ts)
+     struct t_server * ts;
+{
+  memset(ts->bbuf, 0, sizeof(ts->bbuf));
+  memset(ts->vbuf, 0, sizeof(ts->vbuf));
+  memset(ts->saltbuf, 0, sizeof(ts->saltbuf));
+  memset(ts->session_key, 0, sizeof(ts->session_key));
+  free(ts);
+}
diff --git a/package/ead/src/tinysrp/t_server.h b/package/ead/src/tinysrp/t_server.h
new file mode 100644 (file)
index 0000000..20970ff
--- /dev/null
@@ -0,0 +1,138 @@
+/*
+ * Copyright (c) 1997-1999  The Stanford SRP Authentication Project
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL STANFORD BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF
+ * THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * In addition, the following conditions apply:
+ *
+ * 1. Any software that incorporates the SRP authentication technology
+ *    must display the following acknowlegment:
+ *    "This product uses the 'Secure Remote Password' cryptographic
+ *     authentication system developed by Tom Wu (tjw@CS.Stanford.EDU)."
+ *
+ * 2. Any software that incorporates all or part of the SRP distribution
+ *    itself must also display the following acknowledgment:
+ *    "This product includes software developed by Tom Wu and Eugene
+ *     Jhong for the SRP Distribution (http://srp.stanford.edu/srp/)."
+ *
+ * 3. Redistributions in source or binary form must retain an intact copy
+ *    of this copyright notice and list of conditions.
+ */
+
+#ifndef T_SERVER_H
+#define T_SERVER_H
+
+#include "t_sha.h"
+
+#if     !defined(P)
+#ifdef  __STDC__
+#define P(x)    x
+#else
+#define P(x)    ()
+#endif
+#endif
+
+#ifndef _DLLDECL
+#define _DLLDECL
+
+#ifdef MSVC15   /* MSVC1.5 support for 16 bit apps */
+#define _MSVC15EXPORT _export
+#define _MSVC20EXPORT
+#define _DLLAPI _export _pascal
+#define _TYPE(a) a _MSVC15EXPORT
+#define DLLEXPORT 1
+
+#elif MSVC20
+#define _MSVC15EXPORT
+#define _MSVC20EXPORT _declspec(dllexport)
+#define _DLLAPI
+#define _TYPE(a) _MSVC20EXPORT a
+#define DLLEXPORT 1
+
+#else                   /* Default, non-dll.  Use this for Unix or DOS */
+#define _MSVC15DEXPORT
+#define _MSVC20EXPORT
+#define _DLLAPI
+#define _TYPE(a) a
+#endif
+#endif
+
+#define BLEN 32
+
+struct t_server {
+  int index;
+  struct t_num n;
+  struct t_num g;
+  struct t_num v;
+  struct t_num s;
+
+  struct t_num b;
+  struct t_num B;
+
+  SHA1_CTX oldhash, hash, oldckhash, ckhash;
+
+  unsigned char session_key[SESSION_KEY_LEN];
+  unsigned char session_response[RESPONSE_LEN];
+
+  unsigned char nbuf[MAXPARAMLEN], gbuf[MAXPARAMLEN], vbuf[MAXPARAMLEN];
+  unsigned char saltbuf[MAXSALTLEN], bbuf[BLEN], Bbuf[MAXPARAMLEN];
+};
+
+/*
+ * SRP server-side negotiation
+ *
+ * This code negotiates the server side of an SRP exchange.
+ * "t_serveropen" accepts a username (sent by the client), a pointer
+ *   to an open password file, and a pointer to an open configuration
+ *   file.  The server should then call...
+ * "t_servergenexp" will generate a random 256-bit exponent and
+ *   raise g (from the configuration file) to that power, returning
+ *   the result.  This result should be sent to the client as y(p).
+ * "t_servergetkey" accepts the exponential w(p), which should be
+ *   sent by the client, and computes the 256-bit session key.
+ *   This data should be saved before the session is closed.
+ * "t_serverresponse" computes the session key proof as SHA(w(p), K).
+ * "t_serverclose" closes the session and frees its memory.
+ *
+ * Note that authentication is not performed per se; it is up
+ * to either/both sides of the protocol to now verify securely
+ * that their session keys agree in order to establish authenticity.
+ * One possible way is through "oracle hashing"; one side sends
+ * r, the other replies with H(r,K), where H() is a hash function.
+ *
+ * t_serverresponse and t_serververify now implement a version of
+ * the session-key verification described above.
+ */
+_TYPE( struct t_server * )
+  t_serveropen P((const char *));
+_TYPE( struct t_server * )
+  t_serveropenfromfiles P((const char *, struct t_pw *, struct t_conf *));
+_TYPE( struct t_server * )
+  t_serveropenraw P((struct t_pwent *, struct t_confent *));
+_TYPE( struct t_num * ) t_servergenexp P((struct t_server *));
+_TYPE( unsigned char * ) t_servergetkey P((struct t_server *, struct t_num *));
+_TYPE( int ) t_serververify P((struct t_server *, unsigned char *));
+_TYPE( unsigned char * ) t_serverresponse P((struct t_server *));
+_TYPE( void ) t_serverclose P((struct t_server *));
+
+#endif
diff --git a/package/ead/src/tinysrp/t_sha.c b/package/ead/src/tinysrp/t_sha.c
new file mode 100644 (file)
index 0000000..cc41d64
--- /dev/null
@@ -0,0 +1,166 @@
+#include "t_defines.h"
+#include "t_sha.h"
+
+/*
+SHA-1 in C
+By Steve Reid <steve@edmweb.com>
+100% Public Domain
+
+Test Vectors (from FIPS PUB 180-1)
+"abc"
+  A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D
+"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
+  84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1
+A million repetitions of "a"
+  34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F
+*/
+
+/* #define WORDS_BIGENDIAN * This should be #define'd if true. */
+/* #define SHA1HANDSOFF * Copies data before messing with it. */
+
+#include <stdio.h>
+#include <string.h>
+
+static void SHA1Transform(uint32 state[5], const unsigned char buffer[64]);
+
+#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))
+
+/* blk0() and blk() perform the initial expand. */
+/* I got the idea of expanding during the round function from SSLeay */
+#ifndef WORDS_BIGENDIAN
+#define blk0(i) (block->l[i] = (rol(block->l[i],24)&0xFF00FF00) \
+    |(rol(block->l[i],8)&0x00FF00FF))
+#else
+#define blk0(i) block->l[i]
+#endif
+#define blk(i) (block->l[i&15] = rol(block->l[(i+13)&15]^block->l[(i+8)&15] \
+    ^block->l[(i+2)&15]^block->l[i&15],1))
+
+/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */
+#define R0(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rol(v,5);w=rol(w,30);
+#define R1(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=rol(w,30);
+#define R2(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30);
+#define R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30);
+#define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30);
+
+/* Hash a single 512-bit block. This is the core of the algorithm. */
+
+static void SHA1Transform(uint32 state[5], const unsigned char buffer[64])
+{
+uint32 a, b, c, d, e;
+typedef union {
+    unsigned char c[64];
+    uint32 l[16];
+} CHAR64LONG16;
+CHAR64LONG16* block;
+#ifdef SHA1HANDSOFF
+static unsigned char workspace[64];
+    block = (CHAR64LONG16*)workspace;
+    memcpy(block, buffer, 64);
+#else
+    block = (CHAR64LONG16*)buffer;
+#endif
+    /* Copy context->state[] to working vars */
+    a = state[0];
+    b = state[1];
+    c = state[2];
+    d = state[3];
+    e = state[4];
+    /* 4 rounds of 20 operations each. Loop unrolled. */
+    R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3);
+    R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7);
+    R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11);
+    R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15);
+    R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19);
+    R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23);
+    R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27);
+    R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31);
+    R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35);
+    R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39);
+    R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43);
+    R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47);
+    R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51);
+    R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55);
+    R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59);
+    R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63);
+    R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67);
+    R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71);
+    R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75);
+    R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79);
+    /* Add the working vars back into context.state[] */
+    state[0] += a;
+    state[1] += b;
+    state[2] += c;
+    state[3] += d;
+    state[4] += e;
+    /* Wipe variables */
+    a = b = c = d = e = 0;
+}
+
+
+/* SHA1Init - Initialize new context */
+
+void SHA1Init(SHA1_CTX* context)
+{
+    /* SHA1 initialization constants */
+    context->state[0] = 0x67452301;
+    context->state[1] = 0xEFCDAB89;
+    context->state[2] = 0x98BADCFE;
+    context->state[3] = 0x10325476;
+    context->state[4] = 0xC3D2E1F0;
+    context->count[0] = context->count[1] = 0;
+}
+
+
+/* Run your data through this. */
+
+void SHA1Update(SHA1_CTX* context, const unsigned char* data, unsigned int len)
+{
+unsigned int i, j;
+
+    j = (context->count[0] >> 3) & 63;
+    if ((context->count[0] += len << 3) < (len << 3)) context->count[1]++;
+    context->count[1] += (len >> 29);
+    if ((j + len) > 63) {
+       memcpy(&context->buffer[j], data, (i = 64-j));
+       SHA1Transform(context->state, context->buffer);
+       for ( ; i + 63 < len; i += 64) {
+           SHA1Transform(context->state, &data[i]);
+       }
+       j = 0;
+    }
+    else i = 0;
+    memcpy(&context->buffer[j], &data[i], len - i);
+}
+
+
+/* Add padding and return the message digest. */
+
+void SHA1Final(unsigned char digest[20], SHA1_CTX* context)
+{
+uint32 i, j;
+unsigned char finalcount[8];
+
+    for (i = 0; i < 8; i++) {
+       finalcount[i] = (unsigned char)((context->count[(i >= 4 ? 0 : 1)]
+        >> ((3-(i & 3)) * 8) ) & 255);  /* Endian independent */
+    }
+    SHA1Update(context, (unsigned char *)"\200", 1);
+    while ((context->count[0] & 504) != 448) {
+       SHA1Update(context, (unsigned char *)"\0", 1);
+    }
+    SHA1Update(context, finalcount, 8);  /* Should cause a SHA1Transform() */
+    for (i = 0; i < 20; i++) {
+       digest[i] = (unsigned char)
+        ((context->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255);
+    }
+    /* Wipe variables */
+    i = j = 0;
+    memset(context->buffer, 0, 64);
+    memset(context->state, 0, 20);
+    memset(context->count, 0, 8);
+    memset(&finalcount, 0, 8);
+#ifdef SHA1HANDSOFF  /* make SHA1Transform overwrite its own static vars */
+    SHA1Transform(context->state, context->buffer);
+#endif
+}
diff --git a/package/ead/src/tinysrp/t_sha.h b/package/ead/src/tinysrp/t_sha.h
new file mode 100644 (file)
index 0000000..d10115e
--- /dev/null
@@ -0,0 +1,26 @@
+#ifndef T_SHA_H
+#define T_SHA_H
+
+#if     !defined(P)
+#ifdef  __STDC__
+#define P(x)    x
+#else
+#define P(x)    ()
+#endif
+#endif
+
+#define SHA_DIGESTSIZE 20
+
+typedef unsigned int uint32;
+
+typedef struct {
+    uint32 state[5];
+    uint32 count[2];
+    unsigned char buffer[64];
+} SHA1_CTX;
+
+void SHA1Init P((SHA1_CTX* context));
+void SHA1Update P((SHA1_CTX* context, const unsigned char* data, unsigned int len));
+void SHA1Final P((unsigned char digest[20], SHA1_CTX* context));
+
+#endif /* T_SHA_H */
diff --git a/package/ead/src/tinysrp/t_truerand.c b/package/ead/src/tinysrp/t_truerand.c
new file mode 100644 (file)
index 0000000..fa0d6ce
--- /dev/null
@@ -0,0 +1,151 @@
+/*
+ *      Physically random numbers (very nearly uniform)
+ *      D. P. Mitchell
+ *      Modified by Matt Blaze 7/95
+ */
+/*
+ * The authors of this software are Don Mitchell and Matt Blaze.
+ *              Copyright (c) 1995 by AT&T.
+ * Permission to use, copy, and modify this software without fee
+ * is hereby granted, provided that this entire notice is included in
+ * all copies of any software which is or includes a copy or
+ * modification of this software and in all copies of the supporting
+ * documentation for such software.
+ *
+ * This software may be subject to United States export controls.
+ *
+ * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTY.  IN PARTICULAR, NEITHER THE AUTHORS NOR AT&T MAKE ANY
+ * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
+ * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
+ */
+
+/*
+ * WARNING: depending on the particular platform, raw_truerand()
+ * output may be biased or correlated.  In general, you can expect
+ * about 16 bits of "pseudo-entropy" out of each 32 bit word returned
+ * by truerand(), but it may not be uniformly diffused.  You should
+ * raw_therefore run the output through some post-whitening function
+ * (like MD5 or DES or whatever) before using it to generate key
+ * material.  (RSAREF's random package does this for you when you feed
+ * raw_truerand() bits to the seed input function.)
+ *
+ * The application interface, for 8, 16, and 32 bit properly "whitened"
+ * random numbers, can be found in trand8(), trand16(), and trand32().
+ * Use those instead of calling raw_truerand() directly.
+ *
+ * The basic idea here is that between clock "skew" and various
+ * hard-to-predict OS event arrivals, counting a tight loop will yield
+ * a little (maybe a third of a bit or so) of "good" randomness per
+ * interval clock tick.  This seems to work well even on unloaded
+ * machines.  If there is a human operator at the machine, you should
+ * augment truerand with other measure, like keyboard event timing.
+ * On server machines (e.g., when you need to generate a
+ * Diffie-Hellman secret) truerand alone may be good enough.
+ *
+ * Test these assumptions on your own platform before fielding a
+ * system based on this software or these techniques.
+ *
+ * This software seems to work well (at 10 or so bits per
+ * raw_truerand() call) on a Sun Sparc-20 under SunOS 4.1.3 and on a
+ * P100 under BSDI 2.0.  You're on your own elsewhere.
+ *
+ */
+
+#include "t_defines.h"
+
+#include <signal.h>
+#include <setjmp.h>
+#include <sys/time.h>
+#include <math.h>
+#include <stdio.h>
+
+#ifdef OLD_TRUERAND
+static jmp_buf env;
+#endif
+static unsigned volatile count
+#ifndef OLD_TRUERAND
+  , done = 0
+#endif
+;
+
+static unsigned ocount;
+static unsigned buffer;
+
+static void
+tick()
+{
+       struct itimerval it, oit;
+
+       it.it_interval.tv_sec = 0;
+       it.it_interval.tv_usec = 0;
+       it.it_value.tv_sec = 0;
+       it.it_value.tv_usec = 16665;
+       if (setitimer(ITIMER_REAL, &it, &oit) < 0)
+               perror("tick");
+}
+
+static void
+interrupt()
+{
+       if (count) {
+#ifdef OLD_TRUERAND
+               longjmp(env, 1);
+#else
+               ++done;
+               return;
+#endif
+       }
+
+       (void) signal(SIGALRM, interrupt);
+       tick();
+}
+
+static unsigned long
+roulette()
+{
+#ifdef OLD_TRUERAND
+       if (setjmp(env)) {
+               count ^= (count>>3) ^ (count>>6) ^ ocount;
+               count &= 0x7;
+               ocount=count;
+               buffer = (buffer<<3) ^ count;
+               return buffer;
+       }
+#else
+       done = 0;
+#endif
+       (void) signal(SIGALRM, interrupt);
+       count = 0;
+       tick();
+#ifdef OLD_TRUERAND
+       for (;;)
+#else
+       while(done == 0)
+#endif
+               count++;        /* about 1 MHz on VAX 11/780 */
+#ifndef OLD_TRUERAND
+       count ^= (count>>3) ^ (count>>6) ^ ocount;
+       count &= 0x7;
+       ocount=count;
+       buffer = (buffer<<3) ^ count;
+       return buffer;
+#endif
+}
+
+unsigned long
+raw_truerand()
+{
+       count=0;
+       (void) roulette();
+       (void) roulette();
+       (void) roulette();
+       (void) roulette();
+       (void) roulette();
+       (void) roulette();
+       (void) roulette();
+       (void) roulette();
+       (void) roulette();
+       (void) roulette();
+       return roulette();
+}
diff --git a/package/ead/src/tinysrp/tconf.c b/package/ead/src/tinysrp/tconf.c
new file mode 100644 (file)
index 0000000..ad77f4c
--- /dev/null
@@ -0,0 +1,157 @@
+/*
+ * Copyright (c) 1997-2000  The Stanford SRP Authentication Project
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL STANFORD BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF
+ * THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * In addition, the following conditions apply:
+ *
+ * 1. Any software that incorporates the SRP authentication technology
+ *    must display the following acknowlegment:
+ *    "This product uses the 'Secure Remote Password' cryptographic
+ *     authentication system developed by Tom Wu (tjw@CS.Stanford.EDU)."
+ *
+ * 2. Any software that incorporates all or part of the SRP distribution
+ *    itself must also display the following acknowledgment:
+ *    "This product includes software developed by Tom Wu and Eugene
+ *     Jhong for the SRP Distribution (http://srp.stanford.edu/srp/)."
+ *
+ * 3. Redistributions in source or binary form must retain an intact copy
+ *    of this copyright notice and list of conditions.
+ */
+
+#include <unistd.h>     /* close getlogin */
+#include <stdlib.h>     /* atexit exit */
+#include <stdio.h>
+#include <string.h>
+
+#include "t_pwd.h"
+
+#define MIN_BASIS_BITS 512
+#define BASIS_BITS 2048
+
+extern int  optind;
+extern char *optarg;
+
+extern int errno;
+
+char *progName;
+
+int  debug   = 0;
+int  verbose = 0;
+int  composite = 0;
+
+int main(argc, argv)
+     int argc;
+     char *argv[];
+{
+  char *chp;
+  char *configFile = NULL;
+  char cbuf[256];
+  char b64buf[MAXB64PARAMLEN];
+  int c, ch, i, lastidx, keylen, yesno, fsize, status, nparams;
+  FILE *efp;
+
+  struct t_preconf * tpc;
+  struct t_conf tcs;
+  struct t_conf * tc = &tcs;
+  struct t_confent * tcent;
+
+  progName = *argv;
+  if ((chp = strrchr(progName, '/')) != (char *) 0) progName = chp + 1;
+
+  while ((ch = getopt(argc, argv, "dv2c:")) != EOF)
+    switch(ch) {
+    case 'c':
+      configFile = optarg;
+      break;
+    case 'v':
+      verbose++;
+      break;
+    case 'd':
+      debug++;
+      break;
+    case '2':
+      composite++;
+      break;
+    default:
+      fprintf(stderr, "usage: %s [-dv2] [-c configfile]\n", progName);
+      exit(1);
+    }
+
+  argc -= optind;
+  argv += optind;
+
+  lastidx = 0;
+  keylen = 0;
+
+  tcent = t_newconfent(tc);
+
+  printf("\nThis program will generate a set of parameters for the EPS\n");
+  printf("password file.  The size of these parameters, measured in bits,\n");
+  printf("determines the level of security offered by SRP, and is related\n");
+  printf("to the security of similarly-sized RSA or Diffie-Hellman keys.\n");
+  printf("Choosing a predefined field is generally preferable to generating\n");
+  printf("a new field because clients can avoid costly parameter verification.\n");
+  printf("Either way, the values generated by this program are public and\n");
+  printf("can even shared between systems.\n");
+
+  printf("\nEnter the new field size, in bits.  Suggested sizes:\n\n");
+  printf(" 512 (fast, minimally secure)\n");
+  printf(" 768 (moderate security)\n");
+  printf("1024 (most popular default)\n");
+  printf("1536 (additional security, possibly slow)\n");
+  printf("2048 (maximum supported security level)\n");
+  printf("\nField size (%d to %d): ", MIN_BASIS_BITS, BASIS_BITS);
+
+  fgets(cbuf, sizeof(cbuf), stdin);
+  fsize = atoi(cbuf);
+  if(fsize < MIN_BASIS_BITS || fsize > BASIS_BITS) {
+    fprintf(stderr, "%s: field size must be between %d and %d\n",
+           progName, MIN_BASIS_BITS, BASIS_BITS);
+    exit(1);
+  }
+
+  if(fsize <= keylen)
+    fprintf(stderr, "Warning: new field size is not larger than old field size\n");
+
+  printf("\nInitializing random number generator...");
+  fflush(stdout);
+  t_initrand();
+
+  if(composite)
+    printf("done.\n\nGenerating a %d-bit composite with safe prime factors.  This may take a while.\n", fsize);
+  else
+    printf("done.\n\nGenerating a %d-bit safe prime.  This may take a while.\n", fsize);
+
+  while((tcent = (composite ? t_makeconfent_c(tc, fsize) :
+                             t_makeconfent(tc, fsize))) == NULL)
+    printf("Parameter generation failed, retrying...\n");
+  tcent->index = lastidx + 1;
+
+  printf("\nParameters successfully generated.\n");
+  printf("N = [%s]\n", t_tob64(b64buf,
+                              tcent->modulus.data, tcent->modulus.len));
+  printf("g = [%s]\n", t_tob64(b64buf,
+                              tcent->generator.data, tcent->generator.len));
+  printf("\nYou must update the pre_params array in t_getconf.c\n");
+}
diff --git a/package/ead/src/tinysrp/tinysrp.c b/package/ead/src/tinysrp/tinysrp.c
new file mode 100644 (file)
index 0000000..fc01055
--- /dev/null
@@ -0,0 +1,235 @@
+/* This bit implements a simple API for using the SRP library over sockets. */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include "t_defines.h"
+#include "t_pwd.h"
+#include "t_server.h"
+#include "t_client.h"
+#include "tinysrp.h"
+
+#ifndef MSG_WAITALL
+#ifdef linux
+#define MSG_WAITALL 0x100       /* somehow not defined on my box */
+#endif
+#endif
+
+/* This is called by the client with a connected socket, username, and
+passphrase.  pass can be NULL in which case the user is queried. */
+
+int tsrp_client_authenticate(int s, char *user, char *pass, TSRP_SESSION *tsrp)
+{
+       int i, index;
+       unsigned char username[MAXUSERLEN + 1], sbuf[MAXSALTLEN];
+       unsigned char msgbuf[MAXPARAMLEN + 1], bbuf[MAXPARAMLEN];
+       unsigned char passbuf[128], *skey;
+       struct t_client *tc;
+       struct t_preconf *tcp;          /* @@@ should go away */
+       struct t_num salt, *A, B;
+
+       /* Send the username. */
+
+       i = strlen(user);
+       if (i > MAXUSERLEN) {
+               i = MAXUSERLEN;
+       }
+       msgbuf[0] = i;
+       memcpy(msgbuf + 1, user, i);
+       if (send(s, msgbuf, i + 1, 0) < 0) {
+               return 0;
+       }
+       memcpy(username, user, i);
+       username[i] = '\0';
+
+       /* Get the prime index and salt. */
+
+       i = recv(s, msgbuf, 2, MSG_WAITALL);
+       if (i <= 0) {
+               return 0;
+       }
+       index = msgbuf[0];
+       if (index <= 0 || index > t_getprecount()) {
+               return 0;
+       }
+       tcp = t_getpreparam(index - 1);
+       salt.len = msgbuf[1];
+       if (salt.len > MAXSALTLEN) {
+               return 0;
+       }
+       salt.data = sbuf;
+       i = recv(s, sbuf, salt.len, MSG_WAITALL);
+       if (i <= 0) {
+               return 0;
+       }
+
+       /* @@@ t_clientopen() needs a variant that takes the index */
+
+       tc = t_clientopen(username, &tcp->modulus, &tcp->generator, &salt);
+       if (tc == NULL) {
+               return 0;
+       }
+
+       /* Calculate A and send it to the server. */
+
+       A = t_clientgenexp(tc);
+       msgbuf[0] = A->len - 1;         /* len is max 256 */
+       memcpy(msgbuf + 1, A->data, A->len);
+       if (send(s, msgbuf, A->len + 1, 0) < 0) {
+               return 0;
+       }
+
+       /* Ask the user for the passphrase. */
+
+       if (pass == NULL) {
+               t_getpass(passbuf, sizeof(passbuf), "Enter password:");
+               pass = passbuf;
+       }
+       t_clientpasswd(tc, pass);
+
+       /* Get B from the server. */
+
+       i = recv(s, msgbuf, 1, 0);
+       if (i <= 0) {
+               return 0;
+       }
+       B.len = msgbuf[0] + 1;
+       B.data = bbuf;
+       i = recv(s, bbuf, B.len, MSG_WAITALL);
+       if (i <= 0) {
+               return 0;
+       }
+
+       /* Compute the session key. */
+
+       skey = t_clientgetkey(tc, &B);
+       if (skey == NULL) {
+               return 0;
+       }
+
+       /* Send the response. */
+
+       if (send(s, t_clientresponse(tc), RESPONSE_LEN, 0) < 0) {
+               return 0;
+       }
+
+       /* Get the server's response. */
+
+       i = recv(s, msgbuf, RESPONSE_LEN, MSG_WAITALL);
+       if (i <= 0) {
+               return 0;
+       }
+       if (t_clientverify(tc, msgbuf) != 0) {
+               return 0;
+       }
+
+       /* All done.  Now copy the key and clean up. */
+
+       if (tsrp) {
+               memcpy(tsrp->username, username, strlen(username) + 1);
+               memcpy(tsrp->key, skey, SESSION_KEY_LEN);
+       }
+       t_clientclose(tc);
+
+       return 1;
+}
+
+/* This is called by the server with a connected socket. */
+
+int tsrp_server_authenticate(int s, TSRP_SESSION *tsrp)
+{
+       int i, j;
+       unsigned char username[MAXUSERLEN], *skey;
+       unsigned char msgbuf[MAXPARAMLEN + 1], abuf[MAXPARAMLEN];
+       struct t_server *ts;
+       struct t_num A, *B;
+
+       /* Get the username. */
+
+       i = recv(s, msgbuf, 1, 0);
+       if (i <= 0) {
+               return 0;
+       }
+       j = msgbuf[0];
+       i = recv(s, username, j, MSG_WAITALL);
+       if (i <= 0) {
+               return 0;
+       }
+       username[j] = '\0';
+
+       ts = t_serveropen(username);
+       if (ts == NULL) {
+               return 0;
+       }
+
+       /* Send the prime index and the salt. */
+
+       msgbuf[0] = ts->index;                  /* max 256 primes... */
+       i = ts->s.len;
+       msgbuf[1] = i;
+       memcpy(msgbuf + 2, ts->s.data, i);
+       if (send(s, msgbuf, i + 2, 0) < 0) {
+               return 0;
+       }
+
+       /* Calculate B while we're waiting. */
+
+       B = t_servergenexp(ts);
+
+       /* Get A from the client. */
+
+       i = recv(s, msgbuf, 1, 0);
+       if (i <= 0) {
+               return 0;
+       }
+       A.len = msgbuf[0] + 1;
+       A.data = abuf;
+       i = recv(s, abuf, A.len, MSG_WAITALL);
+       if (i <= 0) {
+               return 0;
+       }
+
+       /* Now send B. */
+
+       msgbuf[0] = B->len - 1;
+       memcpy(msgbuf + 1, B->data, B->len);
+       if (send(s, msgbuf, B->len + 1, 0) < 0) {
+               return 0;
+       }
+
+       /* Calculate the session key while we're waiting. */
+
+       skey = t_servergetkey(ts, &A);
+       if (skey == NULL) {
+               return 0;
+       }
+
+       /* Get the response from the client. */
+
+       i = recv(s, msgbuf, RESPONSE_LEN, MSG_WAITALL);
+       if (i <= 0) {
+               return 0;
+       }
+       if (t_serververify(ts, msgbuf) != 0) {
+               return 0;
+       }
+
+       /* Client authenticated.  Now authenticate ourselves to the client. */
+
+       if (send(s, t_serverresponse(ts), RESPONSE_LEN, 0) < 0) {
+               return 0;
+       }
+
+       /* Copy the key and clean up. */
+
+       if (tsrp) {
+               memcpy(tsrp->username, username, strlen(username) + 1);
+               memcpy(tsrp->key, skey, SESSION_KEY_LEN);
+       }
+       t_serverclose(ts);
+
+       return 1;
+}
diff --git a/package/ead/src/tinysrp/tinysrp.h b/package/ead/src/tinysrp/tinysrp.h
new file mode 100644 (file)
index 0000000..4420a19
--- /dev/null
@@ -0,0 +1,18 @@
+/* Simple API for the tinysrp library. */
+
+#ifndef T_PWD_H
+#define MAXUSERLEN      32
+#define SESSION_KEY_LEN 40      /* 320-bit session key */
+#endif
+
+typedef struct {
+       char username[MAXUSERLEN + 1];
+       unsigned char key[SESSION_KEY_LEN];
+} TSRP_SESSION;
+
+/* These functions are passed a connected socket, and return true for a
+successful authentication.  If tsrp is not NULL, the username and key
+fields are filled in. */
+
+extern int tsrp_server_authenticate(int s, TSRP_SESSION *tsrp);
+extern int tsrp_client_authenticate(int s, char *user, char *pass, TSRP_SESSION *tsrp);
diff --git a/package/ead/src/tinysrp/tpasswd b/package/ead/src/tinysrp/tpasswd
new file mode 100644 (file)
index 0000000..2ac7e2a
--- /dev/null
@@ -0,0 +1,2 @@
+moo:A9lHvOGAMJvw1m3vcDsQRUFovh6/QUmLDKqwhv.drKQzbE9nS7HrOZLUPx2MmS6ewwybN8RHqpWqnUJRCMFT14FMbYXR7kYNUUQNx43A7F.xrVOU7tlFq5NjoK9sfFtp6PMdbIOP5wzWmipiNFlCOu4sjlSZb.o7C1chLzTKU.0:19AI0Hc9jEkdFc:5
+new user:1FsanML2fbTOEsa072bLjyRD1LEqoRD2GwElfN0VmHeR.FAg5A.2.G5bTjIHmMmHL60kgoAHJZhRrgopalYmujlyAuQoKiHJb98SHm1oJaQ9nl/DrZCvfyw5LpVMqg.CupdiWz6OtmOz8fwC96ItExFnNDt6SmsVDIOn4HqXG6C0lLaqEvcqlN3gFDlJXyP2yldM.LJ1TkHTHmA3DjRkmWEUL3mWEgzkEHyPcRB3Jd5ncDT7jaNbJTTLRoOtgRsaqE7OXuPADoK8MGBcUquYBRrGwyU4Y/wW4gLc3QmV793zxkk.P3.dxkLSjro/Kk94D7kC6fx3K9tadLJyzd94rr:3v/KRlxT0.oYF1:1
diff --git a/package/ead/src/tinysrp/tphrase.c b/package/ead/src/tinysrp/tphrase.c
new file mode 100644 (file)
index 0000000..1aede0c
--- /dev/null
@@ -0,0 +1,348 @@
+/* Add passphrases to the tpasswd file.  Use the last entry in the config
+file by default or a particular one specified by index. */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include "config.h"
+#include "t_pwd.h"
+#include "t_read.h"
+#include "t_sha.h"
+#include "t_defines.h"
+
+char *Progname;
+char Usage[] = "usage: %s [-n configindex] [-p passfile] user\n";
+#define USAGE() fprintf(stderr, Usage, Progname)
+
+void doit(char *);
+
+int Configindex = -1;
+char *Passfile = DEFAULT_PASSWD;
+
+int main(int argc, char **argv)
+{
+       int c;
+
+       Progname = *argv;
+
+       /* Parse option arguments. */
+
+       while ((c = getopt(argc, argv, "n:p:")) != EOF) {
+               switch (c) {
+
+               case 'n':
+                       Configindex = atoi(optarg);
+                       break;
+
+               case 'p':
+                       Passfile = optarg;
+                       break;
+
+               default:
+                       USAGE();
+                       exit(1);
+               }
+       }
+       argc -= optind;
+       argv += optind;
+
+       if (argc != 1) {
+               USAGE();
+               exit(1);
+       }
+       doit(argv[0]);
+
+       return 0;
+}
+
+void doit(char *name)
+{
+       char passphrase[128], passphrase1[128];
+       FILE *f;
+       struct t_conf *tc;
+       struct t_confent *tcent;
+       struct t_pw eps_passwd;
+
+       /* Get the config entry. */
+
+       if (Configindex <= 0) {
+               Configindex = t_getprecount();
+       }
+       tcent = gettcid(Configindex);
+       if (tcent == NULL) {
+               fprintf(stderr, "Invalid configuration file entry.\n");
+               exit(1);
+       }
+
+       /* Ask for the passphrase twice. */
+
+       printf("Setting passphrase for %s\n", name);
+
+       if (t_getpass(passphrase, sizeof(passphrase), "Enter passphrase: ") < 0) {
+               exit(1);
+       }
+       if (t_getpass(passphrase1, sizeof(passphrase1), "Verify: ") < 0) {
+               exit(1);
+       }
+       if (strcmp(passphrase, passphrase1) != 0) {
+               fprintf(stderr, "mismatch\n");
+               exit(1);
+       }
+
+       /* Create the passphrase verifier. */
+
+       t_makepwent(&eps_passwd, name, passphrase, NULL, tcent);
+
+       /* Don't need these anymore. */
+
+       memset(passphrase, 0, sizeof(passphrase));
+       memset(passphrase1, 0, sizeof(passphrase1));
+
+       /* See if the passphrase file is there; create it if not. */
+
+       if ((f = fopen(Passfile, "r+")) == NULL) {
+               creat(Passfile, 0400);
+       } else {
+               fclose(f);
+       }
+
+       /* Change the passphrase. */
+
+       if (t_changepw(Passfile, &eps_passwd.pebuf) < 0) {
+               fprintf(stderr, "Error changing passphrase\n");
+               exit(1);
+       }
+}
+
+/* TODO: Implement a more general method to handle delete/change */
+
+_TYPE( int )
+t_changepw(pwname, diff)
+     const char * pwname;
+     const struct t_pwent * diff;
+{
+  char * bakfile;
+  char * bakfile2;
+  struct stat st;
+  FILE * passfp;
+  FILE * bakfp;
+
+  if(pwname == NULL)
+    pwname = DEFAULT_PASSWD;
+
+  if((passfp = fopen(pwname, "rb")) == NULL || fstat(fileno(passfp), &st) < 0)
+    return -1;
+
+  if((bakfile = malloc(strlen(pwname) + 5)) == NULL) {
+    fclose(passfp);
+    return -1;
+  }
+  else if((bakfile2 = malloc(strlen(pwname) + 5)) == NULL) {
+    fclose(passfp);
+    free(bakfile);
+    return -1;
+  }
+
+  sprintf(bakfile, "%s.bak", pwname);
+  sprintf(bakfile2, "%s.sav", pwname);
+
+  if((bakfp = fopen(bakfile2, "wb")) == NULL &&
+     (unlink(bakfile2) < 0 || (bakfp = fopen(bakfile2, "wb")) == NULL)) {
+    fclose(passfp);
+    fclose(bakfp);
+    return -1;
+  }
+
+#ifdef NO_FCHMOD
+  chmod(bakfile2, st.st_mode & 0777);
+#else
+  fchmod(fileno(bakfp), st.st_mode & 0777);
+#endif
+
+  t_pwcopy(bakfp, passfp, diff);
+
+  fclose(bakfp);
+  fclose(passfp);
+
+#ifdef USE_RENAME
+  unlink(bakfile);
+  if(rename(pwname, bakfile) < 0)
+    return -1;
+  if(rename(bakfile2, pwname) < 0)
+    return -1;
+#else
+  unlink(bakfile);
+  link(pwname, bakfile);
+  unlink(pwname);
+  link(bakfile2, pwname);
+  unlink(bakfile2);
+#endif
+  free(bakfile);
+  free(bakfile2);
+
+  return 0;
+}
+
+_TYPE( struct t_pwent * )
+t_makepwent(tpw, user, pass, salt, confent)
+     struct t_pw * tpw;
+     const char * user;
+     const char * pass;
+     const struct t_num * salt;
+     const struct t_confent * confent;
+{
+  BigInteger x, v, n, g;
+  unsigned char dig[SHA_DIGESTSIZE];
+  SHA1_CTX ctxt;
+
+  tpw->pebuf.name = tpw->userbuf;
+  tpw->pebuf.password.data = tpw->pwbuf;
+  tpw->pebuf.salt.data = tpw->saltbuf;
+
+  strncpy(tpw->pebuf.name, user, MAXUSERLEN);
+  tpw->pebuf.index = confent->index;
+
+  if(salt) {
+    tpw->pebuf.salt.len = salt->len;
+    memcpy(tpw->pebuf.salt.data, salt->data, salt->len);
+  }
+  else {
+    memset(dig, 0, SALTLEN);            /* salt is 80 bits */
+    tpw->pebuf.salt.len = SALTLEN;
+    do {
+      t_random(tpw->pebuf.salt.data, SALTLEN);
+    } while(memcmp(tpw->pebuf.salt.data, dig, SALTLEN) == 0);
+    if(tpw->pebuf.salt.data[0] == 0)
+      tpw->pebuf.salt.data[0] = 0xff;
+  }
+
+  n = BigIntegerFromBytes(confent->modulus.data, confent->modulus.len);
+  g = BigIntegerFromBytes(confent->generator.data, confent->generator.len);
+  v = BigIntegerFromInt(0);
+
+  SHA1Init(&ctxt);
+  SHA1Update(&ctxt, user, strlen(user));
+  SHA1Update(&ctxt, ":", 1);
+  SHA1Update(&ctxt, pass, strlen(pass));
+  SHA1Final(dig, &ctxt);
+
+  SHA1Init(&ctxt);
+  SHA1Update(&ctxt, tpw->pebuf.salt.data, tpw->pebuf.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);
+  tpw->pebuf.password.len = BigIntegerToBytes(v, tpw->pebuf.password.data);
+
+  BigIntegerFree(v);
+  BigIntegerFree(x);
+  BigIntegerFree(g);
+  BigIntegerFree(n);
+
+  return &tpw->pebuf;
+}
+
+int
+t_pwcopy(pwdest, pwsrc, diff)
+     FILE * pwdest;
+     FILE * pwsrc;
+     struct t_pwent * diff;
+{
+  struct t_pw * src;
+  struct t_pwent * ent;
+
+  if((src = t_openpw(pwsrc)) == NULL)
+    return -1;
+
+  while((ent = t_getpwent(src)) != NULL)
+    if(diff && strcmp(diff->name, ent->name) == 0) {
+      t_putpwent(diff, pwdest);
+      diff = NULL;
+    }
+    else
+      t_putpwent(ent, pwdest);
+
+  if(diff)
+    t_putpwent(diff, pwdest);
+
+  return 0;
+}
+
+_TYPE( struct t_pwent * )
+t_getpwent(tpw)
+     struct t_pw * tpw;
+{
+  char indexbuf[16];
+  char passbuf[MAXB64PARAMLEN];
+  char saltstr[MAXB64SALTLEN];
+
+#ifdef ENABLE_YP
+  struct t_passwd * nisent;
+  /* FIXME: should tell caller to get conf entry from NIS also */
+
+  if(tpw->state == IN_NIS) {
+    nisent = _yp_gettpent();
+    if(nisent != NULL) {
+      savepwent(tpw, &nisent->tp);
+      return &tpw->pebuf;
+    }
+    tpw->state = FILE_NIS;
+  }
+#endif
+
+  while(1) {
+    if(t_nextfield(tpw->instream, tpw->userbuf, MAXUSERLEN) > 0) {
+#ifdef ENABLE_YP
+      if(tpw->state == FILE_NIS && *tpw->userbuf == '+') {
+       t_nextline(tpw->instream);
+       if(strlen(tpw->userbuf) > 1) {  /* +name:... */
+         nisent = _yp_gettpnam(tpw->userbuf + 1);
+         if(nisent != NULL) {
+           savepwent(tpw, nisent);
+           return &tpw->pebuf;
+         }
+       }
+       else {  /* +:... */
+         tpw->state = IN_NIS;
+         _yp_settpent();
+         return t_getpwent(tpw);
+       }
+      }
+#endif
+      if(t_nextfield(tpw->instream, passbuf, MAXB64PARAMLEN) > 0 &&
+        (tpw->pebuf.password.len = t_fromb64(tpw->pwbuf, passbuf)) > 0 &&
+        t_nextfield(tpw->instream, saltstr, MAXB64SALTLEN) > 0 &&
+        (tpw->pebuf.salt.len = t_fromb64(tpw->saltbuf, saltstr)) > 0 &&
+        t_nextfield(tpw->instream, indexbuf, 16) > 0 &&
+        (tpw->pebuf.index = atoi(indexbuf)) > 0) {
+       tpw->pebuf.name = tpw->userbuf;
+       tpw->pebuf.password.data = tpw->pwbuf;
+       tpw->pebuf.salt.data = tpw->saltbuf;
+       t_nextline(tpw->instream);
+       return &tpw->pebuf;
+      }
+    }
+    if(t_nextline(tpw->instream) < 0)
+      return NULL;
+  }
+}
+
+_TYPE( void )
+t_putpwent(ent, fp)
+     const struct t_pwent * ent;
+     FILE * fp;
+{
+  char strbuf[MAXB64PARAMLEN];
+  char saltbuf[MAXB64SALTLEN];
+
+  fprintf(fp, "%s:%s:%s:%d\n", ent->name,
+         t_tob64(strbuf, ent->password.data, ent->password.len),
+         t_tob64(saltbuf, ent->salt.data, ent->salt.len), ent->index);
+}
+