summaryrefslogtreecommitdiffstats
path: root/third_party/heimdal/lib/otp
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/heimdal/lib/otp')
-rw-r--r--third_party/heimdal/lib/otp/ChangeLog128
-rw-r--r--third_party/heimdal/lib/otp/Makefile.am90
-rw-r--r--third_party/heimdal/lib/otp/NTMakefile35
-rw-r--r--third_party/heimdal/lib/otp/otp.c63
-rw-r--r--third_party/heimdal/lib/otp/otp.h101
-rw-r--r--third_party/heimdal/lib/otp/otp_challenge.c68
-rw-r--r--third_party/heimdal/lib/otp/otp_db.c233
-rw-r--r--third_party/heimdal/lib/otp/otp_locl.h70
-rw-r--r--third_party/heimdal/lib/otp/otp_md.c231
-rw-r--r--third_party/heimdal/lib/otp/otp_md.h46
-rw-r--r--third_party/heimdal/lib/otp/otp_parse.c2522
-rw-r--r--third_party/heimdal/lib/otp/otp_print.c99
-rw-r--r--third_party/heimdal/lib/otp/otp_verify.c78
-rw-r--r--third_party/heimdal/lib/otp/otptest.c142
-rw-r--r--third_party/heimdal/lib/otp/roken_rename.h73
-rw-r--r--third_party/heimdal/lib/otp/version-script.map25
16 files changed, 4004 insertions, 0 deletions
diff --git a/third_party/heimdal/lib/otp/ChangeLog b/third_party/heimdal/lib/otp/ChangeLog
new file mode 100644
index 0000000..d4fda44
--- /dev/null
+++ b/third_party/heimdal/lib/otp/ChangeLog
@@ -0,0 +1,128 @@
+2007-07-17 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * Makefile.am: split source files in dist and nodist.
+
+2007-07-10 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * Makefile.am: New library version
+
+2007-06-07 Assar Westerlund <assar@kth.se>
+
+ * otp_parse.c: NIIL should be NIL
+
+2006-05-08 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * otp_parse.c: Less "pointer targets in passing argument differ in
+ signedness" warnings.
+
+2005-07-09 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * otp.h: remove parameter names to avoid shadow warnings
+
+2005-07-07 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * otp_parse.c (parse_words): avoid const warnings by making a
+ (shorter) copy of the string instead of truncating it
+
+2005-01-09 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * otp_parse.c: cast argument to tolower to unsigned char
+
+2003-04-16 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * roken_rename.h: rename strlcat, strlcpy
+ * Makefile.am: (ES): add strlcpy.c and strlcat.c
+ * otp_db.c: use strlcpy, from openbsd
+ * otp_md.c: use strlcat/strlcpy, from openbsd
+ * otp_challenge.c: do strdup again, we desupport ultrix
+
+2002-09-10 Johan Danielsson <joda@pdc.kth.se>
+
+ * otp_md.c: if we only have old hash names, we need to include
+ functions here that do the work
+
+2002-05-20 Johan Danielsson <joda@pdc.kth.se>
+
+ * otp_db.c: fix ndbm test
+
+2002-05-17 Johan Danielsson <joda@pdc.kth.se>
+
+ * Makefile.am: add hooks for ndbm_wrap
+
+ * otp_db.c: use ndbm_wrap
+
+2001-07-12 Assar Westerlund <assar@sics.se>
+
+ * Makefile.am: add required library dependencies
+
+2001-01-30 Assar Westerlund <assar@sics.se>
+
+ * Makefile.am (libotp_la_LDFLAGS): bump version to 1:2:1
+
+2001-01-29 Assar Westerlund <assar@sics.se>
+
+ * otp_md.c: update to new md4/md5/sha API
+
+2000-12-11 Assar Westerlund <assar@sics.se>
+
+ * Makefile.am (INCLUDES): add krb4 includes here, which are
+ somewhat bogusly used when linking against libdes supplied by krb4
+
+2000-07-25 Johan Danielsson <joda@pdc.kth.se>
+
+ * Makefile.am: bump version to 1:1:1
+
+2000-07-01 Assar Westerlund <assar@sics.se>
+
+ * const-ify
+
+2000-02-07 Assar Westerlund <assar@sics.se>
+
+ * Makefile.am: update version to 1:0:1
+
+2000-01-26 Assar Westerlund <assar@sics.se>
+
+ * otp_md.c: update to pseudo-standard APIs for md4,md5,sha.
+ * otp_md.c: start using the pseudo-standard APIs for the hash
+ functions
+
+1999-10-20 Assar Westerlund <assar@sics.se>
+
+ * Makefile.am: set version to 0:1:0
+
+Fri Mar 19 14:52:48 1999 Johan Danielsson <joda@hella.pdc.kth.se>
+
+ * Makefile.am: add version-info
+
+Thu Mar 18 11:24:19 1999 Johan Danielsson <joda@hella.pdc.kth.se>
+
+ * Makefile.am: include Makefile.am.common
+
+Sat Mar 13 22:27:10 1999 Assar Westerlund <assar@sics.se>
+
+ * otp_parse.c: unsigned-ify
+
+Sun Nov 22 10:44:16 1998 Assar Westerlund <assar@sics.se>
+
+ * Makefile.in (WFLAGS): set
+
+Mon May 25 05:27:07 1998 Assar Westerlund <assar@sics.se>
+
+ * Makefile.in (clean): try to remove shared library debris
+
+Sat May 23 20:54:28 1998 Assar Westerlund <assar@sics.se>
+
+ * Makefile.am: link with DBLIB
+
+Sun Apr 19 09:59:46 1998 Assar Westerlund <assar@sics.se>
+
+ * Makefile.in: add symlink magic for linux
+
+Sat Feb 7 07:27:18 1998 Assar Westerlund <assar@sics.se>
+
+ * otp_db.c (otp_put): make sure we don't overrun `buf'
+
+Sun Nov 9 07:14:59 1997 Assar Westerlund <assar@sics.se>
+
+ * otp_locl.h: use xdbm.h
+
diff --git a/third_party/heimdal/lib/otp/Makefile.am b/third_party/heimdal/lib/otp/Makefile.am
new file mode 100644
index 0000000..018e4ef
--- /dev/null
+++ b/third_party/heimdal/lib/otp/Makefile.am
@@ -0,0 +1,90 @@
+# $Id$
+
+include $(top_srcdir)/Makefile.am.common
+
+AM_CPPFLAGS += $(ROKEN_RENAME)
+if HAVE_DBHEADER
+AM_CPPFLAGS += -I$(DBHEADER)
+endif
+
+noinst_PROGRAMS = otptest
+
+check_PROGRAMS = otptest
+
+otptest_LDADD = libotp.la
+
+include_HEADERS = otp.h
+
+lib_LTLIBRARIES = libotp.la
+libotp_la_LDFLAGS = -version-info 1:5:1
+libotp_la_LIBADD = $(LIB_hcrypto) $(LIB_roken)
+
+if HAVE_DB3
+ndbm_wrap = ndbm_wrap.c ndbm_wrap.h
+libotp_la_LIBADD += $(DB3LIB)
+else
+if HAVE_DB1
+ndbm_wrap = ndbm_wrap.c ndbm_wrap.h
+libotp_la_LIBADD += $(DB1LIB)
+else
+ndbm_wrap =
+libotp_la_LIBADD += $(NDBMLIB)
+endif
+endif
+
+dist_libotp_la_SOURCES = \
+ otp.c \
+ otp_challenge.c \
+ otp_db.c \
+ otp_md.c \
+ otp_parse.c \
+ otp_print.c \
+ otp_verify.c \
+ otp_locl.h \
+ otp_md.h \
+ roken_rename.h
+
+nodist_libotp_la_SOURCES = $(ndbm_wrap) $(ROKEN_SRCS)
+
+libotp_la_DEPENDENCIES = version-script.map
+
+if do_roken_rename
+ROKEN_SRCS = snprintf.c strcasecmp.c strncasecmp.c strlwr.c strlcpy.c strlcat.c
+endif
+
+if versionscript
+libotp_la_LDFLAGS += $(LDFLAGS_VERSION_SCRIPT)$(srcdir)/version-script.map
+endif
+
+$(libotp_la_OBJECTS): $(ndbm_wrap)
+
+ndbm_wrap.c:
+ $(LN_S) $(srcdir)/../roken/ndbm_wrap.c .
+ndbm_wrap.h:
+ (echo '#define dbm_rename(X) __otp_ ## X'; cat $(srcdir)/../roken/ndbm_wrap.h) > ndbm_wrap.h
+
+
+snprintf.c:
+ $(LN_S) $(srcdir)/../roken/snprintf.c .
+strcasecmp.c:
+ $(LN_S) $(srcdir)/../roken/strcasecmp.c .
+strncasecmp.c:
+ $(LN_S) $(srcdir)/../roken/strncasecmp.c .
+strlwr.c:
+ $(LN_S) $(srcdir)/../roken/strlwr.c .
+strlcpy.c:
+ $(LN_S) $(srcdir)/../roken/strlcpy.c .
+strlcat.c:
+ $(LN_S) $(srcdir)/../roken/strlcat.c .
+
+CLEANFILES = \
+ ndbm_wrap.c \
+ ndbm_wrap.h \
+ snprintf.c \
+ strcasecmp.c \
+ strlcat.c \
+ strlcpy.c \
+ strlwr.c \
+ strncasecmp.c
+
+EXTRA_DIST = NTMakefile version-script.map
diff --git a/third_party/heimdal/lib/otp/NTMakefile b/third_party/heimdal/lib/otp/NTMakefile
new file mode 100644
index 0000000..a531c8b
--- /dev/null
+++ b/third_party/heimdal/lib/otp/NTMakefile
@@ -0,0 +1,35 @@
+########################################################################
+#
+# Copyright (c) 2009, Secure Endpoints Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# - Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#
+# - Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT HOLDER 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.
+#
+
+RELDIR=lib\otp
+
+!include ../../windows/NTMakefile.w32
+
diff --git a/third_party/heimdal/lib/otp/otp.c b/third_party/heimdal/lib/otp/otp.c
new file mode 100644
index 0000000..906f72c
--- /dev/null
+++ b/third_party/heimdal/lib/otp/otp.c
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 1995 - 2000 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute 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 THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+RCSID("$Id$");
+#endif
+
+#include "otp_locl.h"
+#include "otp_md.h"
+
+static OtpAlgorithm algorithms[] = {
+ {OTP_ALG_MD4, "md4", 16, otp_md4_hash, otp_md4_init, otp_md4_next},
+ {OTP_ALG_MD5, "md5", 16, otp_md5_hash, otp_md5_init, otp_md5_next},
+ {OTP_ALG_SHA, "sha", 20, otp_sha_hash, otp_sha_init, otp_sha_next}
+};
+
+OtpAlgorithm *
+otp_find_alg (char *name)
+{
+ int i;
+
+ for (i = 0; i < sizeof(algorithms)/sizeof(*algorithms); ++i)
+ if (strcmp (name, algorithms[i].name) == 0)
+ return &algorithms[i];
+ return NULL;
+}
+
+char *
+otp_error (OtpContext *o)
+{
+ return o->err;
+}
diff --git a/third_party/heimdal/lib/otp/otp.h b/third_party/heimdal/lib/otp/otp.h
new file mode 100644
index 0000000..3a4e549
--- /dev/null
+++ b/third_party/heimdal/lib/otp/otp.h
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 1995 - 2000 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute 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 THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE 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.
+ */
+
+/* $Id$ */
+
+#ifndef _OTP_H
+#define _OTP_H
+
+#include <stdlib.h>
+#include <time.h>
+
+enum {OTPKEYSIZE = 8};
+
+typedef unsigned char OtpKey[OTPKEYSIZE];
+
+#define OTP_MIN_PASSPHRASE 10
+#define OTP_MAX_PASSPHRASE 63
+
+#define OTP_USER_TIMEOUT 120
+#define OTP_DB_TIMEOUT 60
+
+#define OTP_HEXPREFIX "hex:"
+#define OTP_WORDPREFIX "word:"
+
+typedef enum { OTP_ALG_MD4, OTP_ALG_MD5, OTP_ALG_SHA } OtpAlgID;
+
+#define OTP_ALG_DEFAULT "md5"
+
+typedef struct {
+ OtpAlgID id;
+ char *name;
+ int hashsize;
+ int (*hash)(const char *, size_t, unsigned char *);
+ int (*init)(OtpKey, const char *, const char *);
+ int (*next)(OtpKey);
+} OtpAlgorithm;
+
+typedef struct {
+ char *user;
+ OtpAlgorithm *alg;
+ unsigned n;
+ char seed[17];
+ OtpKey key;
+ int challengep;
+ time_t lock_time;
+ char *err;
+} OtpContext;
+
+OtpAlgorithm *otp_find_alg (char *);
+void otp_print_stddict (OtpKey, char *, size_t);
+void otp_print_hex (OtpKey, char *, size_t);
+void otp_print_stddict_extended (OtpKey, char *, size_t);
+void otp_print_hex_extended (OtpKey, char *, size_t);
+unsigned otp_checksum (OtpKey);
+int otp_parse_hex (OtpKey, const char *);
+int otp_parse_stddict (OtpKey, const char *);
+int otp_parse_altdict (OtpKey, const char *, OtpAlgorithm *);
+int otp_parse (OtpKey, const char *, OtpAlgorithm *);
+int otp_challenge (OtpContext *, char *, char *, size_t);
+int otp_verify_user (OtpContext *, const char *);
+int otp_verify_user_1 (OtpContext *, const char *);
+char *otp_error (OtpContext *);
+
+void *otp_db_open (void);
+void otp_db_close (void *);
+int otp_put (void *, OtpContext *);
+int otp_get (void *, OtpContext *);
+int otp_simple_get (void *, OtpContext *);
+int otp_delete (void *, OtpContext *);
+
+#endif /* _OTP_H */
diff --git a/third_party/heimdal/lib/otp/otp_challenge.c b/third_party/heimdal/lib/otp/otp_challenge.c
new file mode 100644
index 0000000..76b3768
--- /dev/null
+++ b/third_party/heimdal/lib/otp/otp_challenge.c
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute 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 THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+RCSID("$Id$");
+#endif
+
+#include "otp_locl.h"
+
+int
+otp_challenge (OtpContext *ctx, char *user, char *str, size_t len)
+{
+ void *dbm;
+ int ret;
+
+ ctx->challengep = 0;
+ ctx->err = NULL;
+ ctx->user = strdup(user);
+ if (ctx->user == NULL) {
+ ctx->err = "Out of memory";
+ return -1;
+ }
+ dbm = otp_db_open ();
+ if (dbm == NULL) {
+ ctx->err = "Cannot open database";
+ return -1;
+ }
+ ret = otp_get (dbm, ctx);
+ otp_db_close (dbm);
+ if (ret)
+ return ret;
+ snprintf (str, len,
+ "[ otp-%s %u %s ]",
+ ctx->alg->name, ctx->n-1, ctx->seed);
+ ctx->challengep = 1;
+ return 0;
+}
diff --git a/third_party/heimdal/lib/otp/otp_db.c b/third_party/heimdal/lib/otp/otp_db.c
new file mode 100644
index 0000000..76daa87
--- /dev/null
+++ b/third_party/heimdal/lib/otp/otp_db.c
@@ -0,0 +1,233 @@
+/*
+ * Copyright (c) 1995, 1996, 1997, 1998 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute 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 THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+RCSID("$Id$");
+#endif
+
+#include "otp_locl.h"
+
+#if !defined(HAVE_NDBM) && !defined(HAVE_DB_NDBM)
+#include "ndbm_wrap.h"
+#endif
+
+#define RETRIES 5
+
+void *
+otp_db_open (void)
+{
+ int lock;
+ int i;
+ void *ret;
+
+ for(i = 0; i < RETRIES; ++i) {
+ struct stat statbuf;
+
+ lock = open (OTP_DB_LOCK, O_WRONLY | O_CREAT | O_EXCL, 0666);
+ if (lock >= 0) {
+ close(lock);
+ break;
+ }
+ if (stat (OTP_DB_LOCK, &statbuf) == 0) {
+ if (time(NULL) - statbuf.st_mtime > OTP_DB_TIMEOUT)
+ unlink (OTP_DB_LOCK);
+ else
+ sleep (1);
+ }
+ }
+ if (i == RETRIES)
+ return NULL;
+ ret = dbm_open (OTP_DB, O_RDWR | O_CREAT, 0600);
+ if (ret == NULL)
+ unlink (OTP_DB_LOCK);
+ return ret;
+}
+
+void
+otp_db_close (void *dbm)
+{
+ dbm_close ((DBM *)dbm);
+ unlink (OTP_DB_LOCK);
+}
+
+/*
+ * Remove this entry from the database.
+ * return 0 if ok.
+ */
+
+int
+otp_delete (void *v, OtpContext *ctx)
+{
+ DBM *dbm = (DBM *)v;
+ datum key;
+
+ key.dsize = strlen(ctx->user);
+ key.dptr = ctx->user;
+
+ return dbm_delete(dbm, key);
+}
+
+/*
+ * Read this entry from the database and lock it if lockp.
+ */
+
+static int
+otp_get_internal (void *v, OtpContext *ctx, int lockp)
+{
+ DBM *dbm = (DBM *)v;
+ datum dat, key;
+ char *p;
+ time_t now, then;
+
+ key.dsize = strlen(ctx->user);
+ key.dptr = ctx->user;
+
+ dat = dbm_fetch (dbm, key);
+ if (dat.dptr == NULL) {
+ ctx->err = "Entry not found";
+ return -1;
+ }
+ p = dat.dptr;
+
+ memcpy (&then, p, sizeof(then));
+ ctx->lock_time = then;
+ if (lockp) {
+ time(&now);
+ if (then && now - then < OTP_USER_TIMEOUT) {
+ ctx->err = "Entry locked";
+ return -1;
+ }
+ memcpy (p, &now, sizeof(now));
+ }
+ p += sizeof(now);
+ ctx->alg = otp_find_alg (p);
+ if (ctx->alg == NULL) {
+ ctx->err = "Bad algorithm";
+ return -1;
+ }
+ p += strlen(p) + 1;
+ {
+ unsigned char *up = (unsigned char *)p;
+ ctx->n = (up[0] << 24) | (up[1] << 16) | (up[2] << 8) | up[3];
+ }
+ p += 4;
+ memcpy (ctx->key, p, OTPKEYSIZE);
+ p += OTPKEYSIZE;
+ strlcpy (ctx->seed, p, sizeof(ctx->seed));
+ if (lockp)
+ return dbm_store (dbm, key, dat, DBM_REPLACE);
+ else
+ return 0;
+}
+
+/*
+ * Get and lock.
+ */
+
+int
+otp_get (void *v, OtpContext *ctx)
+{
+ return otp_get_internal (v, ctx, 1);
+}
+
+/*
+ * Get and don't lock.
+ */
+
+int
+otp_simple_get (void *v, OtpContext *ctx)
+{
+ return otp_get_internal (v, ctx, 0);
+}
+
+/*
+ * Write this entry to the database.
+ */
+
+int
+otp_put (void *v, OtpContext *ctx)
+{
+ DBM *dbm = (DBM *)v;
+ datum dat, key;
+ char buf[1024], *p;
+ time_t zero = 0;
+ size_t len, rem;
+
+ key.dsize = strlen(ctx->user);
+ key.dptr = ctx->user;
+
+ p = buf;
+ rem = sizeof(buf);
+
+ if (rem < sizeof(zero))
+ return -1;
+ memcpy (p, &zero, sizeof(zero));
+ p += sizeof(zero);
+ rem -= sizeof(zero);
+ len = strlen(ctx->alg->name) + 1;
+
+ if (rem < len)
+ return -1;
+ strlcpy (p, ctx->alg->name, rem);
+ p += len;
+ rem -= len;
+
+ if (rem < 4)
+ return -1;
+ {
+ unsigned char *up = (unsigned char *)p;
+ *up++ = (ctx->n >> 24) & 0xFF;
+ *up++ = (ctx->n >> 16) & 0xFF;
+ *up++ = (ctx->n >> 8) & 0xFF;
+ *up++ = (ctx->n >> 0) & 0xFF;
+ }
+ p += 4;
+ rem -= 4;
+
+ if (rem < OTPKEYSIZE)
+ return -1;
+ memcpy (p, ctx->key, OTPKEYSIZE);
+ p += OTPKEYSIZE;
+ rem -= OTPKEYSIZE;
+
+ len = strlen(ctx->seed) + 1;
+ if (rem < len)
+ return -1;
+ strlcpy (p, ctx->seed, rem);
+ p += len;
+ rem -= len;
+ dat.dptr = buf;
+ dat.dsize = p - buf;
+ return dbm_store (dbm, key, dat, DBM_REPLACE);
+}
diff --git a/third_party/heimdal/lib/otp/otp_locl.h b/third_party/heimdal/lib/otp/otp_locl.h
new file mode 100644
index 0000000..29b455e
--- /dev/null
+++ b/third_party/heimdal/lib/otp/otp_locl.h
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute 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 THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE 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.
+ */
+
+/* $Id$ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <string.h>
+#include <time.h>
+#include <errno.h>
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#ifdef HAVE_PWD_H
+#include <pwd.h>
+#endif
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#ifdef HAVE_IO_H
+#include <io.h>
+#endif
+
+#include <roken.h>
+
+#include <otp.h>
+
+#include <xdbm.h>
+
+#define OTPKEYS "/.otpkeys"
+
+#define OTP_DB SYSCONFDIR "/otp"
+#define OTP_DB_LOCK SYSCONFDIR "/otp-lock"
diff --git a/third_party/heimdal/lib/otp/otp_md.c b/third_party/heimdal/lib/otp/otp_md.c
new file mode 100644
index 0000000..9338a20
--- /dev/null
+++ b/third_party/heimdal/lib/otp/otp_md.c
@@ -0,0 +1,231 @@
+/*
+ * Copyright (c) 1995 - 2003 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute 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 THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE 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 HC_DEPRECATED_CRYPTO
+
+#include "config.h"
+
+#include "otp_locl.h"
+
+#include "otp_md.h"
+#include "crypto-headers.h"
+
+/*
+ * Compress len bytes from md into key
+ */
+
+static void
+compressmd (OtpKey key, unsigned char *md, size_t len)
+{
+ u_char *p = key;
+
+ memset (p, 0, OTPKEYSIZE);
+ while(len) {
+ *p++ ^= *md++;
+ *p++ ^= *md++;
+ *p++ ^= *md++;
+ *p++ ^= *md++;
+ len -= 4;
+ if (p == key + OTPKEYSIZE)
+ p = key;
+ }
+}
+
+/*
+ * For histerical reasons, in the OTP definition it's said that
+ * the result from SHA must be stored in little-endian order. See
+ * draft-ietf-otp-01.txt.
+ */
+
+static void
+little_endian(unsigned char *res, size_t len)
+{
+ unsigned char t;
+ size_t i;
+
+ for (i = 0; i < len; i += 4) {
+ t = res[i + 0]; res[i + 0] = res[i + 3]; res[i + 3] = t;
+ t = res[i + 1]; res[i + 1] = res[i + 2]; res[i + 2] = t;
+ }
+}
+
+static int
+otp_md_init (OtpKey key,
+ const char *pwd,
+ const char *seed,
+ const EVP_MD *md,
+ int le,
+ unsigned char *res,
+ size_t ressz)
+{
+ EVP_MD_CTX *ctx;
+ char *p;
+ int len;
+
+ len = strlen(pwd) + strlen(seed);
+ p = malloc (len + 1);
+ if (p == NULL)
+ return -1;
+ strlcpy (p, seed, len + 1);
+ strlwr (p);
+ strlcat (p, pwd, len + 1);
+
+ ctx = EVP_MD_CTX_create();
+
+ EVP_DigestInit_ex(ctx, md, NULL);
+ EVP_DigestUpdate(ctx, p, len);
+ EVP_DigestFinal_ex(ctx, res, NULL);
+
+ EVP_MD_CTX_destroy(ctx);
+
+ if (le)
+ little_endian(res, ressz);
+
+ free (p);
+ compressmd (key, res, ressz);
+ return 0;
+}
+
+static int
+otp_md_next (OtpKey key,
+ const EVP_MD *md,
+ int le,
+ unsigned char *res,
+ size_t ressz)
+{
+ EVP_MD_CTX *ctx;
+
+ ctx = EVP_MD_CTX_create();
+
+ EVP_DigestInit_ex(ctx, md, NULL);
+ EVP_DigestUpdate(ctx, key, OTPKEYSIZE);
+ EVP_DigestFinal_ex(ctx, res, NULL);
+
+ EVP_MD_CTX_destroy(ctx);
+
+ if (le)
+ little_endian(res, ressz);
+
+ compressmd (key, res, ressz);
+ return 0;
+}
+
+static int
+otp_md_hash (const char *data,
+ size_t len,
+ const EVP_MD *md,
+ int le,
+ unsigned char *res,
+ size_t ressz)
+{
+ EVP_MD_CTX *ctx;
+ ctx = EVP_MD_CTX_create();
+
+ EVP_DigestInit_ex(ctx, md, NULL);
+ EVP_DigestUpdate(ctx, data, len);
+ EVP_DigestFinal_ex(ctx, res, NULL);
+
+ EVP_MD_CTX_destroy(ctx);
+
+ if (le)
+ little_endian(res, ressz);
+
+ return 0;
+}
+
+int
+otp_md4_init (OtpKey key, const char *pwd, const char *seed)
+{
+ unsigned char res[16];
+ return otp_md_init (key, pwd, seed, EVP_md4(), 0, res, sizeof(res));
+}
+
+int
+otp_md4_hash (const char *data,
+ size_t len,
+ unsigned char *res)
+{
+ return otp_md_hash (data, len, EVP_md4(), 0, res, 16);
+}
+
+int
+otp_md4_next (OtpKey key)
+{
+ unsigned char res[16];
+ return otp_md_next (key, EVP_md4(), 0, res, sizeof(res));
+}
+
+
+int
+otp_md5_init (OtpKey key, const char *pwd, const char *seed)
+{
+ unsigned char res[16];
+ return otp_md_init (key, pwd, seed, EVP_md5(), 0, res, sizeof(res));
+}
+
+int
+otp_md5_hash (const char *data,
+ size_t len,
+ unsigned char *res)
+{
+ return otp_md_hash (data, len, EVP_md5(), 0, res, 16);
+}
+
+int
+otp_md5_next (OtpKey key)
+{
+ unsigned char res[16];
+ return otp_md_next (key, EVP_md5(), 0, res, sizeof(res));
+}
+
+int
+otp_sha_init (OtpKey key, const char *pwd, const char *seed)
+{
+ unsigned char res[20];
+ return otp_md_init (key, pwd, seed, EVP_sha1(), 1, res, sizeof(res));
+}
+
+int
+otp_sha_hash (const char *data,
+ size_t len,
+ unsigned char *res)
+{
+ return otp_md_hash (data, len, EVP_sha1(), 1, res, 20);
+}
+
+int
+otp_sha_next (OtpKey key)
+{
+ unsigned char res[20];
+ return otp_md_next (key, EVP_sha1(), 1, res, sizeof(res));
+}
diff --git a/third_party/heimdal/lib/otp/otp_md.h b/third_party/heimdal/lib/otp/otp_md.h
new file mode 100644
index 0000000..645ac1a
--- /dev/null
+++ b/third_party/heimdal/lib/otp/otp_md.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 1995 - 2000 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute 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 THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE 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.
+ */
+
+/* $Id$ */
+
+int otp_md4_init (OtpKey key, const char *pwd, const char *seed);
+int otp_md4_hash (const char *, size_t, unsigned char *res);
+int otp_md4_next (OtpKey key);
+
+int otp_md5_init (OtpKey key, const char *pwd, const char *seed);
+int otp_md5_hash (const char *, size_t, unsigned char *res);
+int otp_md5_next (OtpKey key);
+
+int otp_sha_init (OtpKey key, const char *pwd, const char *seed);
+int otp_sha_hash (const char *, size_t, unsigned char *res);
+int otp_sha_next (OtpKey key);
diff --git a/third_party/heimdal/lib/otp/otp_parse.c b/third_party/heimdal/lib/otp/otp_parse.c
new file mode 100644
index 0000000..385f043
--- /dev/null
+++ b/third_party/heimdal/lib/otp/otp_parse.c
@@ -0,0 +1,2522 @@
+/*
+ * Copyright (c) 1995-2000, 2005-2007 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute 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 THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+RCSID("$Id$");
+#endif
+
+#include "otp_locl.h"
+
+struct e {
+ const char *s;
+ unsigned n;
+};
+
+extern const struct e inv_std_dict[2048];
+
+static int
+cmp(const void *a, const void *b)
+{
+ const struct e *e1, *e2;
+
+ e1 = (const struct e *)a;
+ e2 = (const struct e *)b;
+ return strcasecmp (e1->s, e2->s);
+}
+
+static int
+get_stdword (const char *s, void *v)
+{
+ struct e e, *r;
+
+ e.s = s;
+ e.n = -1;
+ r = (struct e *) bsearch (&e, inv_std_dict,
+ sizeof(inv_std_dict)/sizeof(*inv_std_dict),
+ sizeof(*inv_std_dict), cmp);
+ if (r)
+ return r->n;
+ else
+ return -1;
+}
+
+static void
+compress (OtpKey key, unsigned wn[])
+{
+ key[0] = wn[0] >> 3;
+ key[1] = ((wn[0] & 0x07) << 5) | (wn[1] >> 6);
+ key[2] = ((wn[1] & 0x3F) << 2) | (wn[2] >> 9);
+ key[3] = ((wn[2] >> 1) & 0xFF);
+ key[4] = ((wn[2] & 0x01) << 7) | (wn[3] >> 4);
+ key[5] = ((wn[3] & 0x0F) << 4) | (wn[4] >> 7);
+ key[6] = ((wn[4] & 0x7F) << 1) | (wn[5] >> 10);
+ key[7] = ((wn[5] >> 2) & 0xFF);
+}
+
+static int
+get_altword (const char *s, void *a)
+{
+ OtpAlgorithm *alg = (OtpAlgorithm *)a;
+ int ret;
+ unsigned char *res = malloc(alg->hashsize);
+
+ if (res == NULL)
+ return -1;
+ alg->hash (s, strlen(s), res);
+ ret = (unsigned)(res[alg->hashsize - 1]) |
+ ((res[alg->hashsize - 2] & 0x03) << 8);
+ free (res);
+ return ret;
+}
+
+static int
+parse_words(unsigned wn[],
+ const char *str,
+ int (*convert)(const char *, void *),
+ void *arg)
+{
+ const unsigned char *w, *wend;
+ char *wcopy;
+ int i;
+ int tmp;
+
+ w = (const unsigned char *)str;
+ for (i = 0; i < 6; ++i) {
+ while (isspace(*w))
+ ++w;
+ wend = w;
+ while (isalpha (*wend))
+ ++wend;
+
+ tmp = wend - w;
+ wcopy = malloc(tmp + 1);
+ if (wcopy == NULL)
+ return -1;
+ memcpy(wcopy, w, tmp);
+ wcopy[tmp] = '\0';
+
+ tmp = (*convert)(wcopy, arg);
+ free(wcopy);
+ w = wend;
+ if (tmp < 0)
+ return -1;
+ wn[i] = tmp;
+ }
+ return 0;
+}
+
+static int
+otp_parse_internal (OtpKey key, const char *str,
+ OtpAlgorithm *alg,
+ int (*convert)(const char *, void *))
+{
+ unsigned wn[6];
+
+ if (parse_words (wn, str, convert, alg))
+ return -1;
+ compress (key, wn);
+ if (otp_checksum (key) != (wn[5] & 0x03))
+ return -1;
+ return 0;
+}
+
+int
+otp_parse_stddict (OtpKey key, const char *str)
+{
+ return otp_parse_internal (key, str, NULL, get_stdword);
+}
+
+int
+otp_parse_altdict (OtpKey key, const char *str, OtpAlgorithm *alg)
+{
+ return otp_parse_internal (key, str, alg, get_altword);
+}
+
+int
+otp_parse_hex (OtpKey key, const char *s)
+{
+ char buf[17], *b;
+ int is[8];
+ int i;
+
+ b = buf;
+ while (*s) {
+ if (strchr ("0123456789ABCDEFabcdef", *s)) {
+ if (b - buf >= 16)
+ return -1;
+ else
+ *b++ = tolower((unsigned char)*s);
+ }
+ s++;
+ }
+ *b = '\0';
+ if (sscanf (buf, "%2x%2x%2x%2x%2x%2x%2x%2x",
+ &is[0], &is[1], &is[2], &is[3], &is[4],
+ &is[5], &is[6], &is[7]) != 8)
+ return -1;
+ for (i = 0; i < OTPKEYSIZE; ++i)
+ key[i] = is[i];
+ return 0;
+}
+
+int
+otp_parse (OtpKey key, const char *s, OtpAlgorithm *alg)
+{
+ int ret;
+ int dohex = 1;
+
+ if (strncmp (s, OTP_HEXPREFIX, strlen(OTP_HEXPREFIX)) == 0)
+ return otp_parse_hex (key, s + strlen(OTP_HEXPREFIX));
+ if (strncmp (s, OTP_WORDPREFIX, strlen(OTP_WORDPREFIX)) == 0) {
+ s += strlen(OTP_WORDPREFIX);
+ dohex = 0;
+ }
+
+ ret = otp_parse_stddict (key, s);
+ if (ret)
+ ret = otp_parse_altdict (key, s, alg);
+ if (ret && dohex)
+ ret = otp_parse_hex (key, s);
+ return ret;
+}
+
+const char *const std_dict[2048] =
+{ "A", "ABE", "ACE", "ACT", "AD", "ADA", "ADD",
+"AGO", "AID", "AIM", "AIR", "ALL", "ALP", "AM", "AMY",
+"AN", "ANA", "AND", "ANN", "ANT", "ANY", "APE", "APS",
+"APT", "ARC", "ARE", "ARK", "ARM", "ART", "AS", "ASH",
+"ASK", "AT", "ATE", "AUG", "AUK", "AVE", "AWE", "AWK",
+"AWL", "AWN", "AX", "AYE", "BAD", "BAG", "BAH", "BAM",
+"BAN", "BAR", "BAT", "BAY", "BE", "BED", "BEE", "BEG",
+"BEN", "BET", "BEY", "BIB", "BID", "BIG", "BIN", "BIT",
+"BOB", "BOG", "BON", "BOO", "BOP", "BOW", "BOY", "BUB",
+"BUD", "BUG", "BUM", "BUN", "BUS", "BUT", "BUY", "BY",
+"BYE", "CAB", "CAL", "CAM", "CAN", "CAP", "CAR", "CAT",
+"CAW", "COD", "COG", "COL", "CON", "COO", "COP", "COT",
+"COW", "COY", "CRY", "CUB", "CUE", "CUP", "CUR", "CUT",
+"DAB", "DAD", "DAM", "DAN", "DAR", "DAY", "DEE", "DEL",
+"DEN", "DES", "DEW", "DID", "DIE", "DIG", "DIN", "DIP",
+"DO", "DOE", "DOG", "DON", "DOT", "DOW", "DRY", "DUB",
+"DUD", "DUE", "DUG", "DUN", "EAR", "EAT", "ED", "EEL",
+"EGG", "EGO", "ELI", "ELK", "ELM", "ELY", "EM", "END",
+"EST", "ETC", "EVA", "EVE", "EWE", "EYE", "FAD", "FAN",
+"FAR", "FAT", "FAY", "FED", "FEE", "FEW", "FIB", "FIG",
+"FIN", "FIR", "FIT", "FLO", "FLY", "FOE", "FOG", "FOR",
+"FRY", "FUM", "FUN", "FUR", "GAB", "GAD", "GAG", "GAL",
+"GAM", "GAP", "GAS", "GAY", "GEE", "GEL", "GEM", "GET",
+"GIG", "GIL", "GIN", "GO", "GOT", "GUM", "GUN", "GUS",
+"GUT", "GUY", "GYM", "GYP", "HA", "HAD", "HAL", "HAM",
+"HAN", "HAP", "HAS", "HAT", "HAW", "HAY", "HE", "HEM",
+"HEN", "HER", "HEW", "HEY", "HI", "HID", "HIM", "HIP",
+"HIS", "HIT", "HO", "HOB", "HOC", "HOE", "HOG", "HOP",
+"HOT", "HOW", "HUB", "HUE", "HUG", "HUH", "HUM", "HUT",
+"I", "ICY", "IDA", "IF", "IKE", "ILL", "INK", "INN",
+"IO", "ION", "IQ", "IRA", "IRE", "IRK", "IS", "IT",
+"ITS", "IVY", "JAB", "JAG", "JAM", "JAN", "JAR", "JAW",
+"JAY", "JET", "JIG", "JIM", "JO", "JOB", "JOE", "JOG",
+"JOT", "JOY", "JUG", "JUT", "KAY", "KEG", "KEN", "KEY",
+"KID", "KIM", "KIN", "KIT", "LA", "LAB", "LAC", "LAD",
+"LAG", "LAM", "LAP", "LAW", "LAY", "LEA", "LED", "LEE",
+"LEG", "LEN", "LEO", "LET", "LEW", "LID", "LIE", "LIN",
+"LIP", "LIT", "LO", "LOB", "LOG", "LOP", "LOS", "LOT",
+"LOU", "LOW", "LOY", "LUG", "LYE", "MA", "MAC", "MAD",
+"MAE", "MAN", "MAO", "MAP", "MAT", "MAW", "MAY", "ME",
+"MEG", "MEL", "MEN", "MET", "MEW", "MID", "MIN", "MIT",
+"MOB", "MOD", "MOE", "MOO", "MOP", "MOS", "MOT", "MOW",
+"MUD", "MUG", "MUM", "MY", "NAB", "NAG", "NAN", "NAP",
+"NAT", "NAY", "NE", "NED", "NEE", "NET", "NEW", "NIB",
+"NIL", "NIP", "NIT", "NO", "NOB", "NOD", "NON", "NOR",
+"NOT", "NOV", "NOW", "NU", "NUN", "NUT", "O", "OAF",
+"OAK", "OAR", "OAT", "ODD", "ODE", "OF", "OFF", "OFT",
+"OH", "OIL", "OK", "OLD", "ON", "ONE", "OR", "ORB",
+"ORE", "ORR", "OS", "OTT", "OUR", "OUT", "OVA", "OW",
+"OWE", "OWL", "OWN", "OX", "PA", "PAD", "PAL", "PAM",
+"PAN", "PAP", "PAR", "PAT", "PAW", "PAY", "PEA", "PEG",
+"PEN", "PEP", "PER", "PET", "PEW", "PHI", "PI", "PIE",
+"PIN", "PIT", "PLY", "PO", "POD", "POE", "POP", "POT",
+"POW", "PRO", "PRY", "PUB", "PUG", "PUN", "PUP", "PUT",
+"QUO", "RAG", "RAM", "RAN", "RAP", "RAT", "RAW", "RAY",
+"REB", "RED", "REP", "RET", "RIB", "RID", "RIG", "RIM",
+"RIO", "RIP", "ROB", "ROD", "ROE", "RON", "ROT", "ROW",
+"ROY", "RUB", "RUE", "RUG", "RUM", "RUN", "RYE", "SAC",
+"SAD", "SAG", "SAL", "SAM", "SAN", "SAP", "SAT", "SAW",
+"SAY", "SEA", "SEC", "SEE", "SEN", "SET", "SEW", "SHE",
+"SHY", "SIN", "SIP", "SIR", "SIS", "SIT", "SKI", "SKY",
+"SLY", "SO", "SOB", "SOD", "SON", "SOP", "SOW", "SOY",
+"SPA", "SPY", "SUB", "SUD", "SUE", "SUM", "SUN", "SUP",
+"TAB", "TAD", "TAG", "TAN", "TAP", "TAR", "TEA", "TED",
+"TEE", "TEN", "THE", "THY", "TIC", "TIE", "TIM", "TIN",
+"TIP", "TO", "TOE", "TOG", "TOM", "TON", "TOO", "TOP",
+"TOW", "TOY", "TRY", "TUB", "TUG", "TUM", "TUN", "TWO",
+"UN", "UP", "US", "USE", "VAN", "VAT", "VET", "VIE",
+"WAD", "WAG", "WAR", "WAS", "WAY", "WE", "WEB", "WED",
+"WEE", "WET", "WHO", "WHY", "WIN", "WIT", "WOK", "WON",
+"WOO", "WOW", "WRY", "WU", "YAM", "YAP", "YAW", "YE",
+"YEA", "YES", "YET", "YOU", "ABED", "ABEL", "ABET", "ABLE",
+"ABUT", "ACHE", "ACID", "ACME", "ACRE", "ACTA", "ACTS", "ADAM",
+"ADDS", "ADEN", "AFAR", "AFRO", "AGEE", "AHEM", "AHOY", "AIDA",
+"AIDE", "AIDS", "AIRY", "AJAR", "AKIN", "ALAN", "ALEC", "ALGA",
+"ALIA", "ALLY", "ALMA", "ALOE", "ALSO", "ALTO", "ALUM", "ALVA",
+"AMEN", "AMES", "AMID", "AMMO", "AMOK", "AMOS", "AMRA", "ANDY",
+"ANEW", "ANNA", "ANNE", "ANTE", "ANTI", "AQUA", "ARAB", "ARCH",
+"AREA", "ARGO", "ARID", "ARMY", "ARTS", "ARTY", "ASIA", "ASKS",
+"ATOM", "AUNT", "AURA", "AUTO", "AVER", "AVID", "AVIS", "AVON",
+"AVOW", "AWAY", "AWRY", "BABE", "BABY", "BACH", "BACK", "BADE",
+"BAIL", "BAIT", "BAKE", "BALD", "BALE", "BALI", "BALK", "BALL",
+"BALM", "BAND", "BANE", "BANG", "BANK", "BARB", "BARD", "BARE",
+"BARK", "BARN", "BARR", "BASE", "BASH", "BASK", "BASS", "BATE",
+"BATH", "BAWD", "BAWL", "BEAD", "BEAK", "BEAM", "BEAN", "BEAR",
+"BEAT", "BEAU", "BECK", "BEEF", "BEEN", "BEER", "BEET", "BELA",
+"BELL", "BELT", "BEND", "BENT", "BERG", "BERN", "BERT", "BESS",
+"BEST", "BETA", "BETH", "BHOY", "BIAS", "BIDE", "BIEN", "BILE",
+"BILK", "BILL", "BIND", "BING", "BIRD", "BITE", "BITS", "BLAB",
+"BLAT", "BLED", "BLEW", "BLOB", "BLOC", "BLOT", "BLOW", "BLUE",
+"BLUM", "BLUR", "BOAR", "BOAT", "BOCA", "BOCK", "BODE", "BODY",
+"BOGY", "BOHR", "BOIL", "BOLD", "BOLO", "BOLT", "BOMB", "BONA",
+"BOND", "BONE", "BONG", "BONN", "BONY", "BOOK", "BOOM", "BOON",
+"BOOT", "BORE", "BORG", "BORN", "BOSE", "BOSS", "BOTH", "BOUT",
+"BOWL", "BOYD", "BRAD", "BRAE", "BRAG", "BRAN", "BRAY", "BRED",
+"BREW", "BRIG", "BRIM", "BROW", "BUCK", "BUDD", "BUFF", "BULB",
+"BULK", "BULL", "BUNK", "BUNT", "BUOY", "BURG", "BURL", "BURN",
+"BURR", "BURT", "BURY", "BUSH", "BUSS", "BUST", "BUSY", "BYTE",
+"CADY", "CAFE", "CAGE", "CAIN", "CAKE", "CALF", "CALL", "CALM",
+"CAME", "CANE", "CANT", "CARD", "CARE", "CARL", "CARR", "CART",
+"CASE", "CASH", "CASK", "CAST", "CAVE", "CEIL", "CELL", "CENT",
+"CERN", "CHAD", "CHAR", "CHAT", "CHAW", "CHEF", "CHEN", "CHEW",
+"CHIC", "CHIN", "CHOU", "CHOW", "CHUB", "CHUG", "CHUM", "CITE",
+"CITY", "CLAD", "CLAM", "CLAN", "CLAW", "CLAY", "CLOD", "CLOG",
+"CLOT", "CLUB", "CLUE", "COAL", "COAT", "COCA", "COCK", "COCO",
+"CODA", "CODE", "CODY", "COED", "COIL", "COIN", "COKE", "COLA",
+"COLD", "COLT", "COMA", "COMB", "COME", "COOK", "COOL", "COON",
+"COOT", "CORD", "CORE", "CORK", "CORN", "COST", "COVE", "COWL",
+"CRAB", "CRAG", "CRAM", "CRAY", "CREW", "CRIB", "CROW", "CRUD",
+"CUBA", "CUBE", "CUFF", "CULL", "CULT", "CUNY", "CURB", "CURD",
+"CURE", "CURL", "CURT", "CUTS", "DADE", "DALE", "DAME", "DANA",
+"DANE", "DANG", "DANK", "DARE", "DARK", "DARN", "DART", "DASH",
+"DATA", "DATE", "DAVE", "DAVY", "DAWN", "DAYS", "DEAD", "DEAF",
+"DEAL", "DEAN", "DEAR", "DEBT", "DECK", "DEED", "DEEM", "DEER",
+"DEFT", "DEFY", "DELL", "DENT", "DENY", "DESK", "DIAL", "DICE",
+"DIED", "DIET", "DIME", "DINE", "DING", "DINT", "DIRE", "DIRT",
+"DISC", "DISH", "DISK", "DIVE", "DOCK", "DOES", "DOLE", "DOLL",
+"DOLT", "DOME", "DONE", "DOOM", "DOOR", "DORA", "DOSE", "DOTE",
+"DOUG", "DOUR", "DOVE", "DOWN", "DRAB", "DRAG", "DRAM", "DRAW",
+"DREW", "DRUB", "DRUG", "DRUM", "DUAL", "DUCK", "DUCT", "DUEL",
+"DUET", "DUKE", "DULL", "DUMB", "DUNE", "DUNK", "DUSK", "DUST",
+"DUTY", "EACH", "EARL", "EARN", "EASE", "EAST", "EASY", "EBEN",
+"ECHO", "EDDY", "EDEN", "EDGE", "EDGY", "EDIT", "EDNA", "EGAN",
+"ELAN", "ELBA", "ELLA", "ELSE", "EMIL", "EMIT", "EMMA", "ENDS",
+"ERIC", "EROS", "EVEN", "EVER", "EVIL", "EYED", "FACE", "FACT",
+"FADE", "FAIL", "FAIN", "FAIR", "FAKE", "FALL", "FAME", "FANG",
+"FARM", "FAST", "FATE", "FAWN", "FEAR", "FEAT", "FEED", "FEEL",
+"FEET", "FELL", "FELT", "FEND", "FERN", "FEST", "FEUD", "FIEF",
+"FIGS", "FILE", "FILL", "FILM", "FIND", "FINE", "FINK", "FIRE",
+"FIRM", "FISH", "FISK", "FIST", "FITS", "FIVE", "FLAG", "FLAK",
+"FLAM", "FLAT", "FLAW", "FLEA", "FLED", "FLEW", "FLIT", "FLOC",
+"FLOG", "FLOW", "FLUB", "FLUE", "FOAL", "FOAM", "FOGY", "FOIL",
+"FOLD", "FOLK", "FOND", "FONT", "FOOD", "FOOL", "FOOT", "FORD",
+"FORE", "FORK", "FORM", "FORT", "FOSS", "FOUL", "FOUR", "FOWL",
+"FRAU", "FRAY", "FRED", "FREE", "FRET", "FREY", "FROG", "FROM",
+"FUEL", "FULL", "FUME", "FUND", "FUNK", "FURY", "FUSE", "FUSS",
+"GAFF", "GAGE", "GAIL", "GAIN", "GAIT", "GALA", "GALE", "GALL",
+"GALT", "GAME", "GANG", "GARB", "GARY", "GASH", "GATE", "GAUL",
+"GAUR", "GAVE", "GAWK", "GEAR", "GELD", "GENE", "GENT", "GERM",
+"GETS", "GIBE", "GIFT", "GILD", "GILL", "GILT", "GINA", "GIRD",
+"GIRL", "GIST", "GIVE", "GLAD", "GLEE", "GLEN", "GLIB", "GLOB",
+"GLOM", "GLOW", "GLUE", "GLUM", "GLUT", "GOAD", "GOAL", "GOAT",
+"GOER", "GOES", "GOLD", "GOLF", "GONE", "GONG", "GOOD", "GOOF",
+"GORE", "GORY", "GOSH", "GOUT", "GOWN", "GRAB", "GRAD", "GRAY",
+"GREG", "GREW", "GREY", "GRID", "GRIM", "GRIN", "GRIT", "GROW",
+"GRUB", "GULF", "GULL", "GUNK", "GURU", "GUSH", "GUST", "GWEN",
+"GWYN", "HAAG", "HAAS", "HACK", "HAIL", "HAIR", "HALE", "HALF",
+"HALL", "HALO", "HALT", "HAND", "HANG", "HANK", "HANS", "HARD",
+"HARK", "HARM", "HART", "HASH", "HAST", "HATE", "HATH", "HAUL",
+"HAVE", "HAWK", "HAYS", "HEAD", "HEAL", "HEAR", "HEAT", "HEBE",
+"HECK", "HEED", "HEEL", "HEFT", "HELD", "HELL", "HELM", "HERB",
+"HERD", "HERE", "HERO", "HERS", "HESS", "HEWN", "HICK", "HIDE",
+"HIGH", "HIKE", "HILL", "HILT", "HIND", "HINT", "HIRE", "HISS",
+"HIVE", "HOBO", "HOCK", "HOFF", "HOLD", "HOLE", "HOLM", "HOLT",
+"HOME", "HONE", "HONK", "HOOD", "HOOF", "HOOK", "HOOT", "HORN",
+"HOSE", "HOST", "HOUR", "HOVE", "HOWE", "HOWL", "HOYT", "HUCK",
+"HUED", "HUFF", "HUGE", "HUGH", "HUGO", "HULK", "HULL", "HUNK",
+"HUNT", "HURD", "HURL", "HURT", "HUSH", "HYDE", "HYMN", "IBIS",
+"ICON", "IDEA", "IDLE", "IFFY", "INCA", "INCH", "INTO", "IONS",
+"IOTA", "IOWA", "IRIS", "IRMA", "IRON", "ISLE", "ITCH", "ITEM",
+"IVAN", "JACK", "JADE", "JAIL", "JAKE", "JANE", "JAVA", "JEAN",
+"JEFF", "JERK", "JESS", "JEST", "JIBE", "JILL", "JILT", "JIVE",
+"JOAN", "JOBS", "JOCK", "JOEL", "JOEY", "JOHN", "JOIN", "JOKE",
+"JOLT", "JOVE", "JUDD", "JUDE", "JUDO", "JUDY", "JUJU", "JUKE",
+"JULY", "JUNE", "JUNK", "JUNO", "JURY", "JUST", "JUTE", "KAHN",
+"KALE", "KANE", "KANT", "KARL", "KATE", "KEEL", "KEEN", "KENO",
+"KENT", "KERN", "KERR", "KEYS", "KICK", "KILL", "KIND", "KING",
+"KIRK", "KISS", "KITE", "KLAN", "KNEE", "KNEW", "KNIT", "KNOB",
+"KNOT", "KNOW", "KOCH", "KONG", "KUDO", "KURD", "KURT", "KYLE",
+"LACE", "LACK", "LACY", "LADY", "LAID", "LAIN", "LAIR", "LAKE",
+"LAMB", "LAME", "LAND", "LANE", "LANG", "LARD", "LARK", "LASS",
+"LAST", "LATE", "LAUD", "LAVA", "LAWN", "LAWS", "LAYS", "LEAD",
+"LEAF", "LEAK", "LEAN", "LEAR", "LEEK", "LEER", "LEFT", "LEND",
+"LENS", "LENT", "LEON", "LESK", "LESS", "LEST", "LETS", "LIAR",
+"LICE", "LICK", "LIED", "LIEN", "LIES", "LIEU", "LIFE", "LIFT",
+"LIKE", "LILA", "LILT", "LILY", "LIMA", "LIMB", "LIME", "LIND",
+"LINE", "LINK", "LINT", "LION", "LISA", "LIST", "LIVE", "LOAD",
+"LOAF", "LOAM", "LOAN", "LOCK", "LOFT", "LOGE", "LOIS", "LOLA",
+"LONE", "LONG", "LOOK", "LOON", "LOOT", "LORD", "LORE", "LOSE",
+"LOSS", "LOST", "LOUD", "LOVE", "LOWE", "LUCK", "LUCY", "LUGE",
+"LUKE", "LULU", "LUND", "LUNG", "LURA", "LURE", "LURK", "LUSH",
+"LUST", "LYLE", "LYNN", "LYON", "LYRA", "MACE", "MADE", "MAGI",
+"MAID", "MAIL", "MAIN", "MAKE", "MALE", "MALI", "MALL", "MALT",
+"MANA", "MANN", "MANY", "MARC", "MARE", "MARK", "MARS", "MART",
+"MARY", "MASH", "MASK", "MASS", "MAST", "MATE", "MATH", "MAUL",
+"MAYO", "MEAD", "MEAL", "MEAN", "MEAT", "MEEK", "MEET", "MELD",
+"MELT", "MEMO", "MEND", "MENU", "MERT", "MESH", "MESS", "MICE",
+"MIKE", "MILD", "MILE", "MILK", "MILL", "MILT", "MIMI", "MIND",
+"MINE", "MINI", "MINK", "MINT", "MIRE", "MISS", "MIST", "MITE",
+"MITT", "MOAN", "MOAT", "MOCK", "MODE", "MOLD", "MOLE", "MOLL",
+"MOLT", "MONA", "MONK", "MONT", "MOOD", "MOON", "MOOR", "MOOT",
+"MORE", "MORN", "MORT", "MOSS", "MOST", "MOTH", "MOVE", "MUCH",
+"MUCK", "MUDD", "MUFF", "MULE", "MULL", "MURK", "MUSH", "MUST",
+"MUTE", "MUTT", "MYRA", "MYTH", "NAGY", "NAIL", "NAIR", "NAME",
+"NARY", "NASH", "NAVE", "NAVY", "NEAL", "NEAR", "NEAT", "NECK",
+"NEED", "NEIL", "NELL", "NEON", "NERO", "NESS", "NEST", "NEWS",
+"NEWT", "NIBS", "NICE", "NICK", "NILE", "NINA", "NINE", "NOAH",
+"NODE", "NOEL", "NOLL", "NONE", "NOOK", "NOON", "NORM", "NOSE",
+"NOTE", "NOUN", "NOVA", "NUDE", "NULL", "NUMB", "OATH", "OBEY",
+"OBOE", "ODIN", "OHIO", "OILY", "OINT", "OKAY", "OLAF", "OLDY",
+"OLGA", "OLIN", "OMAN", "OMEN", "OMIT", "ONCE", "ONES", "ONLY",
+"ONTO", "ONUS", "ORAL", "ORGY", "OSLO", "OTIS", "OTTO", "OUCH",
+"OUST", "OUTS", "OVAL", "OVEN", "OVER", "OWLY", "OWNS", "QUAD",
+"QUIT", "QUOD", "RACE", "RACK", "RACY", "RAFT", "RAGE", "RAID",
+"RAIL", "RAIN", "RAKE", "RANK", "RANT", "RARE", "RASH", "RATE",
+"RAVE", "RAYS", "READ", "REAL", "REAM", "REAR", "RECK", "REED",
+"REEF", "REEK", "REEL", "REID", "REIN", "RENA", "REND", "RENT",
+"REST", "RICE", "RICH", "RICK", "RIDE", "RIFT", "RILL", "RIME",
+"RING", "RINK", "RISE", "RISK", "RITE", "ROAD", "ROAM", "ROAR",
+"ROBE", "ROCK", "RODE", "ROIL", "ROLL", "ROME", "ROOD", "ROOF",
+"ROOK", "ROOM", "ROOT", "ROSA", "ROSE", "ROSS", "ROSY", "ROTH",
+"ROUT", "ROVE", "ROWE", "ROWS", "RUBE", "RUBY", "RUDE", "RUDY",
+"RUIN", "RULE", "RUNG", "RUNS", "RUNT", "RUSE", "RUSH", "RUSK",
+"RUSS", "RUST", "RUTH", "SACK", "SAFE", "SAGE", "SAID", "SAIL",
+"SALE", "SALK", "SALT", "SAME", "SAND", "SANE", "SANG", "SANK",
+"SARA", "SAUL", "SAVE", "SAYS", "SCAN", "SCAR", "SCAT", "SCOT",
+"SEAL", "SEAM", "SEAR", "SEAT", "SEED", "SEEK", "SEEM", "SEEN",
+"SEES", "SELF", "SELL", "SEND", "SENT", "SETS", "SEWN", "SHAG",
+"SHAM", "SHAW", "SHAY", "SHED", "SHIM", "SHIN", "SHOD", "SHOE",
+"SHOT", "SHOW", "SHUN", "SHUT", "SICK", "SIDE", "SIFT", "SIGH",
+"SIGN", "SILK", "SILL", "SILO", "SILT", "SINE", "SING", "SINK",
+"SIRE", "SITE", "SITS", "SITU", "SKAT", "SKEW", "SKID", "SKIM",
+"SKIN", "SKIT", "SLAB", "SLAM", "SLAT", "SLAY", "SLED", "SLEW",
+"SLID", "SLIM", "SLIT", "SLOB", "SLOG", "SLOT", "SLOW", "SLUG",
+"SLUM", "SLUR", "SMOG", "SMUG", "SNAG", "SNOB", "SNOW", "SNUB",
+"SNUG", "SOAK", "SOAR", "SOCK", "SODA", "SOFA", "SOFT", "SOIL",
+"SOLD", "SOME", "SONG", "SOON", "SOOT", "SORE", "SORT", "SOUL",
+"SOUR", "SOWN", "STAB", "STAG", "STAN", "STAR", "STAY", "STEM",
+"STEW", "STIR", "STOW", "STUB", "STUN", "SUCH", "SUDS", "SUIT",
+"SULK", "SUMS", "SUNG", "SUNK", "SURE", "SURF", "SWAB", "SWAG",
+"SWAM", "SWAN", "SWAT", "SWAY", "SWIM", "SWUM", "TACK", "TACT",
+"TAIL", "TAKE", "TALE", "TALK", "TALL", "TANK", "TASK", "TATE",
+"TAUT", "TEAL", "TEAM", "TEAR", "TECH", "TEEM", "TEEN", "TEET",
+"TELL", "TEND", "TENT", "TERM", "TERN", "TESS", "TEST", "THAN",
+"THAT", "THEE", "THEM", "THEN", "THEY", "THIN", "THIS", "THUD",
+"THUG", "TICK", "TIDE", "TIDY", "TIED", "TIER", "TILE", "TILL",
+"TILT", "TIME", "TINA", "TINE", "TINT", "TINY", "TIRE", "TOAD",
+"TOGO", "TOIL", "TOLD", "TOLL", "TONE", "TONG", "TONY", "TOOK",
+"TOOL", "TOOT", "TORE", "TORN", "TOTE", "TOUR", "TOUT", "TOWN",
+"TRAG", "TRAM", "TRAY", "TREE", "TREK", "TRIG", "TRIM", "TRIO",
+"TROD", "TROT", "TROY", "TRUE", "TUBA", "TUBE", "TUCK", "TUFT",
+"TUNA", "TUNE", "TUNG", "TURF", "TURN", "TUSK", "TWIG", "TWIN",
+"TWIT", "ULAN", "UNIT", "URGE", "USED", "USER", "USES", "UTAH",
+"VAIL", "VAIN", "VALE", "VARY", "VASE", "VAST", "VEAL", "VEDA",
+"VEIL", "VEIN", "VEND", "VENT", "VERB", "VERY", "VETO", "VICE",
+"VIEW", "VINE", "VISE", "VOID", "VOLT", "VOTE", "WACK", "WADE",
+"WAGE", "WAIL", "WAIT", "WAKE", "WALE", "WALK", "WALL", "WALT",
+"WAND", "WANE", "WANG", "WANT", "WARD", "WARM", "WARN", "WART",
+"WASH", "WAST", "WATS", "WATT", "WAVE", "WAVY", "WAYS", "WEAK",
+"WEAL", "WEAN", "WEAR", "WEED", "WEEK", "WEIR", "WELD", "WELL",
+"WELT", "WENT", "WERE", "WERT", "WEST", "WHAM", "WHAT", "WHEE",
+"WHEN", "WHET", "WHOA", "WHOM", "WICK", "WIFE", "WILD", "WILL",
+"WIND", "WINE", "WING", "WINK", "WINO", "WIRE", "WISE", "WISH",
+"WITH", "WOLF", "WONT", "WOOD", "WOOL", "WORD", "WORE", "WORK",
+"WORM", "WORN", "WOVE", "WRIT", "WYNN", "YALE", "YANG", "YANK",
+"YARD", "YARN", "YAWL", "YAWN", "YEAH", "YEAR", "YELL", "YOGA",
+"YOKE" };
+
+const struct e inv_std_dict[2048] = {
+{"A", 0},
+{"ABE", 1},
+{"ABED", 571},
+{"ABEL", 572},
+{"ABET", 573},
+{"ABLE", 574},
+{"ABUT", 575},
+{"ACE", 2},
+{"ACHE", 576},
+{"ACID", 577},
+{"ACME", 578},
+{"ACRE", 579},
+{"ACT", 3},
+{"ACTA", 580},
+{"ACTS", 581},
+{"AD", 4},
+{"ADA", 5},
+{"ADAM", 582},
+{"ADD", 6},
+{"ADDS", 583},
+{"ADEN", 584},
+{"AFAR", 585},
+{"AFRO", 586},
+{"AGEE", 587},
+{"AGO", 7},
+{"AHEM", 588},
+{"AHOY", 589},
+{"AID", 8},
+{"AIDA", 590},
+{"AIDE", 591},
+{"AIDS", 592},
+{"AIM", 9},
+{"AIR", 10},
+{"AIRY", 593},
+{"AJAR", 594},
+{"AKIN", 595},
+{"ALAN", 596},
+{"ALEC", 597},
+{"ALGA", 598},
+{"ALIA", 599},
+{"ALL", 11},
+{"ALLY", 600},
+{"ALMA", 601},
+{"ALOE", 602},
+{"ALP", 12},
+{"ALSO", 603},
+{"ALTO", 604},
+{"ALUM", 605},
+{"ALVA", 606},
+{"AM", 13},
+{"AMEN", 607},
+{"AMES", 608},
+{"AMID", 609},
+{"AMMO", 610},
+{"AMOK", 611},
+{"AMOS", 612},
+{"AMRA", 613},
+{"AMY", 14},
+{"AN", 15},
+{"ANA", 16},
+{"AND", 17},
+{"ANDY", 614},
+{"ANEW", 615},
+{"ANN", 18},
+{"ANNA", 616},
+{"ANNE", 617},
+{"ANT", 19},
+{"ANTE", 618},
+{"ANTI", 619},
+{"ANY", 20},
+{"APE", 21},
+{"APS", 22},
+{"APT", 23},
+{"AQUA", 620},
+{"ARAB", 621},
+{"ARC", 24},
+{"ARCH", 622},
+{"ARE", 25},
+{"AREA", 623},
+{"ARGO", 624},
+{"ARID", 625},
+{"ARK", 26},
+{"ARM", 27},
+{"ARMY", 626},
+{"ART", 28},
+{"ARTS", 627},
+{"ARTY", 628},
+{"AS", 29},
+{"ASH", 30},
+{"ASIA", 629},
+{"ASK", 31},
+{"ASKS", 630},
+{"AT", 32},
+{"ATE", 33},
+{"ATOM", 631},
+{"AUG", 34},
+{"AUK", 35},
+{"AUNT", 632},
+{"AURA", 633},
+{"AUTO", 634},
+{"AVE", 36},
+{"AVER", 635},
+{"AVID", 636},
+{"AVIS", 637},
+{"AVON", 638},
+{"AVOW", 639},
+{"AWAY", 640},
+{"AWE", 37},
+{"AWK", 38},
+{"AWL", 39},
+{"AWN", 40},
+{"AWRY", 641},
+{"AX", 41},
+{"AYE", 42},
+{"BABE", 642},
+{"BABY", 643},
+{"BACH", 644},
+{"BACK", 645},
+{"BAD", 43},
+{"BADE", 646},
+{"BAG", 44},
+{"BAH", 45},
+{"BAIL", 647},
+{"BAIT", 648},
+{"BAKE", 649},
+{"BALD", 650},
+{"BALE", 651},
+{"BALI", 652},
+{"BALK", 653},
+{"BALL", 654},
+{"BALM", 655},
+{"BAM", 46},
+{"BAN", 47},
+{"BAND", 656},
+{"BANE", 657},
+{"BANG", 658},
+{"BANK", 659},
+{"BAR", 48},
+{"BARB", 660},
+{"BARD", 661},
+{"BARE", 662},
+{"BARK", 663},
+{"BARN", 664},
+{"BARR", 665},
+{"BASE", 666},
+{"BASH", 667},
+{"BASK", 668},
+{"BASS", 669},
+{"BAT", 49},
+{"BATE", 670},
+{"BATH", 671},
+{"BAWD", 672},
+{"BAWL", 673},
+{"BAY", 50},
+{"BE", 51},
+{"BEAD", 674},
+{"BEAK", 675},
+{"BEAM", 676},
+{"BEAN", 677},
+{"BEAR", 678},
+{"BEAT", 679},
+{"BEAU", 680},
+{"BECK", 681},
+{"BED", 52},
+{"BEE", 53},
+{"BEEF", 682},
+{"BEEN", 683},
+{"BEER", 684},
+{"BEET", 685},
+{"BEG", 54},
+{"BELA", 686},
+{"BELL", 687},
+{"BELT", 688},
+{"BEN", 55},
+{"BEND", 689},
+{"BENT", 690},
+{"BERG", 691},
+{"BERN", 692},
+{"BERT", 693},
+{"BESS", 694},
+{"BEST", 695},
+{"BET", 56},
+{"BETA", 696},
+{"BETH", 697},
+{"BEY", 57},
+{"BHOY", 698},
+{"BIAS", 699},
+{"BIB", 58},
+{"BID", 59},
+{"BIDE", 700},
+{"BIEN", 701},
+{"BIG", 60},
+{"BILE", 702},
+{"BILK", 703},
+{"BILL", 704},
+{"BIN", 61},
+{"BIND", 705},
+{"BING", 706},
+{"BIRD", 707},
+{"BIT", 62},
+{"BITE", 708},
+{"BITS", 709},
+{"BLAB", 710},
+{"BLAT", 711},
+{"BLED", 712},
+{"BLEW", 713},
+{"BLOB", 714},
+{"BLOC", 715},
+{"BLOT", 716},
+{"BLOW", 717},
+{"BLUE", 718},
+{"BLUM", 719},
+{"BLUR", 720},
+{"BOAR", 721},
+{"BOAT", 722},
+{"BOB", 63},
+{"BOCA", 723},
+{"BOCK", 724},
+{"BODE", 725},
+{"BODY", 726},
+{"BOG", 64},
+{"BOGY", 727},
+{"BOHR", 728},
+{"BOIL", 729},
+{"BOLD", 730},
+{"BOLO", 731},
+{"BOLT", 732},
+{"BOMB", 733},
+{"BON", 65},
+{"BONA", 734},
+{"BOND", 735},
+{"BONE", 736},
+{"BONG", 737},
+{"BONN", 738},
+{"BONY", 739},
+{"BOO", 66},
+{"BOOK", 740},
+{"BOOM", 741},
+{"BOON", 742},
+{"BOOT", 743},
+{"BOP", 67},
+{"BORE", 744},
+{"BORG", 745},
+{"BORN", 746},
+{"BOSE", 747},
+{"BOSS", 748},
+{"BOTH", 749},
+{"BOUT", 750},
+{"BOW", 68},
+{"BOWL", 751},
+{"BOY", 69},
+{"BOYD", 752},
+{"BRAD", 753},
+{"BRAE", 754},
+{"BRAG", 755},
+{"BRAN", 756},
+{"BRAY", 757},
+{"BRED", 758},
+{"BREW", 759},
+{"BRIG", 760},
+{"BRIM", 761},
+{"BROW", 762},
+{"BUB", 70},
+{"BUCK", 763},
+{"BUD", 71},
+{"BUDD", 764},
+{"BUFF", 765},
+{"BUG", 72},
+{"BULB", 766},
+{"BULK", 767},
+{"BULL", 768},
+{"BUM", 73},
+{"BUN", 74},
+{"BUNK", 769},
+{"BUNT", 770},
+{"BUOY", 771},
+{"BURG", 772},
+{"BURL", 773},
+{"BURN", 774},
+{"BURR", 775},
+{"BURT", 776},
+{"BURY", 777},
+{"BUS", 75},
+{"BUSH", 778},
+{"BUSS", 779},
+{"BUST", 780},
+{"BUSY", 781},
+{"BUT", 76},
+{"BUY", 77},
+{"BY", 78},
+{"BYE", 79},
+{"BYTE", 782},
+{"CAB", 80},
+{"CADY", 783},
+{"CAFE", 784},
+{"CAGE", 785},
+{"CAIN", 786},
+{"CAKE", 787},
+{"CAL", 81},
+{"CALF", 788},
+{"CALL", 789},
+{"CALM", 790},
+{"CAM", 82},
+{"CAME", 791},
+{"CAN", 83},
+{"CANE", 792},
+{"CANT", 793},
+{"CAP", 84},
+{"CAR", 85},
+{"CARD", 794},
+{"CARE", 795},
+{"CARL", 796},
+{"CARR", 797},
+{"CART", 798},
+{"CASE", 799},
+{"CASH", 800},
+{"CASK", 801},
+{"CAST", 802},
+{"CAT", 86},
+{"CAVE", 803},
+{"CAW", 87},
+{"CEIL", 804},
+{"CELL", 805},
+{"CENT", 806},
+{"CERN", 807},
+{"CHAD", 808},
+{"CHAR", 809},
+{"CHAT", 810},
+{"CHAW", 811},
+{"CHEF", 812},
+{"CHEN", 813},
+{"CHEW", 814},
+{"CHIC", 815},
+{"CHIN", 816},
+{"CHOU", 817},
+{"CHOW", 818},
+{"CHUB", 819},
+{"CHUG", 820},
+{"CHUM", 821},
+{"CITE", 822},
+{"CITY", 823},
+{"CLAD", 824},
+{"CLAM", 825},
+{"CLAN", 826},
+{"CLAW", 827},
+{"CLAY", 828},
+{"CLOD", 829},
+{"CLOG", 830},
+{"CLOT", 831},
+{"CLUB", 832},
+{"CLUE", 833},
+{"COAL", 834},
+{"COAT", 835},
+{"COCA", 836},
+{"COCK", 837},
+{"COCO", 838},
+{"COD", 88},
+{"CODA", 839},
+{"CODE", 840},
+{"CODY", 841},
+{"COED", 842},
+{"COG", 89},
+{"COIL", 843},
+{"COIN", 844},
+{"COKE", 845},
+{"COL", 90},
+{"COLA", 846},
+{"COLD", 847},
+{"COLT", 848},
+{"COMA", 849},
+{"COMB", 850},
+{"COME", 851},
+{"CON", 91},
+{"COO", 92},
+{"COOK", 852},
+{"COOL", 853},
+{"COON", 854},
+{"COOT", 855},
+{"COP", 93},
+{"CORD", 856},
+{"CORE", 857},
+{"CORK", 858},
+{"CORN", 859},
+{"COST", 860},
+{"COT", 94},
+{"COVE", 861},
+{"COW", 95},
+{"COWL", 862},
+{"COY", 96},
+{"CRAB", 863},
+{"CRAG", 864},
+{"CRAM", 865},
+{"CRAY", 866},
+{"CREW", 867},
+{"CRIB", 868},
+{"CROW", 869},
+{"CRUD", 870},
+{"CRY", 97},
+{"CUB", 98},
+{"CUBA", 871},
+{"CUBE", 872},
+{"CUE", 99},
+{"CUFF", 873},
+{"CULL", 874},
+{"CULT", 875},
+{"CUNY", 876},
+{"CUP", 100},
+{"CUR", 101},
+{"CURB", 877},
+{"CURD", 878},
+{"CURE", 879},
+{"CURL", 880},
+{"CURT", 881},
+{"CUT", 102},
+{"CUTS", 882},
+{"DAB", 103},
+{"DAD", 104},
+{"DADE", 883},
+{"DALE", 884},
+{"DAM", 105},
+{"DAME", 885},
+{"DAN", 106},
+{"DANA", 886},
+{"DANE", 887},
+{"DANG", 888},
+{"DANK", 889},
+{"DAR", 107},
+{"DARE", 890},
+{"DARK", 891},
+{"DARN", 892},
+{"DART", 893},
+{"DASH", 894},
+{"DATA", 895},
+{"DATE", 896},
+{"DAVE", 897},
+{"DAVY", 898},
+{"DAWN", 899},
+{"DAY", 108},
+{"DAYS", 900},
+{"DEAD", 901},
+{"DEAF", 902},
+{"DEAL", 903},
+{"DEAN", 904},
+{"DEAR", 905},
+{"DEBT", 906},
+{"DECK", 907},
+{"DEE", 109},
+{"DEED", 908},
+{"DEEM", 909},
+{"DEER", 910},
+{"DEFT", 911},
+{"DEFY", 912},
+{"DEL", 110},
+{"DELL", 913},
+{"DEN", 111},
+{"DENT", 914},
+{"DENY", 915},
+{"DES", 112},
+{"DESK", 916},
+{"DEW", 113},
+{"DIAL", 917},
+{"DICE", 918},
+{"DID", 114},
+{"DIE", 115},
+{"DIED", 919},
+{"DIET", 920},
+{"DIG", 116},
+{"DIME", 921},
+{"DIN", 117},
+{"DINE", 922},
+{"DING", 923},
+{"DINT", 924},
+{"DIP", 118},
+{"DIRE", 925},
+{"DIRT", 926},
+{"DISC", 927},
+{"DISH", 928},
+{"DISK", 929},
+{"DIVE", 930},
+{"DO", 119},
+{"DOCK", 931},
+{"DOE", 120},
+{"DOES", 932},
+{"DOG", 121},
+{"DOLE", 933},
+{"DOLL", 934},
+{"DOLT", 935},
+{"DOME", 936},
+{"DON", 122},
+{"DONE", 937},
+{"DOOM", 938},
+{"DOOR", 939},
+{"DORA", 940},
+{"DOSE", 941},
+{"DOT", 123},
+{"DOTE", 942},
+{"DOUG", 943},
+{"DOUR", 944},
+{"DOVE", 945},
+{"DOW", 124},
+{"DOWN", 946},
+{"DRAB", 947},
+{"DRAG", 948},
+{"DRAM", 949},
+{"DRAW", 950},
+{"DREW", 951},
+{"DRUB", 952},
+{"DRUG", 953},
+{"DRUM", 954},
+{"DRY", 125},
+{"DUAL", 955},
+{"DUB", 126},
+{"DUCK", 956},
+{"DUCT", 957},
+{"DUD", 127},
+{"DUE", 128},
+{"DUEL", 958},
+{"DUET", 959},
+{"DUG", 129},
+{"DUKE", 960},
+{"DULL", 961},
+{"DUMB", 962},
+{"DUN", 130},
+{"DUNE", 963},
+{"DUNK", 964},
+{"DUSK", 965},
+{"DUST", 966},
+{"DUTY", 967},
+{"EACH", 968},
+{"EAR", 131},
+{"EARL", 969},
+{"EARN", 970},
+{"EASE", 971},
+{"EAST", 972},
+{"EASY", 973},
+{"EAT", 132},
+{"EBEN", 974},
+{"ECHO", 975},
+{"ED", 133},
+{"EDDY", 976},
+{"EDEN", 977},
+{"EDGE", 978},
+{"EDGY", 979},
+{"EDIT", 980},
+{"EDNA", 981},
+{"EEL", 134},
+{"EGAN", 982},
+{"EGG", 135},
+{"EGO", 136},
+{"ELAN", 983},
+{"ELBA", 984},
+{"ELI", 137},
+{"ELK", 138},
+{"ELLA", 985},
+{"ELM", 139},
+{"ELSE", 986},
+{"ELY", 140},
+{"EM", 141},
+{"EMIL", 987},
+{"EMIT", 988},
+{"EMMA", 989},
+{"END", 142},
+{"ENDS", 990},
+{"ERIC", 991},
+{"EROS", 992},
+{"EST", 143},
+{"ETC", 144},
+{"EVA", 145},
+{"EVE", 146},
+{"EVEN", 993},
+{"EVER", 994},
+{"EVIL", 995},
+{"EWE", 147},
+{"EYE", 148},
+{"EYED", 996},
+{"FACE", 997},
+{"FACT", 998},
+{"FAD", 149},
+{"FADE", 999},
+{"FAIL", 1000},
+{"FAIN", 1001},
+{"FAIR", 1002},
+{"FAKE", 1003},
+{"FALL", 1004},
+{"FAME", 1005},
+{"FAN", 150},
+{"FANG", 1006},
+{"FAR", 151},
+{"FARM", 1007},
+{"FAST", 1008},
+{"FAT", 152},
+{"FATE", 1009},
+{"FAWN", 1010},
+{"FAY", 153},
+{"FEAR", 1011},
+{"FEAT", 1012},
+{"FED", 154},
+{"FEE", 155},
+{"FEED", 1013},
+{"FEEL", 1014},
+{"FEET", 1015},
+{"FELL", 1016},
+{"FELT", 1017},
+{"FEND", 1018},
+{"FERN", 1019},
+{"FEST", 1020},
+{"FEUD", 1021},
+{"FEW", 156},
+{"FIB", 157},
+{"FIEF", 1022},
+{"FIG", 158},
+{"FIGS", 1023},
+{"FILE", 1024},
+{"FILL", 1025},
+{"FILM", 1026},
+{"FIN", 159},
+{"FIND", 1027},
+{"FINE", 1028},
+{"FINK", 1029},
+{"FIR", 160},
+{"FIRE", 1030},
+{"FIRM", 1031},
+{"FISH", 1032},
+{"FISK", 1033},
+{"FIST", 1034},
+{"FIT", 161},
+{"FITS", 1035},
+{"FIVE", 1036},
+{"FLAG", 1037},
+{"FLAK", 1038},
+{"FLAM", 1039},
+{"FLAT", 1040},
+{"FLAW", 1041},
+{"FLEA", 1042},
+{"FLED", 1043},
+{"FLEW", 1044},
+{"FLIT", 1045},
+{"FLO", 162},
+{"FLOC", 1046},
+{"FLOG", 1047},
+{"FLOW", 1048},
+{"FLUB", 1049},
+{"FLUE", 1050},
+{"FLY", 163},
+{"FOAL", 1051},
+{"FOAM", 1052},
+{"FOE", 164},
+{"FOG", 165},
+{"FOGY", 1053},
+{"FOIL", 1054},
+{"FOLD", 1055},
+{"FOLK", 1056},
+{"FOND", 1057},
+{"FONT", 1058},
+{"FOOD", 1059},
+{"FOOL", 1060},
+{"FOOT", 1061},
+{"FOR", 166},
+{"FORD", 1062},
+{"FORE", 1063},
+{"FORK", 1064},
+{"FORM", 1065},
+{"FORT", 1066},
+{"FOSS", 1067},
+{"FOUL", 1068},
+{"FOUR", 1069},
+{"FOWL", 1070},
+{"FRAU", 1071},
+{"FRAY", 1072},
+{"FRED", 1073},
+{"FREE", 1074},
+{"FRET", 1075},
+{"FREY", 1076},
+{"FROG", 1077},
+{"FROM", 1078},
+{"FRY", 167},
+{"FUEL", 1079},
+{"FULL", 1080},
+{"FUM", 168},
+{"FUME", 1081},
+{"FUN", 169},
+{"FUND", 1082},
+{"FUNK", 1083},
+{"FUR", 170},
+{"FURY", 1084},
+{"FUSE", 1085},
+{"FUSS", 1086},
+{"GAB", 171},
+{"GAD", 172},
+{"GAFF", 1087},
+{"GAG", 173},
+{"GAGE", 1088},
+{"GAIL", 1089},
+{"GAIN", 1090},
+{"GAIT", 1091},
+{"GAL", 174},
+{"GALA", 1092},
+{"GALE", 1093},
+{"GALL", 1094},
+{"GALT", 1095},
+{"GAM", 175},
+{"GAME", 1096},
+{"GANG", 1097},
+{"GAP", 176},
+{"GARB", 1098},
+{"GARY", 1099},
+{"GAS", 177},
+{"GASH", 1100},
+{"GATE", 1101},
+{"GAUL", 1102},
+{"GAUR", 1103},
+{"GAVE", 1104},
+{"GAWK", 1105},
+{"GAY", 178},
+{"GEAR", 1106},
+{"GEE", 179},
+{"GEL", 180},
+{"GELD", 1107},
+{"GEM", 181},
+{"GENE", 1108},
+{"GENT", 1109},
+{"GERM", 1110},
+{"GET", 182},
+{"GETS", 1111},
+{"GIBE", 1112},
+{"GIFT", 1113},
+{"GIG", 183},
+{"GIL", 184},
+{"GILD", 1114},
+{"GILL", 1115},
+{"GILT", 1116},
+{"GIN", 185},
+{"GINA", 1117},
+{"GIRD", 1118},
+{"GIRL", 1119},
+{"GIST", 1120},
+{"GIVE", 1121},
+{"GLAD", 1122},
+{"GLEE", 1123},
+{"GLEN", 1124},
+{"GLIB", 1125},
+{"GLOB", 1126},
+{"GLOM", 1127},
+{"GLOW", 1128},
+{"GLUE", 1129},
+{"GLUM", 1130},
+{"GLUT", 1131},
+{"GO", 186},
+{"GOAD", 1132},
+{"GOAL", 1133},
+{"GOAT", 1134},
+{"GOER", 1135},
+{"GOES", 1136},
+{"GOLD", 1137},
+{"GOLF", 1138},
+{"GONE", 1139},
+{"GONG", 1140},
+{"GOOD", 1141},
+{"GOOF", 1142},
+{"GORE", 1143},
+{"GORY", 1144},
+{"GOSH", 1145},
+{"GOT", 187},
+{"GOUT", 1146},
+{"GOWN", 1147},
+{"GRAB", 1148},
+{"GRAD", 1149},
+{"GRAY", 1150},
+{"GREG", 1151},
+{"GREW", 1152},
+{"GREY", 1153},
+{"GRID", 1154},
+{"GRIM", 1155},
+{"GRIN", 1156},
+{"GRIT", 1157},
+{"GROW", 1158},
+{"GRUB", 1159},
+{"GULF", 1160},
+{"GULL", 1161},
+{"GUM", 188},
+{"GUN", 189},
+{"GUNK", 1162},
+{"GURU", 1163},
+{"GUS", 190},
+{"GUSH", 1164},
+{"GUST", 1165},
+{"GUT", 191},
+{"GUY", 192},
+{"GWEN", 1166},
+{"GWYN", 1167},
+{"GYM", 193},
+{"GYP", 194},
+{"HA", 195},
+{"HAAG", 1168},
+{"HAAS", 1169},
+{"HACK", 1170},
+{"HAD", 196},
+{"HAIL", 1171},
+{"HAIR", 1172},
+{"HAL", 197},
+{"HALE", 1173},
+{"HALF", 1174},
+{"HALL", 1175},
+{"HALO", 1176},
+{"HALT", 1177},
+{"HAM", 198},
+{"HAN", 199},
+{"HAND", 1178},
+{"HANG", 1179},
+{"HANK", 1180},
+{"HANS", 1181},
+{"HAP", 200},
+{"HARD", 1182},
+{"HARK", 1183},
+{"HARM", 1184},
+{"HART", 1185},
+{"HAS", 201},
+{"HASH", 1186},
+{"HAST", 1187},
+{"HAT", 202},
+{"HATE", 1188},
+{"HATH", 1189},
+{"HAUL", 1190},
+{"HAVE", 1191},
+{"HAW", 203},
+{"HAWK", 1192},
+{"HAY", 204},
+{"HAYS", 1193},
+{"HE", 205},
+{"HEAD", 1194},
+{"HEAL", 1195},
+{"HEAR", 1196},
+{"HEAT", 1197},
+{"HEBE", 1198},
+{"HECK", 1199},
+{"HEED", 1200},
+{"HEEL", 1201},
+{"HEFT", 1202},
+{"HELD", 1203},
+{"HELL", 1204},
+{"HELM", 1205},
+{"HEM", 206},
+{"HEN", 207},
+{"HER", 208},
+{"HERB", 1206},
+{"HERD", 1207},
+{"HERE", 1208},
+{"HERO", 1209},
+{"HERS", 1210},
+{"HESS", 1211},
+{"HEW", 209},
+{"HEWN", 1212},
+{"HEY", 210},
+{"HI", 211},
+{"HICK", 1213},
+{"HID", 212},
+{"HIDE", 1214},
+{"HIGH", 1215},
+{"HIKE", 1216},
+{"HILL", 1217},
+{"HILT", 1218},
+{"HIM", 213},
+{"HIND", 1219},
+{"HINT", 1220},
+{"HIP", 214},
+{"HIRE", 1221},
+{"HIS", 215},
+{"HISS", 1222},
+{"HIT", 216},
+{"HIVE", 1223},
+{"HO", 217},
+{"HOB", 218},
+{"HOBO", 1224},
+{"HOC", 219},
+{"HOCK", 1225},
+{"HOE", 220},
+{"HOFF", 1226},
+{"HOG", 221},
+{"HOLD", 1227},
+{"HOLE", 1228},
+{"HOLM", 1229},
+{"HOLT", 1230},
+{"HOME", 1231},
+{"HONE", 1232},
+{"HONK", 1233},
+{"HOOD", 1234},
+{"HOOF", 1235},
+{"HOOK", 1236},
+{"HOOT", 1237},
+{"HOP", 222},
+{"HORN", 1238},
+{"HOSE", 1239},
+{"HOST", 1240},
+{"HOT", 223},
+{"HOUR", 1241},
+{"HOVE", 1242},
+{"HOW", 224},
+{"HOWE", 1243},
+{"HOWL", 1244},
+{"HOYT", 1245},
+{"HUB", 225},
+{"HUCK", 1246},
+{"HUE", 226},
+{"HUED", 1247},
+{"HUFF", 1248},
+{"HUG", 227},
+{"HUGE", 1249},
+{"HUGH", 1250},
+{"HUGO", 1251},
+{"HUH", 228},
+{"HULK", 1252},
+{"HULL", 1253},
+{"HUM", 229},
+{"HUNK", 1254},
+{"HUNT", 1255},
+{"HURD", 1256},
+{"HURL", 1257},
+{"HURT", 1258},
+{"HUSH", 1259},
+{"HUT", 230},
+{"HYDE", 1260},
+{"HYMN", 1261},
+{"I", 231},
+{"IBIS", 1262},
+{"ICON", 1263},
+{"ICY", 232},
+{"IDA", 233},
+{"IDEA", 1264},
+{"IDLE", 1265},
+{"IF", 234},
+{"IFFY", 1266},
+{"IKE", 235},
+{"ILL", 236},
+{"INCA", 1267},
+{"INCH", 1268},
+{"INK", 237},
+{"INN", 238},
+{"INTO", 1269},
+{"IO", 239},
+{"ION", 240},
+{"IONS", 1270},
+{"IOTA", 1271},
+{"IOWA", 1272},
+{"IQ", 241},
+{"IRA", 242},
+{"IRE", 243},
+{"IRIS", 1273},
+{"IRK", 244},
+{"IRMA", 1274},
+{"IRON", 1275},
+{"IS", 245},
+{"ISLE", 1276},
+{"IT", 246},
+{"ITCH", 1277},
+{"ITEM", 1278},
+{"ITS", 247},
+{"IVAN", 1279},
+{"IVY", 248},
+{"JAB", 249},
+{"JACK", 1280},
+{"JADE", 1281},
+{"JAG", 250},
+{"JAIL", 1282},
+{"JAKE", 1283},
+{"JAM", 251},
+{"JAN", 252},
+{"JANE", 1284},
+{"JAR", 253},
+{"JAVA", 1285},
+{"JAW", 254},
+{"JAY", 255},
+{"JEAN", 1286},
+{"JEFF", 1287},
+{"JERK", 1288},
+{"JESS", 1289},
+{"JEST", 1290},
+{"JET", 256},
+{"JIBE", 1291},
+{"JIG", 257},
+{"JILL", 1292},
+{"JILT", 1293},
+{"JIM", 258},
+{"JIVE", 1294},
+{"JO", 259},
+{"JOAN", 1295},
+{"JOB", 260},
+{"JOBS", 1296},
+{"JOCK", 1297},
+{"JOE", 261},
+{"JOEL", 1298},
+{"JOEY", 1299},
+{"JOG", 262},
+{"JOHN", 1300},
+{"JOIN", 1301},
+{"JOKE", 1302},
+{"JOLT", 1303},
+{"JOT", 263},
+{"JOVE", 1304},
+{"JOY", 264},
+{"JUDD", 1305},
+{"JUDE", 1306},
+{"JUDO", 1307},
+{"JUDY", 1308},
+{"JUG", 265},
+{"JUJU", 1309},
+{"JUKE", 1310},
+{"JULY", 1311},
+{"JUNE", 1312},
+{"JUNK", 1313},
+{"JUNO", 1314},
+{"JURY", 1315},
+{"JUST", 1316},
+{"JUT", 266},
+{"JUTE", 1317},
+{"KAHN", 1318},
+{"KALE", 1319},
+{"KANE", 1320},
+{"KANT", 1321},
+{"KARL", 1322},
+{"KATE", 1323},
+{"KAY", 267},
+{"KEEL", 1324},
+{"KEEN", 1325},
+{"KEG", 268},
+{"KEN", 269},
+{"KENO", 1326},
+{"KENT", 1327},
+{"KERN", 1328},
+{"KERR", 1329},
+{"KEY", 270},
+{"KEYS", 1330},
+{"KICK", 1331},
+{"KID", 271},
+{"KILL", 1332},
+{"KIM", 272},
+{"KIN", 273},
+{"KIND", 1333},
+{"KING", 1334},
+{"KIRK", 1335},
+{"KISS", 1336},
+{"KIT", 274},
+{"KITE", 1337},
+{"KLAN", 1338},
+{"KNEE", 1339},
+{"KNEW", 1340},
+{"KNIT", 1341},
+{"KNOB", 1342},
+{"KNOT", 1343},
+{"KNOW", 1344},
+{"KOCH", 1345},
+{"KONG", 1346},
+{"KUDO", 1347},
+{"KURD", 1348},
+{"KURT", 1349},
+{"KYLE", 1350},
+{"LA", 275},
+{"LAB", 276},
+{"LAC", 277},
+{"LACE", 1351},
+{"LACK", 1352},
+{"LACY", 1353},
+{"LAD", 278},
+{"LADY", 1354},
+{"LAG", 279},
+{"LAID", 1355},
+{"LAIN", 1356},
+{"LAIR", 1357},
+{"LAKE", 1358},
+{"LAM", 280},
+{"LAMB", 1359},
+{"LAME", 1360},
+{"LAND", 1361},
+{"LANE", 1362},
+{"LANG", 1363},
+{"LAP", 281},
+{"LARD", 1364},
+{"LARK", 1365},
+{"LASS", 1366},
+{"LAST", 1367},
+{"LATE", 1368},
+{"LAUD", 1369},
+{"LAVA", 1370},
+{"LAW", 282},
+{"LAWN", 1371},
+{"LAWS", 1372},
+{"LAY", 283},
+{"LAYS", 1373},
+{"LEA", 284},
+{"LEAD", 1374},
+{"LEAF", 1375},
+{"LEAK", 1376},
+{"LEAN", 1377},
+{"LEAR", 1378},
+{"LED", 285},
+{"LEE", 286},
+{"LEEK", 1379},
+{"LEER", 1380},
+{"LEFT", 1381},
+{"LEG", 287},
+{"LEN", 288},
+{"LEND", 1382},
+{"LENS", 1383},
+{"LENT", 1384},
+{"LEO", 289},
+{"LEON", 1385},
+{"LESK", 1386},
+{"LESS", 1387},
+{"LEST", 1388},
+{"LET", 290},
+{"LETS", 1389},
+{"LEW", 291},
+{"LIAR", 1390},
+{"LICE", 1391},
+{"LICK", 1392},
+{"LID", 292},
+{"LIE", 293},
+{"LIED", 1393},
+{"LIEN", 1394},
+{"LIES", 1395},
+{"LIEU", 1396},
+{"LIFE", 1397},
+{"LIFT", 1398},
+{"LIKE", 1399},
+{"LILA", 1400},
+{"LILT", 1401},
+{"LILY", 1402},
+{"LIMA", 1403},
+{"LIMB", 1404},
+{"LIME", 1405},
+{"LIN", 294},
+{"LIND", 1406},
+{"LINE", 1407},
+{"LINK", 1408},
+{"LINT", 1409},
+{"LION", 1410},
+{"LIP", 295},
+{"LISA", 1411},
+{"LIST", 1412},
+{"LIT", 296},
+{"LIVE", 1413},
+{"LO", 297},
+{"LOAD", 1414},
+{"LOAF", 1415},
+{"LOAM", 1416},
+{"LOAN", 1417},
+{"LOB", 298},
+{"LOCK", 1418},
+{"LOFT", 1419},
+{"LOG", 299},
+{"LOGE", 1420},
+{"LOIS", 1421},
+{"LOLA", 1422},
+{"LONE", 1423},
+{"LONG", 1424},
+{"LOOK", 1425},
+{"LOON", 1426},
+{"LOOT", 1427},
+{"LOP", 300},
+{"LORD", 1428},
+{"LORE", 1429},
+{"LOS", 301},
+{"LOSE", 1430},
+{"LOSS", 1431},
+{"LOST", 1432},
+{"LOT", 302},
+{"LOU", 303},
+{"LOUD", 1433},
+{"LOVE", 1434},
+{"LOW", 304},
+{"LOWE", 1435},
+{"LOY", 305},
+{"LUCK", 1436},
+{"LUCY", 1437},
+{"LUG", 306},
+{"LUGE", 1438},
+{"LUKE", 1439},
+{"LULU", 1440},
+{"LUND", 1441},
+{"LUNG", 1442},
+{"LURA", 1443},
+{"LURE", 1444},
+{"LURK", 1445},
+{"LUSH", 1446},
+{"LUST", 1447},
+{"LYE", 307},
+{"LYLE", 1448},
+{"LYNN", 1449},
+{"LYON", 1450},
+{"LYRA", 1451},
+{"MA", 308},
+{"MAC", 309},
+{"MACE", 1452},
+{"MAD", 310},
+{"MADE", 1453},
+{"MAE", 311},
+{"MAGI", 1454},
+{"MAID", 1455},
+{"MAIL", 1456},
+{"MAIN", 1457},
+{"MAKE", 1458},
+{"MALE", 1459},
+{"MALI", 1460},
+{"MALL", 1461},
+{"MALT", 1462},
+{"MAN", 312},
+{"MANA", 1463},
+{"MANN", 1464},
+{"MANY", 1465},
+{"MAO", 313},
+{"MAP", 314},
+{"MARC", 1466},
+{"MARE", 1467},
+{"MARK", 1468},
+{"MARS", 1469},
+{"MART", 1470},
+{"MARY", 1471},
+{"MASH", 1472},
+{"MASK", 1473},
+{"MASS", 1474},
+{"MAST", 1475},
+{"MAT", 315},
+{"MATE", 1476},
+{"MATH", 1477},
+{"MAUL", 1478},
+{"MAW", 316},
+{"MAY", 317},
+{"MAYO", 1479},
+{"ME", 318},
+{"MEAD", 1480},
+{"MEAL", 1481},
+{"MEAN", 1482},
+{"MEAT", 1483},
+{"MEEK", 1484},
+{"MEET", 1485},
+{"MEG", 319},
+{"MEL", 320},
+{"MELD", 1486},
+{"MELT", 1487},
+{"MEMO", 1488},
+{"MEN", 321},
+{"MEND", 1489},
+{"MENU", 1490},
+{"MERT", 1491},
+{"MESH", 1492},
+{"MESS", 1493},
+{"MET", 322},
+{"MEW", 323},
+{"MICE", 1494},
+{"MID", 324},
+{"MIKE", 1495},
+{"MILD", 1496},
+{"MILE", 1497},
+{"MILK", 1498},
+{"MILL", 1499},
+{"MILT", 1500},
+{"MIMI", 1501},
+{"MIN", 325},
+{"MIND", 1502},
+{"MINE", 1503},
+{"MINI", 1504},
+{"MINK", 1505},
+{"MINT", 1506},
+{"MIRE", 1507},
+{"MISS", 1508},
+{"MIST", 1509},
+{"MIT", 326},
+{"MITE", 1510},
+{"MITT", 1511},
+{"MOAN", 1512},
+{"MOAT", 1513},
+{"MOB", 327},
+{"MOCK", 1514},
+{"MOD", 328},
+{"MODE", 1515},
+{"MOE", 329},
+{"MOLD", 1516},
+{"MOLE", 1517},
+{"MOLL", 1518},
+{"MOLT", 1519},
+{"MONA", 1520},
+{"MONK", 1521},
+{"MONT", 1522},
+{"MOO", 330},
+{"MOOD", 1523},
+{"MOON", 1524},
+{"MOOR", 1525},
+{"MOOT", 1526},
+{"MOP", 331},
+{"MORE", 1527},
+{"MORN", 1528},
+{"MORT", 1529},
+{"MOS", 332},
+{"MOSS", 1530},
+{"MOST", 1531},
+{"MOT", 333},
+{"MOTH", 1532},
+{"MOVE", 1533},
+{"MOW", 334},
+{"MUCH", 1534},
+{"MUCK", 1535},
+{"MUD", 335},
+{"MUDD", 1536},
+{"MUFF", 1537},
+{"MUG", 336},
+{"MULE", 1538},
+{"MULL", 1539},
+{"MUM", 337},
+{"MURK", 1540},
+{"MUSH", 1541},
+{"MUST", 1542},
+{"MUTE", 1543},
+{"MUTT", 1544},
+{"MY", 338},
+{"MYRA", 1545},
+{"MYTH", 1546},
+{"NAB", 339},
+{"NAG", 340},
+{"NAGY", 1547},
+{"NAIL", 1548},
+{"NAIR", 1549},
+{"NAME", 1550},
+{"NAN", 341},
+{"NAP", 342},
+{"NARY", 1551},
+{"NASH", 1552},
+{"NAT", 343},
+{"NAVE", 1553},
+{"NAVY", 1554},
+{"NAY", 344},
+{"NE", 345},
+{"NEAL", 1555},
+{"NEAR", 1556},
+{"NEAT", 1557},
+{"NECK", 1558},
+{"NED", 346},
+{"NEE", 347},
+{"NEED", 1559},
+{"NEIL", 1560},
+{"NELL", 1561},
+{"NEON", 1562},
+{"NERO", 1563},
+{"NESS", 1564},
+{"NEST", 1565},
+{"NET", 348},
+{"NEW", 349},
+{"NEWS", 1566},
+{"NEWT", 1567},
+{"NIB", 350},
+{"NIBS", 1568},
+{"NICE", 1569},
+{"NICK", 1570},
+{"NIL", 351},
+{"NILE", 1571},
+{"NINA", 1572},
+{"NINE", 1573},
+{"NIP", 352},
+{"NIT", 353},
+{"NO", 354},
+{"NOAH", 1574},
+{"NOB", 355},
+{"NOD", 356},
+{"NODE", 1575},
+{"NOEL", 1576},
+{"NOLL", 1577},
+{"NON", 357},
+{"NONE", 1578},
+{"NOOK", 1579},
+{"NOON", 1580},
+{"NOR", 358},
+{"NORM", 1581},
+{"NOSE", 1582},
+{"NOT", 359},
+{"NOTE", 1583},
+{"NOUN", 1584},
+{"NOV", 360},
+{"NOVA", 1585},
+{"NOW", 361},
+{"NU", 362},
+{"NUDE", 1586},
+{"NULL", 1587},
+{"NUMB", 1588},
+{"NUN", 363},
+{"NUT", 364},
+{"O", 365},
+{"OAF", 366},
+{"OAK", 367},
+{"OAR", 368},
+{"OAT", 369},
+{"OATH", 1589},
+{"OBEY", 1590},
+{"OBOE", 1591},
+{"ODD", 370},
+{"ODE", 371},
+{"ODIN", 1592},
+{"OF", 372},
+{"OFF", 373},
+{"OFT", 374},
+{"OH", 375},
+{"OHIO", 1593},
+{"OIL", 376},
+{"OILY", 1594},
+{"OINT", 1595},
+{"OK", 377},
+{"OKAY", 1596},
+{"OLAF", 1597},
+{"OLD", 378},
+{"OLDY", 1598},
+{"OLGA", 1599},
+{"OLIN", 1600},
+{"OMAN", 1601},
+{"OMEN", 1602},
+{"OMIT", 1603},
+{"ON", 379},
+{"ONCE", 1604},
+{"ONE", 380},
+{"ONES", 1605},
+{"ONLY", 1606},
+{"ONTO", 1607},
+{"ONUS", 1608},
+{"OR", 381},
+{"ORAL", 1609},
+{"ORB", 382},
+{"ORE", 383},
+{"ORGY", 1610},
+{"ORR", 384},
+{"OS", 385},
+{"OSLO", 1611},
+{"OTIS", 1612},
+{"OTT", 386},
+{"OTTO", 1613},
+{"OUCH", 1614},
+{"OUR", 387},
+{"OUST", 1615},
+{"OUT", 388},
+{"OUTS", 1616},
+{"OVA", 389},
+{"OVAL", 1617},
+{"OVEN", 1618},
+{"OVER", 1619},
+{"OW", 390},
+{"OWE", 391},
+{"OWL", 392},
+{"OWLY", 1620},
+{"OWN", 393},
+{"OWNS", 1621},
+{"OX", 394},
+{"PA", 395},
+{"PAD", 396},
+{"PAL", 397},
+{"PAM", 398},
+{"PAN", 399},
+{"PAP", 400},
+{"PAR", 401},
+{"PAT", 402},
+{"PAW", 403},
+{"PAY", 404},
+{"PEA", 405},
+{"PEG", 406},
+{"PEN", 407},
+{"PEP", 408},
+{"PER", 409},
+{"PET", 410},
+{"PEW", 411},
+{"PHI", 412},
+{"PI", 413},
+{"PIE", 414},
+{"PIN", 415},
+{"PIT", 416},
+{"PLY", 417},
+{"PO", 418},
+{"POD", 419},
+{"POE", 420},
+{"POP", 421},
+{"POT", 422},
+{"POW", 423},
+{"PRO", 424},
+{"PRY", 425},
+{"PUB", 426},
+{"PUG", 427},
+{"PUN", 428},
+{"PUP", 429},
+{"PUT", 430},
+{"QUAD", 1622},
+{"QUIT", 1623},
+{"QUO", 431},
+{"QUOD", 1624},
+{"RACE", 1625},
+{"RACK", 1626},
+{"RACY", 1627},
+{"RAFT", 1628},
+{"RAG", 432},
+{"RAGE", 1629},
+{"RAID", 1630},
+{"RAIL", 1631},
+{"RAIN", 1632},
+{"RAKE", 1633},
+{"RAM", 433},
+{"RAN", 434},
+{"RANK", 1634},
+{"RANT", 1635},
+{"RAP", 435},
+{"RARE", 1636},
+{"RASH", 1637},
+{"RAT", 436},
+{"RATE", 1638},
+{"RAVE", 1639},
+{"RAW", 437},
+{"RAY", 438},
+{"RAYS", 1640},
+{"READ", 1641},
+{"REAL", 1642},
+{"REAM", 1643},
+{"REAR", 1644},
+{"REB", 439},
+{"RECK", 1645},
+{"RED", 440},
+{"REED", 1646},
+{"REEF", 1647},
+{"REEK", 1648},
+{"REEL", 1649},
+{"REID", 1650},
+{"REIN", 1651},
+{"RENA", 1652},
+{"REND", 1653},
+{"RENT", 1654},
+{"REP", 441},
+{"REST", 1655},
+{"RET", 442},
+{"RIB", 443},
+{"RICE", 1656},
+{"RICH", 1657},
+{"RICK", 1658},
+{"RID", 444},
+{"RIDE", 1659},
+{"RIFT", 1660},
+{"RIG", 445},
+{"RILL", 1661},
+{"RIM", 446},
+{"RIME", 1662},
+{"RING", 1663},
+{"RINK", 1664},
+{"RIO", 447},
+{"RIP", 448},
+{"RISE", 1665},
+{"RISK", 1666},
+{"RITE", 1667},
+{"ROAD", 1668},
+{"ROAM", 1669},
+{"ROAR", 1670},
+{"ROB", 449},
+{"ROBE", 1671},
+{"ROCK", 1672},
+{"ROD", 450},
+{"RODE", 1673},
+{"ROE", 451},
+{"ROIL", 1674},
+{"ROLL", 1675},
+{"ROME", 1676},
+{"RON", 452},
+{"ROOD", 1677},
+{"ROOF", 1678},
+{"ROOK", 1679},
+{"ROOM", 1680},
+{"ROOT", 1681},
+{"ROSA", 1682},
+{"ROSE", 1683},
+{"ROSS", 1684},
+{"ROSY", 1685},
+{"ROT", 453},
+{"ROTH", 1686},
+{"ROUT", 1687},
+{"ROVE", 1688},
+{"ROW", 454},
+{"ROWE", 1689},
+{"ROWS", 1690},
+{"ROY", 455},
+{"RUB", 456},
+{"RUBE", 1691},
+{"RUBY", 1692},
+{"RUDE", 1693},
+{"RUDY", 1694},
+{"RUE", 457},
+{"RUG", 458},
+{"RUIN", 1695},
+{"RULE", 1696},
+{"RUM", 459},
+{"RUN", 460},
+{"RUNG", 1697},
+{"RUNS", 1698},
+{"RUNT", 1699},
+{"RUSE", 1700},
+{"RUSH", 1701},
+{"RUSK", 1702},
+{"RUSS", 1703},
+{"RUST", 1704},
+{"RUTH", 1705},
+{"RYE", 461},
+{"SAC", 462},
+{"SACK", 1706},
+{"SAD", 463},
+{"SAFE", 1707},
+{"SAG", 464},
+{"SAGE", 1708},
+{"SAID", 1709},
+{"SAIL", 1710},
+{"SAL", 465},
+{"SALE", 1711},
+{"SALK", 1712},
+{"SALT", 1713},
+{"SAM", 466},
+{"SAME", 1714},
+{"SAN", 467},
+{"SAND", 1715},
+{"SANE", 1716},
+{"SANG", 1717},
+{"SANK", 1718},
+{"SAP", 468},
+{"SARA", 1719},
+{"SAT", 469},
+{"SAUL", 1720},
+{"SAVE", 1721},
+{"SAW", 470},
+{"SAY", 471},
+{"SAYS", 1722},
+{"SCAN", 1723},
+{"SCAR", 1724},
+{"SCAT", 1725},
+{"SCOT", 1726},
+{"SEA", 472},
+{"SEAL", 1727},
+{"SEAM", 1728},
+{"SEAR", 1729},
+{"SEAT", 1730},
+{"SEC", 473},
+{"SEE", 474},
+{"SEED", 1731},
+{"SEEK", 1732},
+{"SEEM", 1733},
+{"SEEN", 1734},
+{"SEES", 1735},
+{"SELF", 1736},
+{"SELL", 1737},
+{"SEN", 475},
+{"SEND", 1738},
+{"SENT", 1739},
+{"SET", 476},
+{"SETS", 1740},
+{"SEW", 477},
+{"SEWN", 1741},
+{"SHAG", 1742},
+{"SHAM", 1743},
+{"SHAW", 1744},
+{"SHAY", 1745},
+{"SHE", 478},
+{"SHED", 1746},
+{"SHIM", 1747},
+{"SHIN", 1748},
+{"SHOD", 1749},
+{"SHOE", 1750},
+{"SHOT", 1751},
+{"SHOW", 1752},
+{"SHUN", 1753},
+{"SHUT", 1754},
+{"SHY", 479},
+{"SICK", 1755},
+{"SIDE", 1756},
+{"SIFT", 1757},
+{"SIGH", 1758},
+{"SIGN", 1759},
+{"SILK", 1760},
+{"SILL", 1761},
+{"SILO", 1762},
+{"SILT", 1763},
+{"SIN", 480},
+{"SINE", 1764},
+{"SING", 1765},
+{"SINK", 1766},
+{"SIP", 481},
+{"SIR", 482},
+{"SIRE", 1767},
+{"SIS", 483},
+{"SIT", 484},
+{"SITE", 1768},
+{"SITS", 1769},
+{"SITU", 1770},
+{"SKAT", 1771},
+{"SKEW", 1772},
+{"SKI", 485},
+{"SKID", 1773},
+{"SKIM", 1774},
+{"SKIN", 1775},
+{"SKIT", 1776},
+{"SKY", 486},
+{"SLAB", 1777},
+{"SLAM", 1778},
+{"SLAT", 1779},
+{"SLAY", 1780},
+{"SLED", 1781},
+{"SLEW", 1782},
+{"SLID", 1783},
+{"SLIM", 1784},
+{"SLIT", 1785},
+{"SLOB", 1786},
+{"SLOG", 1787},
+{"SLOT", 1788},
+{"SLOW", 1789},
+{"SLUG", 1790},
+{"SLUM", 1791},
+{"SLUR", 1792},
+{"SLY", 487},
+{"SMOG", 1793},
+{"SMUG", 1794},
+{"SNAG", 1795},
+{"SNOB", 1796},
+{"SNOW", 1797},
+{"SNUB", 1798},
+{"SNUG", 1799},
+{"SO", 488},
+{"SOAK", 1800},
+{"SOAR", 1801},
+{"SOB", 489},
+{"SOCK", 1802},
+{"SOD", 490},
+{"SODA", 1803},
+{"SOFA", 1804},
+{"SOFT", 1805},
+{"SOIL", 1806},
+{"SOLD", 1807},
+{"SOME", 1808},
+{"SON", 491},
+{"SONG", 1809},
+{"SOON", 1810},
+{"SOOT", 1811},
+{"SOP", 492},
+{"SORE", 1812},
+{"SORT", 1813},
+{"SOUL", 1814},
+{"SOUR", 1815},
+{"SOW", 493},
+{"SOWN", 1816},
+{"SOY", 494},
+{"SPA", 495},
+{"SPY", 496},
+{"STAB", 1817},
+{"STAG", 1818},
+{"STAN", 1819},
+{"STAR", 1820},
+{"STAY", 1821},
+{"STEM", 1822},
+{"STEW", 1823},
+{"STIR", 1824},
+{"STOW", 1825},
+{"STUB", 1826},
+{"STUN", 1827},
+{"SUB", 497},
+{"SUCH", 1828},
+{"SUD", 498},
+{"SUDS", 1829},
+{"SUE", 499},
+{"SUIT", 1830},
+{"SULK", 1831},
+{"SUM", 500},
+{"SUMS", 1832},
+{"SUN", 501},
+{"SUNG", 1833},
+{"SUNK", 1834},
+{"SUP", 502},
+{"SURE", 1835},
+{"SURF", 1836},
+{"SWAB", 1837},
+{"SWAG", 1838},
+{"SWAM", 1839},
+{"SWAN", 1840},
+{"SWAT", 1841},
+{"SWAY", 1842},
+{"SWIM", 1843},
+{"SWUM", 1844},
+{"TAB", 503},
+{"TACK", 1845},
+{"TACT", 1846},
+{"TAD", 504},
+{"TAG", 505},
+{"TAIL", 1847},
+{"TAKE", 1848},
+{"TALE", 1849},
+{"TALK", 1850},
+{"TALL", 1851},
+{"TAN", 506},
+{"TANK", 1852},
+{"TAP", 507},
+{"TAR", 508},
+{"TASK", 1853},
+{"TATE", 1854},
+{"TAUT", 1855},
+{"TEA", 509},
+{"TEAL", 1856},
+{"TEAM", 1857},
+{"TEAR", 1858},
+{"TECH", 1859},
+{"TED", 510},
+{"TEE", 511},
+{"TEEM", 1860},
+{"TEEN", 1861},
+{"TEET", 1862},
+{"TELL", 1863},
+{"TEN", 512},
+{"TEND", 1864},
+{"TENT", 1865},
+{"TERM", 1866},
+{"TERN", 1867},
+{"TESS", 1868},
+{"TEST", 1869},
+{"THAN", 1870},
+{"THAT", 1871},
+{"THE", 513},
+{"THEE", 1872},
+{"THEM", 1873},
+{"THEN", 1874},
+{"THEY", 1875},
+{"THIN", 1876},
+{"THIS", 1877},
+{"THUD", 1878},
+{"THUG", 1879},
+{"THY", 514},
+{"TIC", 515},
+{"TICK", 1880},
+{"TIDE", 1881},
+{"TIDY", 1882},
+{"TIE", 516},
+{"TIED", 1883},
+{"TIER", 1884},
+{"TILE", 1885},
+{"TILL", 1886},
+{"TILT", 1887},
+{"TIM", 517},
+{"TIME", 1888},
+{"TIN", 518},
+{"TINA", 1889},
+{"TINE", 1890},
+{"TINT", 1891},
+{"TINY", 1892},
+{"TIP", 519},
+{"TIRE", 1893},
+{"TO", 520},
+{"TOAD", 1894},
+{"TOE", 521},
+{"TOG", 522},
+{"TOGO", 1895},
+{"TOIL", 1896},
+{"TOLD", 1897},
+{"TOLL", 1898},
+{"TOM", 523},
+{"TON", 524},
+{"TONE", 1899},
+{"TONG", 1900},
+{"TONY", 1901},
+{"TOO", 525},
+{"TOOK", 1902},
+{"TOOL", 1903},
+{"TOOT", 1904},
+{"TOP", 526},
+{"TORE", 1905},
+{"TORN", 1906},
+{"TOTE", 1907},
+{"TOUR", 1908},
+{"TOUT", 1909},
+{"TOW", 527},
+{"TOWN", 1910},
+{"TOY", 528},
+{"TRAG", 1911},
+{"TRAM", 1912},
+{"TRAY", 1913},
+{"TREE", 1914},
+{"TREK", 1915},
+{"TRIG", 1916},
+{"TRIM", 1917},
+{"TRIO", 1918},
+{"TROD", 1919},
+{"TROT", 1920},
+{"TROY", 1921},
+{"TRUE", 1922},
+{"TRY", 529},
+{"TUB", 530},
+{"TUBA", 1923},
+{"TUBE", 1924},
+{"TUCK", 1925},
+{"TUFT", 1926},
+{"TUG", 531},
+{"TUM", 532},
+{"TUN", 533},
+{"TUNA", 1927},
+{"TUNE", 1928},
+{"TUNG", 1929},
+{"TURF", 1930},
+{"TURN", 1931},
+{"TUSK", 1932},
+{"TWIG", 1933},
+{"TWIN", 1934},
+{"TWIT", 1935},
+{"TWO", 534},
+{"ULAN", 1936},
+{"UN", 535},
+{"UNIT", 1937},
+{"UP", 536},
+{"URGE", 1938},
+{"US", 537},
+{"USE", 538},
+{"USED", 1939},
+{"USER", 1940},
+{"USES", 1941},
+{"UTAH", 1942},
+{"VAIL", 1943},
+{"VAIN", 1944},
+{"VALE", 1945},
+{"VAN", 539},
+{"VARY", 1946},
+{"VASE", 1947},
+{"VAST", 1948},
+{"VAT", 540},
+{"VEAL", 1949},
+{"VEDA", 1950},
+{"VEIL", 1951},
+{"VEIN", 1952},
+{"VEND", 1953},
+{"VENT", 1954},
+{"VERB", 1955},
+{"VERY", 1956},
+{"VET", 541},
+{"VETO", 1957},
+{"VICE", 1958},
+{"VIE", 542},
+{"VIEW", 1959},
+{"VINE", 1960},
+{"VISE", 1961},
+{"VOID", 1962},
+{"VOLT", 1963},
+{"VOTE", 1964},
+{"WACK", 1965},
+{"WAD", 543},
+{"WADE", 1966},
+{"WAG", 544},
+{"WAGE", 1967},
+{"WAIL", 1968},
+{"WAIT", 1969},
+{"WAKE", 1970},
+{"WALE", 1971},
+{"WALK", 1972},
+{"WALL", 1973},
+{"WALT", 1974},
+{"WAND", 1975},
+{"WANE", 1976},
+{"WANG", 1977},
+{"WANT", 1978},
+{"WAR", 545},
+{"WARD", 1979},
+{"WARM", 1980},
+{"WARN", 1981},
+{"WART", 1982},
+{"WAS", 546},
+{"WASH", 1983},
+{"WAST", 1984},
+{"WATS", 1985},
+{"WATT", 1986},
+{"WAVE", 1987},
+{"WAVY", 1988},
+{"WAY", 547},
+{"WAYS", 1989},
+{"WE", 548},
+{"WEAK", 1990},
+{"WEAL", 1991},
+{"WEAN", 1992},
+{"WEAR", 1993},
+{"WEB", 549},
+{"WED", 550},
+{"WEE", 551},
+{"WEED", 1994},
+{"WEEK", 1995},
+{"WEIR", 1996},
+{"WELD", 1997},
+{"WELL", 1998},
+{"WELT", 1999},
+{"WENT", 2000},
+{"WERE", 2001},
+{"WERT", 2002},
+{"WEST", 2003},
+{"WET", 552},
+{"WHAM", 2004},
+{"WHAT", 2005},
+{"WHEE", 2006},
+{"WHEN", 2007},
+{"WHET", 2008},
+{"WHO", 553},
+{"WHOA", 2009},
+{"WHOM", 2010},
+{"WHY", 554},
+{"WICK", 2011},
+{"WIFE", 2012},
+{"WILD", 2013},
+{"WILL", 2014},
+{"WIN", 555},
+{"WIND", 2015},
+{"WINE", 2016},
+{"WING", 2017},
+{"WINK", 2018},
+{"WINO", 2019},
+{"WIRE", 2020},
+{"WISE", 2021},
+{"WISH", 2022},
+{"WIT", 556},
+{"WITH", 2023},
+{"WOK", 557},
+{"WOLF", 2024},
+{"WON", 558},
+{"WONT", 2025},
+{"WOO", 559},
+{"WOOD", 2026},
+{"WOOL", 2027},
+{"WORD", 2028},
+{"WORE", 2029},
+{"WORK", 2030},
+{"WORM", 2031},
+{"WORN", 2032},
+{"WOVE", 2033},
+{"WOW", 560},
+{"WRIT", 2034},
+{"WRY", 561},
+{"WU", 562},
+{"WYNN", 2035},
+{"YALE", 2036},
+{"YAM", 563},
+{"YANG", 2037},
+{"YANK", 2038},
+{"YAP", 564},
+{"YARD", 2039},
+{"YARN", 2040},
+{"YAW", 565},
+{"YAWL", 2041},
+{"YAWN", 2042},
+{"YE", 566},
+{"YEA", 567},
+{"YEAH", 2043},
+{"YEAR", 2044},
+{"YELL", 2045},
+{"YES", 568},
+{"YET", 569},
+{"YOGA", 2046},
+{"YOKE", 2047},
+{"YOU", 570}
+};
diff --git a/third_party/heimdal/lib/otp/otp_print.c b/third_party/heimdal/lib/otp/otp_print.c
new file mode 100644
index 0000000..372ddcf
--- /dev/null
+++ b/third_party/heimdal/lib/otp/otp_print.c
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute 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 THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+RCSID("$Id$");
+#endif
+
+#include "otp_locl.h"
+
+extern const char *const std_dict[];
+
+unsigned
+otp_checksum (OtpKey key)
+{
+ int i;
+ unsigned sum = 0;
+
+ for (i = 0; i < OTPKEYSIZE; ++i)
+ sum += ((key[i] >> 0) & 0x03)
+ + ((key[i] >> 2) & 0x03)
+ + ((key[i] >> 4) & 0x03)
+ + ((key[i] >> 6) & 0x03);
+ sum &= 0x03;
+ return sum;
+}
+
+void
+otp_print_stddict (OtpKey key, char *str, size_t sz)
+{
+ unsigned sum;
+
+ sum = otp_checksum (key);
+ snprintf (str, sz,
+ "%s %s %s %s %s %s",
+ std_dict[(key[0] << 3) | (key[1] >> 5)],
+ std_dict[((key[1] & 0x1F) << 6) | (key[2] >> 2)],
+ std_dict[((key[2] & 0x03) << 9) | (key[3] << 1) | (key[4] >> 7)],
+ std_dict[((key[4] & 0x7F) << 4) | (key[5] >> 4)],
+ std_dict[((key[5] & 0x0F) << 7) | (key[6] >> 1)],
+ std_dict[((key[6] & 0x01) << 10) | (key[7] << 2) | sum]);
+}
+
+void
+otp_print_hex (OtpKey key, char *str, size_t sz)
+{
+ snprintf (str, sz,
+ "%02x%02x%02x%02x%02x%02x%02x%02x",
+ key[0], key[1], key[2], key[3],
+ key[4], key[5], key[6], key[7]);
+}
+
+void
+otp_print_hex_extended (OtpKey key, char *str, size_t sz)
+{
+ strlcpy (str, OTP_HEXPREFIX, sz);
+ otp_print_hex (key,
+ str + strlen(OTP_HEXPREFIX),
+ sz - strlen(OTP_HEXPREFIX));
+}
+
+void
+otp_print_stddict_extended (OtpKey key, char *str, size_t sz)
+{
+ strlcpy (str, OTP_WORDPREFIX, sz);
+ otp_print_stddict (key,
+ str + strlen(OTP_WORDPREFIX),
+ sz - strlen(OTP_WORDPREFIX));
+}
diff --git a/third_party/heimdal/lib/otp/otp_verify.c b/third_party/heimdal/lib/otp/otp_verify.c
new file mode 100644
index 0000000..8a1c743
--- /dev/null
+++ b/third_party/heimdal/lib/otp/otp_verify.c
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 1995 - 2000 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute 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 THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+RCSID("$Id$");
+#endif
+
+#include "otp_locl.h"
+
+int
+otp_verify_user_1 (OtpContext *ctx, const char *passwd)
+{
+ OtpKey key1, key2;
+
+ if (otp_parse (key1, passwd, ctx->alg)) {
+ ctx->err = "Syntax error in reply";
+ return -1;
+ }
+ memcpy (key2, key1, sizeof(key1));
+ ctx->alg->next (key2);
+ if (memcmp (ctx->key, key2, sizeof(key2)) == 0) {
+ --ctx->n;
+ memcpy (ctx->key, key1, sizeof(key1));
+ return 0;
+ } else
+ return -1;
+}
+
+int
+otp_verify_user (OtpContext *ctx, const char *passwd)
+{
+ void *dbm;
+ int ret;
+
+ if (!ctx->challengep)
+ return -1;
+ ret = otp_verify_user_1 (ctx, passwd);
+ dbm = otp_db_open ();
+ if (dbm == NULL) {
+ free(ctx->user);
+ return -1;
+ }
+ otp_put (dbm, ctx);
+ free(ctx->user);
+ otp_db_close (dbm);
+ return ret;
+}
diff --git a/third_party/heimdal/lib/otp/otptest.c b/third_party/heimdal/lib/otp/otptest.c
new file mode 100644
index 0000000..dbf2131
--- /dev/null
+++ b/third_party/heimdal/lib/otp/otptest.c
@@ -0,0 +1,142 @@
+/*
+ * Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute 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 THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE 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 "config.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <otp.h>
+
+static int
+test_one(OtpKey key1, char *name, char *val,
+ void (*print)(OtpKey,char*, size_t),
+ OtpAlgorithm *alg)
+{
+ char buf[256];
+ OtpKey key2;
+
+ (*print)(key1, buf, sizeof(buf));
+ printf ("%s: %s, ", name, buf);
+ if (strcmp (buf, val) != 0) {
+ printf ("failed(*%s* != *%s*)\n", buf, val);
+ return 1;
+ }
+ if (otp_parse (key2, buf, alg)) {
+ printf ("parse of %s failed\n", name);
+ return 1;
+ }
+ if (memcmp (key1, key2, OTPKEYSIZE) != 0) {
+ printf ("key1 != key2, ");
+ }
+ printf ("success\n");
+ return 0;
+}
+
+static int
+test (void)
+{
+ struct test {
+ char *alg;
+ char *passphrase;
+ char *seed;
+ int count;
+ char *hex;
+ char *word;
+ } tests[] = {
+
+ /* md4 */
+ {"md4", "This is a test.", "TeSt", 0, "d1854218ebbb0b51", "ROME MUG FRED SCAN LIVE LACE"},
+ {"md4", "This is a test.", "TeSt", 1, "63473ef01cd0b444", "CARD SAD MINI RYE COL KIN"},
+ {"md4", "This is a test.", "TeSt", 99, "c5e612776e6c237a", "NOTE OUT IBIS SINK NAVE MODE"},
+ {"md4", "AbCdEfGhIjK", "alpha1", 0, "50076f47eb1ade4e", "AWAY SEN ROOK SALT LICE MAP"},
+ {"md4", "AbCdEfGhIjK", "alpha1", 1, "65d20d1949b5f7ab", "CHEW GRIM WU HANG BUCK SAID"},
+ {"md4", "AbCdEfGhIjK", "alpha1", 99, "d150c82cce6f62d1", "ROIL FREE COG HUNK WAIT COCA"},
+ {"md4", "OTP's are good", "correct", 0, "849c79d4f6f55388", "FOOL STEM DONE TOOL BECK NILE"},
+ {"md4", "OTP's are good", "correct", 1, "8c0992fb250847b1", "GIST AMOS MOOT AIDS FOOD SEEM"},
+ {"md4", "OTP's are good", "correct",99, "3f3bf4b4145fd74b", "TAG SLOW NOV MIN WOOL KENO"},
+
+
+ /* md5 */
+ {"md5", "This is a test.", "TeSt", 0, "9e876134d90499dd", "INCH SEA ANNE LONG AHEM TOUR"},
+ {"md5", "This is a test.", "TeSt", 1, "7965e05436f5029f", "EASE OIL FUM CURE AWRY AVIS"},
+ {"md5", "This is a test.", "TeSt", 99, "50fe1962c4965880", "BAIL TUFT BITS GANG CHEF THY"},
+ {"md5", "AbCdEfGhIjK", "alpha1", 0, "87066dd9644bf206", "FULL PEW DOWN ONCE MORT ARC"},
+ {"md5", "AbCdEfGhIjK", "alpha1", 1, "7cd34c1040add14b", "FACT HOOF AT FIST SITE KENT"},
+ {"md5", "AbCdEfGhIjK", "alpha1", 99, "5aa37a81f212146c", "BODE HOP JAKE STOW JUT RAP"},
+ {"md5", "OTP's are good", "correct", 0, "f205753943de4cf9", "ULAN NEW ARMY FUSE SUIT EYED"},
+ {"md5", "OTP's are good", "correct", 1, "ddcdac956f234937", "SKIM CULT LOB SLAM POE HOWL"},
+ {"md5", "OTP's are good", "correct",99, "b203e28fa525be47", "LONG IVY JULY AJAR BOND LEE"},
+
+ /* sha */
+ {"sha", "This is a test.", "TeSt", 0, "bb9e6ae1979d8ff4", "MILT VARY MAST OK SEES WENT"},
+ {"sha", "This is a test.", "TeSt", 1, "63d936639734385b", "CART OTTO HIVE ODE VAT NUT"},
+ {"sha", "This is a test.", "TeSt", 99, "87fec7768b73ccf9", "GAFF WAIT SKID GIG SKY EYED"},
+ {"sha", "AbCdEfGhIjK", "alpha1", 0, "ad85f658ebe383c9", "LEST OR HEEL SCOT ROB SUIT"},
+ {"sha", "AbCdEfGhIjK", "alpha1", 1, "d07ce229b5cf119b", "RITE TAKE GELD COST TUNE RECK"},
+ {"sha", "AbCdEfGhIjK", "alpha1", 99, "27bc71035aaf3dc6", "MAY STAR TIN LYON VEDA STAN"},
+ {"sha", "OTP's are good", "correct", 0, "d51f3e99bf8e6f0b", "RUST WELT KICK FELL TAIL FRAU"},
+ {"sha", "OTP's are good", "correct", 1, "82aeb52d943774e4", "FLIT DOSE ALSO MEW DRUM DEFY"},
+ {"sha", "OTP's are good", "correct", 99, "4f296a74fe1567ec", "AURA ALOE HURL WING BERG WAIT"},
+ {NULL, NULL, NULL, 0, NULL, NULL}
+ };
+
+ struct test *t;
+ int sum = 0;
+
+ for(t = tests; t->alg; ++t) {
+ int i;
+ OtpAlgorithm *alg = otp_find_alg (t->alg);
+ OtpKey key;
+
+ if (alg == NULL) {
+ printf ("Could not find alg %s\n", t->alg);
+ return 1;
+ }
+ if(alg->init (key, t->passphrase, t->seed))
+ return 1;
+ for (i = 0; i < t->count; ++i) {
+ if (alg->next (key))
+ return 1;
+ }
+ sum += test_one (key, "hexadecimal", t->hex, otp_print_hex,
+ alg) +
+ test_one (key, "standard_word", t->word, otp_print_stddict, alg);
+ }
+ return sum;
+}
+
+int
+main (void)
+{
+ return test ();
+}
diff --git a/third_party/heimdal/lib/otp/roken_rename.h b/third_party/heimdal/lib/otp/roken_rename.h
new file mode 100644
index 0000000..07c3249
--- /dev/null
+++ b/third_party/heimdal/lib/otp/roken_rename.h
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 1998 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute 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 THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE 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.
+ */
+
+/* $Id$ */
+
+#ifndef __roken_rename_h__
+#define __roken_rename_h__
+
+#ifndef HAVE_SNPRINTF
+#define rk_snprintf _otp_snprintf
+#endif
+#ifndef HAVE_ASPRINTF
+#define rk_asprintf _otp_asprintf
+#endif
+#ifndef HAVE_ASNPRINTF
+#define rk_asnprintf _otp_asnprintf
+#endif
+#ifndef HAVE_VASPRINTF
+#define rk_vasprintf _otp_vasprintf
+#endif
+#ifndef HAVE_VASNPRINTF
+#define rk_vasnprintf _otp_vasnprintf
+#endif
+#ifndef HAVE_VSNPRINTF
+#define rk_vsnprintf _otp_vsnprintf
+#endif
+#ifndef HAVE_STRCASECMP
+#define rk_strcasecmp _otp_strcasecmp
+#endif
+#ifndef HAVE_STRNCASECMP
+#define rk_strncasecmp _otp_strncasecmp
+#endif
+#ifndef HAVE_STRLWR
+#define rk_strlwr _otp_strlwr
+#endif
+#ifndef HAVE_STRLCAT
+#define rk_strlcat _otp_strlcat
+#endif
+#ifndef HAVE_STRLCPY
+#define rk_strlcpy _otp_strlcpy
+#endif
+
+#endif /* __roken_rename_h__ */
diff --git a/third_party/heimdal/lib/otp/version-script.map b/third_party/heimdal/lib/otp/version-script.map
new file mode 100644
index 0000000..499943f
--- /dev/null
+++ b/third_party/heimdal/lib/otp/version-script.map
@@ -0,0 +1,25 @@
+HEIMDAL_OTP_1.0 {
+ global:
+ otp_challenge;
+ otp_checksum;
+ otp_db_close;
+ otp_db_open;
+ otp_delete;
+ otp_error;
+ otp_find_alg;
+ otp_get;
+ otp_parse;
+ otp_parse_altdict;
+ otp_parse_hex;
+ otp_parse_stddict;
+ otp_print_hex;
+ otp_print_hex_extended;
+ otp_print_stddict;
+ otp_print_stddict_extended;
+ otp_put;
+ otp_simple_get;
+ otp_verify_user;
+ otp_verify_user_1;
+ local:
+ *;
+};