libxcrypt/libxcrypt-4.0.1_to_develop.patch
Björn Esser 1412649890
Add patch to update to recent development branch
Re-enable SUNMD5 support as it is BSD licensed now
Build compatibility symbols for glibc only
2018-07-13 12:23:28 +02:00

12688 lines
563 KiB
Diff

From 0bf9b35bb04b9f35a43e2ff6493d6a5ecc3c9db1 Mon Sep 17 00:00:00 2001
From: Thorsten Kukuk <kukuk@thkukuk.de>
Date: Tue, 22 May 2018 11:42:07 +0200
Subject: [PATCH 01/38] Fix spelling of SUSE
---
Makefile.am | 4 ++--
README.md | 2 +-
libcrypt.map.in | 2 +-
3 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/Makefile.am b/Makefile.am
index a7e726f..90fe733 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -71,7 +71,7 @@ crypt.h: crypt-base.h gen-crypt-h.awk config.h
$(AM_V_at)mv -f crypt.h.T crypt.h
# When we are being binary compatible, also install symbolic links to
-# mimic SuSE's libowcrypt; any program that uses -lowcrypt in its
+# mimic SUSE's libowcrypt; any program that uses -lowcrypt in its
# build, or already has a NEEDED entry for libowcrypt.so.1, will be
# redirected to libcrypt. The OW_CRYPT_1.0 symbol versions are already
# present in libcrypt.so.1.
@@ -80,7 +80,7 @@ crypt.h: crypt-base.h gen-crypt-h.awk config.h
# libraries involved, libcrypt.so.1 and libowcrypt.so.1. (We should
# be able to get away with this because in any circumstance where the
# soname of libcrypt isn't libcrypt.so.1, ENABLE_OBSOLETE_API should
-# be automatically turned off, and as best I can tell, SuSE only ever
+# be automatically turned off, and as best I can tell, SUSE only ever
# shipped libowcrypt.so.1.)
if ENABLE_OBSOLETE_API
if ENABLE_STATIC
diff --git a/README.md b/README.md
index 05319f3..869d46f 100644
--- a/README.md
+++ b/README.md
@@ -75,7 +75,7 @@ libcrypt.so.1. We have taken pains to provide exactly the same
"symbol versions" as were used by glibc on various CPU architectures,
and to account for the variety of ways in which the Openwall
extensions were patched into glibc's libcrypt by some Linux
-distributions. (For instance, compatibility symlinks for SuSE's
+distributions. (For instance, compatibility symlinks for SUSE's
"libowcrypt" are provided.)
However, the converse is not true: programs linked against libxcrypt
diff --git a/libcrypt.map.in b/libcrypt.map.in
index 2de7d1b..18aac79 100644
--- a/libcrypt.map.in
+++ b/libcrypt.map.in
@@ -7,7 +7,7 @@ crypt XCRYPT_2.0 GLIBC_2.0
crypt_r XCRYPT_2.0 GLIBC_2.0
# Actively supported Openwall extensions; never actually added to
-# upstream GNU libc, but present in at least Openwall, ALT, and SuSE
+# upstream GNU libc, but present in at least Openwall, ALT, and SUSE
# Linux distributions with one or more of these symbol versions
crypt_rn XCRYPT_2.0 GLIBC_2.0 GLIBC_2.2.1
crypt_gensalt XCRYPT_2.0 GLIBC_2.0 GLIBC_2.2.1 OW_CRYPT_1.0
From 089d679b81a3c4e821f5f9cfaacb33e67370eeed Mon Sep 17 00:00:00 2001
From: "Dmitry V. Levin" <ldv@altlinux.org>
Date: Fri, 22 Jun 2018 00:07:54 +0000
Subject: [PATCH 02/38] Lower the minimum required automake version
The minimum required automake version was raised from 1.7 to 1.15 by
commit a6c11d6cd89ac391dfb81bc2b7eb2b9fb31d7da6. This new requirement
seems to be unnecessarily high, at least, the project builds using
automake 1.14 just fine.
---
Makefile.am | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Makefile.am b/Makefile.am
index 90fe733..491dfae 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -4,7 +4,7 @@
# Author: Thorsten Kukuk <kukuk@suse.de>
#
-AUTOMAKE_OPTIONS = 1.15 gnits
+AUTOMAKE_OPTIONS = 1.14 gnits
ACLOCAL_AMFLAGS = -I m4
AM_CFLAGS = $(WARN_CFLAGS)
From fab17cc338b3e18cb74ebed8da3a876e485e3c95 Mon Sep 17 00:00:00 2001
From: "Dmitry V. Levin" <ldv@altlinux.org>
Date: Fri, 22 Jun 2018 00:07:54 +0000
Subject: [PATCH 03/38] gen-vers.awk: fix typo in comment
---
gen-vers.awk | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/gen-vers.awk b/gen-vers.awk
index 602195a..4870d05 100644
--- a/gen-vers.awk
+++ b/gen-vers.awk
@@ -15,7 +15,7 @@
# the macros generated by this program.
#
# Note: if you change the format of .map.in files you probably need to
-# update gen-vers.awk too.
+# update gen-map.awk too.
#
# Note: we currently don't support compatibility symbols that need
# a different definition from the default version.
From b1d83b002039a561233ce55986d9205e76138a14 Mon Sep 17 00:00:00 2001
From: "Dmitry V. Levin" <ldv@altlinux.org>
Date: Wed, 27 Jun 2018 14:58:49 +0000
Subject: [PATCH 04/38] Fix build with USE_SWAPCONTEXT turned off
Due to regression introduced by commit v4.0.0~100, the project no longer
builds when USE_SWAPCONTEXT is not available or explicitly turned off.
This is not a very big deal as this build mode seems to be not very
popular, but fix it anyway.
---
crypt.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/crypt.c b/crypt.c
index d7f0ffc..2aa9491 100644
--- a/crypt.c
+++ b/crypt.c
@@ -288,7 +288,7 @@ do_crypt (const char *phrase, const char *setting, struct crypt_data *data)
swapcontext (&outer_ctx, &cint->inner_ctx);
}
#else
- cfn (phrase, setting,
+ h->crypt (phrase, setting,
(unsigned char *)data->output, sizeof data->output,
cint->alg_specific, sizeof cint->alg_specific);
#endif
From 942d51bbe41f6f84138916c2b180b5b669d65b27 Mon Sep 17 00:00:00 2001
From: "Dmitry V. Levin" <ldv@altlinux.org>
Date: Fri, 29 Jun 2018 11:07:48 +0000
Subject: [PATCH 05/38] Include crypt-port.h in two remaining source files
crypt-port.h must be the first header file included by each source file,
this guarantees that config.h is included before any system header.
---
test-crypt-badsalt.c | 1 +
test-crypt-nonnull.c | 1 +
2 files changed, 2 insertions(+)
diff --git a/test-crypt-badsalt.c b/test-crypt-badsalt.c
index 1e1e840..c46848d 100644
--- a/test-crypt-badsalt.c
+++ b/test-crypt-badsalt.c
@@ -16,6 +16,7 @@
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
+#include "crypt-port.h"
#include <stdio.h>
#include <string.h>
#include <unistd.h>
diff --git a/test-crypt-nonnull.c b/test-crypt-nonnull.c
index 27313f0..5e4f118 100644
--- a/test-crypt-nonnull.c
+++ b/test-crypt-nonnull.c
@@ -16,6 +16,7 @@
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
+#include "crypt-port.h"
#include <stdio.h>
#include <string.h>
#include <unistd.h>
From e9b661ffd4d58788f61c46ad1e8e29380b43f464 Mon Sep 17 00:00:00 2001
From: "Dmitry V. Levin" <ldv@altlinux.org>
Date: Fri, 29 Jun 2018 11:07:48 +0000
Subject: [PATCH 06/38] Use ARRAY_SIZE instead of open-coding it in every use
case
Introduce ARRAY_SIZE macro, use it in all cases like
sizeof (tests) / sizeof (tests[0])
The definition of ARRAY_SIZE is the simplest one, a guard that
its argument is an array can be added later if necessary.
---
crypt-port.h | 3 +++
test-alg-md4.c | 2 +-
test-alg-md5.c | 2 +-
test-alg-sha256.c | 2 +-
test-alg-sha512.c | 2 +-
test-byteorder.c | 8 ++++----
test-crypt-badsalt.c | 2 +-
test-crypt-des.c | 2 +-
test-crypt-nonnull.c | 2 +-
test-crypt-nthash.c | 2 +-
test-crypt-pbkdf1-sha1.c | 2 +-
test-crypt-sha256.c | 2 +-
test-crypt-sha512.c | 2 +-
test-crypt-sunmd5.c | 2 +-
test-des-cases.h | 2 +-
test-gensalt.c | 2 +-
16 files changed, 21 insertions(+), 18 deletions(-)
diff --git a/crypt-port.h b/crypt-port.h
index 2b74ec9..99717f3 100644
--- a/crypt-port.h
+++ b/crypt-port.h
@@ -87,6 +87,9 @@ typedef union
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
#define MAX(a, b) (((a) > (b)) ? (a) : (b))
+/* ARRAY_SIZE is used in tests. */
+#define ARRAY_SIZE(a_) (sizeof (a_) / sizeof ((a_)[0]))
+
/* Provide a guaranteed way to erase sensitive memory at the best we
can, given the possibilities of the system. */
#if defined HAVE_MEMSET_S
diff --git a/test-alg-md4.c b/test-alg-md4.c
index 3476c35..ab6ad87 100644
--- a/test-alg-md4.c
+++ b/test-alg-md4.c
@@ -73,7 +73,7 @@ main (void)
int cnt;
int i;
- for (cnt = 0; cnt < (int) (sizeof (tests) / sizeof (tests[0])); ++cnt)
+ for (cnt = 0; cnt < (int) ARRAY_SIZE (tests); ++cnt)
{
md4_init_ctx (&ctx);
md4_process_bytes ((const unsigned char*)tests[cnt].input, &ctx, strlen (tests[cnt].input));
diff --git a/test-alg-md5.c b/test-alg-md5.c
index 8bde121..9908ab8 100644
--- a/test-alg-md5.c
+++ b/test-alg-md5.c
@@ -80,7 +80,7 @@ main (void)
int cnt;
int i;
- for (cnt = 0; cnt < (int) (sizeof (tests) / sizeof (tests[0])); ++cnt)
+ for (cnt = 0; cnt < (int) ARRAY_SIZE (tests); ++cnt)
{
md5_init_ctx (&ctx);
md5_process_bytes (tests[cnt].input, strlen (tests[cnt].input), &ctx);
diff --git a/test-alg-sha256.c b/test-alg-sha256.c
index 86b1e8c..45345e2 100644
--- a/test-alg-sha256.c
+++ b/test-alg-sha256.c
@@ -88,7 +88,7 @@ main (void)
int cnt;
int i;
- for (cnt = 0; cnt < (int) (sizeof (tests) / sizeof (tests[0])); ++cnt)
+ for (cnt = 0; cnt < (int) ARRAY_SIZE (tests); ++cnt)
{
sha256_init_ctx (&ctx);
sha256_process_bytes (tests[cnt].input, strlen (tests[cnt].input),
diff --git a/test-alg-sha512.c b/test-alg-sha512.c
index d6eae93..0e24ad5 100644
--- a/test-alg-sha512.c
+++ b/test-alg-sha512.c
@@ -116,7 +116,7 @@ main (void)
int cnt;
int i;
- for (cnt = 0; cnt < (int) (sizeof (tests) / sizeof (tests[0])); ++cnt)
+ for (cnt = 0; cnt < (int) ARRAY_SIZE (tests); ++cnt)
{
sha512_init_ctx (&ctx);
sha512_process_bytes (tests[cnt].input, strlen (tests[cnt].input),
diff --git a/test-byteorder.c b/test-byteorder.c
index 58bc9a7..7be0895 100644
--- a/test-byteorder.c
+++ b/test-byteorder.c
@@ -46,7 +46,7 @@ test_le32 (void)
{ 0x000000FF, "\xFF\x00\x00\x00" },
{ 0x01234567, "\x67\x45\x23\x01" },
};
- size_t n_cases = sizeof cases / sizeof cases[0];
+ size_t n_cases = ARRAY_SIZE (cases);
size_t i;
uint32_t v;
unsigned char x[4];
@@ -93,7 +93,7 @@ test_be32 (void)
{ 0x000000FF, "\x00\x00\x00\xFF" },
{ 0x01234567, "\x01\x23\x45\x67" },
};
- size_t n_cases = sizeof cases / sizeof cases[0];
+ size_t n_cases = ARRAY_SIZE (cases);
size_t i;
uint32_t v;
unsigned char x[4];
@@ -144,7 +144,7 @@ test_le64 (void)
{ 0xFF00000000000000ull, "\x00\x00\x00\x00\x00\x00\x00\xFF" },
{ 0x0123456789ABCDEFull, "\xEF\xCD\xAB\x89\x67\x45\x23\x01" },
};
- size_t n_cases = sizeof cases / sizeof cases[0];
+ size_t n_cases = ARRAY_SIZE (cases);
size_t i;
uint64_t v;
unsigned char x[8];
@@ -201,7 +201,7 @@ test_be64 (void)
{ 0xFF00000000000000ull, "\xFF\x00\x00\x00\x00\x00\x00\x00" },
{ 0x0123456789ABCDEFull, "\x01\x23\x45\x67\x89\xAB\xCD\xEF" },
};
- size_t n_cases = sizeof cases / sizeof cases[0];
+ size_t n_cases = ARRAY_SIZE (cases);
size_t i;
uint64_t v;
unsigned char x[8];
diff --git a/test-crypt-badsalt.c b/test-crypt-badsalt.c
index c46848d..a5e0e01 100644
--- a/test-crypt-badsalt.c
+++ b/test-crypt-badsalt.c
@@ -45,7 +45,7 @@ main (void)
int result = 0;
struct crypt_data cd;
struct crypt_data *cdptr = &cd;
- size_t n = sizeof (tests) / sizeof (*tests);
+ size_t n = ARRAY_SIZE (tests);
size_t pagesize = (size_t) sysconf (_SC_PAGESIZE);
char *page, *retval;
const char *saltstr, *special = "%";
diff --git a/test-crypt-des.c b/test-crypt-des.c
index d2266e4..dbe44e0 100644
--- a/test-crypt-des.c
+++ b/test-crypt-des.c
@@ -65,7 +65,7 @@ static const struct
},
};
-#define ntests (sizeof (tests) / sizeof (tests[0]))
+#define ntests ARRAY_SIZE (tests)
int
main (void)
diff --git a/test-crypt-nonnull.c b/test-crypt-nonnull.c
index 5e4f118..e4738ff 100644
--- a/test-crypt-nonnull.c
+++ b/test-crypt-nonnull.c
@@ -44,7 +44,7 @@ main (void)
int result = 0;
struct crypt_data cd;
struct crypt_data *cdptr = &cd;
- size_t n = sizeof (tests) / sizeof (*tests);
+ size_t n = ARRAY_SIZE (tests);
size_t pagesize = (size_t) sysconf (_SC_PAGESIZE);
char *page;
const char *saltstr, *special = "%";
diff --git a/test-crypt-nthash.c b/test-crypt-nthash.c
index dc1f320..6f897fe 100644
--- a/test-crypt-nthash.c
+++ b/test-crypt-nthash.c
@@ -120,7 +120,7 @@ static const struct
}
};
-#define ntests (sizeof (tests) / sizeof (tests[0]))
+#define ntests ARRAY_SIZE (tests)
int
main (void)
diff --git a/test-crypt-pbkdf1-sha1.c b/test-crypt-pbkdf1-sha1.c
index c86abd4..aadc0fe 100644
--- a/test-crypt-pbkdf1-sha1.c
+++ b/test-crypt-pbkdf1-sha1.c
@@ -58,7 +58,7 @@ const char *tests[][2] =
},
};
-#define ntests (sizeof (tests) / sizeof (tests[0]))
+#define ntests ARRAY_SIZE (tests)
int
main (void)
diff --git a/test-crypt-sha256.c b/test-crypt-sha256.c
index c742aae..23da81c 100644
--- a/test-crypt-sha256.c
+++ b/test-crypt-sha256.c
@@ -48,7 +48,7 @@ static const struct
},
};
-#define ntests (sizeof (tests) / sizeof (tests[0]))
+#define ntests ARRAY_SIZE (tests)
diff --git a/test-crypt-sha512.c b/test-crypt-sha512.c
index a18cea8..1aa0b71 100644
--- a/test-crypt-sha512.c
+++ b/test-crypt-sha512.c
@@ -49,7 +49,7 @@ static const struct
"hLsPuWGsUSklZt58jaTfF4ZEQpyUNGc0dqbpBYYBaHHrsX."
},
};
-#define ntests (sizeof (tests) / sizeof (tests[0]))
+#define ntests ARRAY_SIZE (tests)
int
diff --git a/test-crypt-sunmd5.c b/test-crypt-sunmd5.c
index d4fc0dc..d67781b 100644
--- a/test-crypt-sunmd5.c
+++ b/test-crypt-sunmd5.c
@@ -88,7 +88,7 @@ const char *tests[][3] =
},
};
-#define ntests (sizeof (tests) / sizeof (tests[0]))
+#define ntests ARRAY_SIZE (tests)
int
main (void)
diff --git a/test-des-cases.h b/test-des-cases.h
index 03ca837..8354df7 100644
--- a/test-des-cases.h
+++ b/test-des-cases.h
@@ -191,6 +191,6 @@ static const struct des_testcase des_testcases[] =
{ "\x01\x83\x10\xdc\x40\x9b\x26\xd6", "\x1d\x9d\x5c\x50\x18\xf7\x28\xc2", "\x5f\x4c\x03\x8e\xd1\x2b\x2e\x41" },
{ "\x1c\x58\x7f\x1c\x13\x92\x4f\xef", "\x30\x55\x32\x28\x6d\x6f\x29\x5a", "\x63\xfa\xc0\xd0\x34\xd9\xf7\x93" },
};
-static const size_t N_DES_TESTCASES = sizeof des_testcases / sizeof des_testcases[0];
+static const size_t N_DES_TESTCASES = ARRAY_SIZE (des_testcases);
#endif /* test-des-cases.h */
diff --git a/test-gensalt.c b/test-gensalt.c
index dfe194c..4b3a0e1 100644
--- a/test-gensalt.c
+++ b/test-gensalt.c
@@ -51,7 +51,7 @@ main (void)
for (tcase = testcases; tcase->prefix; tcase++)
{
XCRYPT_SECURE_MEMSET (prev_output, CRYPT_GENSALT_OUTPUT_SIZE);
- for (ent = 0; ent < (sizeof entropy / sizeof entropy[0]); ent++)
+ for (ent = 0; ent < ARRAY_SIZE (entropy); ent++)
{
XCRYPT_SECURE_MEMSET (output, CRYPT_GENSALT_OUTPUT_SIZE);
char *salt = crypt_gensalt_rn (tcase->prefix, 0,
From 10483284a8fbefde59e71700089a28e3f18cbe5b Mon Sep 17 00:00:00 2001
From: "Dmitry V. Levin" <ldv@altlinux.org>
Date: Fri, 22 Jun 2018 00:07:54 +0000
Subject: [PATCH 07/38] Extend --enable-weak-hashes configure option
Extend --enable-weak-hashes configure option to accept optional "glibc"
parameter. When specified, it enables only those of weak hashes that
are supported by historic versions of the GNU libc.
Closes: https://github.com/besser82/libxcrypt/issues/7
---
Makefile.am | 20 ++++++++++++++------
configure.ac | 29 ++++++++++++++++++++++-------
crypt-des.c | 9 ++++++++-
crypt-port.h | 4 ++++
crypt-private.h | 20 ++++++++++++++------
crypt.c | 15 +++++++++++++++
test-crypt-des.c | 2 ++
test-gensalt.c | 4 +++-
8 files changed, 82 insertions(+), 21 deletions(-)
diff --git a/Makefile.am b/Makefile.am
index 491dfae..c219bac 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -114,9 +114,13 @@ check_PROGRAMS = \
if ENABLE_WEAK_HASHES
libcrypt_la_SOURCES += \
- crypt-md5.c crypt-des.c crypt-nthash.c crypt-pbkdf1-sha1.c \
- crypt-sunmd5.c \
- alg-des.c alg-hmac-sha1.c alg-md4.c alg-md5.c alg-sha1.c
+ crypt-des.c crypt-md5.c alg-des.c alg-md5.c
+
+if ENABLE_WEAK_NON_GLIBC_HASHES
+libcrypt_la_SOURCES += \
+ crypt-nthash.c crypt-pbkdf1-sha1.c crypt-sunmd5.c \
+ alg-hmac-sha1.c alg-md4.c alg-sha1.c
+endif
nodist_libcrypt_la_SOURCES = \
alg-des-tables.c
@@ -143,11 +147,15 @@ alg-des-tables.c: gen-des-tables
$(AM_V_at)mv -f alg-des-tables.c.T alg-des-tables.c
check_PROGRAMS += \
- test-alg-des test-alg-hmac-sha1 test-alg-md4 \
- test-alg-md5 test-alg-sha1 \
- test-crypt-badsalt test-crypt-des test-crypt-md5 \
+ test-alg-des test-alg-md5 test-crypt-des test-crypt-md5 \
+ test-crypt-badsalt
+
+if ENABLE_WEAK_NON_GLIBC_HASHES
+check_PROGRAMS += \
+ test-alg-hmac-sha1 test-alg-md4 test-alg-sha1 \
test-crypt-nthash test-crypt-sunmd5 test-crypt-pbkdf1-sha1
endif
+endif
if ENABLE_OBSOLETE_API
libcrypt_la_SOURCES += crypt-des-obsolete.c
diff --git a/configure.ac b/configure.ac
index 9bc41d1..9846e3f 100644
--- a/configure.ac
+++ b/configure.ac
@@ -204,17 +204,28 @@ AC_ARG_ENABLE([obsolete-api],
AC_ARG_ENABLE([weak-hashes],
AS_HELP_STRING(
- [--disable-weak-hashes],
- [do not include any support for weak hashes (DES, MD5).
- Implies --disable-obsolete-api, and breaks binary compatibility
- with glibc's libcrypt.]
+ [--enable-weak-hashes[=ARG]],
+ [When set to "yes", all of the hashing methods documented in crypt(5)
+ are supported for authenticating existing password hashes, including
+ several that are too weak to use for new passwords.
+
+ When set to "glibc", only the weak hashes supported by historic
+ versions of GNU libc are supported: traditional DES and FreeBSD-style
+ MD5, but not bigcrypt-DES, BSDi extended DES, SHA1, SUNMD5, or NTHASH.
+
+ When set to "no", only bcrypt, SHA512, and SHA256 are supported.
+ This mode implies --disable-obsolete-api and breaks binary
+ compatibility with glibc's libcrypt.
+
+ [default=yes]]
),
[case "${enableval}" in
- yes) enable_weak_hashes=1 ;;
- no) enable_weak_hashes=0 ;;
+ yes) enable_weak_hashes=1; enable_weak_non_glibc_hashes=1 ;;
+ glibc) enable_weak_hashes=1; enable_weak_non_glibc_hashes=0 ;;
+ no) enable_weak_hashes=0; enable_weak_non_glibc_hashes=0 ;;
*) AC_MSG_ERROR([bad value ${enableval} for --enable-weak-hashes]) ;;
esac],
- [enable_weak_hashes=1]
+ [enable_weak_hashes=1; enable_weak_non_glibc_hashes=1]
)
# If weak hashes are disabled, then the obsolete APIs won't work anyway
@@ -293,6 +304,10 @@ AC_DEFINE_UNQUOTED([ENABLE_WEAK_HASHES], [$enable_weak_hashes],
If this is 0, ENABLE_OBSOLETE_API must also be 0.])
AM_CONDITIONAL([ENABLE_WEAK_HASHES], [test $enable_weak_hashes = 1])
+AC_DEFINE_UNQUOTED([ENABLE_WEAK_NON_GLIBC_HASHES], [$enable_weak_non_glibc_hashes],
+ [Define as 1 if weak hashes not supported by glibc should be included, 0 otherwise.])
+AM_CONDITIONAL([ENABLE_WEAK_NON_GLIBC_HASHES], [test $enable_weak_non_glibc_hashes = 1])
+
# The Makefile needs to know which versions of the library we are building.
AM_CONDITIONAL([ENABLE_STATIC], [test $enable_static = yes])
AM_CONDITIONAL([ENABLE_SHARED], [test $enable_shared = yes])
diff --git a/crypt-des.c b/crypt-des.c
index 467be8d..79b3144 100644
--- a/crypt-des.c
+++ b/crypt-des.c
@@ -144,7 +144,10 @@ des_gen_hash (struct des_ctx *ctx, uint32_t count, uint8_t *output,
}
/* The original UNIX DES-based password hash, no extensions. */
-static void
+#if ENABLE_WEAK_NON_GLIBC_HASHES
+static
+#endif
+void
crypt_des_trd_rn (const char *phrase, const char *setting,
uint8_t *output, size_t o_size,
void *scratch, size_t s_size)
@@ -192,6 +195,7 @@ crypt_des_trd_rn (const char *phrase, const char *setting,
des_gen_hash (ctx, 25, cp, pkbuf);
}
+#if ENABLE_WEAK_NON_GLIBC_HASHES
/* This algorithm is algorithm 0 (default) shipped with the C2 secure
implementation of Digital UNIX.
@@ -342,6 +346,7 @@ crypt_des_xbsd_rn (const char *phrase, const char *setting,
des_set_salt (ctx, salt);
des_gen_hash (ctx, count, cp, pkbuf);
}
+#endif /* ENABLE_WEAK_NON_GLIBC_HASHES */
void
gensalt_des_trd_rn (unsigned long count,
@@ -365,6 +370,7 @@ gensalt_des_trd_rn (unsigned long count,
output[2] = '\0';
}
+#if ENABLE_WEAK_NON_GLIBC_HASHES
void
gensalt_des_xbsd_rn (unsigned long count,
const uint8_t *rbytes, size_t nrbytes,
@@ -406,3 +412,4 @@ gensalt_des_xbsd_rn (unsigned long count,
output[9] = '\0';
}
+#endif /* ENABLE_WEAK_NON_GLIBC_HASHES */
diff --git a/crypt-port.h b/crypt-port.h
index 99717f3..8b21f56 100644
--- a/crypt-port.h
+++ b/crypt-port.h
@@ -217,7 +217,11 @@ void _xcrypt_secure_memset (void *s, size_t len)
#if ENABLE_WEAK_HASHES
#define comp_maskl _crypt_comp_maskl
#define comp_maskr _crypt_comp_maskr
+#if ENABLE_WEAK_NON_GLIBC_HASHES
#define crypt_des_trd_or_big_rn _crypt_crypt_des_trd_or_big_rn
+#else
+#define crypt_des_trd_rn _crypt_crypt_des_trd_rn
+#endif
#define crypt_des_xbsd_rn _crypt_crypt_des_xbsd_rn
#define crypt_md5_rn _crypt_crypt_md5_rn
#define crypt_nthash_rn _crypt_crypt_nthash_rn
diff --git a/crypt-private.h b/crypt-private.h
index 80a916d..c5db3bd 100644
--- a/crypt-private.h
+++ b/crypt-private.h
@@ -39,15 +39,16 @@ extern void gensalt_sha_rn (char tag, size_t maxsalt, unsigned long defcount,
/* Individual hash functions */
#if ENABLE_WEAK_HASHES
+extern void crypt_md5_rn (const char *phrase, const char *setting,
+ uint8_t *output, size_t o_size,
+ void *scratch, size_t s_size);
+#if ENABLE_WEAK_NON_GLIBC_HASHES
extern void crypt_des_trd_or_big_rn (const char *phrase, const char *setting,
uint8_t *output, size_t o_size,
void *scratch, size_t s_size);
extern void crypt_des_xbsd_rn (const char *phrase, const char *setting,
uint8_t *output, size_t o_size,
void *scratch, size_t s_size);
-extern void crypt_md5_rn (const char *phrase, const char *setting,
- uint8_t *output, size_t o_size,
- void *scratch, size_t s_size);
extern void crypt_nthash_rn (const char *phrase, const char *setting,
uint8_t *output, size_t o_size,
void *scratch, size_t s_size);
@@ -57,6 +58,11 @@ extern void crypt_sha1_rn (const char *phrase, const char *setting,
extern void crypt_sunmd5_rn (const char *phrase, const char *setting,
uint8_t *output, size_t o_size,
void *scratch, size_t s_size);
+#else
+extern void crypt_des_trd_rn (const char *phrase, const char *setting,
+ uint8_t *output, size_t o_size,
+ void *scratch, size_t s_size);
+#endif
#endif
extern void crypt_sha256_rn (const char *phrase, const char *setting,
@@ -73,12 +79,13 @@ extern void crypt_bcrypt_rn (const char *phrase, const char *setting,
extern void gensalt_des_trd_rn (unsigned long count,
const uint8_t *rbytes, size_t nrbytes,
uint8_t *output, size_t o_size);
-extern void gensalt_des_xbsd_rn (unsigned long count,
- const uint8_t *rbytes, size_t nrbytes,
- uint8_t *output, size_t o_size);
extern void gensalt_md5_rn (unsigned long count,
const uint8_t *rbytes, size_t nrbytes,
uint8_t *output, size_t o_size);
+#if ENABLE_WEAK_NON_GLIBC_HASHES
+extern void gensalt_des_xbsd_rn (unsigned long count,
+ const uint8_t *rbytes, size_t nrbytes,
+ uint8_t *output, size_t o_size);
extern void gensalt_nthash_rn (unsigned long count,
const uint8_t *rbytes, size_t nrbytes,
uint8_t *output, size_t o_size);
@@ -89,6 +96,7 @@ extern void gensalt_sunmd5_rn (unsigned long count,
const uint8_t *rbytes, size_t nrbytes,
uint8_t *output, size_t o_size);
#endif
+#endif
extern void gensalt_sha256_rn (unsigned long count,
const uint8_t *rbytes, size_t nrbytes,
diff --git a/crypt.c b/crypt.c
index 2aa9491..38dfca9 100644
--- a/crypt.c
+++ b/crypt.c
@@ -87,9 +87,11 @@ static const struct hashfn tagged_hashes[] =
/* legacy hashes */
#if ENABLE_WEAK_HASHES
{ "$1$", crypt_md5_rn, gensalt_md5_rn },
+#if ENABLE_WEAK_NON_GLIBC_HASHES
{ "$3$", crypt_nthash_rn, gensalt_nthash_rn },
{ "$md5", crypt_sunmd5_rn, gensalt_sunmd5_rn },
{ "$sha1", crypt_sha1_rn, gensalt_sha1_rn },
+#endif
#endif
{ "$5$", crypt_sha256_rn, gensalt_sha256_rn },
{ "$6$", crypt_sha512_rn, gensalt_sha512_rn },
@@ -97,6 +99,7 @@ static const struct hashfn tagged_hashes[] =
};
#if ENABLE_WEAK_HASHES
+#if ENABLE_WEAK_NON_GLIBC_HASHES
/* BSD-style extended DES */
static const struct hashfn bsdi_extended_hash =
{
@@ -109,6 +112,16 @@ static const struct hashfn traditional_hash =
"", crypt_des_trd_or_big_rn, gensalt_des_trd_rn
};
+#else
+
+/* Traditional DES */
+static const struct hashfn traditional_hash =
+{
+ "", crypt_des_trd_rn, gensalt_des_trd_rn
+};
+
+#endif
+
static int
is_des_salt_char (char c)
{
@@ -131,8 +144,10 @@ get_hashfn (const char *setting)
return 0;
}
#if ENABLE_WEAK_HASHES
+#if ENABLE_WEAK_NON_GLIBC_HASHES
else if (setting[0] == '_')
return &bsdi_extended_hash;
+#endif
else if (setting[0] == '\0' ||
(is_des_salt_char (setting[0]) && is_des_salt_char (setting[1])))
return &traditional_hash;
diff --git a/test-crypt-des.c b/test-crypt-des.c
index dbe44e0..e541885 100644
--- a/test-crypt-des.c
+++ b/test-crypt-des.c
@@ -20,6 +20,7 @@ static const struct
{ "XX", "XXxzOu6maQKqQ", "*U*U*U*U" },
{ "SD", "SDbsugeBiC58A", "" },
+#if ENABLE_WEAK_NON_GLIBC_HASHES
/* BSDI-extended-DES, ditto */
{ "_J9..CCCC", "_J9..CCCCXBrJUJV154M", "U*U*U*U*" },
{ "_J9..CCCC", "_J9..CCCCXUhOBTXzaiE", "U*U***U" },
@@ -63,6 +64,7 @@ static const struct
"6M..............", "6MvZdspyAL4QEId8ugLUEeDs",
"\xf3\xf4\xe5\xf0\xe8\xe1\xee\xe9\xe5" /* stephanie */
},
+#endif
};
#define ntests ARRAY_SIZE (tests)
diff --git a/test-gensalt.c b/test-gensalt.c
index 4b3a0e1..39a5435 100644
--- a/test-gensalt.c
+++ b/test-gensalt.c
@@ -24,11 +24,13 @@ static const struct testcase testcases[] =
{
#if ENABLE_WEAK_HASHES
{ "", 2 }, // DES
- { "_", 9 }, // BSDi extended DES
{ "$1$", 11 }, // MD5
+#if ENABLE_WEAK_NON_GLIBC_HASHES
+ { "_", 9 }, // BSDi extended DES
{ "$3$", 29 }, // NTHASH
{ "$md5", 27 }, // SUNMD5
{ "$sha1", 34 }, // PBKDF with SHA1
+#endif
#endif
{ "$5$", 19 }, // SHA-2-256
{ "$6$", 19 }, // SHA-2-512
From 84134e4d8e773fa6e27df1de2088f001e8042ef2 Mon Sep 17 00:00:00 2001
From: "Dmitry V. Levin" <ldv@altlinux.org>
Date: Tue, 26 Jun 2018 22:45:01 +0000
Subject: [PATCH 08/38] crypt_gensalt_rn: fix the number of automatically
obtained random bytes
Commit v4.0.0~94 extended crypt_gensalt_ra to obtained random bytes
automatically when rbytes argument is NULL. The number of random bytes
was fixed to 16, subsequent commit v4.0.0~6 changed this fixed number
to 18. However, the approach of using a fixed number for every
algorithm has two problems. Firstly, it is too wasteful for some
of currently implemented algorithms that use less than 18 bytes
of randomness. Secondly, other algorithms can use more than 18 random
bytes. Fix these issues by specifying the number of random bytes along
with functions in tagged_hashes table.
---
crypt.c | 43 ++++++++++++++++++++++---------------------
test-gensalt.c | 34 +++++++++++++++++++---------------
2 files changed, 41 insertions(+), 36 deletions(-)
diff --git a/crypt.c b/crypt.c
index 38dfca9..26f3537 100644
--- a/crypt.c
+++ b/crypt.c
@@ -21,9 +21,9 @@
#include <errno.h>
#include <stdlib.h>
+#include <limits.h>
#ifdef USE_SWAPCONTEXT
-#include <limits.h>
#include <ucontext.h>
#endif
@@ -72,6 +72,9 @@ struct hashfn
const char *prefix;
crypt_fn crypt;
gensalt_fn gensalt;
+ /* The type of this field is unsigned char to ensure that it cannot
+ be set larger than the size of an internal buffer in crypt_gensalt_rn. */
+ unsigned char nrbytes;
};
/* This table should always begin with the algorithm that should be used
@@ -79,23 +82,23 @@ struct hashfn
static const struct hashfn tagged_hashes[] =
{
/* bcrypt */
- { "$2b$", crypt_bcrypt_rn, gensalt_bcrypt_b_rn },
- { "$2a$", crypt_bcrypt_rn, gensalt_bcrypt_a_rn },
- { "$2x$", crypt_bcrypt_rn, gensalt_bcrypt_x_rn },
- { "$2y$", crypt_bcrypt_rn, gensalt_bcrypt_y_rn },
+ { "$2b$", crypt_bcrypt_rn, gensalt_bcrypt_b_rn, 16 },
+ { "$2a$", crypt_bcrypt_rn, gensalt_bcrypt_a_rn, 16 },
+ { "$2x$", crypt_bcrypt_rn, gensalt_bcrypt_x_rn, 16 },
+ { "$2y$", crypt_bcrypt_rn, gensalt_bcrypt_y_rn, 16 },
/* legacy hashes */
#if ENABLE_WEAK_HASHES
- { "$1$", crypt_md5_rn, gensalt_md5_rn },
+ { "$1$", crypt_md5_rn, gensalt_md5_rn, 9 },
#if ENABLE_WEAK_NON_GLIBC_HASHES
- { "$3$", crypt_nthash_rn, gensalt_nthash_rn },
- { "$md5", crypt_sunmd5_rn, gensalt_sunmd5_rn },
- { "$sha1", crypt_sha1_rn, gensalt_sha1_rn },
+ { "$3$", crypt_nthash_rn, gensalt_nthash_rn, 16 },
+ { "$md5", crypt_sunmd5_rn, gensalt_sunmd5_rn, 8 },
+ { "$sha1", crypt_sha1_rn, gensalt_sha1_rn, 48 },
#endif
#endif
- { "$5$", crypt_sha256_rn, gensalt_sha256_rn },
- { "$6$", crypt_sha512_rn, gensalt_sha512_rn },
- { 0, 0, 0 }
+ { "$5$", crypt_sha256_rn, gensalt_sha256_rn, 15 },
+ { "$6$", crypt_sha512_rn, gensalt_sha512_rn, 15 },
+ { 0, 0, 0, 0 }
};
#if ENABLE_WEAK_HASHES
@@ -103,13 +106,13 @@ static const struct hashfn tagged_hashes[] =
/* BSD-style extended DES */
static const struct hashfn bsdi_extended_hash =
{
- "_", crypt_des_xbsd_rn, gensalt_des_xbsd_rn
+ "_", crypt_des_xbsd_rn, gensalt_des_xbsd_rn, 3
};
/* Traditional DES or bigcrypt-style extended DES */
static const struct hashfn traditional_hash =
{
- "", crypt_des_trd_or_big_rn, gensalt_des_trd_rn
+ "", crypt_des_trd_or_big_rn, gensalt_des_trd_rn, 2
};
#else
@@ -117,7 +120,7 @@ static const struct hashfn traditional_hash =
/* Traditional DES */
static const struct hashfn traditional_hash =
{
- "", crypt_des_trd_rn, gensalt_des_trd_rn
+ "", crypt_des_trd_rn, gensalt_des_trd_rn, 2
};
#endif
@@ -375,10 +378,6 @@ crypt_gensalt_rn (const char *prefix, unsigned long count,
const char *rbytes, int nrbytes, char *output,
int output_size)
{
- /* Always add two padding bytes to make sure the whole string
- will be random on Base64 encoding. */
- char internal_rbytes[16 + 2];
-
make_failure_token ("", output, output_size);
/* Individual gensalt functions will check for adequate space for
@@ -404,15 +403,17 @@ crypt_gensalt_rn (const char *prefix, unsigned long count,
return 0;
}
+ char internal_rbytes[UCHAR_MAX];
+
/* If rbytes is 0, read random bytes from the operating system if
possible. */
if (!rbytes)
{
- if (!get_random_bytes(internal_rbytes, sizeof internal_rbytes))
+ if (!get_random_bytes (internal_rbytes, h->nrbytes))
return 0;
rbytes = internal_rbytes;
- nrbytes = sizeof internal_rbytes;
+ nrbytes = h->nrbytes;
}
/* Individual gensalt functions will check for sufficient random bits
diff --git a/test-gensalt.c b/test-gensalt.c
index 39a5435..f4d0629 100644
--- a/test-gensalt.c
+++ b/test-gensalt.c
@@ -18,27 +18,28 @@ struct testcase
{
const char *prefix;
unsigned int expected_len;
+ unsigned int expected_auto_len;
};
static const struct testcase testcases[] =
{
#if ENABLE_WEAK_HASHES
- { "", 2 }, // DES
- { "$1$", 11 }, // MD5
+ { "", 2, 0 }, // DES
+ { "$1$", 11, 0 }, // MD5
#if ENABLE_WEAK_NON_GLIBC_HASHES
- { "_", 9 }, // BSDi extended DES
- { "$3$", 29 }, // NTHASH
- { "$md5", 27 }, // SUNMD5
- { "$sha1", 34 }, // PBKDF with SHA1
+ { "_", 9, 0 }, // BSDi extended DES
+ { "$3$", 29, 0 }, // NTHASH
+ { "$md5", 27, 0 }, // SUNMD5
+ { "$sha1", 34, 74 }, // PBKDF with SHA1
#endif
#endif
- { "$5$", 19 }, // SHA-2-256
- { "$6$", 19 }, // SHA-2-512
- { "$2a$", 29 }, // bcrypt mode A
- { "$2b$", 29 }, // bcrypt mode B
- { "$2x$", 29 }, // bcrypt mode X
- { "$2y$", 29 }, // bcrypt mode Y
- { 0, 0 }
+ { "$5$", 19, 0 }, // SHA-2-256
+ { "$6$", 19, 0 }, // SHA-2-512
+ { "$2a$", 29, 0 }, // bcrypt mode A
+ { "$2b$", 29, 0 }, // bcrypt mode B
+ { "$2x$", 29, 0 }, // bcrypt mode X
+ { "$2y$", 29, 0 }, // bcrypt mode Y
+ { 0, 0, 0 }
};
int
@@ -74,11 +75,14 @@ main (void)
continue;
}
size_t slen = strlen (salt);
- if (slen != tcase->expected_len)
+ unsigned int expected_len =
+ (!entropy[ent] && tcase->expected_auto_len) ?
+ tcase->expected_auto_len : tcase->expected_len;
+ if (slen != expected_len)
{
fprintf (stderr,
"ERROR: %s/%u -> %s (expected len=%u got %zu)\n",
- tcase->prefix, ent, salt, tcase->expected_len, slen);
+ tcase->prefix, ent, salt, expected_len, slen);
status = 1;
}
else if (strncmp (salt, tcase->prefix, strlen (tcase->prefix)))
From 2973606ece4ebc17ffea4882b090eec68555f0b0 Mon Sep 17 00:00:00 2001
From: "Dmitry V. Levin" <ldv@altlinux.org>
Date: Wed, 27 Jun 2018 17:59:36 +0000
Subject: [PATCH 09/38] crypt_gensalt_rn: fix the leak of obtained random bytes
Erase the memory containing automatically obtained random bytes
to avoid leak of sensitive data after return from the function.
---
crypt.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/crypt.c b/crypt.c
index 26f3537..12d50fd 100644
--- a/crypt.c
+++ b/crypt.c
@@ -404,6 +404,8 @@ crypt_gensalt_rn (const char *prefix, unsigned long count,
}
char internal_rbytes[UCHAR_MAX];
+ /* typeof (internal_nrbytes) == typeof (h->nrbytes). */
+ unsigned char internal_nrbytes = 0;
/* If rbytes is 0, read random bytes from the operating system if
possible. */
@@ -413,7 +415,7 @@ crypt_gensalt_rn (const char *prefix, unsigned long count,
return 0;
rbytes = internal_rbytes;
- nrbytes = h->nrbytes;
+ nrbytes = internal_nrbytes = h->nrbytes;
}
/* Individual gensalt functions will check for sufficient random bits
@@ -429,6 +431,9 @@ crypt_gensalt_rn (const char *prefix, unsigned long count,
(const unsigned char *)rbytes, (size_t)nrbytes,
(unsigned char *)output, (size_t)output_size);
+ if (internal_nrbytes)
+ XCRYPT_SECURE_MEMSET (internal_rbytes, internal_nrbytes);
+
return output[0] == '*' ? 0 : output;
}
SYMVER_crypt_gensalt_rn;
From 19ac122ea84b370e421a8cb5a174a64577f6fa4e Mon Sep 17 00:00:00 2001
From: "Dmitry V. Levin" <ldv@altlinux.org>
Date: Fri, 29 Jun 2018 02:59:42 +0000
Subject: [PATCH 10/38] test-gensalt: extend checks of expected output
In addition to checks for expected output length,
check expected output strings for deterministic methods.
---
test-gensalt.c | 96 ++++++++++++++++++++++++++++++++++++++++++++++++++--------
1 file changed, 83 insertions(+), 13 deletions(-)
diff --git a/test-gensalt.c b/test-gensalt.c
index f4d0629..2705671 100644
--- a/test-gensalt.c
+++ b/test-gensalt.c
@@ -14,9 +14,72 @@ static const char *const entropy[] =
0
};
+#if ENABLE_WEAK_HASHES
+static const char *const des_expected_output[] = { "Mp", "Pp", "ZH", "Uh"};
+static const char *const md5_expected_output[] = {
+ "$1$MJHnaAke",
+ "$1$PKXc3hCO",
+ "$1$ZAFlICwY",
+ "$1$UqGBkVu0"
+};
+#if ENABLE_WEAK_NON_GLIBC_HASHES
+static const char *const bsdi_expected_output[] = {
+ "_J9..MJHn",
+ "_J9..PKXc",
+ "_J9..ZAFl",
+ "_J9..UqGB"
+};
+static const char *const nthash_expected_output[] = {
+ "$3$__not_used__c809a450df09a3",
+ "$3$__not_used__30d0d6f834c0c3",
+ "$3$__not_used__0eeeebb83d6fe4",
+ "$3$__not_used__1c690d6a9ef88c"
+};
+#define sunmd5_expected_output 0 /* output is not deterministic */
+#define pbkdf_expected_output 0 /* output is not deterministic */
+#endif
+#endif
+static const char *const sha256_expected_output[] = {
+ "$5$MJHnaAkegEVYHsFK",
+ "$5$PKXc3hCOSyMqdaEQ",
+ "$5$ZAFlICwYRETzIzIj",
+ "$5$UqGBkVu01rurVZqg"
+};
+static const char *const sha512_expected_output[] = {
+ "$6$MJHnaAkegEVYHsFK",
+ "$6$PKXc3hCOSyMqdaEQ",
+ "$6$ZAFlICwYRETzIzIj",
+ "$6$UqGBkVu01rurVZqg"
+};
+static const char *const bcrypt_a_expected_output[] = {
+ "$2a$05$UBVLHeMpJ/QQCv3XqJx8zO",
+ "$2a$05$kxUgPcrmlm9XoOjvxCyfP.",
+ "$2a$05$HPNDjKMRFdR7zC87CMSmA.",
+ "$2a$05$mAyzaIeJu41dWUkxEbn8hO"
+};
+static const char *const bcrypt_b_expected_output[] = {
+ "$2b$05$UBVLHeMpJ/QQCv3XqJx8zO",
+ "$2b$05$kxUgPcrmlm9XoOjvxCyfP.",
+ "$2b$05$HPNDjKMRFdR7zC87CMSmA.",
+ "$2b$05$mAyzaIeJu41dWUkxEbn8hO"
+};
+static const char *const bcrypt_x_expected_output[] = {
+ "$2x$05$UBVLHeMpJ/QQCv3XqJx8zO",
+ "$2x$05$kxUgPcrmlm9XoOjvxCyfP.",
+ "$2x$05$HPNDjKMRFdR7zC87CMSmA.",
+ "$2x$05$mAyzaIeJu41dWUkxEbn8hO"
+};
+static const char *const bcrypt_y_expected_output[] = {
+ "$2y$05$UBVLHeMpJ/QQCv3XqJx8zO",
+ "$2y$05$kxUgPcrmlm9XoOjvxCyfP.",
+ "$2y$05$HPNDjKMRFdR7zC87CMSmA.",
+ "$2y$05$mAyzaIeJu41dWUkxEbn8hO"
+};
+
struct testcase
{
const char *prefix;
+ const char *const *expected_output;
unsigned int expected_len;
unsigned int expected_auto_len;
};
@@ -24,22 +87,22 @@ struct testcase
static const struct testcase testcases[] =
{
#if ENABLE_WEAK_HASHES
- { "", 2, 0 }, // DES
- { "$1$", 11, 0 }, // MD5
+ { "", des_expected_output, 2, 0 }, // DES
+ { "$1$", md5_expected_output, 11, 0 }, // MD5
#if ENABLE_WEAK_NON_GLIBC_HASHES
- { "_", 9, 0 }, // BSDi extended DES
- { "$3$", 29, 0 }, // NTHASH
- { "$md5", 27, 0 }, // SUNMD5
- { "$sha1", 34, 74 }, // PBKDF with SHA1
+ { "_", bsdi_expected_output, 9, 0 }, // BSDi extended DES
+ { "$3$", nthash_expected_output, 29, 0 }, // NTHASH
+ { "$md5", sunmd5_expected_output, 27, 0 }, // SUNMD5
+ { "$sha1", pbkdf_expected_output, 34, 74 }, // PBKDF with SHA1
#endif
#endif
- { "$5$", 19, 0 }, // SHA-2-256
- { "$6$", 19, 0 }, // SHA-2-512
- { "$2a$", 29, 0 }, // bcrypt mode A
- { "$2b$", 29, 0 }, // bcrypt mode B
- { "$2x$", 29, 0 }, // bcrypt mode X
- { "$2y$", 29, 0 }, // bcrypt mode Y
- { 0, 0, 0 }
+ { "$5$", sha256_expected_output, 19, 0 }, // SHA-2-256
+ { "$6$", sha512_expected_output, 19, 0 }, // SHA-2-512
+ { "$2a$", bcrypt_a_expected_output, 29, 0 }, // bcrypt mode A
+ { "$2b$", bcrypt_b_expected_output, 29, 0 }, // bcrypt mode B
+ { "$2x$", bcrypt_x_expected_output, 29, 0 }, // bcrypt mode X
+ { "$2y$", bcrypt_y_expected_output, 29, 0 }, // bcrypt mode Y
+ { 0, 0, 0, 0 }
};
int
@@ -97,6 +160,13 @@ main (void)
tcase->prefix, ent, salt);
status = 1;
}
+ else if (entropy[ent] && tcase->expected_output &&
+ strcmp (salt, tcase->expected_output[ent]))
+ {
+ fprintf (stderr, "ERROR: %s/%u -> %s (expected %s)\n",
+ tcase->prefix, ent, salt, tcase->expected_output[ent]);
+ status = 1;
+ }
else
fprintf (stderr, " ok: %s/%u -> %s\n",
tcase->prefix, ent, salt);
From 75dd1518c70d11093117e5c575cc2d7c121415f9 Mon Sep 17 00:00:00 2001
From: "Dmitry V. Levin" <ldv@altlinux.org>
Date: Sat, 30 Jun 2018 12:26:41 +0000
Subject: [PATCH 11/38] crypt_sha1_rn: fix memory leak
Reported-by: Vitaly Chikunov <vt@altlinux.org>
---
crypt-pbkdf1-sha1.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/crypt-pbkdf1-sha1.c b/crypt-pbkdf1-sha1.c
index ac4f04a..e8427d5 100644
--- a/crypt-pbkdf1-sha1.c
+++ b/crypt-pbkdf1-sha1.c
@@ -218,6 +218,8 @@ crypt_sha1_rn (const char *phrase, const char *setting,
/* Don't leave anything around in vm they could use. */
XCRYPT_SECURE_MEMSET (scratch, s_size)
+ XCRYPT_SECURE_MEMSET (salt, sl)
+ free (salt);
}
/* Modified excerpt from:
From 86f386578f997a1039df42e26ff3f766ed09454b Mon Sep 17 00:00:00 2001
From: "Dmitry V. Levin" <ldv@altlinux.org>
Date: Sat, 30 Jun 2018 12:26:41 +0000
Subject: [PATCH 12/38] gensalt_sha1_rn: fix read of random bytes out of bounds
Reported-by: Vitaly Chikunov <vt@altlinux.org>
---
crypt-pbkdf1-sha1.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/crypt-pbkdf1-sha1.c b/crypt-pbkdf1-sha1.c
index e8427d5..b55d233 100644
--- a/crypt-pbkdf1-sha1.c
+++ b/crypt-pbkdf1-sha1.c
@@ -250,7 +250,8 @@ gensalt_sha1_rn (unsigned long count,
for (c = 0; (c * sizeof (unsigned long)) + sizeof (unsigned long) <= nrbytes &&
(c * enclen) + enclen <= CRYPT_SHA1_SALT_LENGTH; ++c)
{
- memcpy (&encbuf, rbytes + (c * enclen), sizeof (unsigned long));
+ memcpy (&encbuf, rbytes + (c * sizeof (unsigned long)),
+ sizeof (unsigned long));
to64 (output + n + (c * enclen), encbuf, (int)enclen);
}
From fd45d0e95045b49a80a87bfa184fc9be90336779 Mon Sep 17 00:00:00 2001
From: "Dmitry V. Levin" <ldv@altlinux.org>
Date: Fri, 29 Jun 2018 13:22:51 +0000
Subject: [PATCH 13/38] .travis.yml: reduce flakyness
Reduce false positives by wrapping network-related operations
into a loop.
---
.travis.yml | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/.travis.yml b/.travis.yml
index c812e22..7e892b2 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -96,7 +96,7 @@ matrix:
- FCVER="latest"
before_install:
- - docker pull fedora:$FCVER
+ - for i in `seq 0 99`; do docker pull fedora:$FCVER && i= && break || sleep 1; done; [ -z "$i" ]
- perl -pe 's/\$(\w+)/$ENV{$1}/g' .travis.env.in > travis.env
- docker run -t -d -P --env-file travis.env --name buildenv -v $HOME/.ccache:/root/.ccache -v $PWD:/opt/libxcrypt fedora:$FCVER /bin/sh -c "mkdir -p /opt/libxcrypt ; bash"
- docker exec -t buildenv /bin/sh -c "echo \"deltarpm=0\" >> /etc/dnf/dnf.conf"
@@ -104,12 +104,12 @@ before_install:
- docker exec -t buildenv /bin/sh -c "echo \"max_parallel_downloads=20\" >> /etc/dnf/dnf.conf"
- docker exec -t buildenv /bin/sh -c "echo \"\" >> /etc/dnf/dnf.conf"
- if [[ "$FCVER" == "rawhide" ]] ; then docker exec -t buildenv /bin/sh -c "cat /opt/libxcrypt/.travis.dnf.conf.rawhide_latest >> /etc/dnf/dnf.conf" ; fi
- - docker exec -t buildenv /bin/sh -c "dnf makecache"
- - docker exec -t buildenv /bin/sh -c "dnf -y upgrade"
- - docker exec -t buildenv /bin/sh -c "dnf -y groups install buildsys-build"
- - docker exec -t buildenv /bin/sh -c "dnf -y install libtool"
- - if [[ "$CC" == "clang" ]] ; then docker exec -t buildenv /bin/sh -c "dnf -y install clang" ; fi
- - if [[ "$CODECOV" == "1" ]] ; then docker exec -t buildenv /bin/sh -c "dnf -y install '/usr/bin/git' '/usr/bin/lcov' '/usr/bin/pip3'" ; fi
+ - docker exec -t buildenv /bin/sh -c 'for i in `seq 0 99`; do dnf makecache && i= && break || sleep 1; done; [ -z "$i" ]'
+ - docker exec -t buildenv /bin/sh -c 'for i in `seq 0 99`; do dnf -y upgrade && i= && break || sleep 1; done; [ -z "$i" ]'
+ - docker exec -t buildenv /bin/sh -c 'for i in `seq 0 99`; do dnf -y groups install buildsys-build && i= && break || sleep 1; done; [ -z "$i" ]'
+ - docker exec -t buildenv /bin/sh -c 'for i in `seq 0 99`; do dnf -y install libtool && i= && break || sleep 1; done; [ -z "$i" ]'
+ - if [[ "$CC" == "clang" ]] ; then docker exec -t buildenv /bin/sh -c 'for i in `seq 0 99`; do dnf -y install clang && i= && break || sleep 1; done; [ -z "$i" ]' ; fi
+ - if [[ "$CODECOV" == "1" ]] ; then docker exec -t buildenv /bin/sh -c 'for i in `seq 0 99`; do dnf -y install '/usr/bin/git' '/usr/bin/lcov' '/usr/bin/pip3' && i= && break || sleep 1; done; [ -z "$i" ]' ; fi
- if [[ "$CODECOV" == "1" ]] ; then docker exec -t buildenv /bin/sh -c "pip3 install codecov" ; fi
before_script:
From 1a51a81abc609c1a48edb2f4c0887e892e9e968f Mon Sep 17 00:00:00 2001
From: Zack Weinberg <zackw@panix.com>
Date: Wed, 4 Jul 2018 15:07:31 -0400
Subject: [PATCH 14/38] Check in alg-des-tables.c, don't run gen-des-tables at
build time.
This eliminates a whole bunch of dodgy logic from
Makefile.am (Automake doesn't fully comprehend the distinction between
CC and CC_FOR_BUILD) and will also make it easier to support enabling
and disabling of individual hashes without needing AM_CONDITIONALs for
each.
---
.gitignore | 2 -
LICENSING | 6 +-
Makefile.am | 26 +-
alg-des-tables.c | 3844 ++++++++++++++++++++++++++++++++++++++++++++
configure.ac | 1 -
gen-des-tables.c | 11 +-
m4/ax_prog_cc_for_build.m4 | 158 --
7 files changed, 3853 insertions(+), 195 deletions(-)
create mode 100644 alg-des-tables.c
delete mode 100644 m4/ax_prog_cc_for_build.m4
diff --git a/.gitignore b/.gitignore
index 3728add..5e998dd 100644
--- a/.gitignore
+++ b/.gitignore
@@ -42,8 +42,6 @@
*.o
*.so
*.trs
-/gen-des-tables
-/alg-des-tables.c
/crypt.h
/crypt-symbol-vers.h
/libcrypt.map
diff --git a/LICENSING b/LICENSING
index ad5b4b5..b6f5168 100644
--- a/LICENSING
+++ b/LICENSING
@@ -19,7 +19,8 @@ source tree. For specific licensing terms consult the files themselves.
test-crypt-badsalt, test-crypt-nonnull
* Copyright David Burren et al.; 3-clause BSD:
- alg-des.h, alg-des.c, crypt-des.c, crypt-des-obsolete.c, gen-des-tables.c
+ alg-des.h, alg-des.c, alg-des-tables.c,
+ crypt-des.c, crypt-des-obsolete.c, gen-des-tables.c
* Public domain, written by Solar Designer et al.:
alg-md4.h, alg-md4.c, crypt-bcrypt.c, crypt-gensalt.c, test-crypt-bcrypt.c
@@ -49,9 +50,6 @@ source tree. For specific licensing terms consult the files themselves.
GPL (v3 or later), with Autoconf exception:
m4/zw_automodern.m4, m4/zw_simple_warnings.m4
- * Copyright Paolo Bonzini; FSF all-permissive license for short files:
- m4/ax_prog_cc_for_build.m4
-
* Copyright holders unknown, no statement of license (all of these
files are part of the testsuite and do not contribute to the
installed library or its headers):
diff --git a/Makefile.am b/Makefile.am
index c219bac..71fbd62 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -114,7 +114,7 @@ check_PROGRAMS = \
if ENABLE_WEAK_HASHES
libcrypt_la_SOURCES += \
- crypt-des.c crypt-md5.c alg-des.c alg-md5.c
+ crypt-des.c crypt-md5.c alg-des.c alg-des-tables.c alg-md5.c
if ENABLE_WEAK_NON_GLIBC_HASHES
libcrypt_la_SOURCES += \
@@ -122,30 +122,6 @@ libcrypt_la_SOURCES += \
alg-hmac-sha1.c alg-md4.c alg-sha1.c
endif
-nodist_libcrypt_la_SOURCES = \
- alg-des-tables.c
-CLEANFILES += alg-des-tables.c alg-des-tables.c.T
-
-noinst_PROGRAMS = gen-des-tables
-
-LINK_FOR_BUILD = $(CC_FOR_BUILD) $(CFLAGS_FOR_BUILD) $(CPPFLAGS_FOR_BUILD) \
- $(LDFLAGS_FOR_BUILD) $(TARGET_ARCH_FOR_BUILD) -o $@
-
-gen-des-tables$(BUILD_EXEEXT): $(gen_des_tables_OBJECTS)
- @rm -f gen-des-tables$(BUILD_EXEEXT)
- $(AM_V_CCLD)$(LINK_FOR_BUILD) $(gen_des_tables_OBJECTS) $(gen_des_tables_LDADD) $(LIBS)
-# suppress the built-in rule for
-gen-des-tables$(EXEEXT):
-
-$(gen_des_tables_OBJECTS) : CC=$(CC_FOR_BUILD)
-$(gen_des_tables_OBJECTS) : CFLAGS=$(CFLAGS_FOR_BUILD)
-$(gen_des_tables_OBJECTS) : CPPFLAGS=$(CPPFLAGS_FOR_BUILD)
-$(gen_des_tables_OBJECTS) : AM_CFLAGS=$(WARN_CFLAGS_FOR_BUILD)
-
-alg-des-tables.c: gen-des-tables
- $(AM_V_GEN)./gen-des-tables$(BUILD_EXEEXT) > alg-des-tables.c.T
- $(AM_V_at)mv -f alg-des-tables.c.T alg-des-tables.c
-
check_PROGRAMS += \
test-alg-des test-alg-md5 test-crypt-des test-crypt-md5 \
test-crypt-badsalt
diff --git a/alg-des-tables.c b/alg-des-tables.c
new file mode 100644
index 0000000..0bf9c88
--- /dev/null
+++ b/alg-des-tables.c
@@ -0,0 +1,3844 @@
+/*
+ * FreeSec: libcrypt for NetBSD
+ *
+ * Copyright (c) 1994 David Burren
+ * All rights reserved.
+ *
+ * Adapted for FreeBSD-2.0 by Geoffrey M. Rehmet
+ * this file should now *only* export crypt(), in order to make
+ * binaries of libcrypt exportable from the USA
+ *
+ * Adapted for FreeBSD-4.0 by Mark R V Murray
+ * this file should now *only* export crypt_des(), in order to make
+ * a module that can be optionally included in libcrypt.
+ *
+ * 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 author nor the names of other contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This is an original implementation of the DES and the crypt(3) interfaces
+ * by David Burren <davidb@werj.com.au>.
+ */
+
+/*
+ * The tables in this file were generated from a more compact
+ * representation of the DES S-boxes and P-boxes by the program
+ * gen-des-tables.c, which we no longer bother to run at build time.
+ */
+
+#include "crypt-port.h"
+#include "alg-des.h"
+
+const uint8_t m_sbox[4][4096] = {
+ {
+ 0xef, 0xe3, 0xe1, 0xed, 0xe8, 0xe4, 0xee, 0xe7, 0xe6, 0xef, 0xeb, 0xe2,
+ 0xe3, 0xe8, 0xe4, 0xee, 0xe9, 0xec, 0xe7, 0xe0, 0xe2, 0xe1, 0xed, 0xea,
+ 0xec, 0xe6, 0xe0, 0xe9, 0xe5, 0xeb, 0xea, 0xe5, 0xe0, 0xed, 0xee, 0xe8,
+ 0xe7, 0xea, 0xeb, 0xe1, 0xea, 0xe3, 0xe4, 0xef, 0xed, 0xe4, 0xe1, 0xe2,
+ 0xe5, 0xeb, 0xe8, 0xe6, 0xec, 0xe7, 0xe6, 0xec, 0xe9, 0xe0, 0xe3, 0xe5,
+ 0xe2, 0xee, 0xef, 0xe9, 0x0f, 0x03, 0x01, 0x0d, 0x08, 0x04, 0x0e, 0x07,
+ 0x06, 0x0f, 0x0b, 0x02, 0x03, 0x08, 0x04, 0x0e, 0x09, 0x0c, 0x07, 0x00,
+ 0x02, 0x01, 0x0d, 0x0a, 0x0c, 0x06, 0x00, 0x09, 0x05, 0x0b, 0x0a, 0x05,
+ 0x00, 0x0d, 0x0e, 0x08, 0x07, 0x0a, 0x0b, 0x01, 0x0a, 0x03, 0x04, 0x0f,
+ 0x0d, 0x04, 0x01, 0x02, 0x05, 0x0b, 0x08, 0x06, 0x0c, 0x07, 0x06, 0x0c,
+ 0x09, 0x00, 0x03, 0x05, 0x02, 0x0e, 0x0f, 0x09, 0x4f, 0x43, 0x41, 0x4d,
+ 0x48, 0x44, 0x4e, 0x47, 0x46, 0x4f, 0x4b, 0x42, 0x43, 0x48, 0x44, 0x4e,
+ 0x49, 0x4c, 0x47, 0x40, 0x42, 0x41, 0x4d, 0x4a, 0x4c, 0x46, 0x40, 0x49,
+ 0x45, 0x4b, 0x4a, 0x45, 0x40, 0x4d, 0x4e, 0x48, 0x47, 0x4a, 0x4b, 0x41,
+ 0x4a, 0x43, 0x44, 0x4f, 0x4d, 0x44, 0x41, 0x42, 0x45, 0x4b, 0x48, 0x46,
+ 0x4c, 0x47, 0x46, 0x4c, 0x49, 0x40, 0x43, 0x45, 0x42, 0x4e, 0x4f, 0x49,
+ 0xff, 0xf3, 0xf1, 0xfd, 0xf8, 0xf4, 0xfe, 0xf7, 0xf6, 0xff, 0xfb, 0xf2,
+ 0xf3, 0xf8, 0xf4, 0xfe, 0xf9, 0xfc, 0xf7, 0xf0, 0xf2, 0xf1, 0xfd, 0xfa,
+ 0xfc, 0xf6, 0xf0, 0xf9, 0xf5, 0xfb, 0xfa, 0xf5, 0xf0, 0xfd, 0xfe, 0xf8,
+ 0xf7, 0xfa, 0xfb, 0xf1, 0xfa, 0xf3, 0xf4, 0xff, 0xfd, 0xf4, 0xf1, 0xf2,
+ 0xf5, 0xfb, 0xf8, 0xf6, 0xfc, 0xf7, 0xf6, 0xfc, 0xf9, 0xf0, 0xf3, 0xf5,
+ 0xf2, 0xfe, 0xff, 0xf9, 0xdf, 0xd3, 0xd1, 0xdd, 0xd8, 0xd4, 0xde, 0xd7,
+ 0xd6, 0xdf, 0xdb, 0xd2, 0xd3, 0xd8, 0xd4, 0xde, 0xd9, 0xdc, 0xd7, 0xd0,
+ 0xd2, 0xd1, 0xdd, 0xda, 0xdc, 0xd6, 0xd0, 0xd9, 0xd5, 0xdb, 0xda, 0xd5,
+ 0xd0, 0xdd, 0xde, 0xd8, 0xd7, 0xda, 0xdb, 0xd1, 0xda, 0xd3, 0xd4, 0xdf,
+ 0xdd, 0xd4, 0xd1, 0xd2, 0xd5, 0xdb, 0xd8, 0xd6, 0xdc, 0xd7, 0xd6, 0xdc,
+ 0xd9, 0xd0, 0xd3, 0xd5, 0xd2, 0xde, 0xdf, 0xd9, 0x7f, 0x73, 0x71, 0x7d,
+ 0x78, 0x74, 0x7e, 0x77, 0x76, 0x7f, 0x7b, 0x72, 0x73, 0x78, 0x74, 0x7e,
+ 0x79, 0x7c, 0x77, 0x70, 0x72, 0x71, 0x7d, 0x7a, 0x7c, 0x76, 0x70, 0x79,
+ 0x75, 0x7b, 0x7a, 0x75, 0x70, 0x7d, 0x7e, 0x78, 0x77, 0x7a, 0x7b, 0x71,
+ 0x7a, 0x73, 0x74, 0x7f, 0x7d, 0x74, 0x71, 0x72, 0x75, 0x7b, 0x78, 0x76,
+ 0x7c, 0x77, 0x76, 0x7c, 0x79, 0x70, 0x73, 0x75, 0x72, 0x7e, 0x7f, 0x79,
+ 0x1f, 0x13, 0x11, 0x1d, 0x18, 0x14, 0x1e, 0x17, 0x16, 0x1f, 0x1b, 0x12,
+ 0x13, 0x18, 0x14, 0x1e, 0x19, 0x1c, 0x17, 0x10, 0x12, 0x11, 0x1d, 0x1a,
+ 0x1c, 0x16, 0x10, 0x19, 0x15, 0x1b, 0x1a, 0x15, 0x10, 0x1d, 0x1e, 0x18,
+ 0x17, 0x1a, 0x1b, 0x11, 0x1a, 0x13, 0x14, 0x1f, 0x1d, 0x14, 0x11, 0x12,
+ 0x15, 0x1b, 0x18, 0x16, 0x1c, 0x17, 0x16, 0x1c, 0x19, 0x10, 0x13, 0x15,
+ 0x12, 0x1e, 0x1f, 0x19, 0x4f, 0x43, 0x41, 0x4d, 0x48, 0x44, 0x4e, 0x47,
+ 0x46, 0x4f, 0x4b, 0x42, 0x43, 0x48, 0x44, 0x4e, 0x49, 0x4c, 0x47, 0x40,
+ 0x42, 0x41, 0x4d, 0x4a, 0x4c, 0x46, 0x40, 0x49, 0x45, 0x4b, 0x4a, 0x45,
+ 0x40, 0x4d, 0x4e, 0x48, 0x47, 0x4a, 0x4b, 0x41, 0x4a, 0x43, 0x44, 0x4f,
+ 0x4d, 0x44, 0x41, 0x42, 0x45, 0x4b, 0x48, 0x46, 0x4c, 0x47, 0x46, 0x4c,
+ 0x49, 0x40, 0x43, 0x45, 0x42, 0x4e, 0x4f, 0x49, 0x2f, 0x23, 0x21, 0x2d,
+ 0x28, 0x24, 0x2e, 0x27, 0x26, 0x2f, 0x2b, 0x22, 0x23, 0x28, 0x24, 0x2e,
+ 0x29, 0x2c, 0x27, 0x20, 0x22, 0x21, 0x2d, 0x2a, 0x2c, 0x26, 0x20, 0x29,
+ 0x25, 0x2b, 0x2a, 0x25, 0x20, 0x2d, 0x2e, 0x28, 0x27, 0x2a, 0x2b, 0x21,
+ 0x2a, 0x23, 0x24, 0x2f, 0x2d, 0x24, 0x21, 0x22, 0x25, 0x2b, 0x28, 0x26,
+ 0x2c, 0x27, 0x26, 0x2c, 0x29, 0x20, 0x23, 0x25, 0x22, 0x2e, 0x2f, 0x29,
+ 0xef, 0xe3, 0xe1, 0xed, 0xe8, 0xe4, 0xee, 0xe7, 0xe6, 0xef, 0xeb, 0xe2,
+ 0xe3, 0xe8, 0xe4, 0xee, 0xe9, 0xec, 0xe7, 0xe0, 0xe2, 0xe1, 0xed, 0xea,
+ 0xec, 0xe6, 0xe0, 0xe9, 0xe5, 0xeb, 0xea, 0xe5, 0xe0, 0xed, 0xee, 0xe8,
+ 0xe7, 0xea, 0xeb, 0xe1, 0xea, 0xe3, 0xe4, 0xef, 0xed, 0xe4, 0xe1, 0xe2,
+ 0xe5, 0xeb, 0xe8, 0xe6, 0xec, 0xe7, 0xe6, 0xec, 0xe9, 0xe0, 0xe3, 0xe5,
+ 0xe2, 0xee, 0xef, 0xe9, 0xff, 0xf3, 0xf1, 0xfd, 0xf8, 0xf4, 0xfe, 0xf7,
+ 0xf6, 0xff, 0xfb, 0xf2, 0xf3, 0xf8, 0xf4, 0xfe, 0xf9, 0xfc, 0xf7, 0xf0,
+ 0xf2, 0xf1, 0xfd, 0xfa, 0xfc, 0xf6, 0xf0, 0xf9, 0xf5, 0xfb, 0xfa, 0xf5,
+ 0xf0, 0xfd, 0xfe, 0xf8, 0xf7, 0xfa, 0xfb, 0xf1, 0xfa, 0xf3, 0xf4, 0xff,
+ 0xfd, 0xf4, 0xf1, 0xf2, 0xf5, 0xfb, 0xf8, 0xf6, 0xfc, 0xf7, 0xf6, 0xfc,
+ 0xf9, 0xf0, 0xf3, 0xf5, 0xf2, 0xfe, 0xff, 0xf9, 0x2f, 0x23, 0x21, 0x2d,
+ 0x28, 0x24, 0x2e, 0x27, 0x26, 0x2f, 0x2b, 0x22, 0x23, 0x28, 0x24, 0x2e,
+ 0x29, 0x2c, 0x27, 0x20, 0x22, 0x21, 0x2d, 0x2a, 0x2c, 0x26, 0x20, 0x29,
+ 0x25, 0x2b, 0x2a, 0x25, 0x20, 0x2d, 0x2e, 0x28, 0x27, 0x2a, 0x2b, 0x21,
+ 0x2a, 0x23, 0x24, 0x2f, 0x2d, 0x24, 0x21, 0x22, 0x25, 0x2b, 0x28, 0x26,
+ 0x2c, 0x27, 0x26, 0x2c, 0x29, 0x20, 0x23, 0x25, 0x22, 0x2e, 0x2f, 0x29,
+ 0xbf, 0xb3, 0xb1, 0xbd, 0xb8, 0xb4, 0xbe, 0xb7, 0xb6, 0xbf, 0xbb, 0xb2,
+ 0xb3, 0xb8, 0xb4, 0xbe, 0xb9, 0xbc, 0xb7, 0xb0, 0xb2, 0xb1, 0xbd, 0xba,
+ 0xbc, 0xb6, 0xb0, 0xb9, 0xb5, 0xbb, 0xba, 0xb5, 0xb0, 0xbd, 0xbe, 0xb8,
+ 0xb7, 0xba, 0xbb, 0xb1, 0xba, 0xb3, 0xb4, 0xbf, 0xbd, 0xb4, 0xb1, 0xb2,
+ 0xb5, 0xbb, 0xb8, 0xb6, 0xbc, 0xb7, 0xb6, 0xbc, 0xb9, 0xb0, 0xb3, 0xb5,
+ 0xb2, 0xbe, 0xbf, 0xb9, 0xdf, 0xd3, 0xd1, 0xdd, 0xd8, 0xd4, 0xde, 0xd7,
+ 0xd6, 0xdf, 0xdb, 0xd2, 0xd3, 0xd8, 0xd4, 0xde, 0xd9, 0xdc, 0xd7, 0xd0,
+ 0xd2, 0xd1, 0xdd, 0xda, 0xdc, 0xd6, 0xd0, 0xd9, 0xd5, 0xdb, 0xda, 0xd5,
+ 0xd0, 0xdd, 0xde, 0xd8, 0xd7, 0xda, 0xdb, 0xd1, 0xda, 0xd3, 0xd4, 0xdf,
+ 0xdd, 0xd4, 0xd1, 0xd2, 0xd5, 0xdb, 0xd8, 0xd6, 0xdc, 0xd7, 0xd6, 0xdc,
+ 0xd9, 0xd0, 0xd3, 0xd5, 0xd2, 0xde, 0xdf, 0xd9, 0x8f, 0x83, 0x81, 0x8d,
+ 0x88, 0x84, 0x8e, 0x87, 0x86, 0x8f, 0x8b, 0x82, 0x83, 0x88, 0x84, 0x8e,
+ 0x89, 0x8c, 0x87, 0x80, 0x82, 0x81, 0x8d, 0x8a, 0x8c, 0x86, 0x80, 0x89,
+ 0x85, 0x8b, 0x8a, 0x85, 0x80, 0x8d, 0x8e, 0x88, 0x87, 0x8a, 0x8b, 0x81,
+ 0x8a, 0x83, 0x84, 0x8f, 0x8d, 0x84, 0x81, 0x82, 0x85, 0x8b, 0x88, 0x86,
+ 0x8c, 0x87, 0x86, 0x8c, 0x89, 0x80, 0x83, 0x85, 0x82, 0x8e, 0x8f, 0x89,
+ 0x1f, 0x13, 0x11, 0x1d, 0x18, 0x14, 0x1e, 0x17, 0x16, 0x1f, 0x1b, 0x12,
+ 0x13, 0x18, 0x14, 0x1e, 0x19, 0x1c, 0x17, 0x10, 0x12, 0x11, 0x1d, 0x1a,
+ 0x1c, 0x16, 0x10, 0x19, 0x15, 0x1b, 0x1a, 0x15, 0x10, 0x1d, 0x1e, 0x18,
+ 0x17, 0x1a, 0x1b, 0x11, 0x1a, 0x13, 0x14, 0x1f, 0x1d, 0x14, 0x11, 0x12,
+ 0x15, 0x1b, 0x18, 0x16, 0x1c, 0x17, 0x16, 0x1c, 0x19, 0x10, 0x13, 0x15,
+ 0x12, 0x1e, 0x1f, 0x19, 0x3f, 0x33, 0x31, 0x3d, 0x38, 0x34, 0x3e, 0x37,
+ 0x36, 0x3f, 0x3b, 0x32, 0x33, 0x38, 0x34, 0x3e, 0x39, 0x3c, 0x37, 0x30,
+ 0x32, 0x31, 0x3d, 0x3a, 0x3c, 0x36, 0x30, 0x39, 0x35, 0x3b, 0x3a, 0x35,
+ 0x30, 0x3d, 0x3e, 0x38, 0x37, 0x3a, 0x3b, 0x31, 0x3a, 0x33, 0x34, 0x3f,
+ 0x3d, 0x34, 0x31, 0x32, 0x35, 0x3b, 0x38, 0x36, 0x3c, 0x37, 0x36, 0x3c,
+ 0x39, 0x30, 0x33, 0x35, 0x32, 0x3e, 0x3f, 0x39, 0xaf, 0xa3, 0xa1, 0xad,
+ 0xa8, 0xa4, 0xae, 0xa7, 0xa6, 0xaf, 0xab, 0xa2, 0xa3, 0xa8, 0xa4, 0xae,
+ 0xa9, 0xac, 0xa7, 0xa0, 0xa2, 0xa1, 0xad, 0xaa, 0xac, 0xa6, 0xa0, 0xa9,
+ 0xa5, 0xab, 0xaa, 0xa5, 0xa0, 0xad, 0xae, 0xa8, 0xa7, 0xaa, 0xab, 0xa1,
+ 0xaa, 0xa3, 0xa4, 0xaf, 0xad, 0xa4, 0xa1, 0xa2, 0xa5, 0xab, 0xa8, 0xa6,
+ 0xac, 0xa7, 0xa6, 0xac, 0xa9, 0xa0, 0xa3, 0xa5, 0xa2, 0xae, 0xaf, 0xa9,
+ 0xaf, 0xa3, 0xa1, 0xad, 0xa8, 0xa4, 0xae, 0xa7, 0xa6, 0xaf, 0xab, 0xa2,
+ 0xa3, 0xa8, 0xa4, 0xae, 0xa9, 0xac, 0xa7, 0xa0, 0xa2, 0xa1, 0xad, 0xaa,
+ 0xac, 0xa6, 0xa0, 0xa9, 0xa5, 0xab, 0xaa, 0xa5, 0xa0, 0xad, 0xae, 0xa8,
+ 0xa7, 0xaa, 0xab, 0xa1, 0xaa, 0xa3, 0xa4, 0xaf, 0xad, 0xa4, 0xa1, 0xa2,
+ 0xa5, 0xab, 0xa8, 0xa6, 0xac, 0xa7, 0xa6, 0xac, 0xa9, 0xa0, 0xa3, 0xa5,
+ 0xa2, 0xae, 0xaf, 0xa9, 0x6f, 0x63, 0x61, 0x6d, 0x68, 0x64, 0x6e, 0x67,
+ 0x66, 0x6f, 0x6b, 0x62, 0x63, 0x68, 0x64, 0x6e, 0x69, 0x6c, 0x67, 0x60,
+ 0x62, 0x61, 0x6d, 0x6a, 0x6c, 0x66, 0x60, 0x69, 0x65, 0x6b, 0x6a, 0x65,
+ 0x60, 0x6d, 0x6e, 0x68, 0x67, 0x6a, 0x6b, 0x61, 0x6a, 0x63, 0x64, 0x6f,
+ 0x6d, 0x64, 0x61, 0x62, 0x65, 0x6b, 0x68, 0x66, 0x6c, 0x67, 0x66, 0x6c,
+ 0x69, 0x60, 0x63, 0x65, 0x62, 0x6e, 0x6f, 0x69, 0x6f, 0x63, 0x61, 0x6d,
+ 0x68, 0x64, 0x6e, 0x67, 0x66, 0x6f, 0x6b, 0x62, 0x63, 0x68, 0x64, 0x6e,
+ 0x69, 0x6c, 0x67, 0x60, 0x62, 0x61, 0x6d, 0x6a, 0x6c, 0x66, 0x60, 0x69,
+ 0x65, 0x6b, 0x6a, 0x65, 0x60, 0x6d, 0x6e, 0x68, 0x67, 0x6a, 0x6b, 0x61,
+ 0x6a, 0x63, 0x64, 0x6f, 0x6d, 0x64, 0x61, 0x62, 0x65, 0x6b, 0x68, 0x66,
+ 0x6c, 0x67, 0x66, 0x6c, 0x69, 0x60, 0x63, 0x65, 0x62, 0x6e, 0x6f, 0x69,
+ 0xcf, 0xc3, 0xc1, 0xcd, 0xc8, 0xc4, 0xce, 0xc7, 0xc6, 0xcf, 0xcb, 0xc2,
+ 0xc3, 0xc8, 0xc4, 0xce, 0xc9, 0xcc, 0xc7, 0xc0, 0xc2, 0xc1, 0xcd, 0xca,
+ 0xcc, 0xc6, 0xc0, 0xc9, 0xc5, 0xcb, 0xca, 0xc5, 0xc0, 0xcd, 0xce, 0xc8,
+ 0xc7, 0xca, 0xcb, 0xc1, 0xca, 0xc3, 0xc4, 0xcf, 0xcd, 0xc4, 0xc1, 0xc2,
+ 0xc5, 0xcb, 0xc8, 0xc6, 0xcc, 0xc7, 0xc6, 0xcc, 0xc9, 0xc0, 0xc3, 0xc5,
+ 0xc2, 0xce, 0xcf, 0xc9, 0xcf, 0xc3, 0xc1, 0xcd, 0xc8, 0xc4, 0xce, 0xc7,
+ 0xc6, 0xcf, 0xcb, 0xc2, 0xc3, 0xc8, 0xc4, 0xce, 0xc9, 0xcc, 0xc7, 0xc0,
+ 0xc2, 0xc1, 0xcd, 0xca, 0xcc, 0xc6, 0xc0, 0xc9, 0xc5, 0xcb, 0xca, 0xc5,
+ 0xc0, 0xcd, 0xce, 0xc8, 0xc7, 0xca, 0xcb, 0xc1, 0xca, 0xc3, 0xc4, 0xcf,
+ 0xcd, 0xc4, 0xc1, 0xc2, 0xc5, 0xcb, 0xc8, 0xc6, 0xcc, 0xc7, 0xc6, 0xcc,
+ 0xc9, 0xc0, 0xc3, 0xc5, 0xc2, 0xce, 0xcf, 0xc9, 0xbf, 0xb3, 0xb1, 0xbd,
+ 0xb8, 0xb4, 0xbe, 0xb7, 0xb6, 0xbf, 0xbb, 0xb2, 0xb3, 0xb8, 0xb4, 0xbe,
+ 0xb9, 0xbc, 0xb7, 0xb0, 0xb2, 0xb1, 0xbd, 0xba, 0xbc, 0xb6, 0xb0, 0xb9,
+ 0xb5, 0xbb, 0xba, 0xb5, 0xb0, 0xbd, 0xbe, 0xb8, 0xb7, 0xba, 0xbb, 0xb1,
+ 0xba, 0xb3, 0xb4, 0xbf, 0xbd, 0xb4, 0xb1, 0xb2, 0xb5, 0xbb, 0xb8, 0xb6,
+ 0xbc, 0xb7, 0xb6, 0xbc, 0xb9, 0xb0, 0xb3, 0xb5, 0xb2, 0xbe, 0xbf, 0xb9,
+ 0x5f, 0x53, 0x51, 0x5d, 0x58, 0x54, 0x5e, 0x57, 0x56, 0x5f, 0x5b, 0x52,
+ 0x53, 0x58, 0x54, 0x5e, 0x59, 0x5c, 0x57, 0x50, 0x52, 0x51, 0x5d, 0x5a,
+ 0x5c, 0x56, 0x50, 0x59, 0x55, 0x5b, 0x5a, 0x55, 0x50, 0x5d, 0x5e, 0x58,
+ 0x57, 0x5a, 0x5b, 0x51, 0x5a, 0x53, 0x54, 0x5f, 0x5d, 0x54, 0x51, 0x52,
+ 0x55, 0x5b, 0x58, 0x56, 0x5c, 0x57, 0x56, 0x5c, 0x59, 0x50, 0x53, 0x55,
+ 0x52, 0x5e, 0x5f, 0x59, 0x9f, 0x93, 0x91, 0x9d, 0x98, 0x94, 0x9e, 0x97,
+ 0x96, 0x9f, 0x9b, 0x92, 0x93, 0x98, 0x94, 0x9e, 0x99, 0x9c, 0x97, 0x90,
+ 0x92, 0x91, 0x9d, 0x9a, 0x9c, 0x96, 0x90, 0x99, 0x95, 0x9b, 0x9a, 0x95,
+ 0x90, 0x9d, 0x9e, 0x98, 0x97, 0x9a, 0x9b, 0x91, 0x9a, 0x93, 0x94, 0x9f,
+ 0x9d, 0x94, 0x91, 0x92, 0x95, 0x9b, 0x98, 0x96, 0x9c, 0x97, 0x96, 0x9c,
+ 0x99, 0x90, 0x93, 0x95, 0x92, 0x9e, 0x9f, 0x99, 0x9f, 0x93, 0x91, 0x9d,
+ 0x98, 0x94, 0x9e, 0x97, 0x96, 0x9f, 0x9b, 0x92, 0x93, 0x98, 0x94, 0x9e,
+ 0x99, 0x9c, 0x97, 0x90, 0x92, 0x91, 0x9d, 0x9a, 0x9c, 0x96, 0x90, 0x99,
+ 0x95, 0x9b, 0x9a, 0x95, 0x90, 0x9d, 0x9e, 0x98, 0x97, 0x9a, 0x9b, 0x91,
+ 0x9a, 0x93, 0x94, 0x9f, 0x9d, 0x94, 0x91, 0x92, 0x95, 0x9b, 0x98, 0x96,
+ 0x9c, 0x97, 0x96, 0x9c, 0x99, 0x90, 0x93, 0x95, 0x92, 0x9e, 0x9f, 0x99,
+ 0x5f, 0x53, 0x51, 0x5d, 0x58, 0x54, 0x5e, 0x57, 0x56, 0x5f, 0x5b, 0x52,
+ 0x53, 0x58, 0x54, 0x5e, 0x59, 0x5c, 0x57, 0x50, 0x52, 0x51, 0x5d, 0x5a,
+ 0x5c, 0x56, 0x50, 0x59, 0x55, 0x5b, 0x5a, 0x55, 0x50, 0x5d, 0x5e, 0x58,
+ 0x57, 0x5a, 0x5b, 0x51, 0x5a, 0x53, 0x54, 0x5f, 0x5d, 0x54, 0x51, 0x52,
+ 0x55, 0x5b, 0x58, 0x56, 0x5c, 0x57, 0x56, 0x5c, 0x59, 0x50, 0x53, 0x55,
+ 0x52, 0x5e, 0x5f, 0x59, 0x0f, 0x03, 0x01, 0x0d, 0x08, 0x04, 0x0e, 0x07,
+ 0x06, 0x0f, 0x0b, 0x02, 0x03, 0x08, 0x04, 0x0e, 0x09, 0x0c, 0x07, 0x00,
+ 0x02, 0x01, 0x0d, 0x0a, 0x0c, 0x06, 0x00, 0x09, 0x05, 0x0b, 0x0a, 0x05,
+ 0x00, 0x0d, 0x0e, 0x08, 0x07, 0x0a, 0x0b, 0x01, 0x0a, 0x03, 0x04, 0x0f,
+ 0x0d, 0x04, 0x01, 0x02, 0x05, 0x0b, 0x08, 0x06, 0x0c, 0x07, 0x06, 0x0c,
+ 0x09, 0x00, 0x03, 0x05, 0x02, 0x0e, 0x0f, 0x09, 0x3f, 0x33, 0x31, 0x3d,
+ 0x38, 0x34, 0x3e, 0x37, 0x36, 0x3f, 0x3b, 0x32, 0x33, 0x38, 0x34, 0x3e,
+ 0x39, 0x3c, 0x37, 0x30, 0x32, 0x31, 0x3d, 0x3a, 0x3c, 0x36, 0x30, 0x39,
+ 0x35, 0x3b, 0x3a, 0x35, 0x30, 0x3d, 0x3e, 0x38, 0x37, 0x3a, 0x3b, 0x31,
+ 0x3a, 0x33, 0x34, 0x3f, 0x3d, 0x34, 0x31, 0x32, 0x35, 0x3b, 0x38, 0x36,
+ 0x3c, 0x37, 0x36, 0x3c, 0x39, 0x30, 0x33, 0x35, 0x32, 0x3e, 0x3f, 0x39,
+ 0x7f, 0x73, 0x71, 0x7d, 0x78, 0x74, 0x7e, 0x77, 0x76, 0x7f, 0x7b, 0x72,
+ 0x73, 0x78, 0x74, 0x7e, 0x79, 0x7c, 0x77, 0x70, 0x72, 0x71, 0x7d, 0x7a,
+ 0x7c, 0x76, 0x70, 0x79, 0x75, 0x7b, 0x7a, 0x75, 0x70, 0x7d, 0x7e, 0x78,
+ 0x77, 0x7a, 0x7b, 0x71, 0x7a, 0x73, 0x74, 0x7f, 0x7d, 0x74, 0x71, 0x72,
+ 0x75, 0x7b, 0x78, 0x76, 0x7c, 0x77, 0x76, 0x7c, 0x79, 0x70, 0x73, 0x75,
+ 0x72, 0x7e, 0x7f, 0x79, 0x8f, 0x83, 0x81, 0x8d, 0x88, 0x84, 0x8e, 0x87,
+ 0x86, 0x8f, 0x8b, 0x82, 0x83, 0x88, 0x84, 0x8e, 0x89, 0x8c, 0x87, 0x80,
+ 0x82, 0x81, 0x8d, 0x8a, 0x8c, 0x86, 0x80, 0x89, 0x85, 0x8b, 0x8a, 0x85,
+ 0x80, 0x8d, 0x8e, 0x88, 0x87, 0x8a, 0x8b, 0x81, 0x8a, 0x83, 0x84, 0x8f,
+ 0x8d, 0x84, 0x81, 0x82, 0x85, 0x8b, 0x88, 0x86, 0x8c, 0x87, 0x86, 0x8c,
+ 0x89, 0x80, 0x83, 0x85, 0x82, 0x8e, 0x8f, 0x89, 0x4f, 0x43, 0x41, 0x4d,
+ 0x48, 0x44, 0x4e, 0x47, 0x46, 0x4f, 0x4b, 0x42, 0x43, 0x48, 0x44, 0x4e,
+ 0x49, 0x4c, 0x47, 0x40, 0x42, 0x41, 0x4d, 0x4a, 0x4c, 0x46, 0x40, 0x49,
+ 0x45, 0x4b, 0x4a, 0x45, 0x40, 0x4d, 0x4e, 0x48, 0x47, 0x4a, 0x4b, 0x41,
+ 0x4a, 0x43, 0x44, 0x4f, 0x4d, 0x44, 0x41, 0x42, 0x45, 0x4b, 0x48, 0x46,
+ 0x4c, 0x47, 0x46, 0x4c, 0x49, 0x40, 0x43, 0x45, 0x42, 0x4e, 0x4f, 0x49,
+ 0xff, 0xf3, 0xf1, 0xfd, 0xf8, 0xf4, 0xfe, 0xf7, 0xf6, 0xff, 0xfb, 0xf2,
+ 0xf3, 0xf8, 0xf4, 0xfe, 0xf9, 0xfc, 0xf7, 0xf0, 0xf2, 0xf1, 0xfd, 0xfa,
+ 0xfc, 0xf6, 0xf0, 0xf9, 0xf5, 0xfb, 0xfa, 0xf5, 0xf0, 0xfd, 0xfe, 0xf8,
+ 0xf7, 0xfa, 0xfb, 0xf1, 0xfa, 0xf3, 0xf4, 0xff, 0xfd, 0xf4, 0xf1, 0xf2,
+ 0xf5, 0xfb, 0xf8, 0xf6, 0xfc, 0xf7, 0xf6, 0xfc, 0xf9, 0xf0, 0xf3, 0xf5,
+ 0xf2, 0xfe, 0xff, 0xf9, 0x1f, 0x13, 0x11, 0x1d, 0x18, 0x14, 0x1e, 0x17,
+ 0x16, 0x1f, 0x1b, 0x12, 0x13, 0x18, 0x14, 0x1e, 0x19, 0x1c, 0x17, 0x10,
+ 0x12, 0x11, 0x1d, 0x1a, 0x1c, 0x16, 0x10, 0x19, 0x15, 0x1b, 0x1a, 0x15,
+ 0x10, 0x1d, 0x1e, 0x18, 0x17, 0x1a, 0x1b, 0x11, 0x1a, 0x13, 0x14, 0x1f,
+ 0x1d, 0x14, 0x11, 0x12, 0x15, 0x1b, 0x18, 0x16, 0x1c, 0x17, 0x16, 0x1c,
+ 0x19, 0x10, 0x13, 0x15, 0x12, 0x1e, 0x1f, 0x19, 0xcf, 0xc3, 0xc1, 0xcd,
+ 0xc8, 0xc4, 0xce, 0xc7, 0xc6, 0xcf, 0xcb, 0xc2, 0xc3, 0xc8, 0xc4, 0xce,
+ 0xc9, 0xcc, 0xc7, 0xc0, 0xc2, 0xc1, 0xcd, 0xca, 0xcc, 0xc6, 0xc0, 0xc9,
+ 0xc5, 0xcb, 0xca, 0xc5, 0xc0, 0xcd, 0xce, 0xc8, 0xc7, 0xca, 0xcb, 0xc1,
+ 0xca, 0xc3, 0xc4, 0xcf, 0xcd, 0xc4, 0xc1, 0xc2, 0xc5, 0xcb, 0xc8, 0xc6,
+ 0xcc, 0xc7, 0xc6, 0xcc, 0xc9, 0xc0, 0xc3, 0xc5, 0xc2, 0xce, 0xcf, 0xc9,
+ 0xef, 0xe3, 0xe1, 0xed, 0xe8, 0xe4, 0xee, 0xe7, 0xe6, 0xef, 0xeb, 0xe2,
+ 0xe3, 0xe8, 0xe4, 0xee, 0xe9, 0xec, 0xe7, 0xe0, 0xe2, 0xe1, 0xed, 0xea,
+ 0xec, 0xe6, 0xe0, 0xe9, 0xe5, 0xeb, 0xea, 0xe5, 0xe0, 0xed, 0xee, 0xe8,
+ 0xe7, 0xea, 0xeb, 0xe1, 0xea, 0xe3, 0xe4, 0xef, 0xed, 0xe4, 0xe1, 0xe2,
+ 0xe5, 0xeb, 0xe8, 0xe6, 0xec, 0xe7, 0xe6, 0xec, 0xe9, 0xe0, 0xe3, 0xe5,
+ 0xe2, 0xee, 0xef, 0xe9, 0x8f, 0x83, 0x81, 0x8d, 0x88, 0x84, 0x8e, 0x87,
+ 0x86, 0x8f, 0x8b, 0x82, 0x83, 0x88, 0x84, 0x8e, 0x89, 0x8c, 0x87, 0x80,
+ 0x82, 0x81, 0x8d, 0x8a, 0x8c, 0x86, 0x80, 0x89, 0x85, 0x8b, 0x8a, 0x85,
+ 0x80, 0x8d, 0x8e, 0x88, 0x87, 0x8a, 0x8b, 0x81, 0x8a, 0x83, 0x84, 0x8f,
+ 0x8d, 0x84, 0x81, 0x82, 0x85, 0x8b, 0x88, 0x86, 0x8c, 0x87, 0x86, 0x8c,
+ 0x89, 0x80, 0x83, 0x85, 0x82, 0x8e, 0x8f, 0x89, 0x8f, 0x83, 0x81, 0x8d,
+ 0x88, 0x84, 0x8e, 0x87, 0x86, 0x8f, 0x8b, 0x82, 0x83, 0x88, 0x84, 0x8e,
+ 0x89, 0x8c, 0x87, 0x80, 0x82, 0x81, 0x8d, 0x8a, 0x8c, 0x86, 0x80, 0x89,
+ 0x85, 0x8b, 0x8a, 0x85, 0x80, 0x8d, 0x8e, 0x88, 0x87, 0x8a, 0x8b, 0x81,
+ 0x8a, 0x83, 0x84, 0x8f, 0x8d, 0x84, 0x81, 0x82, 0x85, 0x8b, 0x88, 0x86,
+ 0x8c, 0x87, 0x86, 0x8c, 0x89, 0x80, 0x83, 0x85, 0x82, 0x8e, 0x8f, 0x89,
+ 0x2f, 0x23, 0x21, 0x2d, 0x28, 0x24, 0x2e, 0x27, 0x26, 0x2f, 0x2b, 0x22,
+ 0x23, 0x28, 0x24, 0x2e, 0x29, 0x2c, 0x27, 0x20, 0x22, 0x21, 0x2d, 0x2a,
+ 0x2c, 0x26, 0x20, 0x29, 0x25, 0x2b, 0x2a, 0x25, 0x20, 0x2d, 0x2e, 0x28,
+ 0x27, 0x2a, 0x2b, 0x21, 0x2a, 0x23, 0x24, 0x2f, 0x2d, 0x24, 0x21, 0x22,
+ 0x25, 0x2b, 0x28, 0x26, 0x2c, 0x27, 0x26, 0x2c, 0x29, 0x20, 0x23, 0x25,
+ 0x22, 0x2e, 0x2f, 0x29, 0xdf, 0xd3, 0xd1, 0xdd, 0xd8, 0xd4, 0xde, 0xd7,
+ 0xd6, 0xdf, 0xdb, 0xd2, 0xd3, 0xd8, 0xd4, 0xde, 0xd9, 0xdc, 0xd7, 0xd0,
+ 0xd2, 0xd1, 0xdd, 0xda, 0xdc, 0xd6, 0xd0, 0xd9, 0xd5, 0xdb, 0xda, 0xd5,
+ 0xd0, 0xdd, 0xde, 0xd8, 0xd7, 0xda, 0xdb, 0xd1, 0xda, 0xd3, 0xd4, 0xdf,
+ 0xdd, 0xd4, 0xd1, 0xd2, 0xd5, 0xdb, 0xd8, 0xd6, 0xdc, 0xd7, 0xd6, 0xdc,
+ 0xd9, 0xd0, 0xd3, 0xd5, 0xd2, 0xde, 0xdf, 0xd9, 0x4f, 0x43, 0x41, 0x4d,
+ 0x48, 0x44, 0x4e, 0x47, 0x46, 0x4f, 0x4b, 0x42, 0x43, 0x48, 0x44, 0x4e,
+ 0x49, 0x4c, 0x47, 0x40, 0x42, 0x41, 0x4d, 0x4a, 0x4c, 0x46, 0x40, 0x49,
+ 0x45, 0x4b, 0x4a, 0x45, 0x40, 0x4d, 0x4e, 0x48, 0x47, 0x4a, 0x4b, 0x41,
+ 0x4a, 0x43, 0x44, 0x4f, 0x4d, 0x44, 0x41, 0x42, 0x45, 0x4b, 0x48, 0x46,
+ 0x4c, 0x47, 0x46, 0x4c, 0x49, 0x40, 0x43, 0x45, 0x42, 0x4e, 0x4f, 0x49,
+ 0x6f, 0x63, 0x61, 0x6d, 0x68, 0x64, 0x6e, 0x67, 0x66, 0x6f, 0x6b, 0x62,
+ 0x63, 0x68, 0x64, 0x6e, 0x69, 0x6c, 0x67, 0x60, 0x62, 0x61, 0x6d, 0x6a,
+ 0x6c, 0x66, 0x60, 0x69, 0x65, 0x6b, 0x6a, 0x65, 0x60, 0x6d, 0x6e, 0x68,
+ 0x67, 0x6a, 0x6b, 0x61, 0x6a, 0x63, 0x64, 0x6f, 0x6d, 0x64, 0x61, 0x62,
+ 0x65, 0x6b, 0x68, 0x66, 0x6c, 0x67, 0x66, 0x6c, 0x69, 0x60, 0x63, 0x65,
+ 0x62, 0x6e, 0x6f, 0x69, 0x9f, 0x93, 0x91, 0x9d, 0x98, 0x94, 0x9e, 0x97,
+ 0x96, 0x9f, 0x9b, 0x92, 0x93, 0x98, 0x94, 0x9e, 0x99, 0x9c, 0x97, 0x90,
+ 0x92, 0x91, 0x9d, 0x9a, 0x9c, 0x96, 0x90, 0x99, 0x95, 0x9b, 0x9a, 0x95,
+ 0x90, 0x9d, 0x9e, 0x98, 0x97, 0x9a, 0x9b, 0x91, 0x9a, 0x93, 0x94, 0x9f,
+ 0x9d, 0x94, 0x91, 0x92, 0x95, 0x9b, 0x98, 0x96, 0x9c, 0x97, 0x96, 0x9c,
+ 0x99, 0x90, 0x93, 0x95, 0x92, 0x9e, 0x9f, 0x99, 0x2f, 0x23, 0x21, 0x2d,
+ 0x28, 0x24, 0x2e, 0x27, 0x26, 0x2f, 0x2b, 0x22, 0x23, 0x28, 0x24, 0x2e,
+ 0x29, 0x2c, 0x27, 0x20, 0x22, 0x21, 0x2d, 0x2a, 0x2c, 0x26, 0x20, 0x29,
+ 0x25, 0x2b, 0x2a, 0x25, 0x20, 0x2d, 0x2e, 0x28, 0x27, 0x2a, 0x2b, 0x21,
+ 0x2a, 0x23, 0x24, 0x2f, 0x2d, 0x24, 0x21, 0x22, 0x25, 0x2b, 0x28, 0x26,
+ 0x2c, 0x27, 0x26, 0x2c, 0x29, 0x20, 0x23, 0x25, 0x22, 0x2e, 0x2f, 0x29,
+ 0x1f, 0x13, 0x11, 0x1d, 0x18, 0x14, 0x1e, 0x17, 0x16, 0x1f, 0x1b, 0x12,
+ 0x13, 0x18, 0x14, 0x1e, 0x19, 0x1c, 0x17, 0x10, 0x12, 0x11, 0x1d, 0x1a,
+ 0x1c, 0x16, 0x10, 0x19, 0x15, 0x1b, 0x1a, 0x15, 0x10, 0x1d, 0x1e, 0x18,
+ 0x17, 0x1a, 0x1b, 0x11, 0x1a, 0x13, 0x14, 0x1f, 0x1d, 0x14, 0x11, 0x12,
+ 0x15, 0x1b, 0x18, 0x16, 0x1c, 0x17, 0x16, 0x1c, 0x19, 0x10, 0x13, 0x15,
+ 0x12, 0x1e, 0x1f, 0x19, 0xbf, 0xb3, 0xb1, 0xbd, 0xb8, 0xb4, 0xbe, 0xb7,
+ 0xb6, 0xbf, 0xbb, 0xb2, 0xb3, 0xb8, 0xb4, 0xbe, 0xb9, 0xbc, 0xb7, 0xb0,
+ 0xb2, 0xb1, 0xbd, 0xba, 0xbc, 0xb6, 0xb0, 0xb9, 0xb5, 0xbb, 0xba, 0xb5,
+ 0xb0, 0xbd, 0xbe, 0xb8, 0xb7, 0xba, 0xbb, 0xb1, 0xba, 0xb3, 0xb4, 0xbf,
+ 0xbd, 0xb4, 0xb1, 0xb2, 0xb5, 0xbb, 0xb8, 0xb6, 0xbc, 0xb7, 0xb6, 0xbc,
+ 0xb9, 0xb0, 0xb3, 0xb5, 0xb2, 0xbe, 0xbf, 0xb9, 0x7f, 0x73, 0x71, 0x7d,
+ 0x78, 0x74, 0x7e, 0x77, 0x76, 0x7f, 0x7b, 0x72, 0x73, 0x78, 0x74, 0x7e,
+ 0x79, 0x7c, 0x77, 0x70, 0x72, 0x71, 0x7d, 0x7a, 0x7c, 0x76, 0x70, 0x79,
+ 0x75, 0x7b, 0x7a, 0x75, 0x70, 0x7d, 0x7e, 0x78, 0x77, 0x7a, 0x7b, 0x71,
+ 0x7a, 0x73, 0x74, 0x7f, 0x7d, 0x74, 0x71, 0x72, 0x75, 0x7b, 0x78, 0x76,
+ 0x7c, 0x77, 0x76, 0x7c, 0x79, 0x70, 0x73, 0x75, 0x72, 0x7e, 0x7f, 0x79,
+ 0xff, 0xf3, 0xf1, 0xfd, 0xf8, 0xf4, 0xfe, 0xf7, 0xf6, 0xff, 0xfb, 0xf2,
+ 0xf3, 0xf8, 0xf4, 0xfe, 0xf9, 0xfc, 0xf7, 0xf0, 0xf2, 0xf1, 0xfd, 0xfa,
+ 0xfc, 0xf6, 0xf0, 0xf9, 0xf5, 0xfb, 0xfa, 0xf5, 0xf0, 0xfd, 0xfe, 0xf8,
+ 0xf7, 0xfa, 0xfb, 0xf1, 0xfa, 0xf3, 0xf4, 0xff, 0xfd, 0xf4, 0xf1, 0xf2,
+ 0xf5, 0xfb, 0xf8, 0xf6, 0xfc, 0xf7, 0xf6, 0xfc, 0xf9, 0xf0, 0xf3, 0xf5,
+ 0xf2, 0xfe, 0xff, 0xf9, 0x5f, 0x53, 0x51, 0x5d, 0x58, 0x54, 0x5e, 0x57,
+ 0x56, 0x5f, 0x5b, 0x52, 0x53, 0x58, 0x54, 0x5e, 0x59, 0x5c, 0x57, 0x50,
+ 0x52, 0x51, 0x5d, 0x5a, 0x5c, 0x56, 0x50, 0x59, 0x55, 0x5b, 0x5a, 0x55,
+ 0x50, 0x5d, 0x5e, 0x58, 0x57, 0x5a, 0x5b, 0x51, 0x5a, 0x53, 0x54, 0x5f,
+ 0x5d, 0x54, 0x51, 0x52, 0x55, 0x5b, 0x58, 0x56, 0x5c, 0x57, 0x56, 0x5c,
+ 0x59, 0x50, 0x53, 0x55, 0x52, 0x5e, 0x5f, 0x59, 0xcf, 0xc3, 0xc1, 0xcd,
+ 0xc8, 0xc4, 0xce, 0xc7, 0xc6, 0xcf, 0xcb, 0xc2, 0xc3, 0xc8, 0xc4, 0xce,
+ 0xc9, 0xcc, 0xc7, 0xc0, 0xc2, 0xc1, 0xcd, 0xca, 0xcc, 0xc6, 0xc0, 0xc9,
+ 0xc5, 0xcb, 0xca, 0xc5, 0xc0, 0xcd, 0xce, 0xc8, 0xc7, 0xca, 0xcb, 0xc1,
+ 0xca, 0xc3, 0xc4, 0xcf, 0xcd, 0xc4, 0xc1, 0xc2, 0xc5, 0xcb, 0xc8, 0xc6,
+ 0xcc, 0xc7, 0xc6, 0xcc, 0xc9, 0xc0, 0xc3, 0xc5, 0xc2, 0xce, 0xcf, 0xc9,
+ 0xbf, 0xb3, 0xb1, 0xbd, 0xb8, 0xb4, 0xbe, 0xb7, 0xb6, 0xbf, 0xbb, 0xb2,
+ 0xb3, 0xb8, 0xb4, 0xbe, 0xb9, 0xbc, 0xb7, 0xb0, 0xb2, 0xb1, 0xbd, 0xba,
+ 0xbc, 0xb6, 0xb0, 0xb9, 0xb5, 0xbb, 0xba, 0xb5, 0xb0, 0xbd, 0xbe, 0xb8,
+ 0xb7, 0xba, 0xbb, 0xb1, 0xba, 0xb3, 0xb4, 0xbf, 0xbd, 0xb4, 0xb1, 0xb2,
+ 0xb5, 0xbb, 0xb8, 0xb6, 0xbc, 0xb7, 0xb6, 0xbc, 0xb9, 0xb0, 0xb3, 0xb5,
+ 0xb2, 0xbe, 0xbf, 0xb9, 0x9f, 0x93, 0x91, 0x9d, 0x98, 0x94, 0x9e, 0x97,
+ 0x96, 0x9f, 0x9b, 0x92, 0x93, 0x98, 0x94, 0x9e, 0x99, 0x9c, 0x97, 0x90,
+ 0x92, 0x91, 0x9d, 0x9a, 0x9c, 0x96, 0x90, 0x99, 0x95, 0x9b, 0x9a, 0x95,
+ 0x90, 0x9d, 0x9e, 0x98, 0x97, 0x9a, 0x9b, 0x91, 0x9a, 0x93, 0x94, 0x9f,
+ 0x9d, 0x94, 0x91, 0x92, 0x95, 0x9b, 0x98, 0x96, 0x9c, 0x97, 0x96, 0x9c,
+ 0x99, 0x90, 0x93, 0x95, 0x92, 0x9e, 0x9f, 0x99, 0x3f, 0x33, 0x31, 0x3d,
+ 0x38, 0x34, 0x3e, 0x37, 0x36, 0x3f, 0x3b, 0x32, 0x33, 0x38, 0x34, 0x3e,
+ 0x39, 0x3c, 0x37, 0x30, 0x32, 0x31, 0x3d, 0x3a, 0x3c, 0x36, 0x30, 0x39,
+ 0x35, 0x3b, 0x3a, 0x35, 0x30, 0x3d, 0x3e, 0x38, 0x37, 0x3a, 0x3b, 0x31,
+ 0x3a, 0x33, 0x34, 0x3f, 0x3d, 0x34, 0x31, 0x32, 0x35, 0x3b, 0x38, 0x36,
+ 0x3c, 0x37, 0x36, 0x3c, 0x39, 0x30, 0x33, 0x35, 0x32, 0x3e, 0x3f, 0x39,
+ 0x7f, 0x73, 0x71, 0x7d, 0x78, 0x74, 0x7e, 0x77, 0x76, 0x7f, 0x7b, 0x72,
+ 0x73, 0x78, 0x74, 0x7e, 0x79, 0x7c, 0x77, 0x70, 0x72, 0x71, 0x7d, 0x7a,
+ 0x7c, 0x76, 0x70, 0x79, 0x75, 0x7b, 0x7a, 0x75, 0x70, 0x7d, 0x7e, 0x78,
+ 0x77, 0x7a, 0x7b, 0x71, 0x7a, 0x73, 0x74, 0x7f, 0x7d, 0x74, 0x71, 0x72,
+ 0x75, 0x7b, 0x78, 0x76, 0x7c, 0x77, 0x76, 0x7c, 0x79, 0x70, 0x73, 0x75,
+ 0x72, 0x7e, 0x7f, 0x79, 0xef, 0xe3, 0xe1, 0xed, 0xe8, 0xe4, 0xee, 0xe7,
+ 0xe6, 0xef, 0xeb, 0xe2, 0xe3, 0xe8, 0xe4, 0xee, 0xe9, 0xec, 0xe7, 0xe0,
+ 0xe2, 0xe1, 0xed, 0xea, 0xec, 0xe6, 0xe0, 0xe9, 0xe5, 0xeb, 0xea, 0xe5,
+ 0xe0, 0xed, 0xee, 0xe8, 0xe7, 0xea, 0xeb, 0xe1, 0xea, 0xe3, 0xe4, 0xef,
+ 0xed, 0xe4, 0xe1, 0xe2, 0xe5, 0xeb, 0xe8, 0xe6, 0xec, 0xe7, 0xe6, 0xec,
+ 0xe9, 0xe0, 0xe3, 0xe5, 0xe2, 0xee, 0xef, 0xe9, 0x3f, 0x33, 0x31, 0x3d,
+ 0x38, 0x34, 0x3e, 0x37, 0x36, 0x3f, 0x3b, 0x32, 0x33, 0x38, 0x34, 0x3e,
+ 0x39, 0x3c, 0x37, 0x30, 0x32, 0x31, 0x3d, 0x3a, 0x3c, 0x36, 0x30, 0x39,
+ 0x35, 0x3b, 0x3a, 0x35, 0x30, 0x3d, 0x3e, 0x38, 0x37, 0x3a, 0x3b, 0x31,
+ 0x3a, 0x33, 0x34, 0x3f, 0x3d, 0x34, 0x31, 0x32, 0x35, 0x3b, 0x38, 0x36,
+ 0x3c, 0x37, 0x36, 0x3c, 0x39, 0x30, 0x33, 0x35, 0x32, 0x3e, 0x3f, 0x39,
+ 0xaf, 0xa3, 0xa1, 0xad, 0xa8, 0xa4, 0xae, 0xa7, 0xa6, 0xaf, 0xab, 0xa2,
+ 0xa3, 0xa8, 0xa4, 0xae, 0xa9, 0xac, 0xa7, 0xa0, 0xa2, 0xa1, 0xad, 0xaa,
+ 0xac, 0xa6, 0xa0, 0xa9, 0xa5, 0xab, 0xaa, 0xa5, 0xa0, 0xad, 0xae, 0xa8,
+ 0xa7, 0xaa, 0xab, 0xa1, 0xaa, 0xa3, 0xa4, 0xaf, 0xad, 0xa4, 0xa1, 0xa2,
+ 0xa5, 0xab, 0xa8, 0xa6, 0xac, 0xa7, 0xa6, 0xac, 0xa9, 0xa0, 0xa3, 0xa5,
+ 0xa2, 0xae, 0xaf, 0xa9, 0xaf, 0xa3, 0xa1, 0xad, 0xa8, 0xa4, 0xae, 0xa7,
+ 0xa6, 0xaf, 0xab, 0xa2, 0xa3, 0xa8, 0xa4, 0xae, 0xa9, 0xac, 0xa7, 0xa0,
+ 0xa2, 0xa1, 0xad, 0xaa, 0xac, 0xa6, 0xa0, 0xa9, 0xa5, 0xab, 0xaa, 0xa5,
+ 0xa0, 0xad, 0xae, 0xa8, 0xa7, 0xaa, 0xab, 0xa1, 0xaa, 0xa3, 0xa4, 0xaf,
+ 0xad, 0xa4, 0xa1, 0xa2, 0xa5, 0xab, 0xa8, 0xa6, 0xac, 0xa7, 0xa6, 0xac,
+ 0xa9, 0xa0, 0xa3, 0xa5, 0xa2, 0xae, 0xaf, 0xa9, 0x0f, 0x03, 0x01, 0x0d,
+ 0x08, 0x04, 0x0e, 0x07, 0x06, 0x0f, 0x0b, 0x02, 0x03, 0x08, 0x04, 0x0e,
+ 0x09, 0x0c, 0x07, 0x00, 0x02, 0x01, 0x0d, 0x0a, 0x0c, 0x06, 0x00, 0x09,
+ 0x05, 0x0b, 0x0a, 0x05, 0x00, 0x0d, 0x0e, 0x08, 0x07, 0x0a, 0x0b, 0x01,
+ 0x0a, 0x03, 0x04, 0x0f, 0x0d, 0x04, 0x01, 0x02, 0x05, 0x0b, 0x08, 0x06,
+ 0x0c, 0x07, 0x06, 0x0c, 0x09, 0x00, 0x03, 0x05, 0x02, 0x0e, 0x0f, 0x09,
+ 0x5f, 0x53, 0x51, 0x5d, 0x58, 0x54, 0x5e, 0x57, 0x56, 0x5f, 0x5b, 0x52,
+ 0x53, 0x58, 0x54, 0x5e, 0x59, 0x5c, 0x57, 0x50, 0x52, 0x51, 0x5d, 0x5a,
+ 0x5c, 0x56, 0x50, 0x59, 0x55, 0x5b, 0x5a, 0x55, 0x50, 0x5d, 0x5e, 0x58,
+ 0x57, 0x5a, 0x5b, 0x51, 0x5a, 0x53, 0x54, 0x5f, 0x5d, 0x54, 0x51, 0x52,
+ 0x55, 0x5b, 0x58, 0x56, 0x5c, 0x57, 0x56, 0x5c, 0x59, 0x50, 0x53, 0x55,
+ 0x52, 0x5e, 0x5f, 0x59, 0x6f, 0x63, 0x61, 0x6d, 0x68, 0x64, 0x6e, 0x67,
+ 0x66, 0x6f, 0x6b, 0x62, 0x63, 0x68, 0x64, 0x6e, 0x69, 0x6c, 0x67, 0x60,
+ 0x62, 0x61, 0x6d, 0x6a, 0x6c, 0x66, 0x60, 0x69, 0x65, 0x6b, 0x6a, 0x65,
+ 0x60, 0x6d, 0x6e, 0x68, 0x67, 0x6a, 0x6b, 0x61, 0x6a, 0x63, 0x64, 0x6f,
+ 0x6d, 0x64, 0x61, 0x62, 0x65, 0x6b, 0x68, 0x66, 0x6c, 0x67, 0x66, 0x6c,
+ 0x69, 0x60, 0x63, 0x65, 0x62, 0x6e, 0x6f, 0x69, 0x0f, 0x03, 0x01, 0x0d,
+ 0x08, 0x04, 0x0e, 0x07, 0x06, 0x0f, 0x0b, 0x02, 0x03, 0x08, 0x04, 0x0e,
+ 0x09, 0x0c, 0x07, 0x00, 0x02, 0x01, 0x0d, 0x0a, 0x0c, 0x06, 0x00, 0x09,
+ 0x05, 0x0b, 0x0a, 0x05, 0x00, 0x0d, 0x0e, 0x08, 0x07, 0x0a, 0x0b, 0x01,
+ 0x0a, 0x03, 0x04, 0x0f, 0x0d, 0x04, 0x01, 0x02, 0x05, 0x0b, 0x08, 0x06,
+ 0x0c, 0x07, 0x06, 0x0c, 0x09, 0x00, 0x03, 0x05, 0x02, 0x0e, 0x0f, 0x09,
+ 0xdf, 0xd3, 0xd1, 0xdd, 0xd8, 0xd4, 0xde, 0xd7, 0xd6, 0xdf, 0xdb, 0xd2,
+ 0xd3, 0xd8, 0xd4, 0xde, 0xd9, 0xdc, 0xd7, 0xd0, 0xd2, 0xd1, 0xdd, 0xda,
+ 0xdc, 0xd6, 0xd0, 0xd9, 0xd5, 0xdb, 0xda, 0xd5, 0xd0, 0xdd, 0xde, 0xd8,
+ 0xd7, 0xda, 0xdb, 0xd1, 0xda, 0xd3, 0xd4, 0xdf, 0xdd, 0xd4, 0xd1, 0xd2,
+ 0xd5, 0xdb, 0xd8, 0xd6, 0xdc, 0xd7, 0xd6, 0xdc, 0xd9, 0xd0, 0xd3, 0xd5,
+ 0xd2, 0xde, 0xdf, 0xd9,
+ },
+ {
+ 0xa7, 0xad, 0xad, 0xa8, 0xae, 0xab, 0xa3, 0xa5, 0xa0, 0xa6, 0xa6, 0xaf,
+ 0xa9, 0xa0, 0xaa, 0xa3, 0xa1, 0xa4, 0xa2, 0xa7, 0xa8, 0xa2, 0xa5, 0xac,
+ 0xab, 0xa1, 0xac, 0xaa, 0xa4, 0xae, 0xaf, 0xa9, 0xaa, 0xa3, 0xa6, 0xaf,
+ 0xa9, 0xa0, 0xa0, 0xa6, 0xac, 0xaa, 0xab, 0xa1, 0xa7, 0xad, 0xad, 0xa8,
+ 0xaf, 0xa9, 0xa1, 0xa4, 0xa3, 0xa5, 0xae, 0xab, 0xa5, 0xac, 0xa2, 0xa7,
+ 0xa8, 0xa2, 0xa4, 0xae, 0xd7, 0xdd, 0xdd, 0xd8, 0xde, 0xdb, 0xd3, 0xd5,
+ 0xd0, 0xd6, 0xd6, 0xdf, 0xd9, 0xd0, 0xda, 0xd3, 0xd1, 0xd4, 0xd2, 0xd7,
+ 0xd8, 0xd2, 0xd5, 0xdc, 0xdb, 0xd1, 0xdc, 0xda, 0xd4, 0xde, 0xdf, 0xd9,
+ 0xda, 0xd3, 0xd6, 0xdf, 0xd9, 0xd0, 0xd0, 0xd6, 0xdc, 0xda, 0xdb, 0xd1,
+ 0xd7, 0xdd, 0xdd, 0xd8, 0xdf, 0xd9, 0xd1, 0xd4, 0xd3, 0xd5, 0xde, 0xdb,
+ 0xd5, 0xdc, 0xd2, 0xd7, 0xd8, 0xd2, 0xd4, 0xde, 0x07, 0x0d, 0x0d, 0x08,
+ 0x0e, 0x0b, 0x03, 0x05, 0x00, 0x06, 0x06, 0x0f, 0x09, 0x00, 0x0a, 0x03,
+ 0x01, 0x04, 0x02, 0x07, 0x08, 0x02, 0x05, 0x0c, 0x0b, 0x01, 0x0c, 0x0a,
+ 0x04, 0x0e, 0x0f, 0x09, 0x0a, 0x03, 0x06, 0x0f, 0x09, 0x00, 0x00, 0x06,
+ 0x0c, 0x0a, 0x0b, 0x01, 0x07, 0x0d, 0x0d, 0x08, 0x0f, 0x09, 0x01, 0x04,
+ 0x03, 0x05, 0x0e, 0x0b, 0x05, 0x0c, 0x02, 0x07, 0x08, 0x02, 0x04, 0x0e,
+ 0x77, 0x7d, 0x7d, 0x78, 0x7e, 0x7b, 0x73, 0x75, 0x70, 0x76, 0x76, 0x7f,
+ 0x79, 0x70, 0x7a, 0x73, 0x71, 0x74, 0x72, 0x77, 0x78, 0x72, 0x75, 0x7c,
+ 0x7b, 0x71, 0x7c, 0x7a, 0x74, 0x7e, 0x7f, 0x79, 0x7a, 0x73, 0x76, 0x7f,
+ 0x79, 0x70, 0x70, 0x76, 0x7c, 0x7a, 0x7b, 0x71, 0x77, 0x7d, 0x7d, 0x78,
+ 0x7f, 0x79, 0x71, 0x74, 0x73, 0x75, 0x7e, 0x7b, 0x75, 0x7c, 0x72, 0x77,
+ 0x78, 0x72, 0x74, 0x7e, 0x97, 0x9d, 0x9d, 0x98, 0x9e, 0x9b, 0x93, 0x95,
+ 0x90, 0x96, 0x96, 0x9f, 0x99, 0x90, 0x9a, 0x93, 0x91, 0x94, 0x92, 0x97,
+ 0x98, 0x92, 0x95, 0x9c, 0x9b, 0x91, 0x9c, 0x9a, 0x94, 0x9e, 0x9f, 0x99,
+ 0x9a, 0x93, 0x96, 0x9f, 0x99, 0x90, 0x90, 0x96, 0x9c, 0x9a, 0x9b, 0x91,
+ 0x97, 0x9d, 0x9d, 0x98, 0x9f, 0x99, 0x91, 0x94, 0x93, 0x95, 0x9e, 0x9b,
+ 0x95, 0x9c, 0x92, 0x97, 0x98, 0x92, 0x94, 0x9e, 0x07, 0x0d, 0x0d, 0x08,
+ 0x0e, 0x0b, 0x03, 0x05, 0x00, 0x06, 0x06, 0x0f, 0x09, 0x00, 0x0a, 0x03,
+ 0x01, 0x04, 0x02, 0x07, 0x08, 0x02, 0x05, 0x0c, 0x0b, 0x01, 0x0c, 0x0a,
+ 0x04, 0x0e, 0x0f, 0x09, 0x0a, 0x03, 0x06, 0x0f, 0x09, 0x00, 0x00, 0x06,
+ 0x0c, 0x0a, 0x0b, 0x01, 0x07, 0x0d, 0x0d, 0x08, 0x0f, 0x09, 0x01, 0x04,
+ 0x03, 0x05, 0x0e, 0x0b, 0x05, 0x0c, 0x02, 0x07, 0x08, 0x02, 0x04, 0x0e,
+ 0xe7, 0xed, 0xed, 0xe8, 0xee, 0xeb, 0xe3, 0xe5, 0xe0, 0xe6, 0xe6, 0xef,
+ 0xe9, 0xe0, 0xea, 0xe3, 0xe1, 0xe4, 0xe2, 0xe7, 0xe8, 0xe2, 0xe5, 0xec,
+ 0xeb, 0xe1, 0xec, 0xea, 0xe4, 0xee, 0xef, 0xe9, 0xea, 0xe3, 0xe6, 0xef,
+ 0xe9, 0xe0, 0xe0, 0xe6, 0xec, 0xea, 0xeb, 0xe1, 0xe7, 0xed, 0xed, 0xe8,
+ 0xef, 0xe9, 0xe1, 0xe4, 0xe3, 0xe5, 0xee, 0xeb, 0xe5, 0xec, 0xe2, 0xe7,
+ 0xe8, 0xe2, 0xe4, 0xee, 0x97, 0x9d, 0x9d, 0x98, 0x9e, 0x9b, 0x93, 0x95,
+ 0x90, 0x96, 0x96, 0x9f, 0x99, 0x90, 0x9a, 0x93, 0x91, 0x94, 0x92, 0x97,
+ 0x98, 0x92, 0x95, 0x9c, 0x9b, 0x91, 0x9c, 0x9a, 0x94, 0x9e, 0x9f, 0x99,
+ 0x9a, 0x93, 0x96, 0x9f, 0x99, 0x90, 0x90, 0x96, 0x9c, 0x9a, 0x9b, 0x91,
+ 0x97, 0x9d, 0x9d, 0x98, 0x9f, 0x99, 0x91, 0x94, 0x93, 0x95, 0x9e, 0x9b,
+ 0x95, 0x9c, 0x92, 0x97, 0x98, 0x92, 0x94, 0x9e, 0x67, 0x6d, 0x6d, 0x68,
+ 0x6e, 0x6b, 0x63, 0x65, 0x60, 0x66, 0x66, 0x6f, 0x69, 0x60, 0x6a, 0x63,
+ 0x61, 0x64, 0x62, 0x67, 0x68, 0x62, 0x65, 0x6c, 0x6b, 0x61, 0x6c, 0x6a,
+ 0x64, 0x6e, 0x6f, 0x69, 0x6a, 0x63, 0x66, 0x6f, 0x69, 0x60, 0x60, 0x66,
+ 0x6c, 0x6a, 0x6b, 0x61, 0x67, 0x6d, 0x6d, 0x68, 0x6f, 0x69, 0x61, 0x64,
+ 0x63, 0x65, 0x6e, 0x6b, 0x65, 0x6c, 0x62, 0x67, 0x68, 0x62, 0x64, 0x6e,
+ 0x37, 0x3d, 0x3d, 0x38, 0x3e, 0x3b, 0x33, 0x35, 0x30, 0x36, 0x36, 0x3f,
+ 0x39, 0x30, 0x3a, 0x33, 0x31, 0x34, 0x32, 0x37, 0x38, 0x32, 0x35, 0x3c,
+ 0x3b, 0x31, 0x3c, 0x3a, 0x34, 0x3e, 0x3f, 0x39, 0x3a, 0x33, 0x36, 0x3f,
+ 0x39, 0x30, 0x30, 0x36, 0x3c, 0x3a, 0x3b, 0x31, 0x37, 0x3d, 0x3d, 0x38,
+ 0x3f, 0x39, 0x31, 0x34, 0x33, 0x35, 0x3e, 0x3b, 0x35, 0x3c, 0x32, 0x37,
+ 0x38, 0x32, 0x34, 0x3e, 0x37, 0x3d, 0x3d, 0x38, 0x3e, 0x3b, 0x33, 0x35,
+ 0x30, 0x36, 0x36, 0x3f, 0x39, 0x30, 0x3a, 0x33, 0x31, 0x34, 0x32, 0x37,
+ 0x38, 0x32, 0x35, 0x3c, 0x3b, 0x31, 0x3c, 0x3a, 0x34, 0x3e, 0x3f, 0x39,
+ 0x3a, 0x33, 0x36, 0x3f, 0x39, 0x30, 0x30, 0x36, 0x3c, 0x3a, 0x3b, 0x31,
+ 0x37, 0x3d, 0x3d, 0x38, 0x3f, 0x39, 0x31, 0x34, 0x33, 0x35, 0x3e, 0x3b,
+ 0x35, 0x3c, 0x32, 0x37, 0x38, 0x32, 0x34, 0x3e, 0x47, 0x4d, 0x4d, 0x48,
+ 0x4e, 0x4b, 0x43, 0x45, 0x40, 0x46, 0x46, 0x4f, 0x49, 0x40, 0x4a, 0x43,
+ 0x41, 0x44, 0x42, 0x47, 0x48, 0x42, 0x45, 0x4c, 0x4b, 0x41, 0x4c, 0x4a,
+ 0x44, 0x4e, 0x4f, 0x49, 0x4a, 0x43, 0x46, 0x4f, 0x49, 0x40, 0x40, 0x46,
+ 0x4c, 0x4a, 0x4b, 0x41, 0x47, 0x4d, 0x4d, 0x48, 0x4f, 0x49, 0x41, 0x44,
+ 0x43, 0x45, 0x4e, 0x4b, 0x45, 0x4c, 0x42, 0x47, 0x48, 0x42, 0x44, 0x4e,
+ 0xf7, 0xfd, 0xfd, 0xf8, 0xfe, 0xfb, 0xf3, 0xf5, 0xf0, 0xf6, 0xf6, 0xff,
+ 0xf9, 0xf0, 0xfa, 0xf3, 0xf1, 0xf4, 0xf2, 0xf7, 0xf8, 0xf2, 0xf5, 0xfc,
+ 0xfb, 0xf1, 0xfc, 0xfa, 0xf4, 0xfe, 0xff, 0xf9, 0xfa, 0xf3, 0xf6, 0xff,
+ 0xf9, 0xf0, 0xf0, 0xf6, 0xfc, 0xfa, 0xfb, 0xf1, 0xf7, 0xfd, 0xfd, 0xf8,
+ 0xff, 0xf9, 0xf1, 0xf4, 0xf3, 0xf5, 0xfe, 0xfb, 0xf5, 0xfc, 0xf2, 0xf7,
+ 0xf8, 0xf2, 0xf4, 0xfe, 0x67, 0x6d, 0x6d, 0x68, 0x6e, 0x6b, 0x63, 0x65,
+ 0x60, 0x66, 0x66, 0x6f, 0x69, 0x60, 0x6a, 0x63, 0x61, 0x64, 0x62, 0x67,
+ 0x68, 0x62, 0x65, 0x6c, 0x6b, 0x61, 0x6c, 0x6a, 0x64, 0x6e, 0x6f, 0x69,
+ 0x6a, 0x63, 0x66, 0x6f, 0x69, 0x60, 0x60, 0x66, 0x6c, 0x6a, 0x6b, 0x61,
+ 0x67, 0x6d, 0x6d, 0x68, 0x6f, 0x69, 0x61, 0x64, 0x63, 0x65, 0x6e, 0x6b,
+ 0x65, 0x6c, 0x62, 0x67, 0x68, 0x62, 0x64, 0x6e, 0x57, 0x5d, 0x5d, 0x58,
+ 0x5e, 0x5b, 0x53, 0x55, 0x50, 0x56, 0x56, 0x5f, 0x59, 0x50, 0x5a, 0x53,
+ 0x51, 0x54, 0x52, 0x57, 0x58, 0x52, 0x55, 0x5c, 0x5b, 0x51, 0x5c, 0x5a,
+ 0x54, 0x5e, 0x5f, 0x59, 0x5a, 0x53, 0x56, 0x5f, 0x59, 0x50, 0x50, 0x56,
+ 0x5c, 0x5a, 0x5b, 0x51, 0x57, 0x5d, 0x5d, 0x58, 0x5f, 0x59, 0x51, 0x54,
+ 0x53, 0x55, 0x5e, 0x5b, 0x55, 0x5c, 0x52, 0x57, 0x58, 0x52, 0x54, 0x5e,
+ 0xa7, 0xad, 0xad, 0xa8, 0xae, 0xab, 0xa3, 0xa5, 0xa0, 0xa6, 0xa6, 0xaf,
+ 0xa9, 0xa0, 0xaa, 0xa3, 0xa1, 0xa4, 0xa2, 0xa7, 0xa8, 0xa2, 0xa5, 0xac,
+ 0xab, 0xa1, 0xac, 0xaa, 0xa4, 0xae, 0xaf, 0xa9, 0xaa, 0xa3, 0xa6, 0xaf,
+ 0xa9, 0xa0, 0xa0, 0xa6, 0xac, 0xaa, 0xab, 0xa1, 0xa7, 0xad, 0xad, 0xa8,
+ 0xaf, 0xa9, 0xa1, 0xa4, 0xa3, 0xa5, 0xae, 0xab, 0xa5, 0xac, 0xa2, 0xa7,
+ 0xa8, 0xa2, 0xa4, 0xae, 0x17, 0x1d, 0x1d, 0x18, 0x1e, 0x1b, 0x13, 0x15,
+ 0x10, 0x16, 0x16, 0x1f, 0x19, 0x10, 0x1a, 0x13, 0x11, 0x14, 0x12, 0x17,
+ 0x18, 0x12, 0x15, 0x1c, 0x1b, 0x11, 0x1c, 0x1a, 0x14, 0x1e, 0x1f, 0x19,
+ 0x1a, 0x13, 0x16, 0x1f, 0x19, 0x10, 0x10, 0x16, 0x1c, 0x1a, 0x1b, 0x11,
+ 0x17, 0x1d, 0x1d, 0x18, 0x1f, 0x19, 0x11, 0x14, 0x13, 0x15, 0x1e, 0x1b,
+ 0x15, 0x1c, 0x12, 0x17, 0x18, 0x12, 0x14, 0x1e, 0x27, 0x2d, 0x2d, 0x28,
+ 0x2e, 0x2b, 0x23, 0x25, 0x20, 0x26, 0x26, 0x2f, 0x29, 0x20, 0x2a, 0x23,
+ 0x21, 0x24, 0x22, 0x27, 0x28, 0x22, 0x25, 0x2c, 0x2b, 0x21, 0x2c, 0x2a,
+ 0x24, 0x2e, 0x2f, 0x29, 0x2a, 0x23, 0x26, 0x2f, 0x29, 0x20, 0x20, 0x26,
+ 0x2c, 0x2a, 0x2b, 0x21, 0x27, 0x2d, 0x2d, 0x28, 0x2f, 0x29, 0x21, 0x24,
+ 0x23, 0x25, 0x2e, 0x2b, 0x25, 0x2c, 0x22, 0x27, 0x28, 0x22, 0x24, 0x2e,
+ 0xd7, 0xdd, 0xdd, 0xd8, 0xde, 0xdb, 0xd3, 0xd5, 0xd0, 0xd6, 0xd6, 0xdf,
+ 0xd9, 0xd0, 0xda, 0xd3, 0xd1, 0xd4, 0xd2, 0xd7, 0xd8, 0xd2, 0xd5, 0xdc,
+ 0xdb, 0xd1, 0xdc, 0xda, 0xd4, 0xde, 0xdf, 0xd9, 0xda, 0xd3, 0xd6, 0xdf,
+ 0xd9, 0xd0, 0xd0, 0xd6, 0xdc, 0xda, 0xdb, 0xd1, 0xd7, 0xdd, 0xdd, 0xd8,
+ 0xdf, 0xd9, 0xd1, 0xd4, 0xd3, 0xd5, 0xde, 0xdb, 0xd5, 0xdc, 0xd2, 0xd7,
+ 0xd8, 0xd2, 0xd4, 0xde, 0x87, 0x8d, 0x8d, 0x88, 0x8e, 0x8b, 0x83, 0x85,
+ 0x80, 0x86, 0x86, 0x8f, 0x89, 0x80, 0x8a, 0x83, 0x81, 0x84, 0x82, 0x87,
+ 0x88, 0x82, 0x85, 0x8c, 0x8b, 0x81, 0x8c, 0x8a, 0x84, 0x8e, 0x8f, 0x89,
+ 0x8a, 0x83, 0x86, 0x8f, 0x89, 0x80, 0x80, 0x86, 0x8c, 0x8a, 0x8b, 0x81,
+ 0x87, 0x8d, 0x8d, 0x88, 0x8f, 0x89, 0x81, 0x84, 0x83, 0x85, 0x8e, 0x8b,
+ 0x85, 0x8c, 0x82, 0x87, 0x88, 0x82, 0x84, 0x8e, 0xc7, 0xcd, 0xcd, 0xc8,
+ 0xce, 0xcb, 0xc3, 0xc5, 0xc0, 0xc6, 0xc6, 0xcf, 0xc9, 0xc0, 0xca, 0xc3,
+ 0xc1, 0xc4, 0xc2, 0xc7, 0xc8, 0xc2, 0xc5, 0xcc, 0xcb, 0xc1, 0xcc, 0xca,
+ 0xc4, 0xce, 0xcf, 0xc9, 0xca, 0xc3, 0xc6, 0xcf, 0xc9, 0xc0, 0xc0, 0xc6,
+ 0xcc, 0xca, 0xcb, 0xc1, 0xc7, 0xcd, 0xcd, 0xc8, 0xcf, 0xc9, 0xc1, 0xc4,
+ 0xc3, 0xc5, 0xce, 0xcb, 0xc5, 0xcc, 0xc2, 0xc7, 0xc8, 0xc2, 0xc4, 0xce,
+ 0x57, 0x5d, 0x5d, 0x58, 0x5e, 0x5b, 0x53, 0x55, 0x50, 0x56, 0x56, 0x5f,
+ 0x59, 0x50, 0x5a, 0x53, 0x51, 0x54, 0x52, 0x57, 0x58, 0x52, 0x55, 0x5c,
+ 0x5b, 0x51, 0x5c, 0x5a, 0x54, 0x5e, 0x5f, 0x59, 0x5a, 0x53, 0x56, 0x5f,
+ 0x59, 0x50, 0x50, 0x56, 0x5c, 0x5a, 0x5b, 0x51, 0x57, 0x5d, 0x5d, 0x58,
+ 0x5f, 0x59, 0x51, 0x54, 0x53, 0x55, 0x5e, 0x5b, 0x55, 0x5c, 0x52, 0x57,
+ 0x58, 0x52, 0x54, 0x5e, 0x77, 0x7d, 0x7d, 0x78, 0x7e, 0x7b, 0x73, 0x75,
+ 0x70, 0x76, 0x76, 0x7f, 0x79, 0x70, 0x7a, 0x73, 0x71, 0x74, 0x72, 0x77,
+ 0x78, 0x72, 0x75, 0x7c, 0x7b, 0x71, 0x7c, 0x7a, 0x74, 0x7e, 0x7f, 0x79,
+ 0x7a, 0x73, 0x76, 0x7f, 0x79, 0x70, 0x70, 0x76, 0x7c, 0x7a, 0x7b, 0x71,
+ 0x77, 0x7d, 0x7d, 0x78, 0x7f, 0x79, 0x71, 0x74, 0x73, 0x75, 0x7e, 0x7b,
+ 0x75, 0x7c, 0x72, 0x77, 0x78, 0x72, 0x74, 0x7e, 0xe7, 0xed, 0xed, 0xe8,
+ 0xee, 0xeb, 0xe3, 0xe5, 0xe0, 0xe6, 0xe6, 0xef, 0xe9, 0xe0, 0xea, 0xe3,
+ 0xe1, 0xe4, 0xe2, 0xe7, 0xe8, 0xe2, 0xe5, 0xec, 0xeb, 0xe1, 0xec, 0xea,
+ 0xe4, 0xee, 0xef, 0xe9, 0xea, 0xe3, 0xe6, 0xef, 0xe9, 0xe0, 0xe0, 0xe6,
+ 0xec, 0xea, 0xeb, 0xe1, 0xe7, 0xed, 0xed, 0xe8, 0xef, 0xe9, 0xe1, 0xe4,
+ 0xe3, 0xe5, 0xee, 0xeb, 0xe5, 0xec, 0xe2, 0xe7, 0xe8, 0xe2, 0xe4, 0xee,
+ 0xb7, 0xbd, 0xbd, 0xb8, 0xbe, 0xbb, 0xb3, 0xb5, 0xb0, 0xb6, 0xb6, 0xbf,
+ 0xb9, 0xb0, 0xba, 0xb3, 0xb1, 0xb4, 0xb2, 0xb7, 0xb8, 0xb2, 0xb5, 0xbc,
+ 0xbb, 0xb1, 0xbc, 0xba, 0xb4, 0xbe, 0xbf, 0xb9, 0xba, 0xb3, 0xb6, 0xbf,
+ 0xb9, 0xb0, 0xb0, 0xb6, 0xbc, 0xba, 0xbb, 0xb1, 0xb7, 0xbd, 0xbd, 0xb8,
+ 0xbf, 0xb9, 0xb1, 0xb4, 0xb3, 0xb5, 0xbe, 0xbb, 0xb5, 0xbc, 0xb2, 0xb7,
+ 0xb8, 0xb2, 0xb4, 0xbe, 0xc7, 0xcd, 0xcd, 0xc8, 0xce, 0xcb, 0xc3, 0xc5,
+ 0xc0, 0xc6, 0xc6, 0xcf, 0xc9, 0xc0, 0xca, 0xc3, 0xc1, 0xc4, 0xc2, 0xc7,
+ 0xc8, 0xc2, 0xc5, 0xcc, 0xcb, 0xc1, 0xcc, 0xca, 0xc4, 0xce, 0xcf, 0xc9,
+ 0xca, 0xc3, 0xc6, 0xcf, 0xc9, 0xc0, 0xc0, 0xc6, 0xcc, 0xca, 0xcb, 0xc1,
+ 0xc7, 0xcd, 0xcd, 0xc8, 0xcf, 0xc9, 0xc1, 0xc4, 0xc3, 0xc5, 0xce, 0xcb,
+ 0xc5, 0xcc, 0xc2, 0xc7, 0xc8, 0xc2, 0xc4, 0xce, 0x47, 0x4d, 0x4d, 0x48,
+ 0x4e, 0x4b, 0x43, 0x45, 0x40, 0x46, 0x46, 0x4f, 0x49, 0x40, 0x4a, 0x43,
+ 0x41, 0x44, 0x42, 0x47, 0x48, 0x42, 0x45, 0x4c, 0x4b, 0x41, 0x4c, 0x4a,
+ 0x44, 0x4e, 0x4f, 0x49, 0x4a, 0x43, 0x46, 0x4f, 0x49, 0x40, 0x40, 0x46,
+ 0x4c, 0x4a, 0x4b, 0x41, 0x47, 0x4d, 0x4d, 0x48, 0x4f, 0x49, 0x41, 0x44,
+ 0x43, 0x45, 0x4e, 0x4b, 0x45, 0x4c, 0x42, 0x47, 0x48, 0x42, 0x44, 0x4e,
+ 0xb7, 0xbd, 0xbd, 0xb8, 0xbe, 0xbb, 0xb3, 0xb5, 0xb0, 0xb6, 0xb6, 0xbf,
+ 0xb9, 0xb0, 0xba, 0xb3, 0xb1, 0xb4, 0xb2, 0xb7, 0xb8, 0xb2, 0xb5, 0xbc,
+ 0xbb, 0xb1, 0xbc, 0xba, 0xb4, 0xbe, 0xbf, 0xb9, 0xba, 0xb3, 0xb6, 0xbf,
+ 0xb9, 0xb0, 0xb0, 0xb6, 0xbc, 0xba, 0xbb, 0xb1, 0xb7, 0xbd, 0xbd, 0xb8,
+ 0xbf, 0xb9, 0xb1, 0xb4, 0xb3, 0xb5, 0xbe, 0xbb, 0xb5, 0xbc, 0xb2, 0xb7,
+ 0xb8, 0xb2, 0xb4, 0xbe, 0x27, 0x2d, 0x2d, 0x28, 0x2e, 0x2b, 0x23, 0x25,
+ 0x20, 0x26, 0x26, 0x2f, 0x29, 0x20, 0x2a, 0x23, 0x21, 0x24, 0x22, 0x27,
+ 0x28, 0x22, 0x25, 0x2c, 0x2b, 0x21, 0x2c, 0x2a, 0x24, 0x2e, 0x2f, 0x29,
+ 0x2a, 0x23, 0x26, 0x2f, 0x29, 0x20, 0x20, 0x26, 0x2c, 0x2a, 0x2b, 0x21,
+ 0x27, 0x2d, 0x2d, 0x28, 0x2f, 0x29, 0x21, 0x24, 0x23, 0x25, 0x2e, 0x2b,
+ 0x25, 0x2c, 0x22, 0x27, 0x28, 0x22, 0x24, 0x2e, 0xf7, 0xfd, 0xfd, 0xf8,
+ 0xfe, 0xfb, 0xf3, 0xf5, 0xf0, 0xf6, 0xf6, 0xff, 0xf9, 0xf0, 0xfa, 0xf3,
+ 0xf1, 0xf4, 0xf2, 0xf7, 0xf8, 0xf2, 0xf5, 0xfc, 0xfb, 0xf1, 0xfc, 0xfa,
+ 0xf4, 0xfe, 0xff, 0xf9, 0xfa, 0xf3, 0xf6, 0xff, 0xf9, 0xf0, 0xf0, 0xf6,
+ 0xfc, 0xfa, 0xfb, 0xf1, 0xf7, 0xfd, 0xfd, 0xf8, 0xff, 0xf9, 0xf1, 0xf4,
+ 0xf3, 0xf5, 0xfe, 0xfb, 0xf5, 0xfc, 0xf2, 0xf7, 0xf8, 0xf2, 0xf4, 0xfe,
+ 0x87, 0x8d, 0x8d, 0x88, 0x8e, 0x8b, 0x83, 0x85, 0x80, 0x86, 0x86, 0x8f,
+ 0x89, 0x80, 0x8a, 0x83, 0x81, 0x84, 0x82, 0x87, 0x88, 0x82, 0x85, 0x8c,
+ 0x8b, 0x81, 0x8c, 0x8a, 0x84, 0x8e, 0x8f, 0x89, 0x8a, 0x83, 0x86, 0x8f,
+ 0x89, 0x80, 0x80, 0x86, 0x8c, 0x8a, 0x8b, 0x81, 0x87, 0x8d, 0x8d, 0x88,
+ 0x8f, 0x89, 0x81, 0x84, 0x83, 0x85, 0x8e, 0x8b, 0x85, 0x8c, 0x82, 0x87,
+ 0x88, 0x82, 0x84, 0x8e, 0x17, 0x1d, 0x1d, 0x18, 0x1e, 0x1b, 0x13, 0x15,
+ 0x10, 0x16, 0x16, 0x1f, 0x19, 0x10, 0x1a, 0x13, 0x11, 0x14, 0x12, 0x17,
+ 0x18, 0x12, 0x15, 0x1c, 0x1b, 0x11, 0x1c, 0x1a, 0x14, 0x1e, 0x1f, 0x19,
+ 0x1a, 0x13, 0x16, 0x1f, 0x19, 0x10, 0x10, 0x16, 0x1c, 0x1a, 0x1b, 0x11,
+ 0x17, 0x1d, 0x1d, 0x18, 0x1f, 0x19, 0x11, 0x14, 0x13, 0x15, 0x1e, 0x1b,
+ 0x15, 0x1c, 0x12, 0x17, 0x18, 0x12, 0x14, 0x1e, 0xd7, 0xdd, 0xdd, 0xd8,
+ 0xde, 0xdb, 0xd3, 0xd5, 0xd0, 0xd6, 0xd6, 0xdf, 0xd9, 0xd0, 0xda, 0xd3,
+ 0xd1, 0xd4, 0xd2, 0xd7, 0xd8, 0xd2, 0xd5, 0xdc, 0xdb, 0xd1, 0xdc, 0xda,
+ 0xd4, 0xde, 0xdf, 0xd9, 0xda, 0xd3, 0xd6, 0xdf, 0xd9, 0xd0, 0xd0, 0xd6,
+ 0xdc, 0xda, 0xdb, 0xd1, 0xd7, 0xdd, 0xdd, 0xd8, 0xdf, 0xd9, 0xd1, 0xd4,
+ 0xd3, 0xd5, 0xde, 0xdb, 0xd5, 0xdc, 0xd2, 0xd7, 0xd8, 0xd2, 0xd4, 0xde,
+ 0x17, 0x1d, 0x1d, 0x18, 0x1e, 0x1b, 0x13, 0x15, 0x10, 0x16, 0x16, 0x1f,
+ 0x19, 0x10, 0x1a, 0x13, 0x11, 0x14, 0x12, 0x17, 0x18, 0x12, 0x15, 0x1c,
+ 0x1b, 0x11, 0x1c, 0x1a, 0x14, 0x1e, 0x1f, 0x19, 0x1a, 0x13, 0x16, 0x1f,
+ 0x19, 0x10, 0x10, 0x16, 0x1c, 0x1a, 0x1b, 0x11, 0x17, 0x1d, 0x1d, 0x18,
+ 0x1f, 0x19, 0x11, 0x14, 0x13, 0x15, 0x1e, 0x1b, 0x15, 0x1c, 0x12, 0x17,
+ 0x18, 0x12, 0x14, 0x1e, 0x67, 0x6d, 0x6d, 0x68, 0x6e, 0x6b, 0x63, 0x65,
+ 0x60, 0x66, 0x66, 0x6f, 0x69, 0x60, 0x6a, 0x63, 0x61, 0x64, 0x62, 0x67,
+ 0x68, 0x62, 0x65, 0x6c, 0x6b, 0x61, 0x6c, 0x6a, 0x64, 0x6e, 0x6f, 0x69,
+ 0x6a, 0x63, 0x66, 0x6f, 0x69, 0x60, 0x60, 0x66, 0x6c, 0x6a, 0x6b, 0x61,
+ 0x67, 0x6d, 0x6d, 0x68, 0x6f, 0x69, 0x61, 0x64, 0x63, 0x65, 0x6e, 0x6b,
+ 0x65, 0x6c, 0x62, 0x67, 0x68, 0x62, 0x64, 0x6e, 0xa7, 0xad, 0xad, 0xa8,
+ 0xae, 0xab, 0xa3, 0xa5, 0xa0, 0xa6, 0xa6, 0xaf, 0xa9, 0xa0, 0xaa, 0xa3,
+ 0xa1, 0xa4, 0xa2, 0xa7, 0xa8, 0xa2, 0xa5, 0xac, 0xab, 0xa1, 0xac, 0xaa,
+ 0xa4, 0xae, 0xaf, 0xa9, 0xaa, 0xa3, 0xa6, 0xaf, 0xa9, 0xa0, 0xa0, 0xa6,
+ 0xac, 0xaa, 0xab, 0xa1, 0xa7, 0xad, 0xad, 0xa8, 0xaf, 0xa9, 0xa1, 0xa4,
+ 0xa3, 0xa5, 0xae, 0xab, 0xa5, 0xac, 0xa2, 0xa7, 0xa8, 0xa2, 0xa4, 0xae,
+ 0x47, 0x4d, 0x4d, 0x48, 0x4e, 0x4b, 0x43, 0x45, 0x40, 0x46, 0x46, 0x4f,
+ 0x49, 0x40, 0x4a, 0x43, 0x41, 0x44, 0x42, 0x47, 0x48, 0x42, 0x45, 0x4c,
+ 0x4b, 0x41, 0x4c, 0x4a, 0x44, 0x4e, 0x4f, 0x49, 0x4a, 0x43, 0x46, 0x4f,
+ 0x49, 0x40, 0x40, 0x46, 0x4c, 0x4a, 0x4b, 0x41, 0x47, 0x4d, 0x4d, 0x48,
+ 0x4f, 0x49, 0x41, 0x44, 0x43, 0x45, 0x4e, 0x4b, 0x45, 0x4c, 0x42, 0x47,
+ 0x48, 0x42, 0x44, 0x4e, 0xd7, 0xdd, 0xdd, 0xd8, 0xde, 0xdb, 0xd3, 0xd5,
+ 0xd0, 0xd6, 0xd6, 0xdf, 0xd9, 0xd0, 0xda, 0xd3, 0xd1, 0xd4, 0xd2, 0xd7,
+ 0xd8, 0xd2, 0xd5, 0xdc, 0xdb, 0xd1, 0xdc, 0xda, 0xd4, 0xde, 0xdf, 0xd9,
+ 0xda, 0xd3, 0xd6, 0xdf, 0xd9, 0xd0, 0xd0, 0xd6, 0xdc, 0xda, 0xdb, 0xd1,
+ 0xd7, 0xdd, 0xdd, 0xd8, 0xdf, 0xd9, 0xd1, 0xd4, 0xd3, 0xd5, 0xde, 0xdb,
+ 0xd5, 0xdc, 0xd2, 0xd7, 0xd8, 0xd2, 0xd4, 0xde, 0x97, 0x9d, 0x9d, 0x98,
+ 0x9e, 0x9b, 0x93, 0x95, 0x90, 0x96, 0x96, 0x9f, 0x99, 0x90, 0x9a, 0x93,
+ 0x91, 0x94, 0x92, 0x97, 0x98, 0x92, 0x95, 0x9c, 0x9b, 0x91, 0x9c, 0x9a,
+ 0x94, 0x9e, 0x9f, 0x99, 0x9a, 0x93, 0x96, 0x9f, 0x99, 0x90, 0x90, 0x96,
+ 0x9c, 0x9a, 0x9b, 0x91, 0x97, 0x9d, 0x9d, 0x98, 0x9f, 0x99, 0x91, 0x94,
+ 0x93, 0x95, 0x9e, 0x9b, 0x95, 0x9c, 0x92, 0x97, 0x98, 0x92, 0x94, 0x9e,
+ 0x07, 0x0d, 0x0d, 0x08, 0x0e, 0x0b, 0x03, 0x05, 0x00, 0x06, 0x06, 0x0f,
+ 0x09, 0x00, 0x0a, 0x03, 0x01, 0x04, 0x02, 0x07, 0x08, 0x02, 0x05, 0x0c,
+ 0x0b, 0x01, 0x0c, 0x0a, 0x04, 0x0e, 0x0f, 0x09, 0x0a, 0x03, 0x06, 0x0f,
+ 0x09, 0x00, 0x00, 0x06, 0x0c, 0x0a, 0x0b, 0x01, 0x07, 0x0d, 0x0d, 0x08,
+ 0x0f, 0x09, 0x01, 0x04, 0x03, 0x05, 0x0e, 0x0b, 0x05, 0x0c, 0x02, 0x07,
+ 0x08, 0x02, 0x04, 0x0e, 0x87, 0x8d, 0x8d, 0x88, 0x8e, 0x8b, 0x83, 0x85,
+ 0x80, 0x86, 0x86, 0x8f, 0x89, 0x80, 0x8a, 0x83, 0x81, 0x84, 0x82, 0x87,
+ 0x88, 0x82, 0x85, 0x8c, 0x8b, 0x81, 0x8c, 0x8a, 0x84, 0x8e, 0x8f, 0x89,
+ 0x8a, 0x83, 0x86, 0x8f, 0x89, 0x80, 0x80, 0x86, 0x8c, 0x8a, 0x8b, 0x81,
+ 0x87, 0x8d, 0x8d, 0x88, 0x8f, 0x89, 0x81, 0x84, 0x83, 0x85, 0x8e, 0x8b,
+ 0x85, 0x8c, 0x82, 0x87, 0x88, 0x82, 0x84, 0x8e, 0x67, 0x6d, 0x6d, 0x68,
+ 0x6e, 0x6b, 0x63, 0x65, 0x60, 0x66, 0x66, 0x6f, 0x69, 0x60, 0x6a, 0x63,
+ 0x61, 0x64, 0x62, 0x67, 0x68, 0x62, 0x65, 0x6c, 0x6b, 0x61, 0x6c, 0x6a,
+ 0x64, 0x6e, 0x6f, 0x69, 0x6a, 0x63, 0x66, 0x6f, 0x69, 0x60, 0x60, 0x66,
+ 0x6c, 0x6a, 0x6b, 0x61, 0x67, 0x6d, 0x6d, 0x68, 0x6f, 0x69, 0x61, 0x64,
+ 0x63, 0x65, 0x6e, 0x6b, 0x65, 0x6c, 0x62, 0x67, 0x68, 0x62, 0x64, 0x6e,
+ 0xf7, 0xfd, 0xfd, 0xf8, 0xfe, 0xfb, 0xf3, 0xf5, 0xf0, 0xf6, 0xf6, 0xff,
+ 0xf9, 0xf0, 0xfa, 0xf3, 0xf1, 0xf4, 0xf2, 0xf7, 0xf8, 0xf2, 0xf5, 0xfc,
+ 0xfb, 0xf1, 0xfc, 0xfa, 0xf4, 0xfe, 0xff, 0xf9, 0xfa, 0xf3, 0xf6, 0xff,
+ 0xf9, 0xf0, 0xf0, 0xf6, 0xfc, 0xfa, 0xfb, 0xf1, 0xf7, 0xfd, 0xfd, 0xf8,
+ 0xff, 0xf9, 0xf1, 0xf4, 0xf3, 0xf5, 0xfe, 0xfb, 0xf5, 0xfc, 0xf2, 0xf7,
+ 0xf8, 0xf2, 0xf4, 0xfe, 0x97, 0x9d, 0x9d, 0x98, 0x9e, 0x9b, 0x93, 0x95,
+ 0x90, 0x96, 0x96, 0x9f, 0x99, 0x90, 0x9a, 0x93, 0x91, 0x94, 0x92, 0x97,
+ 0x98, 0x92, 0x95, 0x9c, 0x9b, 0x91, 0x9c, 0x9a, 0x94, 0x9e, 0x9f, 0x99,
+ 0x9a, 0x93, 0x96, 0x9f, 0x99, 0x90, 0x90, 0x96, 0x9c, 0x9a, 0x9b, 0x91,
+ 0x97, 0x9d, 0x9d, 0x98, 0x9f, 0x99, 0x91, 0x94, 0x93, 0x95, 0x9e, 0x9b,
+ 0x95, 0x9c, 0x92, 0x97, 0x98, 0x92, 0x94, 0x9e, 0x37, 0x3d, 0x3d, 0x38,
+ 0x3e, 0x3b, 0x33, 0x35, 0x30, 0x36, 0x36, 0x3f, 0x39, 0x30, 0x3a, 0x33,
+ 0x31, 0x34, 0x32, 0x37, 0x38, 0x32, 0x35, 0x3c, 0x3b, 0x31, 0x3c, 0x3a,
+ 0x34, 0x3e, 0x3f, 0x39, 0x3a, 0x33, 0x36, 0x3f, 0x39, 0x30, 0x30, 0x36,
+ 0x3c, 0x3a, 0x3b, 0x31, 0x37, 0x3d, 0x3d, 0x38, 0x3f, 0x39, 0x31, 0x34,
+ 0x33, 0x35, 0x3e, 0x3b, 0x35, 0x3c, 0x32, 0x37, 0x38, 0x32, 0x34, 0x3e,
+ 0x87, 0x8d, 0x8d, 0x88, 0x8e, 0x8b, 0x83, 0x85, 0x80, 0x86, 0x86, 0x8f,
+ 0x89, 0x80, 0x8a, 0x83, 0x81, 0x84, 0x82, 0x87, 0x88, 0x82, 0x85, 0x8c,
+ 0x8b, 0x81, 0x8c, 0x8a, 0x84, 0x8e, 0x8f, 0x89, 0x8a, 0x83, 0x86, 0x8f,
+ 0x89, 0x80, 0x80, 0x86, 0x8c, 0x8a, 0x8b, 0x81, 0x87, 0x8d, 0x8d, 0x88,
+ 0x8f, 0x89, 0x81, 0x84, 0x83, 0x85, 0x8e, 0x8b, 0x85, 0x8c, 0x82, 0x87,
+ 0x88, 0x82, 0x84, 0x8e, 0x07, 0x0d, 0x0d, 0x08, 0x0e, 0x0b, 0x03, 0x05,
+ 0x00, 0x06, 0x06, 0x0f, 0x09, 0x00, 0x0a, 0x03, 0x01, 0x04, 0x02, 0x07,
+ 0x08, 0x02, 0x05, 0x0c, 0x0b, 0x01, 0x0c, 0x0a, 0x04, 0x0e, 0x0f, 0x09,
+ 0x0a, 0x03, 0x06, 0x0f, 0x09, 0x00, 0x00, 0x06, 0x0c, 0x0a, 0x0b, 0x01,
+ 0x07, 0x0d, 0x0d, 0x08, 0x0f, 0x09, 0x01, 0x04, 0x03, 0x05, 0x0e, 0x0b,
+ 0x05, 0x0c, 0x02, 0x07, 0x08, 0x02, 0x04, 0x0e, 0x77, 0x7d, 0x7d, 0x78,
+ 0x7e, 0x7b, 0x73, 0x75, 0x70, 0x76, 0x76, 0x7f, 0x79, 0x70, 0x7a, 0x73,
+ 0x71, 0x74, 0x72, 0x77, 0x78, 0x72, 0x75, 0x7c, 0x7b, 0x71, 0x7c, 0x7a,
+ 0x74, 0x7e, 0x7f, 0x79, 0x7a, 0x73, 0x76, 0x7f, 0x79, 0x70, 0x70, 0x76,
+ 0x7c, 0x7a, 0x7b, 0x71, 0x77, 0x7d, 0x7d, 0x78, 0x7f, 0x79, 0x71, 0x74,
+ 0x73, 0x75, 0x7e, 0x7b, 0x75, 0x7c, 0x72, 0x77, 0x78, 0x72, 0x74, 0x7e,
+ 0xb7, 0xbd, 0xbd, 0xb8, 0xbe, 0xbb, 0xb3, 0xb5, 0xb0, 0xb6, 0xb6, 0xbf,
+ 0xb9, 0xb0, 0xba, 0xb3, 0xb1, 0xb4, 0xb2, 0xb7, 0xb8, 0xb2, 0xb5, 0xbc,
+ 0xbb, 0xb1, 0xbc, 0xba, 0xb4, 0xbe, 0xbf, 0xb9, 0xba, 0xb3, 0xb6, 0xbf,
+ 0xb9, 0xb0, 0xb0, 0xb6, 0xbc, 0xba, 0xbb, 0xb1, 0xb7, 0xbd, 0xbd, 0xb8,
+ 0xbf, 0xb9, 0xb1, 0xb4, 0xb3, 0xb5, 0xbe, 0xbb, 0xb5, 0xbc, 0xb2, 0xb7,
+ 0xb8, 0xb2, 0xb4, 0xbe, 0x47, 0x4d, 0x4d, 0x48, 0x4e, 0x4b, 0x43, 0x45,
+ 0x40, 0x46, 0x46, 0x4f, 0x49, 0x40, 0x4a, 0x43, 0x41, 0x44, 0x42, 0x47,
+ 0x48, 0x42, 0x45, 0x4c, 0x4b, 0x41, 0x4c, 0x4a, 0x44, 0x4e, 0x4f, 0x49,
+ 0x4a, 0x43, 0x46, 0x4f, 0x49, 0x40, 0x40, 0x46, 0x4c, 0x4a, 0x4b, 0x41,
+ 0x47, 0x4d, 0x4d, 0x48, 0x4f, 0x49, 0x41, 0x44, 0x43, 0x45, 0x4e, 0x4b,
+ 0x45, 0x4c, 0x42, 0x47, 0x48, 0x42, 0x44, 0x4e, 0x17, 0x1d, 0x1d, 0x18,
+ 0x1e, 0x1b, 0x13, 0x15, 0x10, 0x16, 0x16, 0x1f, 0x19, 0x10, 0x1a, 0x13,
+ 0x11, 0x14, 0x12, 0x17, 0x18, 0x12, 0x15, 0x1c, 0x1b, 0x11, 0x1c, 0x1a,
+ 0x14, 0x1e, 0x1f, 0x19, 0x1a, 0x13, 0x16, 0x1f, 0x19, 0x10, 0x10, 0x16,
+ 0x1c, 0x1a, 0x1b, 0x11, 0x17, 0x1d, 0x1d, 0x18, 0x1f, 0x19, 0x11, 0x14,
+ 0x13, 0x15, 0x1e, 0x1b, 0x15, 0x1c, 0x12, 0x17, 0x18, 0x12, 0x14, 0x1e,
+ 0xf7, 0xfd, 0xfd, 0xf8, 0xfe, 0xfb, 0xf3, 0xf5, 0xf0, 0xf6, 0xf6, 0xff,
+ 0xf9, 0xf0, 0xfa, 0xf3, 0xf1, 0xf4, 0xf2, 0xf7, 0xf8, 0xf2, 0xf5, 0xfc,
+ 0xfb, 0xf1, 0xfc, 0xfa, 0xf4, 0xfe, 0xff, 0xf9, 0xfa, 0xf3, 0xf6, 0xff,
+ 0xf9, 0xf0, 0xf0, 0xf6, 0xfc, 0xfa, 0xfb, 0xf1, 0xf7, 0xfd, 0xfd, 0xf8,
+ 0xff, 0xf9, 0xf1, 0xf4, 0xf3, 0xf5, 0xfe, 0xfb, 0xf5, 0xfc, 0xf2, 0xf7,
+ 0xf8, 0xf2, 0xf4, 0xfe, 0x27, 0x2d, 0x2d, 0x28, 0x2e, 0x2b, 0x23, 0x25,
+ 0x20, 0x26, 0x26, 0x2f, 0x29, 0x20, 0x2a, 0x23, 0x21, 0x24, 0x22, 0x27,
+ 0x28, 0x22, 0x25, 0x2c, 0x2b, 0x21, 0x2c, 0x2a, 0x24, 0x2e, 0x2f, 0x29,
+ 0x2a, 0x23, 0x26, 0x2f, 0x29, 0x20, 0x20, 0x26, 0x2c, 0x2a, 0x2b, 0x21,
+ 0x27, 0x2d, 0x2d, 0x28, 0x2f, 0x29, 0x21, 0x24, 0x23, 0x25, 0x2e, 0x2b,
+ 0x25, 0x2c, 0x22, 0x27, 0x28, 0x22, 0x24, 0x2e, 0xe7, 0xed, 0xed, 0xe8,
+ 0xee, 0xeb, 0xe3, 0xe5, 0xe0, 0xe6, 0xe6, 0xef, 0xe9, 0xe0, 0xea, 0xe3,
+ 0xe1, 0xe4, 0xe2, 0xe7, 0xe8, 0xe2, 0xe5, 0xec, 0xeb, 0xe1, 0xec, 0xea,
+ 0xe4, 0xee, 0xef, 0xe9, 0xea, 0xe3, 0xe6, 0xef, 0xe9, 0xe0, 0xe0, 0xe6,
+ 0xec, 0xea, 0xeb, 0xe1, 0xe7, 0xed, 0xed, 0xe8, 0xef, 0xe9, 0xe1, 0xe4,
+ 0xe3, 0xe5, 0xee, 0xeb, 0xe5, 0xec, 0xe2, 0xe7, 0xe8, 0xe2, 0xe4, 0xee,
+ 0xc7, 0xcd, 0xcd, 0xc8, 0xce, 0xcb, 0xc3, 0xc5, 0xc0, 0xc6, 0xc6, 0xcf,
+ 0xc9, 0xc0, 0xca, 0xc3, 0xc1, 0xc4, 0xc2, 0xc7, 0xc8, 0xc2, 0xc5, 0xcc,
+ 0xcb, 0xc1, 0xcc, 0xca, 0xc4, 0xce, 0xcf, 0xc9, 0xca, 0xc3, 0xc6, 0xcf,
+ 0xc9, 0xc0, 0xc0, 0xc6, 0xcc, 0xca, 0xcb, 0xc1, 0xc7, 0xcd, 0xcd, 0xc8,
+ 0xcf, 0xc9, 0xc1, 0xc4, 0xc3, 0xc5, 0xce, 0xcb, 0xc5, 0xcc, 0xc2, 0xc7,
+ 0xc8, 0xc2, 0xc4, 0xce, 0x37, 0x3d, 0x3d, 0x38, 0x3e, 0x3b, 0x33, 0x35,
+ 0x30, 0x36, 0x36, 0x3f, 0x39, 0x30, 0x3a, 0x33, 0x31, 0x34, 0x32, 0x37,
+ 0x38, 0x32, 0x35, 0x3c, 0x3b, 0x31, 0x3c, 0x3a, 0x34, 0x3e, 0x3f, 0x39,
+ 0x3a, 0x33, 0x36, 0x3f, 0x39, 0x30, 0x30, 0x36, 0x3c, 0x3a, 0x3b, 0x31,
+ 0x37, 0x3d, 0x3d, 0x38, 0x3f, 0x39, 0x31, 0x34, 0x33, 0x35, 0x3e, 0x3b,
+ 0x35, 0x3c, 0x32, 0x37, 0x38, 0x32, 0x34, 0x3e, 0x57, 0x5d, 0x5d, 0x58,
+ 0x5e, 0x5b, 0x53, 0x55, 0x50, 0x56, 0x56, 0x5f, 0x59, 0x50, 0x5a, 0x53,
+ 0x51, 0x54, 0x52, 0x57, 0x58, 0x52, 0x55, 0x5c, 0x5b, 0x51, 0x5c, 0x5a,
+ 0x54, 0x5e, 0x5f, 0x59, 0x5a, 0x53, 0x56, 0x5f, 0x59, 0x50, 0x50, 0x56,
+ 0x5c, 0x5a, 0x5b, 0x51, 0x57, 0x5d, 0x5d, 0x58, 0x5f, 0x59, 0x51, 0x54,
+ 0x53, 0x55, 0x5e, 0x5b, 0x55, 0x5c, 0x52, 0x57, 0x58, 0x52, 0x54, 0x5e,
+ 0xb7, 0xbd, 0xbd, 0xb8, 0xbe, 0xbb, 0xb3, 0xb5, 0xb0, 0xb6, 0xb6, 0xbf,
+ 0xb9, 0xb0, 0xba, 0xb3, 0xb1, 0xb4, 0xb2, 0xb7, 0xb8, 0xb2, 0xb5, 0xbc,
+ 0xbb, 0xb1, 0xbc, 0xba, 0xb4, 0xbe, 0xbf, 0xb9, 0xba, 0xb3, 0xb6, 0xbf,
+ 0xb9, 0xb0, 0xb0, 0xb6, 0xbc, 0xba, 0xbb, 0xb1, 0xb7, 0xbd, 0xbd, 0xb8,
+ 0xbf, 0xb9, 0xb1, 0xb4, 0xb3, 0xb5, 0xbe, 0xbb, 0xb5, 0xbc, 0xb2, 0xb7,
+ 0xb8, 0xb2, 0xb4, 0xbe, 0xa7, 0xad, 0xad, 0xa8, 0xae, 0xab, 0xa3, 0xa5,
+ 0xa0, 0xa6, 0xa6, 0xaf, 0xa9, 0xa0, 0xaa, 0xa3, 0xa1, 0xa4, 0xa2, 0xa7,
+ 0xa8, 0xa2, 0xa5, 0xac, 0xab, 0xa1, 0xac, 0xaa, 0xa4, 0xae, 0xaf, 0xa9,
+ 0xaa, 0xa3, 0xa6, 0xaf, 0xa9, 0xa0, 0xa0, 0xa6, 0xac, 0xaa, 0xab, 0xa1,
+ 0xa7, 0xad, 0xad, 0xa8, 0xaf, 0xa9, 0xa1, 0xa4, 0xa3, 0xa5, 0xae, 0xab,
+ 0xa5, 0xac, 0xa2, 0xa7, 0xa8, 0xa2, 0xa4, 0xae, 0x57, 0x5d, 0x5d, 0x58,
+ 0x5e, 0x5b, 0x53, 0x55, 0x50, 0x56, 0x56, 0x5f, 0x59, 0x50, 0x5a, 0x53,
+ 0x51, 0x54, 0x52, 0x57, 0x58, 0x52, 0x55, 0x5c, 0x5b, 0x51, 0x5c, 0x5a,
+ 0x54, 0x5e, 0x5f, 0x59, 0x5a, 0x53, 0x56, 0x5f, 0x59, 0x50, 0x50, 0x56,
+ 0x5c, 0x5a, 0x5b, 0x51, 0x57, 0x5d, 0x5d, 0x58, 0x5f, 0x59, 0x51, 0x54,
+ 0x53, 0x55, 0x5e, 0x5b, 0x55, 0x5c, 0x52, 0x57, 0x58, 0x52, 0x54, 0x5e,
+ 0xe7, 0xed, 0xed, 0xe8, 0xee, 0xeb, 0xe3, 0xe5, 0xe0, 0xe6, 0xe6, 0xef,
+ 0xe9, 0xe0, 0xea, 0xe3, 0xe1, 0xe4, 0xe2, 0xe7, 0xe8, 0xe2, 0xe5, 0xec,
+ 0xeb, 0xe1, 0xec, 0xea, 0xe4, 0xee, 0xef, 0xe9, 0xea, 0xe3, 0xe6, 0xef,
+ 0xe9, 0xe0, 0xe0, 0xe6, 0xec, 0xea, 0xeb, 0xe1, 0xe7, 0xed, 0xed, 0xe8,
+ 0xef, 0xe9, 0xe1, 0xe4, 0xe3, 0xe5, 0xee, 0xeb, 0xe5, 0xec, 0xe2, 0xe7,
+ 0xe8, 0xe2, 0xe4, 0xee, 0x27, 0x2d, 0x2d, 0x28, 0x2e, 0x2b, 0x23, 0x25,
+ 0x20, 0x26, 0x26, 0x2f, 0x29, 0x20, 0x2a, 0x23, 0x21, 0x24, 0x22, 0x27,
+ 0x28, 0x22, 0x25, 0x2c, 0x2b, 0x21, 0x2c, 0x2a, 0x24, 0x2e, 0x2f, 0x29,
+ 0x2a, 0x23, 0x26, 0x2f, 0x29, 0x20, 0x20, 0x26, 0x2c, 0x2a, 0x2b, 0x21,
+ 0x27, 0x2d, 0x2d, 0x28, 0x2f, 0x29, 0x21, 0x24, 0x23, 0x25, 0x2e, 0x2b,
+ 0x25, 0x2c, 0x22, 0x27, 0x28, 0x22, 0x24, 0x2e, 0x77, 0x7d, 0x7d, 0x78,
+ 0x7e, 0x7b, 0x73, 0x75, 0x70, 0x76, 0x76, 0x7f, 0x79, 0x70, 0x7a, 0x73,
+ 0x71, 0x74, 0x72, 0x77, 0x78, 0x72, 0x75, 0x7c, 0x7b, 0x71, 0x7c, 0x7a,
+ 0x74, 0x7e, 0x7f, 0x79, 0x7a, 0x73, 0x76, 0x7f, 0x79, 0x70, 0x70, 0x76,
+ 0x7c, 0x7a, 0x7b, 0x71, 0x77, 0x7d, 0x7d, 0x78, 0x7f, 0x79, 0x71, 0x74,
+ 0x73, 0x75, 0x7e, 0x7b, 0x75, 0x7c, 0x72, 0x77, 0x78, 0x72, 0x74, 0x7e,
+ 0xc7, 0xcd, 0xcd, 0xc8, 0xce, 0xcb, 0xc3, 0xc5, 0xc0, 0xc6, 0xc6, 0xcf,
+ 0xc9, 0xc0, 0xca, 0xc3, 0xc1, 0xc4, 0xc2, 0xc7, 0xc8, 0xc2, 0xc5, 0xcc,
+ 0xcb, 0xc1, 0xcc, 0xca, 0xc4, 0xce, 0xcf, 0xc9, 0xca, 0xc3, 0xc6, 0xcf,
+ 0xc9, 0xc0, 0xc0, 0xc6, 0xcc, 0xca, 0xcb, 0xc1, 0xc7, 0xcd, 0xcd, 0xc8,
+ 0xcf, 0xc9, 0xc1, 0xc4, 0xc3, 0xc5, 0xce, 0xcb, 0xc5, 0xcc, 0xc2, 0xc7,
+ 0xc8, 0xc2, 0xc4, 0xce,
+ },
+ {
+ 0x2c, 0x2a, 0x21, 0x2f, 0x2a, 0x24, 0x2f, 0x22, 0x29, 0x27, 0x22, 0x2c,
+ 0x26, 0x29, 0x28, 0x25, 0x20, 0x26, 0x2d, 0x21, 0x23, 0x2d, 0x24, 0x2e,
+ 0x2e, 0x20, 0x27, 0x2b, 0x25, 0x23, 0x2b, 0x28, 0x29, 0x24, 0x2e, 0x23,
+ 0x2f, 0x22, 0x25, 0x2c, 0x22, 0x29, 0x28, 0x25, 0x2c, 0x2f, 0x23, 0x2a,
+ 0x27, 0x2b, 0x20, 0x2e, 0x24, 0x21, 0x2a, 0x27, 0x21, 0x26, 0x2d, 0x20,
+ 0x2b, 0x28, 0x26, 0x2d, 0xec, 0xea, 0xe1, 0xef, 0xea, 0xe4, 0xef, 0xe2,
+ 0xe9, 0xe7, 0xe2, 0xec, 0xe6, 0xe9, 0xe8, 0xe5, 0xe0, 0xe6, 0xed, 0xe1,
+ 0xe3, 0xed, 0xe4, 0xee, 0xee, 0xe0, 0xe7, 0xeb, 0xe5, 0xe3, 0xeb, 0xe8,
+ 0xe9, 0xe4, 0xee, 0xe3, 0xef, 0xe2, 0xe5, 0xec, 0xe2, 0xe9, 0xe8, 0xe5,
+ 0xec, 0xef, 0xe3, 0xea, 0xe7, 0xeb, 0xe0, 0xee, 0xe4, 0xe1, 0xea, 0xe7,
+ 0xe1, 0xe6, 0xed, 0xe0, 0xeb, 0xe8, 0xe6, 0xed, 0xcc, 0xca, 0xc1, 0xcf,
+ 0xca, 0xc4, 0xcf, 0xc2, 0xc9, 0xc7, 0xc2, 0xcc, 0xc6, 0xc9, 0xc8, 0xc5,
+ 0xc0, 0xc6, 0xcd, 0xc1, 0xc3, 0xcd, 0xc4, 0xce, 0xce, 0xc0, 0xc7, 0xcb,
+ 0xc5, 0xc3, 0xcb, 0xc8, 0xc9, 0xc4, 0xce, 0xc3, 0xcf, 0xc2, 0xc5, 0xcc,
+ 0xc2, 0xc9, 0xc8, 0xc5, 0xcc, 0xcf, 0xc3, 0xca, 0xc7, 0xcb, 0xc0, 0xce,
+ 0xc4, 0xc1, 0xca, 0xc7, 0xc1, 0xc6, 0xcd, 0xc0, 0xcb, 0xc8, 0xc6, 0xcd,
+ 0xbc, 0xba, 0xb1, 0xbf, 0xba, 0xb4, 0xbf, 0xb2, 0xb9, 0xb7, 0xb2, 0xbc,
+ 0xb6, 0xb9, 0xb8, 0xb5, 0xb0, 0xb6, 0xbd, 0xb1, 0xb3, 0xbd, 0xb4, 0xbe,
+ 0xbe, 0xb0, 0xb7, 0xbb, 0xb5, 0xb3, 0xbb, 0xb8, 0xb9, 0xb4, 0xbe, 0xb3,
+ 0xbf, 0xb2, 0xb5, 0xbc, 0xb2, 0xb9, 0xb8, 0xb5, 0xbc, 0xbf, 0xb3, 0xba,
+ 0xb7, 0xbb, 0xb0, 0xbe, 0xb4, 0xb1, 0xba, 0xb7, 0xb1, 0xb6, 0xbd, 0xb0,
+ 0xbb, 0xb8, 0xb6, 0xbd, 0x4c, 0x4a, 0x41, 0x4f, 0x4a, 0x44, 0x4f, 0x42,
+ 0x49, 0x47, 0x42, 0x4c, 0x46, 0x49, 0x48, 0x45, 0x40, 0x46, 0x4d, 0x41,
+ 0x43, 0x4d, 0x44, 0x4e, 0x4e, 0x40, 0x47, 0x4b, 0x45, 0x43, 0x4b, 0x48,
+ 0x49, 0x44, 0x4e, 0x43, 0x4f, 0x42, 0x45, 0x4c, 0x42, 0x49, 0x48, 0x45,
+ 0x4c, 0x4f, 0x43, 0x4a, 0x47, 0x4b, 0x40, 0x4e, 0x44, 0x41, 0x4a, 0x47,
+ 0x41, 0x46, 0x4d, 0x40, 0x4b, 0x48, 0x46, 0x4d, 0x2c, 0x2a, 0x21, 0x2f,
+ 0x2a, 0x24, 0x2f, 0x22, 0x29, 0x27, 0x22, 0x2c, 0x26, 0x29, 0x28, 0x25,
+ 0x20, 0x26, 0x2d, 0x21, 0x23, 0x2d, 0x24, 0x2e, 0x2e, 0x20, 0x27, 0x2b,
+ 0x25, 0x23, 0x2b, 0x28, 0x29, 0x24, 0x2e, 0x23, 0x2f, 0x22, 0x25, 0x2c,
+ 0x22, 0x29, 0x28, 0x25, 0x2c, 0x2f, 0x23, 0x2a, 0x27, 0x2b, 0x20, 0x2e,
+ 0x24, 0x21, 0x2a, 0x27, 0x21, 0x26, 0x2d, 0x20, 0x2b, 0x28, 0x26, 0x2d,
+ 0x1c, 0x1a, 0x11, 0x1f, 0x1a, 0x14, 0x1f, 0x12, 0x19, 0x17, 0x12, 0x1c,
+ 0x16, 0x19, 0x18, 0x15, 0x10, 0x16, 0x1d, 0x11, 0x13, 0x1d, 0x14, 0x1e,
+ 0x1e, 0x10, 0x17, 0x1b, 0x15, 0x13, 0x1b, 0x18, 0x19, 0x14, 0x1e, 0x13,
+ 0x1f, 0x12, 0x15, 0x1c, 0x12, 0x19, 0x18, 0x15, 0x1c, 0x1f, 0x13, 0x1a,
+ 0x17, 0x1b, 0x10, 0x1e, 0x14, 0x11, 0x1a, 0x17, 0x11, 0x16, 0x1d, 0x10,
+ 0x1b, 0x18, 0x16, 0x1d, 0xcc, 0xca, 0xc1, 0xcf, 0xca, 0xc4, 0xcf, 0xc2,
+ 0xc9, 0xc7, 0xc2, 0xcc, 0xc6, 0xc9, 0xc8, 0xc5, 0xc0, 0xc6, 0xcd, 0xc1,
+ 0xc3, 0xcd, 0xc4, 0xce, 0xce, 0xc0, 0xc7, 0xcb, 0xc5, 0xc3, 0xcb, 0xc8,
+ 0xc9, 0xc4, 0xce, 0xc3, 0xcf, 0xc2, 0xc5, 0xcc, 0xc2, 0xc9, 0xc8, 0xc5,
+ 0xcc, 0xcf, 0xc3, 0xca, 0xc7, 0xcb, 0xc0, 0xce, 0xc4, 0xc1, 0xca, 0xc7,
+ 0xc1, 0xc6, 0xcd, 0xc0, 0xcb, 0xc8, 0xc6, 0xcd, 0x7c, 0x7a, 0x71, 0x7f,
+ 0x7a, 0x74, 0x7f, 0x72, 0x79, 0x77, 0x72, 0x7c, 0x76, 0x79, 0x78, 0x75,
+ 0x70, 0x76, 0x7d, 0x71, 0x73, 0x7d, 0x74, 0x7e, 0x7e, 0x70, 0x77, 0x7b,
+ 0x75, 0x73, 0x7b, 0x78, 0x79, 0x74, 0x7e, 0x73, 0x7f, 0x72, 0x75, 0x7c,
+ 0x72, 0x79, 0x78, 0x75, 0x7c, 0x7f, 0x73, 0x7a, 0x77, 0x7b, 0x70, 0x7e,
+ 0x74, 0x71, 0x7a, 0x77, 0x71, 0x76, 0x7d, 0x70, 0x7b, 0x78, 0x76, 0x7d,
+ 0x4c, 0x4a, 0x41, 0x4f, 0x4a, 0x44, 0x4f, 0x42, 0x49, 0x47, 0x42, 0x4c,
+ 0x46, 0x49, 0x48, 0x45, 0x40, 0x46, 0x4d, 0x41, 0x43, 0x4d, 0x44, 0x4e,
+ 0x4e, 0x40, 0x47, 0x4b, 0x45, 0x43, 0x4b, 0x48, 0x49, 0x44, 0x4e, 0x43,
+ 0x4f, 0x42, 0x45, 0x4c, 0x42, 0x49, 0x48, 0x45, 0x4c, 0x4f, 0x43, 0x4a,
+ 0x47, 0x4b, 0x40, 0x4e, 0x44, 0x41, 0x4a, 0x47, 0x41, 0x46, 0x4d, 0x40,
+ 0x4b, 0x48, 0x46, 0x4d, 0xac, 0xaa, 0xa1, 0xaf, 0xaa, 0xa4, 0xaf, 0xa2,
+ 0xa9, 0xa7, 0xa2, 0xac, 0xa6, 0xa9, 0xa8, 0xa5, 0xa0, 0xa6, 0xad, 0xa1,
+ 0xa3, 0xad, 0xa4, 0xae, 0xae, 0xa0, 0xa7, 0xab, 0xa5, 0xa3, 0xab, 0xa8,
+ 0xa9, 0xa4, 0xae, 0xa3, 0xaf, 0xa2, 0xa5, 0xac, 0xa2, 0xa9, 0xa8, 0xa5,
+ 0xac, 0xaf, 0xa3, 0xaa, 0xa7, 0xab, 0xa0, 0xae, 0xa4, 0xa1, 0xaa, 0xa7,
+ 0xa1, 0xa6, 0xad, 0xa0, 0xab, 0xa8, 0xa6, 0xad, 0x7c, 0x7a, 0x71, 0x7f,
+ 0x7a, 0x74, 0x7f, 0x72, 0x79, 0x77, 0x72, 0x7c, 0x76, 0x79, 0x78, 0x75,
+ 0x70, 0x76, 0x7d, 0x71, 0x73, 0x7d, 0x74, 0x7e, 0x7e, 0x70, 0x77, 0x7b,
+ 0x75, 0x73, 0x7b, 0x78, 0x79, 0x74, 0x7e, 0x73, 0x7f, 0x72, 0x75, 0x7c,
+ 0x72, 0x79, 0x78, 0x75, 0x7c, 0x7f, 0x73, 0x7a, 0x77, 0x7b, 0x70, 0x7e,
+ 0x74, 0x71, 0x7a, 0x77, 0x71, 0x76, 0x7d, 0x70, 0x7b, 0x78, 0x76, 0x7d,
+ 0xbc, 0xba, 0xb1, 0xbf, 0xba, 0xb4, 0xbf, 0xb2, 0xb9, 0xb7, 0xb2, 0xbc,
+ 0xb6, 0xb9, 0xb8, 0xb5, 0xb0, 0xb6, 0xbd, 0xb1, 0xb3, 0xbd, 0xb4, 0xbe,
+ 0xbe, 0xb0, 0xb7, 0xbb, 0xb5, 0xb3, 0xbb, 0xb8, 0xb9, 0xb4, 0xbe, 0xb3,
+ 0xbf, 0xb2, 0xb5, 0xbc, 0xb2, 0xb9, 0xb8, 0xb5, 0xbc, 0xbf, 0xb3, 0xba,
+ 0xb7, 0xbb, 0xb0, 0xbe, 0xb4, 0xb1, 0xba, 0xb7, 0xb1, 0xb6, 0xbd, 0xb0,
+ 0xbb, 0xb8, 0xb6, 0xbd, 0xdc, 0xda, 0xd1, 0xdf, 0xda, 0xd4, 0xdf, 0xd2,
+ 0xd9, 0xd7, 0xd2, 0xdc, 0xd6, 0xd9, 0xd8, 0xd5, 0xd0, 0xd6, 0xdd, 0xd1,
+ 0xd3, 0xdd, 0xd4, 0xde, 0xde, 0xd0, 0xd7, 0xdb, 0xd5, 0xd3, 0xdb, 0xd8,
+ 0xd9, 0xd4, 0xde, 0xd3, 0xdf, 0xd2, 0xd5, 0xdc, 0xd2, 0xd9, 0xd8, 0xd5,
+ 0xdc, 0xdf, 0xd3, 0xda, 0xd7, 0xdb, 0xd0, 0xde, 0xd4, 0xd1, 0xda, 0xd7,
+ 0xd1, 0xd6, 0xdd, 0xd0, 0xdb, 0xd8, 0xd6, 0xdd, 0x6c, 0x6a, 0x61, 0x6f,
+ 0x6a, 0x64, 0x6f, 0x62, 0x69, 0x67, 0x62, 0x6c, 0x66, 0x69, 0x68, 0x65,
+ 0x60, 0x66, 0x6d, 0x61, 0x63, 0x6d, 0x64, 0x6e, 0x6e, 0x60, 0x67, 0x6b,
+ 0x65, 0x63, 0x6b, 0x68, 0x69, 0x64, 0x6e, 0x63, 0x6f, 0x62, 0x65, 0x6c,
+ 0x62, 0x69, 0x68, 0x65, 0x6c, 0x6f, 0x63, 0x6a, 0x67, 0x6b, 0x60, 0x6e,
+ 0x64, 0x61, 0x6a, 0x67, 0x61, 0x66, 0x6d, 0x60, 0x6b, 0x68, 0x66, 0x6d,
+ 0x1c, 0x1a, 0x11, 0x1f, 0x1a, 0x14, 0x1f, 0x12, 0x19, 0x17, 0x12, 0x1c,
+ 0x16, 0x19, 0x18, 0x15, 0x10, 0x16, 0x1d, 0x11, 0x13, 0x1d, 0x14, 0x1e,
+ 0x1e, 0x10, 0x17, 0x1b, 0x15, 0x13, 0x1b, 0x18, 0x19, 0x14, 0x1e, 0x13,
+ 0x1f, 0x12, 0x15, 0x1c, 0x12, 0x19, 0x18, 0x15, 0x1c, 0x1f, 0x13, 0x1a,
+ 0x17, 0x1b, 0x10, 0x1e, 0x14, 0x11, 0x1a, 0x17, 0x11, 0x16, 0x1d, 0x10,
+ 0x1b, 0x18, 0x16, 0x1d, 0x8c, 0x8a, 0x81, 0x8f, 0x8a, 0x84, 0x8f, 0x82,
+ 0x89, 0x87, 0x82, 0x8c, 0x86, 0x89, 0x88, 0x85, 0x80, 0x86, 0x8d, 0x81,
+ 0x83, 0x8d, 0x84, 0x8e, 0x8e, 0x80, 0x87, 0x8b, 0x85, 0x83, 0x8b, 0x88,
+ 0x89, 0x84, 0x8e, 0x83, 0x8f, 0x82, 0x85, 0x8c, 0x82, 0x89, 0x88, 0x85,
+ 0x8c, 0x8f, 0x83, 0x8a, 0x87, 0x8b, 0x80, 0x8e, 0x84, 0x81, 0x8a, 0x87,
+ 0x81, 0x86, 0x8d, 0x80, 0x8b, 0x88, 0x86, 0x8d, 0x5c, 0x5a, 0x51, 0x5f,
+ 0x5a, 0x54, 0x5f, 0x52, 0x59, 0x57, 0x52, 0x5c, 0x56, 0x59, 0x58, 0x55,
+ 0x50, 0x56, 0x5d, 0x51, 0x53, 0x5d, 0x54, 0x5e, 0x5e, 0x50, 0x57, 0x5b,
+ 0x55, 0x53, 0x5b, 0x58, 0x59, 0x54, 0x5e, 0x53, 0x5f, 0x52, 0x55, 0x5c,
+ 0x52, 0x59, 0x58, 0x55, 0x5c, 0x5f, 0x53, 0x5a, 0x57, 0x5b, 0x50, 0x5e,
+ 0x54, 0x51, 0x5a, 0x57, 0x51, 0x56, 0x5d, 0x50, 0x5b, 0x58, 0x56, 0x5d,
+ 0x5c, 0x5a, 0x51, 0x5f, 0x5a, 0x54, 0x5f, 0x52, 0x59, 0x57, 0x52, 0x5c,
+ 0x56, 0x59, 0x58, 0x55, 0x50, 0x56, 0x5d, 0x51, 0x53, 0x5d, 0x54, 0x5e,
+ 0x5e, 0x50, 0x57, 0x5b, 0x55, 0x53, 0x5b, 0x58, 0x59, 0x54, 0x5e, 0x53,
+ 0x5f, 0x52, 0x55, 0x5c, 0x52, 0x59, 0x58, 0x55, 0x5c, 0x5f, 0x53, 0x5a,
+ 0x57, 0x5b, 0x50, 0x5e, 0x54, 0x51, 0x5a, 0x57, 0x51, 0x56, 0x5d, 0x50,
+ 0x5b, 0x58, 0x56, 0x5d, 0x0c, 0x0a, 0x01, 0x0f, 0x0a, 0x04, 0x0f, 0x02,
+ 0x09, 0x07, 0x02, 0x0c, 0x06, 0x09, 0x08, 0x05, 0x00, 0x06, 0x0d, 0x01,
+ 0x03, 0x0d, 0x04, 0x0e, 0x0e, 0x00, 0x07, 0x0b, 0x05, 0x03, 0x0b, 0x08,
+ 0x09, 0x04, 0x0e, 0x03, 0x0f, 0x02, 0x05, 0x0c, 0x02, 0x09, 0x08, 0x05,
+ 0x0c, 0x0f, 0x03, 0x0a, 0x07, 0x0b, 0x00, 0x0e, 0x04, 0x01, 0x0a, 0x07,
+ 0x01, 0x06, 0x0d, 0x00, 0x0b, 0x08, 0x06, 0x0d, 0x3c, 0x3a, 0x31, 0x3f,
+ 0x3a, 0x34, 0x3f, 0x32, 0x39, 0x37, 0x32, 0x3c, 0x36, 0x39, 0x38, 0x35,
+ 0x30, 0x36, 0x3d, 0x31, 0x33, 0x3d, 0x34, 0x3e, 0x3e, 0x30, 0x37, 0x3b,
+ 0x35, 0x33, 0x3b, 0x38, 0x39, 0x34, 0x3e, 0x33, 0x3f, 0x32, 0x35, 0x3c,
+ 0x32, 0x39, 0x38, 0x35, 0x3c, 0x3f, 0x33, 0x3a, 0x37, 0x3b, 0x30, 0x3e,
+ 0x34, 0x31, 0x3a, 0x37, 0x31, 0x36, 0x3d, 0x30, 0x3b, 0x38, 0x36, 0x3d,
+ 0xfc, 0xfa, 0xf1, 0xff, 0xfa, 0xf4, 0xff, 0xf2, 0xf9, 0xf7, 0xf2, 0xfc,
+ 0xf6, 0xf9, 0xf8, 0xf5, 0xf0, 0xf6, 0xfd, 0xf1, 0xf3, 0xfd, 0xf4, 0xfe,
+ 0xfe, 0xf0, 0xf7, 0xfb, 0xf5, 0xf3, 0xfb, 0xf8, 0xf9, 0xf4, 0xfe, 0xf3,
+ 0xff, 0xf2, 0xf5, 0xfc, 0xf2, 0xf9, 0xf8, 0xf5, 0xfc, 0xff, 0xf3, 0xfa,
+ 0xf7, 0xfb, 0xf0, 0xfe, 0xf4, 0xf1, 0xfa, 0xf7, 0xf1, 0xf6, 0xfd, 0xf0,
+ 0xfb, 0xf8, 0xf6, 0xfd, 0xfc, 0xfa, 0xf1, 0xff, 0xfa, 0xf4, 0xff, 0xf2,
+ 0xf9, 0xf7, 0xf2, 0xfc, 0xf6, 0xf9, 0xf8, 0xf5, 0xf0, 0xf6, 0xfd, 0xf1,
+ 0xf3, 0xfd, 0xf4, 0xfe, 0xfe, 0xf0, 0xf7, 0xfb, 0xf5, 0xf3, 0xfb, 0xf8,
+ 0xf9, 0xf4, 0xfe, 0xf3, 0xff, 0xf2, 0xf5, 0xfc, 0xf2, 0xf9, 0xf8, 0xf5,
+ 0xfc, 0xff, 0xf3, 0xfa, 0xf7, 0xfb, 0xf0, 0xfe, 0xf4, 0xf1, 0xfa, 0xf7,
+ 0xf1, 0xf6, 0xfd, 0xf0, 0xfb, 0xf8, 0xf6, 0xfd, 0xac, 0xaa, 0xa1, 0xaf,
+ 0xaa, 0xa4, 0xaf, 0xa2, 0xa9, 0xa7, 0xa2, 0xac, 0xa6, 0xa9, 0xa8, 0xa5,
+ 0xa0, 0xa6, 0xad, 0xa1, 0xa3, 0xad, 0xa4, 0xae, 0xae, 0xa0, 0xa7, 0xab,
+ 0xa5, 0xa3, 0xab, 0xa8, 0xa9, 0xa4, 0xae, 0xa3, 0xaf, 0xa2, 0xa5, 0xac,
+ 0xa2, 0xa9, 0xa8, 0xa5, 0xac, 0xaf, 0xa3, 0xaa, 0xa7, 0xab, 0xa0, 0xae,
+ 0xa4, 0xa1, 0xaa, 0xa7, 0xa1, 0xa6, 0xad, 0xa0, 0xab, 0xa8, 0xa6, 0xad,
+ 0xdc, 0xda, 0xd1, 0xdf, 0xda, 0xd4, 0xdf, 0xd2, 0xd9, 0xd7, 0xd2, 0xdc,
+ 0xd6, 0xd9, 0xd8, 0xd5, 0xd0, 0xd6, 0xdd, 0xd1, 0xd3, 0xdd, 0xd4, 0xde,
+ 0xde, 0xd0, 0xd7, 0xdb, 0xd5, 0xd3, 0xdb, 0xd8, 0xd9, 0xd4, 0xde, 0xd3,
+ 0xdf, 0xd2, 0xd5, 0xdc, 0xd2, 0xd9, 0xd8, 0xd5, 0xdc, 0xdf, 0xd3, 0xda,
+ 0xd7, 0xdb, 0xd0, 0xde, 0xd4, 0xd1, 0xda, 0xd7, 0xd1, 0xd6, 0xdd, 0xd0,
+ 0xdb, 0xd8, 0xd6, 0xdd, 0x3c, 0x3a, 0x31, 0x3f, 0x3a, 0x34, 0x3f, 0x32,
+ 0x39, 0x37, 0x32, 0x3c, 0x36, 0x39, 0x38, 0x35, 0x30, 0x36, 0x3d, 0x31,
+ 0x33, 0x3d, 0x34, 0x3e, 0x3e, 0x30, 0x37, 0x3b, 0x35, 0x33, 0x3b, 0x38,
+ 0x39, 0x34, 0x3e, 0x33, 0x3f, 0x32, 0x35, 0x3c, 0x32, 0x39, 0x38, 0x35,
+ 0x3c, 0x3f, 0x33, 0x3a, 0x37, 0x3b, 0x30, 0x3e, 0x34, 0x31, 0x3a, 0x37,
+ 0x31, 0x36, 0x3d, 0x30, 0x3b, 0x38, 0x36, 0x3d, 0x0c, 0x0a, 0x01, 0x0f,
+ 0x0a, 0x04, 0x0f, 0x02, 0x09, 0x07, 0x02, 0x0c, 0x06, 0x09, 0x08, 0x05,
+ 0x00, 0x06, 0x0d, 0x01, 0x03, 0x0d, 0x04, 0x0e, 0x0e, 0x00, 0x07, 0x0b,
+ 0x05, 0x03, 0x0b, 0x08, 0x09, 0x04, 0x0e, 0x03, 0x0f, 0x02, 0x05, 0x0c,
+ 0x02, 0x09, 0x08, 0x05, 0x0c, 0x0f, 0x03, 0x0a, 0x07, 0x0b, 0x00, 0x0e,
+ 0x04, 0x01, 0x0a, 0x07, 0x01, 0x06, 0x0d, 0x00, 0x0b, 0x08, 0x06, 0x0d,
+ 0x9c, 0x9a, 0x91, 0x9f, 0x9a, 0x94, 0x9f, 0x92, 0x99, 0x97, 0x92, 0x9c,
+ 0x96, 0x99, 0x98, 0x95, 0x90, 0x96, 0x9d, 0x91, 0x93, 0x9d, 0x94, 0x9e,
+ 0x9e, 0x90, 0x97, 0x9b, 0x95, 0x93, 0x9b, 0x98, 0x99, 0x94, 0x9e, 0x93,
+ 0x9f, 0x92, 0x95, 0x9c, 0x92, 0x99, 0x98, 0x95, 0x9c, 0x9f, 0x93, 0x9a,
+ 0x97, 0x9b, 0x90, 0x9e, 0x94, 0x91, 0x9a, 0x97, 0x91, 0x96, 0x9d, 0x90,
+ 0x9b, 0x98, 0x96, 0x9d, 0xec, 0xea, 0xe1, 0xef, 0xea, 0xe4, 0xef, 0xe2,
+ 0xe9, 0xe7, 0xe2, 0xec, 0xe6, 0xe9, 0xe8, 0xe5, 0xe0, 0xe6, 0xed, 0xe1,
+ 0xe3, 0xed, 0xe4, 0xee, 0xee, 0xe0, 0xe7, 0xeb, 0xe5, 0xe3, 0xeb, 0xe8,
+ 0xe9, 0xe4, 0xee, 0xe3, 0xef, 0xe2, 0xe5, 0xec, 0xe2, 0xe9, 0xe8, 0xe5,
+ 0xec, 0xef, 0xe3, 0xea, 0xe7, 0xeb, 0xe0, 0xee, 0xe4, 0xe1, 0xea, 0xe7,
+ 0xe1, 0xe6, 0xed, 0xe0, 0xeb, 0xe8, 0xe6, 0xed, 0x8c, 0x8a, 0x81, 0x8f,
+ 0x8a, 0x84, 0x8f, 0x82, 0x89, 0x87, 0x82, 0x8c, 0x86, 0x89, 0x88, 0x85,
+ 0x80, 0x86, 0x8d, 0x81, 0x83, 0x8d, 0x84, 0x8e, 0x8e, 0x80, 0x87, 0x8b,
+ 0x85, 0x83, 0x8b, 0x88, 0x89, 0x84, 0x8e, 0x83, 0x8f, 0x82, 0x85, 0x8c,
+ 0x82, 0x89, 0x88, 0x85, 0x8c, 0x8f, 0x83, 0x8a, 0x87, 0x8b, 0x80, 0x8e,
+ 0x84, 0x81, 0x8a, 0x87, 0x81, 0x86, 0x8d, 0x80, 0x8b, 0x88, 0x86, 0x8d,
+ 0x9c, 0x9a, 0x91, 0x9f, 0x9a, 0x94, 0x9f, 0x92, 0x99, 0x97, 0x92, 0x9c,
+ 0x96, 0x99, 0x98, 0x95, 0x90, 0x96, 0x9d, 0x91, 0x93, 0x9d, 0x94, 0x9e,
+ 0x9e, 0x90, 0x97, 0x9b, 0x95, 0x93, 0x9b, 0x98, 0x99, 0x94, 0x9e, 0x93,
+ 0x9f, 0x92, 0x95, 0x9c, 0x92, 0x99, 0x98, 0x95, 0x9c, 0x9f, 0x93, 0x9a,
+ 0x97, 0x9b, 0x90, 0x9e, 0x94, 0x91, 0x9a, 0x97, 0x91, 0x96, 0x9d, 0x90,
+ 0x9b, 0x98, 0x96, 0x9d, 0x6c, 0x6a, 0x61, 0x6f, 0x6a, 0x64, 0x6f, 0x62,
+ 0x69, 0x67, 0x62, 0x6c, 0x66, 0x69, 0x68, 0x65, 0x60, 0x66, 0x6d, 0x61,
+ 0x63, 0x6d, 0x64, 0x6e, 0x6e, 0x60, 0x67, 0x6b, 0x65, 0x63, 0x6b, 0x68,
+ 0x69, 0x64, 0x6e, 0x63, 0x6f, 0x62, 0x65, 0x6c, 0x62, 0x69, 0x68, 0x65,
+ 0x6c, 0x6f, 0x63, 0x6a, 0x67, 0x6b, 0x60, 0x6e, 0x64, 0x61, 0x6a, 0x67,
+ 0x61, 0x66, 0x6d, 0x60, 0x6b, 0x68, 0x66, 0x6d, 0x4c, 0x4a, 0x41, 0x4f,
+ 0x4a, 0x44, 0x4f, 0x42, 0x49, 0x47, 0x42, 0x4c, 0x46, 0x49, 0x48, 0x45,
+ 0x40, 0x46, 0x4d, 0x41, 0x43, 0x4d, 0x44, 0x4e, 0x4e, 0x40, 0x47, 0x4b,
+ 0x45, 0x43, 0x4b, 0x48, 0x49, 0x44, 0x4e, 0x43, 0x4f, 0x42, 0x45, 0x4c,
+ 0x42, 0x49, 0x48, 0x45, 0x4c, 0x4f, 0x43, 0x4a, 0x47, 0x4b, 0x40, 0x4e,
+ 0x44, 0x41, 0x4a, 0x47, 0x41, 0x46, 0x4d, 0x40, 0x4b, 0x48, 0x46, 0x4d,
+ 0xbc, 0xba, 0xb1, 0xbf, 0xba, 0xb4, 0xbf, 0xb2, 0xb9, 0xb7, 0xb2, 0xbc,
+ 0xb6, 0xb9, 0xb8, 0xb5, 0xb0, 0xb6, 0xbd, 0xb1, 0xb3, 0xbd, 0xb4, 0xbe,
+ 0xbe, 0xb0, 0xb7, 0xbb, 0xb5, 0xb3, 0xbb, 0xb8, 0xb9, 0xb4, 0xbe, 0xb3,
+ 0xbf, 0xb2, 0xb5, 0xbc, 0xb2, 0xb9, 0xb8, 0xb5, 0xbc, 0xbf, 0xb3, 0xba,
+ 0xb7, 0xbb, 0xb0, 0xbe, 0xb4, 0xb1, 0xba, 0xb7, 0xb1, 0xb6, 0xbd, 0xb0,
+ 0xbb, 0xb8, 0xb6, 0xbd, 0x2c, 0x2a, 0x21, 0x2f, 0x2a, 0x24, 0x2f, 0x22,
+ 0x29, 0x27, 0x22, 0x2c, 0x26, 0x29, 0x28, 0x25, 0x20, 0x26, 0x2d, 0x21,
+ 0x23, 0x2d, 0x24, 0x2e, 0x2e, 0x20, 0x27, 0x2b, 0x25, 0x23, 0x2b, 0x28,
+ 0x29, 0x24, 0x2e, 0x23, 0x2f, 0x22, 0x25, 0x2c, 0x22, 0x29, 0x28, 0x25,
+ 0x2c, 0x2f, 0x23, 0x2a, 0x27, 0x2b, 0x20, 0x2e, 0x24, 0x21, 0x2a, 0x27,
+ 0x21, 0x26, 0x2d, 0x20, 0x2b, 0x28, 0x26, 0x2d, 0x8c, 0x8a, 0x81, 0x8f,
+ 0x8a, 0x84, 0x8f, 0x82, 0x89, 0x87, 0x82, 0x8c, 0x86, 0x89, 0x88, 0x85,
+ 0x80, 0x86, 0x8d, 0x81, 0x83, 0x8d, 0x84, 0x8e, 0x8e, 0x80, 0x87, 0x8b,
+ 0x85, 0x83, 0x8b, 0x88, 0x89, 0x84, 0x8e, 0x83, 0x8f, 0x82, 0x85, 0x8c,
+ 0x82, 0x89, 0x88, 0x85, 0x8c, 0x8f, 0x83, 0x8a, 0x87, 0x8b, 0x80, 0x8e,
+ 0x84, 0x81, 0x8a, 0x87, 0x81, 0x86, 0x8d, 0x80, 0x8b, 0x88, 0x86, 0x8d,
+ 0x1c, 0x1a, 0x11, 0x1f, 0x1a, 0x14, 0x1f, 0x12, 0x19, 0x17, 0x12, 0x1c,
+ 0x16, 0x19, 0x18, 0x15, 0x10, 0x16, 0x1d, 0x11, 0x13, 0x1d, 0x14, 0x1e,
+ 0x1e, 0x10, 0x17, 0x1b, 0x15, 0x13, 0x1b, 0x18, 0x19, 0x14, 0x1e, 0x13,
+ 0x1f, 0x12, 0x15, 0x1c, 0x12, 0x19, 0x18, 0x15, 0x1c, 0x1f, 0x13, 0x1a,
+ 0x17, 0x1b, 0x10, 0x1e, 0x14, 0x11, 0x1a, 0x17, 0x11, 0x16, 0x1d, 0x10,
+ 0x1b, 0x18, 0x16, 0x1d, 0xcc, 0xca, 0xc1, 0xcf, 0xca, 0xc4, 0xcf, 0xc2,
+ 0xc9, 0xc7, 0xc2, 0xcc, 0xc6, 0xc9, 0xc8, 0xc5, 0xc0, 0xc6, 0xcd, 0xc1,
+ 0xc3, 0xcd, 0xc4, 0xce, 0xce, 0xc0, 0xc7, 0xcb, 0xc5, 0xc3, 0xcb, 0xc8,
+ 0xc9, 0xc4, 0xce, 0xc3, 0xcf, 0xc2, 0xc5, 0xcc, 0xc2, 0xc9, 0xc8, 0xc5,
+ 0xcc, 0xcf, 0xc3, 0xca, 0xc7, 0xcb, 0xc0, 0xce, 0xc4, 0xc1, 0xca, 0xc7,
+ 0xc1, 0xc6, 0xcd, 0xc0, 0xcb, 0xc8, 0xc6, 0xcd, 0xbc, 0xba, 0xb1, 0xbf,
+ 0xba, 0xb4, 0xbf, 0xb2, 0xb9, 0xb7, 0xb2, 0xbc, 0xb6, 0xb9, 0xb8, 0xb5,
+ 0xb0, 0xb6, 0xbd, 0xb1, 0xb3, 0xbd, 0xb4, 0xbe, 0xbe, 0xb0, 0xb7, 0xbb,
+ 0xb5, 0xb3, 0xbb, 0xb8, 0xb9, 0xb4, 0xbe, 0xb3, 0xbf, 0xb2, 0xb5, 0xbc,
+ 0xb2, 0xb9, 0xb8, 0xb5, 0xbc, 0xbf, 0xb3, 0xba, 0xb7, 0xbb, 0xb0, 0xbe,
+ 0xb4, 0xb1, 0xba, 0xb7, 0xb1, 0xb6, 0xbd, 0xb0, 0xbb, 0xb8, 0xb6, 0xbd,
+ 0x7c, 0x7a, 0x71, 0x7f, 0x7a, 0x74, 0x7f, 0x72, 0x79, 0x77, 0x72, 0x7c,
+ 0x76, 0x79, 0x78, 0x75, 0x70, 0x76, 0x7d, 0x71, 0x73, 0x7d, 0x74, 0x7e,
+ 0x7e, 0x70, 0x77, 0x7b, 0x75, 0x73, 0x7b, 0x78, 0x79, 0x74, 0x7e, 0x73,
+ 0x7f, 0x72, 0x75, 0x7c, 0x72, 0x79, 0x78, 0x75, 0x7c, 0x7f, 0x73, 0x7a,
+ 0x77, 0x7b, 0x70, 0x7e, 0x74, 0x71, 0x7a, 0x77, 0x71, 0x76, 0x7d, 0x70,
+ 0x7b, 0x78, 0x76, 0x7d, 0xac, 0xaa, 0xa1, 0xaf, 0xaa, 0xa4, 0xaf, 0xa2,
+ 0xa9, 0xa7, 0xa2, 0xac, 0xa6, 0xa9, 0xa8, 0xa5, 0xa0, 0xa6, 0xad, 0xa1,
+ 0xa3, 0xad, 0xa4, 0xae, 0xae, 0xa0, 0xa7, 0xab, 0xa5, 0xa3, 0xab, 0xa8,
+ 0xa9, 0xa4, 0xae, 0xa3, 0xaf, 0xa2, 0xa5, 0xac, 0xa2, 0xa9, 0xa8, 0xa5,
+ 0xac, 0xaf, 0xa3, 0xaa, 0xa7, 0xab, 0xa0, 0xae, 0xa4, 0xa1, 0xaa, 0xa7,
+ 0xa1, 0xa6, 0xad, 0xa0, 0xab, 0xa8, 0xa6, 0xad, 0x1c, 0x1a, 0x11, 0x1f,
+ 0x1a, 0x14, 0x1f, 0x12, 0x19, 0x17, 0x12, 0x1c, 0x16, 0x19, 0x18, 0x15,
+ 0x10, 0x16, 0x1d, 0x11, 0x13, 0x1d, 0x14, 0x1e, 0x1e, 0x10, 0x17, 0x1b,
+ 0x15, 0x13, 0x1b, 0x18, 0x19, 0x14, 0x1e, 0x13, 0x1f, 0x12, 0x15, 0x1c,
+ 0x12, 0x19, 0x18, 0x15, 0x1c, 0x1f, 0x13, 0x1a, 0x17, 0x1b, 0x10, 0x1e,
+ 0x14, 0x11, 0x1a, 0x17, 0x11, 0x16, 0x1d, 0x10, 0x1b, 0x18, 0x16, 0x1d,
+ 0xdc, 0xda, 0xd1, 0xdf, 0xda, 0xd4, 0xdf, 0xd2, 0xd9, 0xd7, 0xd2, 0xdc,
+ 0xd6, 0xd9, 0xd8, 0xd5, 0xd0, 0xd6, 0xdd, 0xd1, 0xd3, 0xdd, 0xd4, 0xde,
+ 0xde, 0xd0, 0xd7, 0xdb, 0xd5, 0xd3, 0xdb, 0xd8, 0xd9, 0xd4, 0xde, 0xd3,
+ 0xdf, 0xd2, 0xd5, 0xdc, 0xd2, 0xd9, 0xd8, 0xd5, 0xdc, 0xdf, 0xd3, 0xda,
+ 0xd7, 0xdb, 0xd0, 0xde, 0xd4, 0xd1, 0xda, 0xd7, 0xd1, 0xd6, 0xdd, 0xd0,
+ 0xdb, 0xd8, 0xd6, 0xdd, 0xec, 0xea, 0xe1, 0xef, 0xea, 0xe4, 0xef, 0xe2,
+ 0xe9, 0xe7, 0xe2, 0xec, 0xe6, 0xe9, 0xe8, 0xe5, 0xe0, 0xe6, 0xed, 0xe1,
+ 0xe3, 0xed, 0xe4, 0xee, 0xee, 0xe0, 0xe7, 0xeb, 0xe5, 0xe3, 0xeb, 0xe8,
+ 0xe9, 0xe4, 0xee, 0xe3, 0xef, 0xe2, 0xe5, 0xec, 0xe2, 0xe9, 0xe8, 0xe5,
+ 0xec, 0xef, 0xe3, 0xea, 0xe7, 0xeb, 0xe0, 0xee, 0xe4, 0xe1, 0xea, 0xe7,
+ 0xe1, 0xe6, 0xed, 0xe0, 0xeb, 0xe8, 0xe6, 0xed, 0x7c, 0x7a, 0x71, 0x7f,
+ 0x7a, 0x74, 0x7f, 0x72, 0x79, 0x77, 0x72, 0x7c, 0x76, 0x79, 0x78, 0x75,
+ 0x70, 0x76, 0x7d, 0x71, 0x73, 0x7d, 0x74, 0x7e, 0x7e, 0x70, 0x77, 0x7b,
+ 0x75, 0x73, 0x7b, 0x78, 0x79, 0x74, 0x7e, 0x73, 0x7f, 0x72, 0x75, 0x7c,
+ 0x72, 0x79, 0x78, 0x75, 0x7c, 0x7f, 0x73, 0x7a, 0x77, 0x7b, 0x70, 0x7e,
+ 0x74, 0x71, 0x7a, 0x77, 0x71, 0x76, 0x7d, 0x70, 0x7b, 0x78, 0x76, 0x7d,
+ 0x2c, 0x2a, 0x21, 0x2f, 0x2a, 0x24, 0x2f, 0x22, 0x29, 0x27, 0x22, 0x2c,
+ 0x26, 0x29, 0x28, 0x25, 0x20, 0x26, 0x2d, 0x21, 0x23, 0x2d, 0x24, 0x2e,
+ 0x2e, 0x20, 0x27, 0x2b, 0x25, 0x23, 0x2b, 0x28, 0x29, 0x24, 0x2e, 0x23,
+ 0x2f, 0x22, 0x25, 0x2c, 0x22, 0x29, 0x28, 0x25, 0x2c, 0x2f, 0x23, 0x2a,
+ 0x27, 0x2b, 0x20, 0x2e, 0x24, 0x21, 0x2a, 0x27, 0x21, 0x26, 0x2d, 0x20,
+ 0x2b, 0x28, 0x26, 0x2d, 0x8c, 0x8a, 0x81, 0x8f, 0x8a, 0x84, 0x8f, 0x82,
+ 0x89, 0x87, 0x82, 0x8c, 0x86, 0x89, 0x88, 0x85, 0x80, 0x86, 0x8d, 0x81,
+ 0x83, 0x8d, 0x84, 0x8e, 0x8e, 0x80, 0x87, 0x8b, 0x85, 0x83, 0x8b, 0x88,
+ 0x89, 0x84, 0x8e, 0x83, 0x8f, 0x82, 0x85, 0x8c, 0x82, 0x89, 0x88, 0x85,
+ 0x8c, 0x8f, 0x83, 0x8a, 0x87, 0x8b, 0x80, 0x8e, 0x84, 0x81, 0x8a, 0x87,
+ 0x81, 0x86, 0x8d, 0x80, 0x8b, 0x88, 0x86, 0x8d, 0xdc, 0xda, 0xd1, 0xdf,
+ 0xda, 0xd4, 0xdf, 0xd2, 0xd9, 0xd7, 0xd2, 0xdc, 0xd6, 0xd9, 0xd8, 0xd5,
+ 0xd0, 0xd6, 0xdd, 0xd1, 0xd3, 0xdd, 0xd4, 0xde, 0xde, 0xd0, 0xd7, 0xdb,
+ 0xd5, 0xd3, 0xdb, 0xd8, 0xd9, 0xd4, 0xde, 0xd3, 0xdf, 0xd2, 0xd5, 0xdc,
+ 0xd2, 0xd9, 0xd8, 0xd5, 0xdc, 0xdf, 0xd3, 0xda, 0xd7, 0xdb, 0xd0, 0xde,
+ 0xd4, 0xd1, 0xda, 0xd7, 0xd1, 0xd6, 0xdd, 0xd0, 0xdb, 0xd8, 0xd6, 0xdd,
+ 0xfc, 0xfa, 0xf1, 0xff, 0xfa, 0xf4, 0xff, 0xf2, 0xf9, 0xf7, 0xf2, 0xfc,
+ 0xf6, 0xf9, 0xf8, 0xf5, 0xf0, 0xf6, 0xfd, 0xf1, 0xf3, 0xfd, 0xf4, 0xfe,
+ 0xfe, 0xf0, 0xf7, 0xfb, 0xf5, 0xf3, 0xfb, 0xf8, 0xf9, 0xf4, 0xfe, 0xf3,
+ 0xff, 0xf2, 0xf5, 0xfc, 0xf2, 0xf9, 0xf8, 0xf5, 0xfc, 0xff, 0xf3, 0xfa,
+ 0xf7, 0xfb, 0xf0, 0xfe, 0xf4, 0xf1, 0xfa, 0xf7, 0xf1, 0xf6, 0xfd, 0xf0,
+ 0xfb, 0xf8, 0xf6, 0xfd, 0x6c, 0x6a, 0x61, 0x6f, 0x6a, 0x64, 0x6f, 0x62,
+ 0x69, 0x67, 0x62, 0x6c, 0x66, 0x69, 0x68, 0x65, 0x60, 0x66, 0x6d, 0x61,
+ 0x63, 0x6d, 0x64, 0x6e, 0x6e, 0x60, 0x67, 0x6b, 0x65, 0x63, 0x6b, 0x68,
+ 0x69, 0x64, 0x6e, 0x63, 0x6f, 0x62, 0x65, 0x6c, 0x62, 0x69, 0x68, 0x65,
+ 0x6c, 0x6f, 0x63, 0x6a, 0x67, 0x6b, 0x60, 0x6e, 0x64, 0x61, 0x6a, 0x67,
+ 0x61, 0x66, 0x6d, 0x60, 0x6b, 0x68, 0x66, 0x6d, 0x9c, 0x9a, 0x91, 0x9f,
+ 0x9a, 0x94, 0x9f, 0x92, 0x99, 0x97, 0x92, 0x9c, 0x96, 0x99, 0x98, 0x95,
+ 0x90, 0x96, 0x9d, 0x91, 0x93, 0x9d, 0x94, 0x9e, 0x9e, 0x90, 0x97, 0x9b,
+ 0x95, 0x93, 0x9b, 0x98, 0x99, 0x94, 0x9e, 0x93, 0x9f, 0x92, 0x95, 0x9c,
+ 0x92, 0x99, 0x98, 0x95, 0x9c, 0x9f, 0x93, 0x9a, 0x97, 0x9b, 0x90, 0x9e,
+ 0x94, 0x91, 0x9a, 0x97, 0x91, 0x96, 0x9d, 0x90, 0x9b, 0x98, 0x96, 0x9d,
+ 0xfc, 0xfa, 0xf1, 0xff, 0xfa, 0xf4, 0xff, 0xf2, 0xf9, 0xf7, 0xf2, 0xfc,
+ 0xf6, 0xf9, 0xf8, 0xf5, 0xf0, 0xf6, 0xfd, 0xf1, 0xf3, 0xfd, 0xf4, 0xfe,
+ 0xfe, 0xf0, 0xf7, 0xfb, 0xf5, 0xf3, 0xfb, 0xf8, 0xf9, 0xf4, 0xfe, 0xf3,
+ 0xff, 0xf2, 0xf5, 0xfc, 0xf2, 0xf9, 0xf8, 0xf5, 0xfc, 0xff, 0xf3, 0xfa,
+ 0xf7, 0xfb, 0xf0, 0xfe, 0xf4, 0xf1, 0xfa, 0xf7, 0xf1, 0xf6, 0xfd, 0xf0,
+ 0xfb, 0xf8, 0xf6, 0xfd, 0xcc, 0xca, 0xc1, 0xcf, 0xca, 0xc4, 0xcf, 0xc2,
+ 0xc9, 0xc7, 0xc2, 0xcc, 0xc6, 0xc9, 0xc8, 0xc5, 0xc0, 0xc6, 0xcd, 0xc1,
+ 0xc3, 0xcd, 0xc4, 0xce, 0xce, 0xc0, 0xc7, 0xcb, 0xc5, 0xc3, 0xcb, 0xc8,
+ 0xc9, 0xc4, 0xce, 0xc3, 0xcf, 0xc2, 0xc5, 0xcc, 0xc2, 0xc9, 0xc8, 0xc5,
+ 0xcc, 0xcf, 0xc3, 0xca, 0xc7, 0xcb, 0xc0, 0xce, 0xc4, 0xc1, 0xca, 0xc7,
+ 0xc1, 0xc6, 0xcd, 0xc0, 0xcb, 0xc8, 0xc6, 0xcd, 0x0c, 0x0a, 0x01, 0x0f,
+ 0x0a, 0x04, 0x0f, 0x02, 0x09, 0x07, 0x02, 0x0c, 0x06, 0x09, 0x08, 0x05,
+ 0x00, 0x06, 0x0d, 0x01, 0x03, 0x0d, 0x04, 0x0e, 0x0e, 0x00, 0x07, 0x0b,
+ 0x05, 0x03, 0x0b, 0x08, 0x09, 0x04, 0x0e, 0x03, 0x0f, 0x02, 0x05, 0x0c,
+ 0x02, 0x09, 0x08, 0x05, 0x0c, 0x0f, 0x03, 0x0a, 0x07, 0x0b, 0x00, 0x0e,
+ 0x04, 0x01, 0x0a, 0x07, 0x01, 0x06, 0x0d, 0x00, 0x0b, 0x08, 0x06, 0x0d,
+ 0x5c, 0x5a, 0x51, 0x5f, 0x5a, 0x54, 0x5f, 0x52, 0x59, 0x57, 0x52, 0x5c,
+ 0x56, 0x59, 0x58, 0x55, 0x50, 0x56, 0x5d, 0x51, 0x53, 0x5d, 0x54, 0x5e,
+ 0x5e, 0x50, 0x57, 0x5b, 0x55, 0x53, 0x5b, 0x58, 0x59, 0x54, 0x5e, 0x53,
+ 0x5f, 0x52, 0x55, 0x5c, 0x52, 0x59, 0x58, 0x55, 0x5c, 0x5f, 0x53, 0x5a,
+ 0x57, 0x5b, 0x50, 0x5e, 0x54, 0x51, 0x5a, 0x57, 0x51, 0x56, 0x5d, 0x50,
+ 0x5b, 0x58, 0x56, 0x5d, 0x9c, 0x9a, 0x91, 0x9f, 0x9a, 0x94, 0x9f, 0x92,
+ 0x99, 0x97, 0x92, 0x9c, 0x96, 0x99, 0x98, 0x95, 0x90, 0x96, 0x9d, 0x91,
+ 0x93, 0x9d, 0x94, 0x9e, 0x9e, 0x90, 0x97, 0x9b, 0x95, 0x93, 0x9b, 0x98,
+ 0x99, 0x94, 0x9e, 0x93, 0x9f, 0x92, 0x95, 0x9c, 0x92, 0x99, 0x98, 0x95,
+ 0x9c, 0x9f, 0x93, 0x9a, 0x97, 0x9b, 0x90, 0x9e, 0x94, 0x91, 0x9a, 0x97,
+ 0x91, 0x96, 0x9d, 0x90, 0x9b, 0x98, 0x96, 0x9d, 0x6c, 0x6a, 0x61, 0x6f,
+ 0x6a, 0x64, 0x6f, 0x62, 0x69, 0x67, 0x62, 0x6c, 0x66, 0x69, 0x68, 0x65,
+ 0x60, 0x66, 0x6d, 0x61, 0x63, 0x6d, 0x64, 0x6e, 0x6e, 0x60, 0x67, 0x6b,
+ 0x65, 0x63, 0x6b, 0x68, 0x69, 0x64, 0x6e, 0x63, 0x6f, 0x62, 0x65, 0x6c,
+ 0x62, 0x69, 0x68, 0x65, 0x6c, 0x6f, 0x63, 0x6a, 0x67, 0x6b, 0x60, 0x6e,
+ 0x64, 0x61, 0x6a, 0x67, 0x61, 0x66, 0x6d, 0x60, 0x6b, 0x68, 0x66, 0x6d,
+ 0xac, 0xaa, 0xa1, 0xaf, 0xaa, 0xa4, 0xaf, 0xa2, 0xa9, 0xa7, 0xa2, 0xac,
+ 0xa6, 0xa9, 0xa8, 0xa5, 0xa0, 0xa6, 0xad, 0xa1, 0xa3, 0xad, 0xa4, 0xae,
+ 0xae, 0xa0, 0xa7, 0xab, 0xa5, 0xa3, 0xab, 0xa8, 0xa9, 0xa4, 0xae, 0xa3,
+ 0xaf, 0xa2, 0xa5, 0xac, 0xa2, 0xa9, 0xa8, 0xa5, 0xac, 0xaf, 0xa3, 0xaa,
+ 0xa7, 0xab, 0xa0, 0xae, 0xa4, 0xa1, 0xaa, 0xa7, 0xa1, 0xa6, 0xad, 0xa0,
+ 0xab, 0xa8, 0xa6, 0xad, 0x3c, 0x3a, 0x31, 0x3f, 0x3a, 0x34, 0x3f, 0x32,
+ 0x39, 0x37, 0x32, 0x3c, 0x36, 0x39, 0x38, 0x35, 0x30, 0x36, 0x3d, 0x31,
+ 0x33, 0x3d, 0x34, 0x3e, 0x3e, 0x30, 0x37, 0x3b, 0x35, 0x33, 0x3b, 0x38,
+ 0x39, 0x34, 0x3e, 0x33, 0x3f, 0x32, 0x35, 0x3c, 0x32, 0x39, 0x38, 0x35,
+ 0x3c, 0x3f, 0x33, 0x3a, 0x37, 0x3b, 0x30, 0x3e, 0x34, 0x31, 0x3a, 0x37,
+ 0x31, 0x36, 0x3d, 0x30, 0x3b, 0x38, 0x36, 0x3d, 0x4c, 0x4a, 0x41, 0x4f,
+ 0x4a, 0x44, 0x4f, 0x42, 0x49, 0x47, 0x42, 0x4c, 0x46, 0x49, 0x48, 0x45,
+ 0x40, 0x46, 0x4d, 0x41, 0x43, 0x4d, 0x44, 0x4e, 0x4e, 0x40, 0x47, 0x4b,
+ 0x45, 0x43, 0x4b, 0x48, 0x49, 0x44, 0x4e, 0x43, 0x4f, 0x42, 0x45, 0x4c,
+ 0x42, 0x49, 0x48, 0x45, 0x4c, 0x4f, 0x43, 0x4a, 0x47, 0x4b, 0x40, 0x4e,
+ 0x44, 0x41, 0x4a, 0x47, 0x41, 0x46, 0x4d, 0x40, 0x4b, 0x48, 0x46, 0x4d,
+ 0x0c, 0x0a, 0x01, 0x0f, 0x0a, 0x04, 0x0f, 0x02, 0x09, 0x07, 0x02, 0x0c,
+ 0x06, 0x09, 0x08, 0x05, 0x00, 0x06, 0x0d, 0x01, 0x03, 0x0d, 0x04, 0x0e,
+ 0x0e, 0x00, 0x07, 0x0b, 0x05, 0x03, 0x0b, 0x08, 0x09, 0x04, 0x0e, 0x03,
+ 0x0f, 0x02, 0x05, 0x0c, 0x02, 0x09, 0x08, 0x05, 0x0c, 0x0f, 0x03, 0x0a,
+ 0x07, 0x0b, 0x00, 0x0e, 0x04, 0x01, 0x0a, 0x07, 0x01, 0x06, 0x0d, 0x00,
+ 0x0b, 0x08, 0x06, 0x0d, 0x5c, 0x5a, 0x51, 0x5f, 0x5a, 0x54, 0x5f, 0x52,
+ 0x59, 0x57, 0x52, 0x5c, 0x56, 0x59, 0x58, 0x55, 0x50, 0x56, 0x5d, 0x51,
+ 0x53, 0x5d, 0x54, 0x5e, 0x5e, 0x50, 0x57, 0x5b, 0x55, 0x53, 0x5b, 0x58,
+ 0x59, 0x54, 0x5e, 0x53, 0x5f, 0x52, 0x55, 0x5c, 0x52, 0x59, 0x58, 0x55,
+ 0x5c, 0x5f, 0x53, 0x5a, 0x57, 0x5b, 0x50, 0x5e, 0x54, 0x51, 0x5a, 0x57,
+ 0x51, 0x56, 0x5d, 0x50, 0x5b, 0x58, 0x56, 0x5d, 0xec, 0xea, 0xe1, 0xef,
+ 0xea, 0xe4, 0xef, 0xe2, 0xe9, 0xe7, 0xe2, 0xec, 0xe6, 0xe9, 0xe8, 0xe5,
+ 0xe0, 0xe6, 0xed, 0xe1, 0xe3, 0xed, 0xe4, 0xee, 0xee, 0xe0, 0xe7, 0xeb,
+ 0xe5, 0xe3, 0xeb, 0xe8, 0xe9, 0xe4, 0xee, 0xe3, 0xef, 0xe2, 0xe5, 0xec,
+ 0xe2, 0xe9, 0xe8, 0xe5, 0xec, 0xef, 0xe3, 0xea, 0xe7, 0xeb, 0xe0, 0xee,
+ 0xe4, 0xe1, 0xea, 0xe7, 0xe1, 0xe6, 0xed, 0xe0, 0xeb, 0xe8, 0xe6, 0xed,
+ 0x3c, 0x3a, 0x31, 0x3f, 0x3a, 0x34, 0x3f, 0x32, 0x39, 0x37, 0x32, 0x3c,
+ 0x36, 0x39, 0x38, 0x35, 0x30, 0x36, 0x3d, 0x31, 0x33, 0x3d, 0x34, 0x3e,
+ 0x3e, 0x30, 0x37, 0x3b, 0x35, 0x33, 0x3b, 0x38, 0x39, 0x34, 0x3e, 0x33,
+ 0x3f, 0x32, 0x35, 0x3c, 0x32, 0x39, 0x38, 0x35, 0x3c, 0x3f, 0x33, 0x3a,
+ 0x37, 0x3b, 0x30, 0x3e, 0x34, 0x31, 0x3a, 0x37, 0x31, 0x36, 0x3d, 0x30,
+ 0x3b, 0x38, 0x36, 0x3d,
+ },
+ {
+ 0x4d, 0x41, 0x42, 0x4f, 0x48, 0x4d, 0x44, 0x48, 0x46, 0x4a, 0x4f, 0x43,
+ 0x4b, 0x47, 0x41, 0x44, 0x4a, 0x4c, 0x49, 0x45, 0x43, 0x46, 0x4e, 0x4b,
+ 0x45, 0x40, 0x40, 0x4e, 0x4c, 0x49, 0x47, 0x42, 0x47, 0x42, 0x4b, 0x41,
+ 0x44, 0x4e, 0x41, 0x47, 0x49, 0x44, 0x4c, 0x4a, 0x4e, 0x48, 0x42, 0x4d,
+ 0x40, 0x4f, 0x46, 0x4c, 0x4a, 0x49, 0x4d, 0x40, 0x4f, 0x43, 0x43, 0x45,
+ 0x45, 0x46, 0x48, 0x4b, 0xdd, 0xd1, 0xd2, 0xdf, 0xd8, 0xdd, 0xd4, 0xd8,
+ 0xd6, 0xda, 0xdf, 0xd3, 0xdb, 0xd7, 0xd1, 0xd4, 0xda, 0xdc, 0xd9, 0xd5,
+ 0xd3, 0xd6, 0xde, 0xdb, 0xd5, 0xd0, 0xd0, 0xde, 0xdc, 0xd9, 0xd7, 0xd2,
+ 0xd7, 0xd2, 0xdb, 0xd1, 0xd4, 0xde, 0xd1, 0xd7, 0xd9, 0xd4, 0xdc, 0xda,
+ 0xde, 0xd8, 0xd2, 0xdd, 0xd0, 0xdf, 0xd6, 0xdc, 0xda, 0xd9, 0xdd, 0xd0,
+ 0xdf, 0xd3, 0xd3, 0xd5, 0xd5, 0xd6, 0xd8, 0xdb, 0xbd, 0xb1, 0xb2, 0xbf,
+ 0xb8, 0xbd, 0xb4, 0xb8, 0xb6, 0xba, 0xbf, 0xb3, 0xbb, 0xb7, 0xb1, 0xb4,
+ 0xba, 0xbc, 0xb9, 0xb5, 0xb3, 0xb6, 0xbe, 0xbb, 0xb5, 0xb0, 0xb0, 0xbe,
+ 0xbc, 0xb9, 0xb7, 0xb2, 0xb7, 0xb2, 0xbb, 0xb1, 0xb4, 0xbe, 0xb1, 0xb7,
+ 0xb9, 0xb4, 0xbc, 0xba, 0xbe, 0xb8, 0xb2, 0xbd, 0xb0, 0xbf, 0xb6, 0xbc,
+ 0xba, 0xb9, 0xbd, 0xb0, 0xbf, 0xb3, 0xb3, 0xb5, 0xb5, 0xb6, 0xb8, 0xbb,
+ 0x0d, 0x01, 0x02, 0x0f, 0x08, 0x0d, 0x04, 0x08, 0x06, 0x0a, 0x0f, 0x03,
+ 0x0b, 0x07, 0x01, 0x04, 0x0a, 0x0c, 0x09, 0x05, 0x03, 0x06, 0x0e, 0x0b,
+ 0x05, 0x00, 0x00, 0x0e, 0x0c, 0x09, 0x07, 0x02, 0x07, 0x02, 0x0b, 0x01,
+ 0x04, 0x0e, 0x01, 0x07, 0x09, 0x04, 0x0c, 0x0a, 0x0e, 0x08, 0x02, 0x0d,
+ 0x00, 0x0f, 0x06, 0x0c, 0x0a, 0x09, 0x0d, 0x00, 0x0f, 0x03, 0x03, 0x05,
+ 0x05, 0x06, 0x08, 0x0b, 0x2d, 0x21, 0x22, 0x2f, 0x28, 0x2d, 0x24, 0x28,
+ 0x26, 0x2a, 0x2f, 0x23, 0x2b, 0x27, 0x21, 0x24, 0x2a, 0x2c, 0x29, 0x25,
+ 0x23, 0x26, 0x2e, 0x2b, 0x25, 0x20, 0x20, 0x2e, 0x2c, 0x29, 0x27, 0x22,
+ 0x27, 0x22, 0x2b, 0x21, 0x24, 0x2e, 0x21, 0x27, 0x29, 0x24, 0x2c, 0x2a,
+ 0x2e, 0x28, 0x22, 0x2d, 0x20, 0x2f, 0x26, 0x2c, 0x2a, 0x29, 0x2d, 0x20,
+ 0x2f, 0x23, 0x23, 0x25, 0x25, 0x26, 0x28, 0x2b, 0xbd, 0xb1, 0xb2, 0xbf,
+ 0xb8, 0xbd, 0xb4, 0xb8, 0xb6, 0xba, 0xbf, 0xb3, 0xbb, 0xb7, 0xb1, 0xb4,
+ 0xba, 0xbc, 0xb9, 0xb5, 0xb3, 0xb6, 0xbe, 0xbb, 0xb5, 0xb0, 0xb0, 0xbe,
+ 0xbc, 0xb9, 0xb7, 0xb2, 0xb7, 0xb2, 0xbb, 0xb1, 0xb4, 0xbe, 0xb1, 0xb7,
+ 0xb9, 0xb4, 0xbc, 0xba, 0xbe, 0xb8, 0xb2, 0xbd, 0xb0, 0xbf, 0xb6, 0xbc,
+ 0xba, 0xb9, 0xbd, 0xb0, 0xbf, 0xb3, 0xb3, 0xb5, 0xb5, 0xb6, 0xb8, 0xbb,
+ 0xed, 0xe1, 0xe2, 0xef, 0xe8, 0xed, 0xe4, 0xe8, 0xe6, 0xea, 0xef, 0xe3,
+ 0xeb, 0xe7, 0xe1, 0xe4, 0xea, 0xec, 0xe9, 0xe5, 0xe3, 0xe6, 0xee, 0xeb,
+ 0xe5, 0xe0, 0xe0, 0xee, 0xec, 0xe9, 0xe7, 0xe2, 0xe7, 0xe2, 0xeb, 0xe1,
+ 0xe4, 0xee, 0xe1, 0xe7, 0xe9, 0xe4, 0xec, 0xea, 0xee, 0xe8, 0xe2, 0xed,
+ 0xe0, 0xef, 0xe6, 0xec, 0xea, 0xe9, 0xed, 0xe0, 0xef, 0xe3, 0xe3, 0xe5,
+ 0xe5, 0xe6, 0xe8, 0xeb, 0x7d, 0x71, 0x72, 0x7f, 0x78, 0x7d, 0x74, 0x78,
+ 0x76, 0x7a, 0x7f, 0x73, 0x7b, 0x77, 0x71, 0x74, 0x7a, 0x7c, 0x79, 0x75,
+ 0x73, 0x76, 0x7e, 0x7b, 0x75, 0x70, 0x70, 0x7e, 0x7c, 0x79, 0x77, 0x72,
+ 0x77, 0x72, 0x7b, 0x71, 0x74, 0x7e, 0x71, 0x77, 0x79, 0x74, 0x7c, 0x7a,
+ 0x7e, 0x78, 0x72, 0x7d, 0x70, 0x7f, 0x76, 0x7c, 0x7a, 0x79, 0x7d, 0x70,
+ 0x7f, 0x73, 0x73, 0x75, 0x75, 0x76, 0x78, 0x7b, 0xfd, 0xf1, 0xf2, 0xff,
+ 0xf8, 0xfd, 0xf4, 0xf8, 0xf6, 0xfa, 0xff, 0xf3, 0xfb, 0xf7, 0xf1, 0xf4,
+ 0xfa, 0xfc, 0xf9, 0xf5, 0xf3, 0xf6, 0xfe, 0xfb, 0xf5, 0xf0, 0xf0, 0xfe,
+ 0xfc, 0xf9, 0xf7, 0xf2, 0xf7, 0xf2, 0xfb, 0xf1, 0xf4, 0xfe, 0xf1, 0xf7,
+ 0xf9, 0xf4, 0xfc, 0xfa, 0xfe, 0xf8, 0xf2, 0xfd, 0xf0, 0xff, 0xf6, 0xfc,
+ 0xfa, 0xf9, 0xfd, 0xf0, 0xff, 0xf3, 0xf3, 0xf5, 0xf5, 0xf6, 0xf8, 0xfb,
+ 0x4d, 0x41, 0x42, 0x4f, 0x48, 0x4d, 0x44, 0x48, 0x46, 0x4a, 0x4f, 0x43,
+ 0x4b, 0x47, 0x41, 0x44, 0x4a, 0x4c, 0x49, 0x45, 0x43, 0x46, 0x4e, 0x4b,
+ 0x45, 0x40, 0x40, 0x4e, 0x4c, 0x49, 0x47, 0x42, 0x47, 0x42, 0x4b, 0x41,
+ 0x44, 0x4e, 0x41, 0x47, 0x49, 0x44, 0x4c, 0x4a, 0x4e, 0x48, 0x42, 0x4d,
+ 0x40, 0x4f, 0x46, 0x4c, 0x4a, 0x49, 0x4d, 0x40, 0x4f, 0x43, 0x43, 0x45,
+ 0x45, 0x46, 0x48, 0x4b, 0x0d, 0x01, 0x02, 0x0f, 0x08, 0x0d, 0x04, 0x08,
+ 0x06, 0x0a, 0x0f, 0x03, 0x0b, 0x07, 0x01, 0x04, 0x0a, 0x0c, 0x09, 0x05,
+ 0x03, 0x06, 0x0e, 0x0b, 0x05, 0x00, 0x00, 0x0e, 0x0c, 0x09, 0x07, 0x02,
+ 0x07, 0x02, 0x0b, 0x01, 0x04, 0x0e, 0x01, 0x07, 0x09, 0x04, 0x0c, 0x0a,
+ 0x0e, 0x08, 0x02, 0x0d, 0x00, 0x0f, 0x06, 0x0c, 0x0a, 0x09, 0x0d, 0x00,
+ 0x0f, 0x03, 0x03, 0x05, 0x05, 0x06, 0x08, 0x0b, 0x9d, 0x91, 0x92, 0x9f,
+ 0x98, 0x9d, 0x94, 0x98, 0x96, 0x9a, 0x9f, 0x93, 0x9b, 0x97, 0x91, 0x94,
+ 0x9a, 0x9c, 0x99, 0x95, 0x93, 0x96, 0x9e, 0x9b, 0x95, 0x90, 0x90, 0x9e,
+ 0x9c, 0x99, 0x97, 0x92, 0x97, 0x92, 0x9b, 0x91, 0x94, 0x9e, 0x91, 0x97,
+ 0x99, 0x94, 0x9c, 0x9a, 0x9e, 0x98, 0x92, 0x9d, 0x90, 0x9f, 0x96, 0x9c,
+ 0x9a, 0x99, 0x9d, 0x90, 0x9f, 0x93, 0x93, 0x95, 0x95, 0x96, 0x98, 0x9b,
+ 0x8d, 0x81, 0x82, 0x8f, 0x88, 0x8d, 0x84, 0x88, 0x86, 0x8a, 0x8f, 0x83,
+ 0x8b, 0x87, 0x81, 0x84, 0x8a, 0x8c, 0x89, 0x85, 0x83, 0x86, 0x8e, 0x8b,
+ 0x85, 0x80, 0x80, 0x8e, 0x8c, 0x89, 0x87, 0x82, 0x87, 0x82, 0x8b, 0x81,
+ 0x84, 0x8e, 0x81, 0x87, 0x89, 0x84, 0x8c, 0x8a, 0x8e, 0x88, 0x82, 0x8d,
+ 0x80, 0x8f, 0x86, 0x8c, 0x8a, 0x89, 0x8d, 0x80, 0x8f, 0x83, 0x83, 0x85,
+ 0x85, 0x86, 0x88, 0x8b, 0x1d, 0x11, 0x12, 0x1f, 0x18, 0x1d, 0x14, 0x18,
+ 0x16, 0x1a, 0x1f, 0x13, 0x1b, 0x17, 0x11, 0x14, 0x1a, 0x1c, 0x19, 0x15,
+ 0x13, 0x16, 0x1e, 0x1b, 0x15, 0x10, 0x10, 0x1e, 0x1c, 0x19, 0x17, 0x12,
+ 0x17, 0x12, 0x1b, 0x11, 0x14, 0x1e, 0x11, 0x17, 0x19, 0x14, 0x1c, 0x1a,
+ 0x1e, 0x18, 0x12, 0x1d, 0x10, 0x1f, 0x16, 0x1c, 0x1a, 0x19, 0x1d, 0x10,
+ 0x1f, 0x13, 0x13, 0x15, 0x15, 0x16, 0x18, 0x1b, 0xdd, 0xd1, 0xd2, 0xdf,
+ 0xd8, 0xdd, 0xd4, 0xd8, 0xd6, 0xda, 0xdf, 0xd3, 0xdb, 0xd7, 0xd1, 0xd4,
+ 0xda, 0xdc, 0xd9, 0xd5, 0xd3, 0xd6, 0xde, 0xdb, 0xd5, 0xd0, 0xd0, 0xde,
+ 0xdc, 0xd9, 0xd7, 0xd2, 0xd7, 0xd2, 0xdb, 0xd1, 0xd4, 0xde, 0xd1, 0xd7,
+ 0xd9, 0xd4, 0xdc, 0xda, 0xde, 0xd8, 0xd2, 0xdd, 0xd0, 0xdf, 0xd6, 0xdc,
+ 0xda, 0xd9, 0xdd, 0xd0, 0xdf, 0xd3, 0xd3, 0xd5, 0xd5, 0xd6, 0xd8, 0xdb,
+ 0xad, 0xa1, 0xa2, 0xaf, 0xa8, 0xad, 0xa4, 0xa8, 0xa6, 0xaa, 0xaf, 0xa3,
+ 0xab, 0xa7, 0xa1, 0xa4, 0xaa, 0xac, 0xa9, 0xa5, 0xa3, 0xa6, 0xae, 0xab,
+ 0xa5, 0xa0, 0xa0, 0xae, 0xac, 0xa9, 0xa7, 0xa2, 0xa7, 0xa2, 0xab, 0xa1,
+ 0xa4, 0xae, 0xa1, 0xa7, 0xa9, 0xa4, 0xac, 0xaa, 0xae, 0xa8, 0xa2, 0xad,
+ 0xa0, 0xaf, 0xa6, 0xac, 0xaa, 0xa9, 0xad, 0xa0, 0xaf, 0xa3, 0xa3, 0xa5,
+ 0xa5, 0xa6, 0xa8, 0xab, 0x3d, 0x31, 0x32, 0x3f, 0x38, 0x3d, 0x34, 0x38,
+ 0x36, 0x3a, 0x3f, 0x33, 0x3b, 0x37, 0x31, 0x34, 0x3a, 0x3c, 0x39, 0x35,
+ 0x33, 0x36, 0x3e, 0x3b, 0x35, 0x30, 0x30, 0x3e, 0x3c, 0x39, 0x37, 0x32,
+ 0x37, 0x32, 0x3b, 0x31, 0x34, 0x3e, 0x31, 0x37, 0x39, 0x34, 0x3c, 0x3a,
+ 0x3e, 0x38, 0x32, 0x3d, 0x30, 0x3f, 0x36, 0x3c, 0x3a, 0x39, 0x3d, 0x30,
+ 0x3f, 0x33, 0x33, 0x35, 0x35, 0x36, 0x38, 0x3b, 0xed, 0xe1, 0xe2, 0xef,
+ 0xe8, 0xed, 0xe4, 0xe8, 0xe6, 0xea, 0xef, 0xe3, 0xeb, 0xe7, 0xe1, 0xe4,
+ 0xea, 0xec, 0xe9, 0xe5, 0xe3, 0xe6, 0xee, 0xeb, 0xe5, 0xe0, 0xe0, 0xee,
+ 0xec, 0xe9, 0xe7, 0xe2, 0xe7, 0xe2, 0xeb, 0xe1, 0xe4, 0xee, 0xe1, 0xe7,
+ 0xe9, 0xe4, 0xec, 0xea, 0xee, 0xe8, 0xe2, 0xed, 0xe0, 0xef, 0xe6, 0xec,
+ 0xea, 0xe9, 0xed, 0xe0, 0xef, 0xe3, 0xe3, 0xe5, 0xe5, 0xe6, 0xe8, 0xeb,
+ 0xcd, 0xc1, 0xc2, 0xcf, 0xc8, 0xcd, 0xc4, 0xc8, 0xc6, 0xca, 0xcf, 0xc3,
+ 0xcb, 0xc7, 0xc1, 0xc4, 0xca, 0xcc, 0xc9, 0xc5, 0xc3, 0xc6, 0xce, 0xcb,
+ 0xc5, 0xc0, 0xc0, 0xce, 0xcc, 0xc9, 0xc7, 0xc2, 0xc7, 0xc2, 0xcb, 0xc1,
+ 0xc4, 0xce, 0xc1, 0xc7, 0xc9, 0xc4, 0xcc, 0xca, 0xce, 0xc8, 0xc2, 0xcd,
+ 0xc0, 0xcf, 0xc6, 0xcc, 0xca, 0xc9, 0xcd, 0xc0, 0xcf, 0xc3, 0xc3, 0xc5,
+ 0xc5, 0xc6, 0xc8, 0xcb, 0x3d, 0x31, 0x32, 0x3f, 0x38, 0x3d, 0x34, 0x38,
+ 0x36, 0x3a, 0x3f, 0x33, 0x3b, 0x37, 0x31, 0x34, 0x3a, 0x3c, 0x39, 0x35,
+ 0x33, 0x36, 0x3e, 0x3b, 0x35, 0x30, 0x30, 0x3e, 0x3c, 0x39, 0x37, 0x32,
+ 0x37, 0x32, 0x3b, 0x31, 0x34, 0x3e, 0x31, 0x37, 0x39, 0x34, 0x3c, 0x3a,
+ 0x3e, 0x38, 0x32, 0x3d, 0x30, 0x3f, 0x36, 0x3c, 0x3a, 0x39, 0x3d, 0x30,
+ 0x3f, 0x33, 0x33, 0x35, 0x35, 0x36, 0x38, 0x3b, 0x9d, 0x91, 0x92, 0x9f,
+ 0x98, 0x9d, 0x94, 0x98, 0x96, 0x9a, 0x9f, 0x93, 0x9b, 0x97, 0x91, 0x94,
+ 0x9a, 0x9c, 0x99, 0x95, 0x93, 0x96, 0x9e, 0x9b, 0x95, 0x90, 0x90, 0x9e,
+ 0x9c, 0x99, 0x97, 0x92, 0x97, 0x92, 0x9b, 0x91, 0x94, 0x9e, 0x91, 0x97,
+ 0x99, 0x94, 0x9c, 0x9a, 0x9e, 0x98, 0x92, 0x9d, 0x90, 0x9f, 0x96, 0x9c,
+ 0x9a, 0x99, 0x9d, 0x90, 0x9f, 0x93, 0x93, 0x95, 0x95, 0x96, 0x98, 0x9b,
+ 0x5d, 0x51, 0x52, 0x5f, 0x58, 0x5d, 0x54, 0x58, 0x56, 0x5a, 0x5f, 0x53,
+ 0x5b, 0x57, 0x51, 0x54, 0x5a, 0x5c, 0x59, 0x55, 0x53, 0x56, 0x5e, 0x5b,
+ 0x55, 0x50, 0x50, 0x5e, 0x5c, 0x59, 0x57, 0x52, 0x57, 0x52, 0x5b, 0x51,
+ 0x54, 0x5e, 0x51, 0x57, 0x59, 0x54, 0x5c, 0x5a, 0x5e, 0x58, 0x52, 0x5d,
+ 0x50, 0x5f, 0x56, 0x5c, 0x5a, 0x59, 0x5d, 0x50, 0x5f, 0x53, 0x53, 0x55,
+ 0x55, 0x56, 0x58, 0x5b, 0x7d, 0x71, 0x72, 0x7f, 0x78, 0x7d, 0x74, 0x78,
+ 0x76, 0x7a, 0x7f, 0x73, 0x7b, 0x77, 0x71, 0x74, 0x7a, 0x7c, 0x79, 0x75,
+ 0x73, 0x76, 0x7e, 0x7b, 0x75, 0x70, 0x70, 0x7e, 0x7c, 0x79, 0x77, 0x72,
+ 0x77, 0x72, 0x7b, 0x71, 0x74, 0x7e, 0x71, 0x77, 0x79, 0x74, 0x7c, 0x7a,
+ 0x7e, 0x78, 0x72, 0x7d, 0x70, 0x7f, 0x76, 0x7c, 0x7a, 0x79, 0x7d, 0x70,
+ 0x7f, 0x73, 0x73, 0x75, 0x75, 0x76, 0x78, 0x7b, 0xcd, 0xc1, 0xc2, 0xcf,
+ 0xc8, 0xcd, 0xc4, 0xc8, 0xc6, 0xca, 0xcf, 0xc3, 0xcb, 0xc7, 0xc1, 0xc4,
+ 0xca, 0xcc, 0xc9, 0xc5, 0xc3, 0xc6, 0xce, 0xcb, 0xc5, 0xc0, 0xc0, 0xce,
+ 0xcc, 0xc9, 0xc7, 0xc2, 0xc7, 0xc2, 0xcb, 0xc1, 0xc4, 0xce, 0xc1, 0xc7,
+ 0xc9, 0xc4, 0xcc, 0xca, 0xce, 0xc8, 0xc2, 0xcd, 0xc0, 0xcf, 0xc6, 0xcc,
+ 0xca, 0xc9, 0xcd, 0xc0, 0xcf, 0xc3, 0xc3, 0xc5, 0xc5, 0xc6, 0xc8, 0xcb,
+ 0x5d, 0x51, 0x52, 0x5f, 0x58, 0x5d, 0x54, 0x58, 0x56, 0x5a, 0x5f, 0x53,
+ 0x5b, 0x57, 0x51, 0x54, 0x5a, 0x5c, 0x59, 0x55, 0x53, 0x56, 0x5e, 0x5b,
+ 0x55, 0x50, 0x50, 0x5e, 0x5c, 0x59, 0x57, 0x52, 0x57, 0x52, 0x5b, 0x51,
+ 0x54, 0x5e, 0x51, 0x57, 0x59, 0x54, 0x5c, 0x5a, 0x5e, 0x58, 0x52, 0x5d,
+ 0x50, 0x5f, 0x56, 0x5c, 0x5a, 0x59, 0x5d, 0x50, 0x5f, 0x53, 0x53, 0x55,
+ 0x55, 0x56, 0x58, 0x5b, 0x2d, 0x21, 0x22, 0x2f, 0x28, 0x2d, 0x24, 0x28,
+ 0x26, 0x2a, 0x2f, 0x23, 0x2b, 0x27, 0x21, 0x24, 0x2a, 0x2c, 0x29, 0x25,
+ 0x23, 0x26, 0x2e, 0x2b, 0x25, 0x20, 0x20, 0x2e, 0x2c, 0x29, 0x27, 0x22,
+ 0x27, 0x22, 0x2b, 0x21, 0x24, 0x2e, 0x21, 0x27, 0x29, 0x24, 0x2c, 0x2a,
+ 0x2e, 0x28, 0x22, 0x2d, 0x20, 0x2f, 0x26, 0x2c, 0x2a, 0x29, 0x2d, 0x20,
+ 0x2f, 0x23, 0x23, 0x25, 0x25, 0x26, 0x28, 0x2b, 0xad, 0xa1, 0xa2, 0xaf,
+ 0xa8, 0xad, 0xa4, 0xa8, 0xa6, 0xaa, 0xaf, 0xa3, 0xab, 0xa7, 0xa1, 0xa4,
+ 0xaa, 0xac, 0xa9, 0xa5, 0xa3, 0xa6, 0xae, 0xab, 0xa5, 0xa0, 0xa0, 0xae,
+ 0xac, 0xa9, 0xa7, 0xa2, 0xa7, 0xa2, 0xab, 0xa1, 0xa4, 0xae, 0xa1, 0xa7,
+ 0xa9, 0xa4, 0xac, 0xaa, 0xae, 0xa8, 0xa2, 0xad, 0xa0, 0xaf, 0xa6, 0xac,
+ 0xaa, 0xa9, 0xad, 0xa0, 0xaf, 0xa3, 0xa3, 0xa5, 0xa5, 0xa6, 0xa8, 0xab,
+ 0xfd, 0xf1, 0xf2, 0xff, 0xf8, 0xfd, 0xf4, 0xf8, 0xf6, 0xfa, 0xff, 0xf3,
+ 0xfb, 0xf7, 0xf1, 0xf4, 0xfa, 0xfc, 0xf9, 0xf5, 0xf3, 0xf6, 0xfe, 0xfb,
+ 0xf5, 0xf0, 0xf0, 0xfe, 0xfc, 0xf9, 0xf7, 0xf2, 0xf7, 0xf2, 0xfb, 0xf1,
+ 0xf4, 0xfe, 0xf1, 0xf7, 0xf9, 0xf4, 0xfc, 0xfa, 0xfe, 0xf8, 0xf2, 0xfd,
+ 0xf0, 0xff, 0xf6, 0xfc, 0xfa, 0xf9, 0xfd, 0xf0, 0xff, 0xf3, 0xf3, 0xf5,
+ 0xf5, 0xf6, 0xf8, 0xfb, 0x6d, 0x61, 0x62, 0x6f, 0x68, 0x6d, 0x64, 0x68,
+ 0x66, 0x6a, 0x6f, 0x63, 0x6b, 0x67, 0x61, 0x64, 0x6a, 0x6c, 0x69, 0x65,
+ 0x63, 0x66, 0x6e, 0x6b, 0x65, 0x60, 0x60, 0x6e, 0x6c, 0x69, 0x67, 0x62,
+ 0x67, 0x62, 0x6b, 0x61, 0x64, 0x6e, 0x61, 0x67, 0x69, 0x64, 0x6c, 0x6a,
+ 0x6e, 0x68, 0x62, 0x6d, 0x60, 0x6f, 0x66, 0x6c, 0x6a, 0x69, 0x6d, 0x60,
+ 0x6f, 0x63, 0x63, 0x65, 0x65, 0x66, 0x68, 0x6b, 0x8d, 0x81, 0x82, 0x8f,
+ 0x88, 0x8d, 0x84, 0x88, 0x86, 0x8a, 0x8f, 0x83, 0x8b, 0x87, 0x81, 0x84,
+ 0x8a, 0x8c, 0x89, 0x85, 0x83, 0x86, 0x8e, 0x8b, 0x85, 0x80, 0x80, 0x8e,
+ 0x8c, 0x89, 0x87, 0x82, 0x87, 0x82, 0x8b, 0x81, 0x84, 0x8e, 0x81, 0x87,
+ 0x89, 0x84, 0x8c, 0x8a, 0x8e, 0x88, 0x82, 0x8d, 0x80, 0x8f, 0x86, 0x8c,
+ 0x8a, 0x89, 0x8d, 0x80, 0x8f, 0x83, 0x83, 0x85, 0x85, 0x86, 0x88, 0x8b,
+ 0x1d, 0x11, 0x12, 0x1f, 0x18, 0x1d, 0x14, 0x18, 0x16, 0x1a, 0x1f, 0x13,
+ 0x1b, 0x17, 0x11, 0x14, 0x1a, 0x1c, 0x19, 0x15, 0x13, 0x16, 0x1e, 0x1b,
+ 0x15, 0x10, 0x10, 0x1e, 0x1c, 0x19, 0x17, 0x12, 0x17, 0x12, 0x1b, 0x11,
+ 0x14, 0x1e, 0x11, 0x17, 0x19, 0x14, 0x1c, 0x1a, 0x1e, 0x18, 0x12, 0x1d,
+ 0x10, 0x1f, 0x16, 0x1c, 0x1a, 0x19, 0x1d, 0x10, 0x1f, 0x13, 0x13, 0x15,
+ 0x15, 0x16, 0x18, 0x1b, 0x6d, 0x61, 0x62, 0x6f, 0x68, 0x6d, 0x64, 0x68,
+ 0x66, 0x6a, 0x6f, 0x63, 0x6b, 0x67, 0x61, 0x64, 0x6a, 0x6c, 0x69, 0x65,
+ 0x63, 0x66, 0x6e, 0x6b, 0x65, 0x60, 0x60, 0x6e, 0x6c, 0x69, 0x67, 0x62,
+ 0x67, 0x62, 0x6b, 0x61, 0x64, 0x6e, 0x61, 0x67, 0x69, 0x64, 0x6c, 0x6a,
+ 0x6e, 0x68, 0x62, 0x6d, 0x60, 0x6f, 0x66, 0x6c, 0x6a, 0x69, 0x6d, 0x60,
+ 0x6f, 0x63, 0x63, 0x65, 0x65, 0x66, 0x68, 0x6b, 0x1d, 0x11, 0x12, 0x1f,
+ 0x18, 0x1d, 0x14, 0x18, 0x16, 0x1a, 0x1f, 0x13, 0x1b, 0x17, 0x11, 0x14,
+ 0x1a, 0x1c, 0x19, 0x15, 0x13, 0x16, 0x1e, 0x1b, 0x15, 0x10, 0x10, 0x1e,
+ 0x1c, 0x19, 0x17, 0x12, 0x17, 0x12, 0x1b, 0x11, 0x14, 0x1e, 0x11, 0x17,
+ 0x19, 0x14, 0x1c, 0x1a, 0x1e, 0x18, 0x12, 0x1d, 0x10, 0x1f, 0x16, 0x1c,
+ 0x1a, 0x19, 0x1d, 0x10, 0x1f, 0x13, 0x13, 0x15, 0x15, 0x16, 0x18, 0x1b,
+ 0x6d, 0x61, 0x62, 0x6f, 0x68, 0x6d, 0x64, 0x68, 0x66, 0x6a, 0x6f, 0x63,
+ 0x6b, 0x67, 0x61, 0x64, 0x6a, 0x6c, 0x69, 0x65, 0x63, 0x66, 0x6e, 0x6b,
+ 0x65, 0x60, 0x60, 0x6e, 0x6c, 0x69, 0x67, 0x62, 0x67, 0x62, 0x6b, 0x61,
+ 0x64, 0x6e, 0x61, 0x67, 0x69, 0x64, 0x6c, 0x6a, 0x6e, 0x68, 0x62, 0x6d,
+ 0x60, 0x6f, 0x66, 0x6c, 0x6a, 0x69, 0x6d, 0x60, 0x6f, 0x63, 0x63, 0x65,
+ 0x65, 0x66, 0x68, 0x6b, 0x4d, 0x41, 0x42, 0x4f, 0x48, 0x4d, 0x44, 0x48,
+ 0x46, 0x4a, 0x4f, 0x43, 0x4b, 0x47, 0x41, 0x44, 0x4a, 0x4c, 0x49, 0x45,
+ 0x43, 0x46, 0x4e, 0x4b, 0x45, 0x40, 0x40, 0x4e, 0x4c, 0x49, 0x47, 0x42,
+ 0x47, 0x42, 0x4b, 0x41, 0x44, 0x4e, 0x41, 0x47, 0x49, 0x44, 0x4c, 0x4a,
+ 0x4e, 0x48, 0x42, 0x4d, 0x40, 0x4f, 0x46, 0x4c, 0x4a, 0x49, 0x4d, 0x40,
+ 0x4f, 0x43, 0x43, 0x45, 0x45, 0x46, 0x48, 0x4b, 0xbd, 0xb1, 0xb2, 0xbf,
+ 0xb8, 0xbd, 0xb4, 0xb8, 0xb6, 0xba, 0xbf, 0xb3, 0xbb, 0xb7, 0xb1, 0xb4,
+ 0xba, 0xbc, 0xb9, 0xb5, 0xb3, 0xb6, 0xbe, 0xbb, 0xb5, 0xb0, 0xb0, 0xbe,
+ 0xbc, 0xb9, 0xb7, 0xb2, 0xb7, 0xb2, 0xbb, 0xb1, 0xb4, 0xbe, 0xb1, 0xb7,
+ 0xb9, 0xb4, 0xbc, 0xba, 0xbe, 0xb8, 0xb2, 0xbd, 0xb0, 0xbf, 0xb6, 0xbc,
+ 0xba, 0xb9, 0xbd, 0xb0, 0xbf, 0xb3, 0xb3, 0xb5, 0xb5, 0xb6, 0xb8, 0xbb,
+ 0xbd, 0xb1, 0xb2, 0xbf, 0xb8, 0xbd, 0xb4, 0xb8, 0xb6, 0xba, 0xbf, 0xb3,
+ 0xbb, 0xb7, 0xb1, 0xb4, 0xba, 0xbc, 0xb9, 0xb5, 0xb3, 0xb6, 0xbe, 0xbb,
+ 0xb5, 0xb0, 0xb0, 0xbe, 0xbc, 0xb9, 0xb7, 0xb2, 0xb7, 0xb2, 0xbb, 0xb1,
+ 0xb4, 0xbe, 0xb1, 0xb7, 0xb9, 0xb4, 0xbc, 0xba, 0xbe, 0xb8, 0xb2, 0xbd,
+ 0xb0, 0xbf, 0xb6, 0xbc, 0xba, 0xb9, 0xbd, 0xb0, 0xbf, 0xb3, 0xb3, 0xb5,
+ 0xb5, 0xb6, 0xb8, 0xbb, 0xdd, 0xd1, 0xd2, 0xdf, 0xd8, 0xdd, 0xd4, 0xd8,
+ 0xd6, 0xda, 0xdf, 0xd3, 0xdb, 0xd7, 0xd1, 0xd4, 0xda, 0xdc, 0xd9, 0xd5,
+ 0xd3, 0xd6, 0xde, 0xdb, 0xd5, 0xd0, 0xd0, 0xde, 0xdc, 0xd9, 0xd7, 0xd2,
+ 0xd7, 0xd2, 0xdb, 0xd1, 0xd4, 0xde, 0xd1, 0xd7, 0xd9, 0xd4, 0xdc, 0xda,
+ 0xde, 0xd8, 0xd2, 0xdd, 0xd0, 0xdf, 0xd6, 0xdc, 0xda, 0xd9, 0xdd, 0xd0,
+ 0xdf, 0xd3, 0xd3, 0xd5, 0xd5, 0xd6, 0xd8, 0xdb, 0xdd, 0xd1, 0xd2, 0xdf,
+ 0xd8, 0xdd, 0xd4, 0xd8, 0xd6, 0xda, 0xdf, 0xd3, 0xdb, 0xd7, 0xd1, 0xd4,
+ 0xda, 0xdc, 0xd9, 0xd5, 0xd3, 0xd6, 0xde, 0xdb, 0xd5, 0xd0, 0xd0, 0xde,
+ 0xdc, 0xd9, 0xd7, 0xd2, 0xd7, 0xd2, 0xdb, 0xd1, 0xd4, 0xde, 0xd1, 0xd7,
+ 0xd9, 0xd4, 0xdc, 0xda, 0xde, 0xd8, 0xd2, 0xdd, 0xd0, 0xdf, 0xd6, 0xdc,
+ 0xda, 0xd9, 0xdd, 0xd0, 0xdf, 0xd3, 0xd3, 0xd5, 0xd5, 0xd6, 0xd8, 0xdb,
+ 0x8d, 0x81, 0x82, 0x8f, 0x88, 0x8d, 0x84, 0x88, 0x86, 0x8a, 0x8f, 0x83,
+ 0x8b, 0x87, 0x81, 0x84, 0x8a, 0x8c, 0x89, 0x85, 0x83, 0x86, 0x8e, 0x8b,
+ 0x85, 0x80, 0x80, 0x8e, 0x8c, 0x89, 0x87, 0x82, 0x87, 0x82, 0x8b, 0x81,
+ 0x84, 0x8e, 0x81, 0x87, 0x89, 0x84, 0x8c, 0x8a, 0x8e, 0x88, 0x82, 0x8d,
+ 0x80, 0x8f, 0x86, 0x8c, 0x8a, 0x89, 0x8d, 0x80, 0x8f, 0x83, 0x83, 0x85,
+ 0x85, 0x86, 0x88, 0x8b, 0xcd, 0xc1, 0xc2, 0xcf, 0xc8, 0xcd, 0xc4, 0xc8,
+ 0xc6, 0xca, 0xcf, 0xc3, 0xcb, 0xc7, 0xc1, 0xc4, 0xca, 0xcc, 0xc9, 0xc5,
+ 0xc3, 0xc6, 0xce, 0xcb, 0xc5, 0xc0, 0xc0, 0xce, 0xcc, 0xc9, 0xc7, 0xc2,
+ 0xc7, 0xc2, 0xcb, 0xc1, 0xc4, 0xce, 0xc1, 0xc7, 0xc9, 0xc4, 0xcc, 0xca,
+ 0xce, 0xc8, 0xc2, 0xcd, 0xc0, 0xcf, 0xc6, 0xcc, 0xca, 0xc9, 0xcd, 0xc0,
+ 0xcf, 0xc3, 0xc3, 0xc5, 0xc5, 0xc6, 0xc8, 0xcb, 0x1d, 0x11, 0x12, 0x1f,
+ 0x18, 0x1d, 0x14, 0x18, 0x16, 0x1a, 0x1f, 0x13, 0x1b, 0x17, 0x11, 0x14,
+ 0x1a, 0x1c, 0x19, 0x15, 0x13, 0x16, 0x1e, 0x1b, 0x15, 0x10, 0x10, 0x1e,
+ 0x1c, 0x19, 0x17, 0x12, 0x17, 0x12, 0x1b, 0x11, 0x14, 0x1e, 0x11, 0x17,
+ 0x19, 0x14, 0x1c, 0x1a, 0x1e, 0x18, 0x12, 0x1d, 0x10, 0x1f, 0x16, 0x1c,
+ 0x1a, 0x19, 0x1d, 0x10, 0x1f, 0x13, 0x13, 0x15, 0x15, 0x16, 0x18, 0x1b,
+ 0x3d, 0x31, 0x32, 0x3f, 0x38, 0x3d, 0x34, 0x38, 0x36, 0x3a, 0x3f, 0x33,
+ 0x3b, 0x37, 0x31, 0x34, 0x3a, 0x3c, 0x39, 0x35, 0x33, 0x36, 0x3e, 0x3b,
+ 0x35, 0x30, 0x30, 0x3e, 0x3c, 0x39, 0x37, 0x32, 0x37, 0x32, 0x3b, 0x31,
+ 0x34, 0x3e, 0x31, 0x37, 0x39, 0x34, 0x3c, 0x3a, 0x3e, 0x38, 0x32, 0x3d,
+ 0x30, 0x3f, 0x36, 0x3c, 0x3a, 0x39, 0x3d, 0x30, 0x3f, 0x33, 0x33, 0x35,
+ 0x35, 0x36, 0x38, 0x3b, 0x4d, 0x41, 0x42, 0x4f, 0x48, 0x4d, 0x44, 0x48,
+ 0x46, 0x4a, 0x4f, 0x43, 0x4b, 0x47, 0x41, 0x44, 0x4a, 0x4c, 0x49, 0x45,
+ 0x43, 0x46, 0x4e, 0x4b, 0x45, 0x40, 0x40, 0x4e, 0x4c, 0x49, 0x47, 0x42,
+ 0x47, 0x42, 0x4b, 0x41, 0x44, 0x4e, 0x41, 0x47, 0x49, 0x44, 0x4c, 0x4a,
+ 0x4e, 0x48, 0x42, 0x4d, 0x40, 0x4f, 0x46, 0x4c, 0x4a, 0x49, 0x4d, 0x40,
+ 0x4f, 0x43, 0x43, 0x45, 0x45, 0x46, 0x48, 0x4b, 0x7d, 0x71, 0x72, 0x7f,
+ 0x78, 0x7d, 0x74, 0x78, 0x76, 0x7a, 0x7f, 0x73, 0x7b, 0x77, 0x71, 0x74,
+ 0x7a, 0x7c, 0x79, 0x75, 0x73, 0x76, 0x7e, 0x7b, 0x75, 0x70, 0x70, 0x7e,
+ 0x7c, 0x79, 0x77, 0x72, 0x77, 0x72, 0x7b, 0x71, 0x74, 0x7e, 0x71, 0x77,
+ 0x79, 0x74, 0x7c, 0x7a, 0x7e, 0x78, 0x72, 0x7d, 0x70, 0x7f, 0x76, 0x7c,
+ 0x7a, 0x79, 0x7d, 0x70, 0x7f, 0x73, 0x73, 0x75, 0x75, 0x76, 0x78, 0x7b,
+ 0xad, 0xa1, 0xa2, 0xaf, 0xa8, 0xad, 0xa4, 0xa8, 0xa6, 0xaa, 0xaf, 0xa3,
+ 0xab, 0xa7, 0xa1, 0xa4, 0xaa, 0xac, 0xa9, 0xa5, 0xa3, 0xa6, 0xae, 0xab,
+ 0xa5, 0xa0, 0xa0, 0xae, 0xac, 0xa9, 0xa7, 0xa2, 0xa7, 0xa2, 0xab, 0xa1,
+ 0xa4, 0xae, 0xa1, 0xa7, 0xa9, 0xa4, 0xac, 0xaa, 0xae, 0xa8, 0xa2, 0xad,
+ 0xa0, 0xaf, 0xa6, 0xac, 0xaa, 0xa9, 0xad, 0xa0, 0xaf, 0xa3, 0xa3, 0xa5,
+ 0xa5, 0xa6, 0xa8, 0xab, 0xed, 0xe1, 0xe2, 0xef, 0xe8, 0xed, 0xe4, 0xe8,
+ 0xe6, 0xea, 0xef, 0xe3, 0xeb, 0xe7, 0xe1, 0xe4, 0xea, 0xec, 0xe9, 0xe5,
+ 0xe3, 0xe6, 0xee, 0xeb, 0xe5, 0xe0, 0xe0, 0xee, 0xec, 0xe9, 0xe7, 0xe2,
+ 0xe7, 0xe2, 0xeb, 0xe1, 0xe4, 0xee, 0xe1, 0xe7, 0xe9, 0xe4, 0xec, 0xea,
+ 0xee, 0xe8, 0xe2, 0xed, 0xe0, 0xef, 0xe6, 0xec, 0xea, 0xe9, 0xed, 0xe0,
+ 0xef, 0xe3, 0xe3, 0xe5, 0xe5, 0xe6, 0xe8, 0xeb, 0x7d, 0x71, 0x72, 0x7f,
+ 0x78, 0x7d, 0x74, 0x78, 0x76, 0x7a, 0x7f, 0x73, 0x7b, 0x77, 0x71, 0x74,
+ 0x7a, 0x7c, 0x79, 0x75, 0x73, 0x76, 0x7e, 0x7b, 0x75, 0x70, 0x70, 0x7e,
+ 0x7c, 0x79, 0x77, 0x72, 0x77, 0x72, 0x7b, 0x71, 0x74, 0x7e, 0x71, 0x77,
+ 0x79, 0x74, 0x7c, 0x7a, 0x7e, 0x78, 0x72, 0x7d, 0x70, 0x7f, 0x76, 0x7c,
+ 0x7a, 0x79, 0x7d, 0x70, 0x7f, 0x73, 0x73, 0x75, 0x75, 0x76, 0x78, 0x7b,
+ 0xad, 0xa1, 0xa2, 0xaf, 0xa8, 0xad, 0xa4, 0xa8, 0xa6, 0xaa, 0xaf, 0xa3,
+ 0xab, 0xa7, 0xa1, 0xa4, 0xaa, 0xac, 0xa9, 0xa5, 0xa3, 0xa6, 0xae, 0xab,
+ 0xa5, 0xa0, 0xa0, 0xae, 0xac, 0xa9, 0xa7, 0xa2, 0xa7, 0xa2, 0xab, 0xa1,
+ 0xa4, 0xae, 0xa1, 0xa7, 0xa9, 0xa4, 0xac, 0xaa, 0xae, 0xa8, 0xa2, 0xad,
+ 0xa0, 0xaf, 0xa6, 0xac, 0xaa, 0xa9, 0xad, 0xa0, 0xaf, 0xa3, 0xa3, 0xa5,
+ 0xa5, 0xa6, 0xa8, 0xab, 0x9d, 0x91, 0x92, 0x9f, 0x98, 0x9d, 0x94, 0x98,
+ 0x96, 0x9a, 0x9f, 0x93, 0x9b, 0x97, 0x91, 0x94, 0x9a, 0x9c, 0x99, 0x95,
+ 0x93, 0x96, 0x9e, 0x9b, 0x95, 0x90, 0x90, 0x9e, 0x9c, 0x99, 0x97, 0x92,
+ 0x97, 0x92, 0x9b, 0x91, 0x94, 0x9e, 0x91, 0x97, 0x99, 0x94, 0x9c, 0x9a,
+ 0x9e, 0x98, 0x92, 0x9d, 0x90, 0x9f, 0x96, 0x9c, 0x9a, 0x99, 0x9d, 0x90,
+ 0x9f, 0x93, 0x93, 0x95, 0x95, 0x96, 0x98, 0x9b, 0xfd, 0xf1, 0xf2, 0xff,
+ 0xf8, 0xfd, 0xf4, 0xf8, 0xf6, 0xfa, 0xff, 0xf3, 0xfb, 0xf7, 0xf1, 0xf4,
+ 0xfa, 0xfc, 0xf9, 0xf5, 0xf3, 0xf6, 0xfe, 0xfb, 0xf5, 0xf0, 0xf0, 0xfe,
+ 0xfc, 0xf9, 0xf7, 0xf2, 0xf7, 0xf2, 0xfb, 0xf1, 0xf4, 0xfe, 0xf1, 0xf7,
+ 0xf9, 0xf4, 0xfc, 0xfa, 0xfe, 0xf8, 0xf2, 0xfd, 0xf0, 0xff, 0xf6, 0xfc,
+ 0xfa, 0xf9, 0xfd, 0xf0, 0xff, 0xf3, 0xf3, 0xf5, 0xf5, 0xf6, 0xf8, 0xfb,
+ 0x5d, 0x51, 0x52, 0x5f, 0x58, 0x5d, 0x54, 0x58, 0x56, 0x5a, 0x5f, 0x53,
+ 0x5b, 0x57, 0x51, 0x54, 0x5a, 0x5c, 0x59, 0x55, 0x53, 0x56, 0x5e, 0x5b,
+ 0x55, 0x50, 0x50, 0x5e, 0x5c, 0x59, 0x57, 0x52, 0x57, 0x52, 0x5b, 0x51,
+ 0x54, 0x5e, 0x51, 0x57, 0x59, 0x54, 0x5c, 0x5a, 0x5e, 0x58, 0x52, 0x5d,
+ 0x50, 0x5f, 0x56, 0x5c, 0x5a, 0x59, 0x5d, 0x50, 0x5f, 0x53, 0x53, 0x55,
+ 0x55, 0x56, 0x58, 0x5b, 0x6d, 0x61, 0x62, 0x6f, 0x68, 0x6d, 0x64, 0x68,
+ 0x66, 0x6a, 0x6f, 0x63, 0x6b, 0x67, 0x61, 0x64, 0x6a, 0x6c, 0x69, 0x65,
+ 0x63, 0x66, 0x6e, 0x6b, 0x65, 0x60, 0x60, 0x6e, 0x6c, 0x69, 0x67, 0x62,
+ 0x67, 0x62, 0x6b, 0x61, 0x64, 0x6e, 0x61, 0x67, 0x69, 0x64, 0x6c, 0x6a,
+ 0x6e, 0x68, 0x62, 0x6d, 0x60, 0x6f, 0x66, 0x6c, 0x6a, 0x69, 0x6d, 0x60,
+ 0x6f, 0x63, 0x63, 0x65, 0x65, 0x66, 0x68, 0x6b, 0x0d, 0x01, 0x02, 0x0f,
+ 0x08, 0x0d, 0x04, 0x08, 0x06, 0x0a, 0x0f, 0x03, 0x0b, 0x07, 0x01, 0x04,
+ 0x0a, 0x0c, 0x09, 0x05, 0x03, 0x06, 0x0e, 0x0b, 0x05, 0x00, 0x00, 0x0e,
+ 0x0c, 0x09, 0x07, 0x02, 0x07, 0x02, 0x0b, 0x01, 0x04, 0x0e, 0x01, 0x07,
+ 0x09, 0x04, 0x0c, 0x0a, 0x0e, 0x08, 0x02, 0x0d, 0x00, 0x0f, 0x06, 0x0c,
+ 0x0a, 0x09, 0x0d, 0x00, 0x0f, 0x03, 0x03, 0x05, 0x05, 0x06, 0x08, 0x0b,
+ 0x8d, 0x81, 0x82, 0x8f, 0x88, 0x8d, 0x84, 0x88, 0x86, 0x8a, 0x8f, 0x83,
+ 0x8b, 0x87, 0x81, 0x84, 0x8a, 0x8c, 0x89, 0x85, 0x83, 0x86, 0x8e, 0x8b,
+ 0x85, 0x80, 0x80, 0x8e, 0x8c, 0x89, 0x87, 0x82, 0x87, 0x82, 0x8b, 0x81,
+ 0x84, 0x8e, 0x81, 0x87, 0x89, 0x84, 0x8c, 0x8a, 0x8e, 0x88, 0x82, 0x8d,
+ 0x80, 0x8f, 0x86, 0x8c, 0x8a, 0x89, 0x8d, 0x80, 0x8f, 0x83, 0x83, 0x85,
+ 0x85, 0x86, 0x88, 0x8b, 0xfd, 0xf1, 0xf2, 0xff, 0xf8, 0xfd, 0xf4, 0xf8,
+ 0xf6, 0xfa, 0xff, 0xf3, 0xfb, 0xf7, 0xf1, 0xf4, 0xfa, 0xfc, 0xf9, 0xf5,
+ 0xf3, 0xf6, 0xfe, 0xfb, 0xf5, 0xf0, 0xf0, 0xfe, 0xfc, 0xf9, 0xf7, 0xf2,
+ 0xf7, 0xf2, 0xfb, 0xf1, 0xf4, 0xfe, 0xf1, 0xf7, 0xf9, 0xf4, 0xfc, 0xfa,
+ 0xfe, 0xf8, 0xf2, 0xfd, 0xf0, 0xff, 0xf6, 0xfc, 0xfa, 0xf9, 0xfd, 0xf0,
+ 0xff, 0xf3, 0xf3, 0xf5, 0xf5, 0xf6, 0xf8, 0xfb, 0x0d, 0x01, 0x02, 0x0f,
+ 0x08, 0x0d, 0x04, 0x08, 0x06, 0x0a, 0x0f, 0x03, 0x0b, 0x07, 0x01, 0x04,
+ 0x0a, 0x0c, 0x09, 0x05, 0x03, 0x06, 0x0e, 0x0b, 0x05, 0x00, 0x00, 0x0e,
+ 0x0c, 0x09, 0x07, 0x02, 0x07, 0x02, 0x0b, 0x01, 0x04, 0x0e, 0x01, 0x07,
+ 0x09, 0x04, 0x0c, 0x0a, 0x0e, 0x08, 0x02, 0x0d, 0x00, 0x0f, 0x06, 0x0c,
+ 0x0a, 0x09, 0x0d, 0x00, 0x0f, 0x03, 0x03, 0x05, 0x05, 0x06, 0x08, 0x0b,
+ 0xed, 0xe1, 0xe2, 0xef, 0xe8, 0xed, 0xe4, 0xe8, 0xe6, 0xea, 0xef, 0xe3,
+ 0xeb, 0xe7, 0xe1, 0xe4, 0xea, 0xec, 0xe9, 0xe5, 0xe3, 0xe6, 0xee, 0xeb,
+ 0xe5, 0xe0, 0xe0, 0xee, 0xec, 0xe9, 0xe7, 0xe2, 0xe7, 0xe2, 0xeb, 0xe1,
+ 0xe4, 0xee, 0xe1, 0xe7, 0xe9, 0xe4, 0xec, 0xea, 0xee, 0xe8, 0xe2, 0xed,
+ 0xe0, 0xef, 0xe6, 0xec, 0xea, 0xe9, 0xed, 0xe0, 0xef, 0xe3, 0xe3, 0xe5,
+ 0xe5, 0xe6, 0xe8, 0xeb, 0x5d, 0x51, 0x52, 0x5f, 0x58, 0x5d, 0x54, 0x58,
+ 0x56, 0x5a, 0x5f, 0x53, 0x5b, 0x57, 0x51, 0x54, 0x5a, 0x5c, 0x59, 0x55,
+ 0x53, 0x56, 0x5e, 0x5b, 0x55, 0x50, 0x50, 0x5e, 0x5c, 0x59, 0x57, 0x52,
+ 0x57, 0x52, 0x5b, 0x51, 0x54, 0x5e, 0x51, 0x57, 0x59, 0x54, 0x5c, 0x5a,
+ 0x5e, 0x58, 0x52, 0x5d, 0x50, 0x5f, 0x56, 0x5c, 0x5a, 0x59, 0x5d, 0x50,
+ 0x5f, 0x53, 0x53, 0x55, 0x55, 0x56, 0x58, 0x5b, 0x2d, 0x21, 0x22, 0x2f,
+ 0x28, 0x2d, 0x24, 0x28, 0x26, 0x2a, 0x2f, 0x23, 0x2b, 0x27, 0x21, 0x24,
+ 0x2a, 0x2c, 0x29, 0x25, 0x23, 0x26, 0x2e, 0x2b, 0x25, 0x20, 0x20, 0x2e,
+ 0x2c, 0x29, 0x27, 0x22, 0x27, 0x22, 0x2b, 0x21, 0x24, 0x2e, 0x21, 0x27,
+ 0x29, 0x24, 0x2c, 0x2a, 0x2e, 0x28, 0x22, 0x2d, 0x20, 0x2f, 0x26, 0x2c,
+ 0x2a, 0x29, 0x2d, 0x20, 0x2f, 0x23, 0x23, 0x25, 0x25, 0x26, 0x28, 0x2b,
+ 0x9d, 0x91, 0x92, 0x9f, 0x98, 0x9d, 0x94, 0x98, 0x96, 0x9a, 0x9f, 0x93,
+ 0x9b, 0x97, 0x91, 0x94, 0x9a, 0x9c, 0x99, 0x95, 0x93, 0x96, 0x9e, 0x9b,
+ 0x95, 0x90, 0x90, 0x9e, 0x9c, 0x99, 0x97, 0x92, 0x97, 0x92, 0x9b, 0x91,
+ 0x94, 0x9e, 0x91, 0x97, 0x99, 0x94, 0x9c, 0x9a, 0x9e, 0x98, 0x92, 0x9d,
+ 0x90, 0x9f, 0x96, 0x9c, 0x9a, 0x99, 0x9d, 0x90, 0x9f, 0x93, 0x93, 0x95,
+ 0x95, 0x96, 0x98, 0x9b, 0x3d, 0x31, 0x32, 0x3f, 0x38, 0x3d, 0x34, 0x38,
+ 0x36, 0x3a, 0x3f, 0x33, 0x3b, 0x37, 0x31, 0x34, 0x3a, 0x3c, 0x39, 0x35,
+ 0x33, 0x36, 0x3e, 0x3b, 0x35, 0x30, 0x30, 0x3e, 0x3c, 0x39, 0x37, 0x32,
+ 0x37, 0x32, 0x3b, 0x31, 0x34, 0x3e, 0x31, 0x37, 0x39, 0x34, 0x3c, 0x3a,
+ 0x3e, 0x38, 0x32, 0x3d, 0x30, 0x3f, 0x36, 0x3c, 0x3a, 0x39, 0x3d, 0x30,
+ 0x3f, 0x33, 0x33, 0x35, 0x35, 0x36, 0x38, 0x3b, 0x2d, 0x21, 0x22, 0x2f,
+ 0x28, 0x2d, 0x24, 0x28, 0x26, 0x2a, 0x2f, 0x23, 0x2b, 0x27, 0x21, 0x24,
+ 0x2a, 0x2c, 0x29, 0x25, 0x23, 0x26, 0x2e, 0x2b, 0x25, 0x20, 0x20, 0x2e,
+ 0x2c, 0x29, 0x27, 0x22, 0x27, 0x22, 0x2b, 0x21, 0x24, 0x2e, 0x21, 0x27,
+ 0x29, 0x24, 0x2c, 0x2a, 0x2e, 0x28, 0x22, 0x2d, 0x20, 0x2f, 0x26, 0x2c,
+ 0x2a, 0x29, 0x2d, 0x20, 0x2f, 0x23, 0x23, 0x25, 0x25, 0x26, 0x28, 0x2b,
+ 0xcd, 0xc1, 0xc2, 0xcf, 0xc8, 0xcd, 0xc4, 0xc8, 0xc6, 0xca, 0xcf, 0xc3,
+ 0xcb, 0xc7, 0xc1, 0xc4, 0xca, 0xcc, 0xc9, 0xc5, 0xc3, 0xc6, 0xce, 0xcb,
+ 0xc5, 0xc0, 0xc0, 0xce, 0xcc, 0xc9, 0xc7, 0xc2, 0xc7, 0xc2, 0xcb, 0xc1,
+ 0xc4, 0xce, 0xc1, 0xc7, 0xc9, 0xc4, 0xcc, 0xca, 0xce, 0xc8, 0xc2, 0xcd,
+ 0xc0, 0xcf, 0xc6, 0xcc, 0xca, 0xc9, 0xcd, 0xc0, 0xcf, 0xc3, 0xc3, 0xc5,
+ 0xc5, 0xc6, 0xc8, 0xcb,
+ },
+};
+
+const uint32_t ip_maskl[8][256] = {
+ {
+ 0x00000000, 0x00000001, 0x00000000, 0x00000001, 0x00000100, 0x00000101,
+ 0x00000100, 0x00000101, 0x00000000, 0x00000001, 0x00000000, 0x00000001,
+ 0x00000100, 0x00000101, 0x00000100, 0x00000101, 0x00010000, 0x00010001,
+ 0x00010000, 0x00010001, 0x00010100, 0x00010101, 0x00010100, 0x00010101,
+ 0x00010000, 0x00010001, 0x00010000, 0x00010001, 0x00010100, 0x00010101,
+ 0x00010100, 0x00010101, 0x00000000, 0x00000001, 0x00000000, 0x00000001,
+ 0x00000100, 0x00000101, 0x00000100, 0x00000101, 0x00000000, 0x00000001,
+ 0x00000000, 0x00000001, 0x00000100, 0x00000101, 0x00000100, 0x00000101,
+ 0x00010000, 0x00010001, 0x00010000, 0x00010001, 0x00010100, 0x00010101,
+ 0x00010100, 0x00010101, 0x00010000, 0x00010001, 0x00010000, 0x00010001,
+ 0x00010100, 0x00010101, 0x00010100, 0x00010101, 0x01000000, 0x01000001,
+ 0x01000000, 0x01000001, 0x01000100, 0x01000101, 0x01000100, 0x01000101,
+ 0x01000000, 0x01000001, 0x01000000, 0x01000001, 0x01000100, 0x01000101,
+ 0x01000100, 0x01000101, 0x01010000, 0x01010001, 0x01010000, 0x01010001,
+ 0x01010100, 0x01010101, 0x01010100, 0x01010101, 0x01010000, 0x01010001,
+ 0x01010000, 0x01010001, 0x01010100, 0x01010101, 0x01010100, 0x01010101,
+ 0x01000000, 0x01000001, 0x01000000, 0x01000001, 0x01000100, 0x01000101,
+ 0x01000100, 0x01000101, 0x01000000, 0x01000001, 0x01000000, 0x01000001,
+ 0x01000100, 0x01000101, 0x01000100, 0x01000101, 0x01010000, 0x01010001,
+ 0x01010000, 0x01010001, 0x01010100, 0x01010101, 0x01010100, 0x01010101,
+ 0x01010000, 0x01010001, 0x01010000, 0x01010001, 0x01010100, 0x01010101,
+ 0x01010100, 0x01010101, 0x00000000, 0x00000001, 0x00000000, 0x00000001,
+ 0x00000100, 0x00000101, 0x00000100, 0x00000101, 0x00000000, 0x00000001,
+ 0x00000000, 0x00000001, 0x00000100, 0x00000101, 0x00000100, 0x00000101,
+ 0x00010000, 0x00010001, 0x00010000, 0x00010001, 0x00010100, 0x00010101,
+ 0x00010100, 0x00010101, 0x00010000, 0x00010001, 0x00010000, 0x00010001,
+ 0x00010100, 0x00010101, 0x00010100, 0x00010101, 0x00000000, 0x00000001,
+ 0x00000000, 0x00000001, 0x00000100, 0x00000101, 0x00000100, 0x00000101,
+ 0x00000000, 0x00000001, 0x00000000, 0x00000001, 0x00000100, 0x00000101,
+ 0x00000100, 0x00000101, 0x00010000, 0x00010001, 0x00010000, 0x00010001,
+ 0x00010100, 0x00010101, 0x00010100, 0x00010101, 0x00010000, 0x00010001,
+ 0x00010000, 0x00010001, 0x00010100, 0x00010101, 0x00010100, 0x00010101,
+ 0x01000000, 0x01000001, 0x01000000, 0x01000001, 0x01000100, 0x01000101,
+ 0x01000100, 0x01000101, 0x01000000, 0x01000001, 0x01000000, 0x01000001,
+ 0x01000100, 0x01000101, 0x01000100, 0x01000101, 0x01010000, 0x01010001,
+ 0x01010000, 0x01010001, 0x01010100, 0x01010101, 0x01010100, 0x01010101,
+ 0x01010000, 0x01010001, 0x01010000, 0x01010001, 0x01010100, 0x01010101,
+ 0x01010100, 0x01010101, 0x01000000, 0x01000001, 0x01000000, 0x01000001,
+ 0x01000100, 0x01000101, 0x01000100, 0x01000101, 0x01000000, 0x01000001,
+ 0x01000000, 0x01000001, 0x01000100, 0x01000101, 0x01000100, 0x01000101,
+ 0x01010000, 0x01010001, 0x01010000, 0x01010001, 0x01010100, 0x01010101,
+ 0x01010100, 0x01010101, 0x01010000, 0x01010001, 0x01010000, 0x01010001,
+ 0x01010100, 0x01010101, 0x01010100, 0x01010101,
+ },
+ {
+ 0x00000000, 0x00000002, 0x00000000, 0x00000002, 0x00000200, 0x00000202,
+ 0x00000200, 0x00000202, 0x00000000, 0x00000002, 0x00000000, 0x00000002,
+ 0x00000200, 0x00000202, 0x00000200, 0x00000202, 0x00020000, 0x00020002,
+ 0x00020000, 0x00020002, 0x00020200, 0x00020202, 0x00020200, 0x00020202,
+ 0x00020000, 0x00020002, 0x00020000, 0x00020002, 0x00020200, 0x00020202,
+ 0x00020200, 0x00020202, 0x00000000, 0x00000002, 0x00000000, 0x00000002,
+ 0x00000200, 0x00000202, 0x00000200, 0x00000202, 0x00000000, 0x00000002,
+ 0x00000000, 0x00000002, 0x00000200, 0x00000202, 0x00000200, 0x00000202,
+ 0x00020000, 0x00020002, 0x00020000, 0x00020002, 0x00020200, 0x00020202,
+ 0x00020200, 0x00020202, 0x00020000, 0x00020002, 0x00020000, 0x00020002,
+ 0x00020200, 0x00020202, 0x00020200, 0x00020202, 0x02000000, 0x02000002,
+ 0x02000000, 0x02000002, 0x02000200, 0x02000202, 0x02000200, 0x02000202,
+ 0x02000000, 0x02000002, 0x02000000, 0x02000002, 0x02000200, 0x02000202,
+ 0x02000200, 0x02000202, 0x02020000, 0x02020002, 0x02020000, 0x02020002,
+ 0x02020200, 0x02020202, 0x02020200, 0x02020202, 0x02020000, 0x02020002,
+ 0x02020000, 0x02020002, 0x02020200, 0x02020202, 0x02020200, 0x02020202,
+ 0x02000000, 0x02000002, 0x02000000, 0x02000002, 0x02000200, 0x02000202,
+ 0x02000200, 0x02000202, 0x02000000, 0x02000002, 0x02000000, 0x02000002,
+ 0x02000200, 0x02000202, 0x02000200, 0x02000202, 0x02020000, 0x02020002,
+ 0x02020000, 0x02020002, 0x02020200, 0x02020202, 0x02020200, 0x02020202,
+ 0x02020000, 0x02020002, 0x02020000, 0x02020002, 0x02020200, 0x02020202,
+ 0x02020200, 0x02020202, 0x00000000, 0x00000002, 0x00000000, 0x00000002,
+ 0x00000200, 0x00000202, 0x00000200, 0x00000202, 0x00000000, 0x00000002,
+ 0x00000000, 0x00000002, 0x00000200, 0x00000202, 0x00000200, 0x00000202,
+ 0x00020000, 0x00020002, 0x00020000, 0x00020002, 0x00020200, 0x00020202,
+ 0x00020200, 0x00020202, 0x00020000, 0x00020002, 0x00020000, 0x00020002,
+ 0x00020200, 0x00020202, 0x00020200, 0x00020202, 0x00000000, 0x00000002,
+ 0x00000000, 0x00000002, 0x00000200, 0x00000202, 0x00000200, 0x00000202,
+ 0x00000000, 0x00000002, 0x00000000, 0x00000002, 0x00000200, 0x00000202,
+ 0x00000200, 0x00000202, 0x00020000, 0x00020002, 0x00020000, 0x00020002,
+ 0x00020200, 0x00020202, 0x00020200, 0x00020202, 0x00020000, 0x00020002,
+ 0x00020000, 0x00020002, 0x00020200, 0x00020202, 0x00020200, 0x00020202,
+ 0x02000000, 0x02000002, 0x02000000, 0x02000002, 0x02000200, 0x02000202,
+ 0x02000200, 0x02000202, 0x02000000, 0x02000002, 0x02000000, 0x02000002,
+ 0x02000200, 0x02000202, 0x02000200, 0x02000202, 0x02020000, 0x02020002,
+ 0x02020000, 0x02020002, 0x02020200, 0x02020202, 0x02020200, 0x02020202,
+ 0x02020000, 0x02020002, 0x02020000, 0x02020002, 0x02020200, 0x02020202,
+ 0x02020200, 0x02020202, 0x02000000, 0x02000002, 0x02000000, 0x02000002,
+ 0x02000200, 0x02000202, 0x02000200, 0x02000202, 0x02000000, 0x02000002,
+ 0x02000000, 0x02000002, 0x02000200, 0x02000202, 0x02000200, 0x02000202,
+ 0x02020000, 0x02020002, 0x02020000, 0x02020002, 0x02020200, 0x02020202,
+ 0x02020200, 0x02020202, 0x02020000, 0x02020002, 0x02020000, 0x02020002,
+ 0x02020200, 0x02020202, 0x02020200, 0x02020202,
+ },
+ {
+ 0x00000000, 0x00000004, 0x00000000, 0x00000004, 0x00000400, 0x00000404,
+ 0x00000400, 0x00000404, 0x00000000, 0x00000004, 0x00000000, 0x00000004,
+ 0x00000400, 0x00000404, 0x00000400, 0x00000404, 0x00040000, 0x00040004,
+ 0x00040000, 0x00040004, 0x00040400, 0x00040404, 0x00040400, 0x00040404,
+ 0x00040000, 0x00040004, 0x00040000, 0x00040004, 0x00040400, 0x00040404,
+ 0x00040400, 0x00040404, 0x00000000, 0x00000004, 0x00000000, 0x00000004,
+ 0x00000400, 0x00000404, 0x00000400, 0x00000404, 0x00000000, 0x00000004,
+ 0x00000000, 0x00000004, 0x00000400, 0x00000404, 0x00000400, 0x00000404,
+ 0x00040000, 0x00040004, 0x00040000, 0x00040004, 0x00040400, 0x00040404,
+ 0x00040400, 0x00040404, 0x00040000, 0x00040004, 0x00040000, 0x00040004,
+ 0x00040400, 0x00040404, 0x00040400, 0x00040404, 0x04000000, 0x04000004,
+ 0x04000000, 0x04000004, 0x04000400, 0x04000404, 0x04000400, 0x04000404,
+ 0x04000000, 0x04000004, 0x04000000, 0x04000004, 0x04000400, 0x04000404,
+ 0x04000400, 0x04000404, 0x04040000, 0x04040004, 0x04040000, 0x04040004,
+ 0x04040400, 0x04040404, 0x04040400, 0x04040404, 0x04040000, 0x04040004,
+ 0x04040000, 0x04040004, 0x04040400, 0x04040404, 0x04040400, 0x04040404,
+ 0x04000000, 0x04000004, 0x04000000, 0x04000004, 0x04000400, 0x04000404,
+ 0x04000400, 0x04000404, 0x04000000, 0x04000004, 0x04000000, 0x04000004,
+ 0x04000400, 0x04000404, 0x04000400, 0x04000404, 0x04040000, 0x04040004,
+ 0x04040000, 0x04040004, 0x04040400, 0x04040404, 0x04040400, 0x04040404,
+ 0x04040000, 0x04040004, 0x04040000, 0x04040004, 0x04040400, 0x04040404,
+ 0x04040400, 0x04040404, 0x00000000, 0x00000004, 0x00000000, 0x00000004,
+ 0x00000400, 0x00000404, 0x00000400, 0x00000404, 0x00000000, 0x00000004,
+ 0x00000000, 0x00000004, 0x00000400, 0x00000404, 0x00000400, 0x00000404,
+ 0x00040000, 0x00040004, 0x00040000, 0x00040004, 0x00040400, 0x00040404,
+ 0x00040400, 0x00040404, 0x00040000, 0x00040004, 0x00040000, 0x00040004,
+ 0x00040400, 0x00040404, 0x00040400, 0x00040404, 0x00000000, 0x00000004,
+ 0x00000000, 0x00000004, 0x00000400, 0x00000404, 0x00000400, 0x00000404,
+ 0x00000000, 0x00000004, 0x00000000, 0x00000004, 0x00000400, 0x00000404,
+ 0x00000400, 0x00000404, 0x00040000, 0x00040004, 0x00040000, 0x00040004,
+ 0x00040400, 0x00040404, 0x00040400, 0x00040404, 0x00040000, 0x00040004,
+ 0x00040000, 0x00040004, 0x00040400, 0x00040404, 0x00040400, 0x00040404,
+ 0x04000000, 0x04000004, 0x04000000, 0x04000004, 0x04000400, 0x04000404,
+ 0x04000400, 0x04000404, 0x04000000, 0x04000004, 0x04000000, 0x04000004,
+ 0x04000400, 0x04000404, 0x04000400, 0x04000404, 0x04040000, 0x04040004,
+ 0x04040000, 0x04040004, 0x04040400, 0x04040404, 0x04040400, 0x04040404,
+ 0x04040000, 0x04040004, 0x04040000, 0x04040004, 0x04040400, 0x04040404,
+ 0x04040400, 0x04040404, 0x04000000, 0x04000004, 0x04000000, 0x04000004,
+ 0x04000400, 0x04000404, 0x04000400, 0x04000404, 0x04000000, 0x04000004,
+ 0x04000000, 0x04000004, 0x04000400, 0x04000404, 0x04000400, 0x04000404,
+ 0x04040000, 0x04040004, 0x04040000, 0x04040004, 0x04040400, 0x04040404,
+ 0x04040400, 0x04040404, 0x04040000, 0x04040004, 0x04040000, 0x04040004,
+ 0x04040400, 0x04040404, 0x04040400, 0x04040404,
+ },
+ {
+ 0x00000000, 0x00000008, 0x00000000, 0x00000008, 0x00000800, 0x00000808,
+ 0x00000800, 0x00000808, 0x00000000, 0x00000008, 0x00000000, 0x00000008,
+ 0x00000800, 0x00000808, 0x00000800, 0x00000808, 0x00080000, 0x00080008,
+ 0x00080000, 0x00080008, 0x00080800, 0x00080808, 0x00080800, 0x00080808,
+ 0x00080000, 0x00080008, 0x00080000, 0x00080008, 0x00080800, 0x00080808,
+ 0x00080800, 0x00080808, 0x00000000, 0x00000008, 0x00000000, 0x00000008,
+ 0x00000800, 0x00000808, 0x00000800, 0x00000808, 0x00000000, 0x00000008,
+ 0x00000000, 0x00000008, 0x00000800, 0x00000808, 0x00000800, 0x00000808,
+ 0x00080000, 0x00080008, 0x00080000, 0x00080008, 0x00080800, 0x00080808,
+ 0x00080800, 0x00080808, 0x00080000, 0x00080008, 0x00080000, 0x00080008,
+ 0x00080800, 0x00080808, 0x00080800, 0x00080808, 0x08000000, 0x08000008,
+ 0x08000000, 0x08000008, 0x08000800, 0x08000808, 0x08000800, 0x08000808,
+ 0x08000000, 0x08000008, 0x08000000, 0x08000008, 0x08000800, 0x08000808,
+ 0x08000800, 0x08000808, 0x08080000, 0x08080008, 0x08080000, 0x08080008,
+ 0x08080800, 0x08080808, 0x08080800, 0x08080808, 0x08080000, 0x08080008,
+ 0x08080000, 0x08080008, 0x08080800, 0x08080808, 0x08080800, 0x08080808,
+ 0x08000000, 0x08000008, 0x08000000, 0x08000008, 0x08000800, 0x08000808,
+ 0x08000800, 0x08000808, 0x08000000, 0x08000008, 0x08000000, 0x08000008,
+ 0x08000800, 0x08000808, 0x08000800, 0x08000808, 0x08080000, 0x08080008,
+ 0x08080000, 0x08080008, 0x08080800, 0x08080808, 0x08080800, 0x08080808,
+ 0x08080000, 0x08080008, 0x08080000, 0x08080008, 0x08080800, 0x08080808,
+ 0x08080800, 0x08080808, 0x00000000, 0x00000008, 0x00000000, 0x00000008,
+ 0x00000800, 0x00000808, 0x00000800, 0x00000808, 0x00000000, 0x00000008,
+ 0x00000000, 0x00000008, 0x00000800, 0x00000808, 0x00000800, 0x00000808,
+ 0x00080000, 0x00080008, 0x00080000, 0x00080008, 0x00080800, 0x00080808,
+ 0x00080800, 0x00080808, 0x00080000, 0x00080008, 0x00080000, 0x00080008,
+ 0x00080800, 0x00080808, 0x00080800, 0x00080808, 0x00000000, 0x00000008,
+ 0x00000000, 0x00000008, 0x00000800, 0x00000808, 0x00000800, 0x00000808,
+ 0x00000000, 0x00000008, 0x00000000, 0x00000008, 0x00000800, 0x00000808,
+ 0x00000800, 0x00000808, 0x00080000, 0x00080008, 0x00080000, 0x00080008,
+ 0x00080800, 0x00080808, 0x00080800, 0x00080808, 0x00080000, 0x00080008,
+ 0x00080000, 0x00080008, 0x00080800, 0x00080808, 0x00080800, 0x00080808,
+ 0x08000000, 0x08000008, 0x08000000, 0x08000008, 0x08000800, 0x08000808,
+ 0x08000800, 0x08000808, 0x08000000, 0x08000008, 0x08000000, 0x08000008,
+ 0x08000800, 0x08000808, 0x08000800, 0x08000808, 0x08080000, 0x08080008,
+ 0x08080000, 0x08080008, 0x08080800, 0x08080808, 0x08080800, 0x08080808,
+ 0x08080000, 0x08080008, 0x08080000, 0x08080008, 0x08080800, 0x08080808,
+ 0x08080800, 0x08080808, 0x08000000, 0x08000008, 0x08000000, 0x08000008,
+ 0x08000800, 0x08000808, 0x08000800, 0x08000808, 0x08000000, 0x08000008,
+ 0x08000000, 0x08000008, 0x08000800, 0x08000808, 0x08000800, 0x08000808,
+ 0x08080000, 0x08080008, 0x08080000, 0x08080008, 0x08080800, 0x08080808,
+ 0x08080800, 0x08080808, 0x08080000, 0x08080008, 0x08080000, 0x08080008,
+ 0x08080800, 0x08080808, 0x08080800, 0x08080808,
+ },
+ {
+ 0x00000000, 0x00000010, 0x00000000, 0x00000010, 0x00001000, 0x00001010,
+ 0x00001000, 0x00001010, 0x00000000, 0x00000010, 0x00000000, 0x00000010,
+ 0x00001000, 0x00001010, 0x00001000, 0x00001010, 0x00100000, 0x00100010,
+ 0x00100000, 0x00100010, 0x00101000, 0x00101010, 0x00101000, 0x00101010,
+ 0x00100000, 0x00100010, 0x00100000, 0x00100010, 0x00101000, 0x00101010,
+ 0x00101000, 0x00101010, 0x00000000, 0x00000010, 0x00000000, 0x00000010,
+ 0x00001000, 0x00001010, 0x00001000, 0x00001010, 0x00000000, 0x00000010,
+ 0x00000000, 0x00000010, 0x00001000, 0x00001010, 0x00001000, 0x00001010,
+ 0x00100000, 0x00100010, 0x00100000, 0x00100010, 0x00101000, 0x00101010,
+ 0x00101000, 0x00101010, 0x00100000, 0x00100010, 0x00100000, 0x00100010,
+ 0x00101000, 0x00101010, 0x00101000, 0x00101010, 0x10000000, 0x10000010,
+ 0x10000000, 0x10000010, 0x10001000, 0x10001010, 0x10001000, 0x10001010,
+ 0x10000000, 0x10000010, 0x10000000, 0x10000010, 0x10001000, 0x10001010,
+ 0x10001000, 0x10001010, 0x10100000, 0x10100010, 0x10100000, 0x10100010,
+ 0x10101000, 0x10101010, 0x10101000, 0x10101010, 0x10100000, 0x10100010,
+ 0x10100000, 0x10100010, 0x10101000, 0x10101010, 0x10101000, 0x10101010,
+ 0x10000000, 0x10000010, 0x10000000, 0x10000010, 0x10001000, 0x10001010,
+ 0x10001000, 0x10001010, 0x10000000, 0x10000010, 0x10000000, 0x10000010,
+ 0x10001000, 0x10001010, 0x10001000, 0x10001010, 0x10100000, 0x10100010,
+ 0x10100000, 0x10100010, 0x10101000, 0x10101010, 0x10101000, 0x10101010,
+ 0x10100000, 0x10100010, 0x10100000, 0x10100010, 0x10101000, 0x10101010,
+ 0x10101000, 0x10101010, 0x00000000, 0x00000010, 0x00000000, 0x00000010,
+ 0x00001000, 0x00001010, 0x00001000, 0x00001010, 0x00000000, 0x00000010,
+ 0x00000000, 0x00000010, 0x00001000, 0x00001010, 0x00001000, 0x00001010,
+ 0x00100000, 0x00100010, 0x00100000, 0x00100010, 0x00101000, 0x00101010,
+ 0x00101000, 0x00101010, 0x00100000, 0x00100010, 0x00100000, 0x00100010,
+ 0x00101000, 0x00101010, 0x00101000, 0x00101010, 0x00000000, 0x00000010,
+ 0x00000000, 0x00000010, 0x00001000, 0x00001010, 0x00001000, 0x00001010,
+ 0x00000000, 0x00000010, 0x00000000, 0x00000010, 0x00001000, 0x00001010,
+ 0x00001000, 0x00001010, 0x00100000, 0x00100010, 0x00100000, 0x00100010,
+ 0x00101000, 0x00101010, 0x00101000, 0x00101010, 0x00100000, 0x00100010,
+ 0x00100000, 0x00100010, 0x00101000, 0x00101010, 0x00101000, 0x00101010,
+ 0x10000000, 0x10000010, 0x10000000, 0x10000010, 0x10001000, 0x10001010,
+ 0x10001000, 0x10001010, 0x10000000, 0x10000010, 0x10000000, 0x10000010,
+ 0x10001000, 0x10001010, 0x10001000, 0x10001010, 0x10100000, 0x10100010,
+ 0x10100000, 0x10100010, 0x10101000, 0x10101010, 0x10101000, 0x10101010,
+ 0x10100000, 0x10100010, 0x10100000, 0x10100010, 0x10101000, 0x10101010,
+ 0x10101000, 0x10101010, 0x10000000, 0x10000010, 0x10000000, 0x10000010,
+ 0x10001000, 0x10001010, 0x10001000, 0x10001010, 0x10000000, 0x10000010,
+ 0x10000000, 0x10000010, 0x10001000, 0x10001010, 0x10001000, 0x10001010,
+ 0x10100000, 0x10100010, 0x10100000, 0x10100010, 0x10101000, 0x10101010,
+ 0x10101000, 0x10101010, 0x10100000, 0x10100010, 0x10100000, 0x10100010,
+ 0x10101000, 0x10101010, 0x10101000, 0x10101010,
+ },
+ {
+ 0x00000000, 0x00000020, 0x00000000, 0x00000020, 0x00002000, 0x00002020,
+ 0x00002000, 0x00002020, 0x00000000, 0x00000020, 0x00000000, 0x00000020,
+ 0x00002000, 0x00002020, 0x00002000, 0x00002020, 0x00200000, 0x00200020,
+ 0x00200000, 0x00200020, 0x00202000, 0x00202020, 0x00202000, 0x00202020,
+ 0x00200000, 0x00200020, 0x00200000, 0x00200020, 0x00202000, 0x00202020,
+ 0x00202000, 0x00202020, 0x00000000, 0x00000020, 0x00000000, 0x00000020,
+ 0x00002000, 0x00002020, 0x00002000, 0x00002020, 0x00000000, 0x00000020,
+ 0x00000000, 0x00000020, 0x00002000, 0x00002020, 0x00002000, 0x00002020,
+ 0x00200000, 0x00200020, 0x00200000, 0x00200020, 0x00202000, 0x00202020,
+ 0x00202000, 0x00202020, 0x00200000, 0x00200020, 0x00200000, 0x00200020,
+ 0x00202000, 0x00202020, 0x00202000, 0x00202020, 0x20000000, 0x20000020,
+ 0x20000000, 0x20000020, 0x20002000, 0x20002020, 0x20002000, 0x20002020,
+ 0x20000000, 0x20000020, 0x20000000, 0x20000020, 0x20002000, 0x20002020,
+ 0x20002000, 0x20002020, 0x20200000, 0x20200020, 0x20200000, 0x20200020,
+ 0x20202000, 0x20202020, 0x20202000, 0x20202020, 0x20200000, 0x20200020,
+ 0x20200000, 0x20200020, 0x20202000, 0x20202020, 0x20202000, 0x20202020,
+ 0x20000000, 0x20000020, 0x20000000, 0x20000020, 0x20002000, 0x20002020,
+ 0x20002000, 0x20002020, 0x20000000, 0x20000020, 0x20000000, 0x20000020,
+ 0x20002000, 0x20002020, 0x20002000, 0x20002020, 0x20200000, 0x20200020,
+ 0x20200000, 0x20200020, 0x20202000, 0x20202020, 0x20202000, 0x20202020,
+ 0x20200000, 0x20200020, 0x20200000, 0x20200020, 0x20202000, 0x20202020,
+ 0x20202000, 0x20202020, 0x00000000, 0x00000020, 0x00000000, 0x00000020,
+ 0x00002000, 0x00002020, 0x00002000, 0x00002020, 0x00000000, 0x00000020,
+ 0x00000000, 0x00000020, 0x00002000, 0x00002020, 0x00002000, 0x00002020,
+ 0x00200000, 0x00200020, 0x00200000, 0x00200020, 0x00202000, 0x00202020,
+ 0x00202000, 0x00202020, 0x00200000, 0x00200020, 0x00200000, 0x00200020,
+ 0x00202000, 0x00202020, 0x00202000, 0x00202020, 0x00000000, 0x00000020,
+ 0x00000000, 0x00000020, 0x00002000, 0x00002020, 0x00002000, 0x00002020,
+ 0x00000000, 0x00000020, 0x00000000, 0x00000020, 0x00002000, 0x00002020,
+ 0x00002000, 0x00002020, 0x00200000, 0x00200020, 0x00200000, 0x00200020,
+ 0x00202000, 0x00202020, 0x00202000, 0x00202020, 0x00200000, 0x00200020,
+ 0x00200000, 0x00200020, 0x00202000, 0x00202020, 0x00202000, 0x00202020,
+ 0x20000000, 0x20000020, 0x20000000, 0x20000020, 0x20002000, 0x20002020,
+ 0x20002000, 0x20002020, 0x20000000, 0x20000020, 0x20000000, 0x20000020,
+ 0x20002000, 0x20002020, 0x20002000, 0x20002020, 0x20200000, 0x20200020,
+ 0x20200000, 0x20200020, 0x20202000, 0x20202020, 0x20202000, 0x20202020,
+ 0x20200000, 0x20200020, 0x20200000, 0x20200020, 0x20202000, 0x20202020,
+ 0x20202000, 0x20202020, 0x20000000, 0x20000020, 0x20000000, 0x20000020,
+ 0x20002000, 0x20002020, 0x20002000, 0x20002020, 0x20000000, 0x20000020,
+ 0x20000000, 0x20000020, 0x20002000, 0x20002020, 0x20002000, 0x20002020,
+ 0x20200000, 0x20200020, 0x20200000, 0x20200020, 0x20202000, 0x20202020,
+ 0x20202000, 0x20202020, 0x20200000, 0x20200020, 0x20200000, 0x20200020,
+ 0x20202000, 0x20202020, 0x20202000, 0x20202020,
+ },
+ {
+ 0x00000000, 0x00000040, 0x00000000, 0x00000040, 0x00004000, 0x00004040,
+ 0x00004000, 0x00004040, 0x00000000, 0x00000040, 0x00000000, 0x00000040,
+ 0x00004000, 0x00004040, 0x00004000, 0x00004040, 0x00400000, 0x00400040,
+ 0x00400000, 0x00400040, 0x00404000, 0x00404040, 0x00404000, 0x00404040,
+ 0x00400000, 0x00400040, 0x00400000, 0x00400040, 0x00404000, 0x00404040,
+ 0x00404000, 0x00404040, 0x00000000, 0x00000040, 0x00000000, 0x00000040,
+ 0x00004000, 0x00004040, 0x00004000, 0x00004040, 0x00000000, 0x00000040,
+ 0x00000000, 0x00000040, 0x00004000, 0x00004040, 0x00004000, 0x00004040,
+ 0x00400000, 0x00400040, 0x00400000, 0x00400040, 0x00404000, 0x00404040,
+ 0x00404000, 0x00404040, 0x00400000, 0x00400040, 0x00400000, 0x00400040,
+ 0x00404000, 0x00404040, 0x00404000, 0x00404040, 0x40000000, 0x40000040,
+ 0x40000000, 0x40000040, 0x40004000, 0x40004040, 0x40004000, 0x40004040,
+ 0x40000000, 0x40000040, 0x40000000, 0x40000040, 0x40004000, 0x40004040,
+ 0x40004000, 0x40004040, 0x40400000, 0x40400040, 0x40400000, 0x40400040,
+ 0x40404000, 0x40404040, 0x40404000, 0x40404040, 0x40400000, 0x40400040,
+ 0x40400000, 0x40400040, 0x40404000, 0x40404040, 0x40404000, 0x40404040,
+ 0x40000000, 0x40000040, 0x40000000, 0x40000040, 0x40004000, 0x40004040,
+ 0x40004000, 0x40004040, 0x40000000, 0x40000040, 0x40000000, 0x40000040,
+ 0x40004000, 0x40004040, 0x40004000, 0x40004040, 0x40400000, 0x40400040,
+ 0x40400000, 0x40400040, 0x40404000, 0x40404040, 0x40404000, 0x40404040,
+ 0x40400000, 0x40400040, 0x40400000, 0x40400040, 0x40404000, 0x40404040,
+ 0x40404000, 0x40404040, 0x00000000, 0x00000040, 0x00000000, 0x00000040,
+ 0x00004000, 0x00004040, 0x00004000, 0x00004040, 0x00000000, 0x00000040,
+ 0x00000000, 0x00000040, 0x00004000, 0x00004040, 0x00004000, 0x00004040,
+ 0x00400000, 0x00400040, 0x00400000, 0x00400040, 0x00404000, 0x00404040,
+ 0x00404000, 0x00404040, 0x00400000, 0x00400040, 0x00400000, 0x00400040,
+ 0x00404000, 0x00404040, 0x00404000, 0x00404040, 0x00000000, 0x00000040,
+ 0x00000000, 0x00000040, 0x00004000, 0x00004040, 0x00004000, 0x00004040,
+ 0x00000000, 0x00000040, 0x00000000, 0x00000040, 0x00004000, 0x00004040,
+ 0x00004000, 0x00004040, 0x00400000, 0x00400040, 0x00400000, 0x00400040,
+ 0x00404000, 0x00404040, 0x00404000, 0x00404040, 0x00400000, 0x00400040,
+ 0x00400000, 0x00400040, 0x00404000, 0x00404040, 0x00404000, 0x00404040,
+ 0x40000000, 0x40000040, 0x40000000, 0x40000040, 0x40004000, 0x40004040,
+ 0x40004000, 0x40004040, 0x40000000, 0x40000040, 0x40000000, 0x40000040,
+ 0x40004000, 0x40004040, 0x40004000, 0x40004040, 0x40400000, 0x40400040,
+ 0x40400000, 0x40400040, 0x40404000, 0x40404040, 0x40404000, 0x40404040,
+ 0x40400000, 0x40400040, 0x40400000, 0x40400040, 0x40404000, 0x40404040,
+ 0x40404000, 0x40404040, 0x40000000, 0x40000040, 0x40000000, 0x40000040,
+ 0x40004000, 0x40004040, 0x40004000, 0x40004040, 0x40000000, 0x40000040,
+ 0x40000000, 0x40000040, 0x40004000, 0x40004040, 0x40004000, 0x40004040,
+ 0x40400000, 0x40400040, 0x40400000, 0x40400040, 0x40404000, 0x40404040,
+ 0x40404000, 0x40404040, 0x40400000, 0x40400040, 0x40400000, 0x40400040,
+ 0x40404000, 0x40404040, 0x40404000, 0x40404040,
+ },
+ {
+ 0x00000000, 0x00000080, 0x00000000, 0x00000080, 0x00008000, 0x00008080,
+ 0x00008000, 0x00008080, 0x00000000, 0x00000080, 0x00000000, 0x00000080,
+ 0x00008000, 0x00008080, 0x00008000, 0x00008080, 0x00800000, 0x00800080,
+ 0x00800000, 0x00800080, 0x00808000, 0x00808080, 0x00808000, 0x00808080,
+ 0x00800000, 0x00800080, 0x00800000, 0x00800080, 0x00808000, 0x00808080,
+ 0x00808000, 0x00808080, 0x00000000, 0x00000080, 0x00000000, 0x00000080,
+ 0x00008000, 0x00008080, 0x00008000, 0x00008080, 0x00000000, 0x00000080,
+ 0x00000000, 0x00000080, 0x00008000, 0x00008080, 0x00008000, 0x00008080,
+ 0x00800000, 0x00800080, 0x00800000, 0x00800080, 0x00808000, 0x00808080,
+ 0x00808000, 0x00808080, 0x00800000, 0x00800080, 0x00800000, 0x00800080,
+ 0x00808000, 0x00808080, 0x00808000, 0x00808080, 0x80000000, 0x80000080,
+ 0x80000000, 0x80000080, 0x80008000, 0x80008080, 0x80008000, 0x80008080,
+ 0x80000000, 0x80000080, 0x80000000, 0x80000080, 0x80008000, 0x80008080,
+ 0x80008000, 0x80008080, 0x80800000, 0x80800080, 0x80800000, 0x80800080,
+ 0x80808000, 0x80808080, 0x80808000, 0x80808080, 0x80800000, 0x80800080,
+ 0x80800000, 0x80800080, 0x80808000, 0x80808080, 0x80808000, 0x80808080,
+ 0x80000000, 0x80000080, 0x80000000, 0x80000080, 0x80008000, 0x80008080,
+ 0x80008000, 0x80008080, 0x80000000, 0x80000080, 0x80000000, 0x80000080,
+ 0x80008000, 0x80008080, 0x80008000, 0x80008080, 0x80800000, 0x80800080,
+ 0x80800000, 0x80800080, 0x80808000, 0x80808080, 0x80808000, 0x80808080,
+ 0x80800000, 0x80800080, 0x80800000, 0x80800080, 0x80808000, 0x80808080,
+ 0x80808000, 0x80808080, 0x00000000, 0x00000080, 0x00000000, 0x00000080,
+ 0x00008000, 0x00008080, 0x00008000, 0x00008080, 0x00000000, 0x00000080,
+ 0x00000000, 0x00000080, 0x00008000, 0x00008080, 0x00008000, 0x00008080,
+ 0x00800000, 0x00800080, 0x00800000, 0x00800080, 0x00808000, 0x00808080,
+ 0x00808000, 0x00808080, 0x00800000, 0x00800080, 0x00800000, 0x00800080,
+ 0x00808000, 0x00808080, 0x00808000, 0x00808080, 0x00000000, 0x00000080,
+ 0x00000000, 0x00000080, 0x00008000, 0x00008080, 0x00008000, 0x00008080,
+ 0x00000000, 0x00000080, 0x00000000, 0x00000080, 0x00008000, 0x00008080,
+ 0x00008000, 0x00008080, 0x00800000, 0x00800080, 0x00800000, 0x00800080,
+ 0x00808000, 0x00808080, 0x00808000, 0x00808080, 0x00800000, 0x00800080,
+ 0x00800000, 0x00800080, 0x00808000, 0x00808080, 0x00808000, 0x00808080,
+ 0x80000000, 0x80000080, 0x80000000, 0x80000080, 0x80008000, 0x80008080,
+ 0x80008000, 0x80008080, 0x80000000, 0x80000080, 0x80000000, 0x80000080,
+ 0x80008000, 0x80008080, 0x80008000, 0x80008080, 0x80800000, 0x80800080,
+ 0x80800000, 0x80800080, 0x80808000, 0x80808080, 0x80808000, 0x80808080,
+ 0x80800000, 0x80800080, 0x80800000, 0x80800080, 0x80808000, 0x80808080,
+ 0x80808000, 0x80808080, 0x80000000, 0x80000080, 0x80000000, 0x80000080,
+ 0x80008000, 0x80008080, 0x80008000, 0x80008080, 0x80000000, 0x80000080,
+ 0x80000000, 0x80000080, 0x80008000, 0x80008080, 0x80008000, 0x80008080,
+ 0x80800000, 0x80800080, 0x80800000, 0x80800080, 0x80808000, 0x80808080,
+ 0x80808000, 0x80808080, 0x80800000, 0x80800080, 0x80800000, 0x80800080,
+ 0x80808000, 0x80808080, 0x80808000, 0x80808080,
+ },
+};
+
+const uint32_t ip_maskr[8][256] = {
+ {
+ 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000000, 0x00000000,
+ 0x00000001, 0x00000001, 0x00000100, 0x00000100, 0x00000101, 0x00000101,
+ 0x00000100, 0x00000100, 0x00000101, 0x00000101, 0x00000000, 0x00000000,
+ 0x00000001, 0x00000001, 0x00000000, 0x00000000, 0x00000001, 0x00000001,
+ 0x00000100, 0x00000100, 0x00000101, 0x00000101, 0x00000100, 0x00000100,
+ 0x00000101, 0x00000101, 0x00010000, 0x00010000, 0x00010001, 0x00010001,
+ 0x00010000, 0x00010000, 0x00010001, 0x00010001, 0x00010100, 0x00010100,
+ 0x00010101, 0x00010101, 0x00010100, 0x00010100, 0x00010101, 0x00010101,
+ 0x00010000, 0x00010000, 0x00010001, 0x00010001, 0x00010000, 0x00010000,
+ 0x00010001, 0x00010001, 0x00010100, 0x00010100, 0x00010101, 0x00010101,
+ 0x00010100, 0x00010100, 0x00010101, 0x00010101, 0x00000000, 0x00000000,
+ 0x00000001, 0x00000001, 0x00000000, 0x00000000, 0x00000001, 0x00000001,
+ 0x00000100, 0x00000100, 0x00000101, 0x00000101, 0x00000100, 0x00000100,
+ 0x00000101, 0x00000101, 0x00000000, 0x00000000, 0x00000001, 0x00000001,
+ 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000100, 0x00000100,
+ 0x00000101, 0x00000101, 0x00000100, 0x00000100, 0x00000101, 0x00000101,
+ 0x00010000, 0x00010000, 0x00010001, 0x00010001, 0x00010000, 0x00010000,
+ 0x00010001, 0x00010001, 0x00010100, 0x00010100, 0x00010101, 0x00010101,
+ 0x00010100, 0x00010100, 0x00010101, 0x00010101, 0x00010000, 0x00010000,
+ 0x00010001, 0x00010001, 0x00010000, 0x00010000, 0x00010001, 0x00010001,
+ 0x00010100, 0x00010100, 0x00010101, 0x00010101, 0x00010100, 0x00010100,
+ 0x00010101, 0x00010101, 0x01000000, 0x01000000, 0x01000001, 0x01000001,
+ 0x01000000, 0x01000000, 0x01000001, 0x01000001, 0x01000100, 0x01000100,
+ 0x01000101, 0x01000101, 0x01000100, 0x01000100, 0x01000101, 0x01000101,
+ 0x01000000, 0x01000000, 0x01000001, 0x01000001, 0x01000000, 0x01000000,
+ 0x01000001, 0x01000001, 0x01000100, 0x01000100, 0x01000101, 0x01000101,
+ 0x01000100, 0x01000100, 0x01000101, 0x01000101, 0x01010000, 0x01010000,
+ 0x01010001, 0x01010001, 0x01010000, 0x01010000, 0x01010001, 0x01010001,
+ 0x01010100, 0x01010100, 0x01010101, 0x01010101, 0x01010100, 0x01010100,
+ 0x01010101, 0x01010101, 0x01010000, 0x01010000, 0x01010001, 0x01010001,
+ 0x01010000, 0x01010000, 0x01010001, 0x01010001, 0x01010100, 0x01010100,
+ 0x01010101, 0x01010101, 0x01010100, 0x01010100, 0x01010101, 0x01010101,
+ 0x01000000, 0x01000000, 0x01000001, 0x01000001, 0x01000000, 0x01000000,
+ 0x01000001, 0x01000001, 0x01000100, 0x01000100, 0x01000101, 0x01000101,
+ 0x01000100, 0x01000100, 0x01000101, 0x01000101, 0x01000000, 0x01000000,
+ 0x01000001, 0x01000001, 0x01000000, 0x01000000, 0x01000001, 0x01000001,
+ 0x01000100, 0x01000100, 0x01000101, 0x01000101, 0x01000100, 0x01000100,
+ 0x01000101, 0x01000101, 0x01010000, 0x01010000, 0x01010001, 0x01010001,
+ 0x01010000, 0x01010000, 0x01010001, 0x01010001, 0x01010100, 0x01010100,
+ 0x01010101, 0x01010101, 0x01010100, 0x01010100, 0x01010101, 0x01010101,
+ 0x01010000, 0x01010000, 0x01010001, 0x01010001, 0x01010000, 0x01010000,
+ 0x01010001, 0x01010001, 0x01010100, 0x01010100, 0x01010101, 0x01010101,
+ 0x01010100, 0x01010100, 0x01010101, 0x01010101,
+ },
+ {
+ 0x00000000, 0x00000000, 0x00000002, 0x00000002, 0x00000000, 0x00000000,
+ 0x00000002, 0x00000002, 0x00000200, 0x00000200, 0x00000202, 0x00000202,
+ 0x00000200, 0x00000200, 0x00000202, 0x00000202, 0x00000000, 0x00000000,
+ 0x00000002, 0x00000002, 0x00000000, 0x00000000, 0x00000002, 0x00000002,
+ 0x00000200, 0x00000200, 0x00000202, 0x00000202, 0x00000200, 0x00000200,
+ 0x00000202, 0x00000202, 0x00020000, 0x00020000, 0x00020002, 0x00020002,
+ 0x00020000, 0x00020000, 0x00020002, 0x00020002, 0x00020200, 0x00020200,
+ 0x00020202, 0x00020202, 0x00020200, 0x00020200, 0x00020202, 0x00020202,
+ 0x00020000, 0x00020000, 0x00020002, 0x00020002, 0x00020000, 0x00020000,
+ 0x00020002, 0x00020002, 0x00020200, 0x00020200, 0x00020202, 0x00020202,
+ 0x00020200, 0x00020200, 0x00020202, 0x00020202, 0x00000000, 0x00000000,
+ 0x00000002, 0x00000002, 0x00000000, 0x00000000, 0x00000002, 0x00000002,
+ 0x00000200, 0x00000200, 0x00000202, 0x00000202, 0x00000200, 0x00000200,
+ 0x00000202, 0x00000202, 0x00000000, 0x00000000, 0x00000002, 0x00000002,
+ 0x00000000, 0x00000000, 0x00000002, 0x00000002, 0x00000200, 0x00000200,
+ 0x00000202, 0x00000202, 0x00000200, 0x00000200, 0x00000202, 0x00000202,
+ 0x00020000, 0x00020000, 0x00020002, 0x00020002, 0x00020000, 0x00020000,
+ 0x00020002, 0x00020002, 0x00020200, 0x00020200, 0x00020202, 0x00020202,
+ 0x00020200, 0x00020200, 0x00020202, 0x00020202, 0x00020000, 0x00020000,
+ 0x00020002, 0x00020002, 0x00020000, 0x00020000, 0x00020002, 0x00020002,
+ 0x00020200, 0x00020200, 0x00020202, 0x00020202, 0x00020200, 0x00020200,
+ 0x00020202, 0x00020202, 0x02000000, 0x02000000, 0x02000002, 0x02000002,
+ 0x02000000, 0x02000000, 0x02000002, 0x02000002, 0x02000200, 0x02000200,
+ 0x02000202, 0x02000202, 0x02000200, 0x02000200, 0x02000202, 0x02000202,
+ 0x02000000, 0x02000000, 0x02000002, 0x02000002, 0x02000000, 0x02000000,
+ 0x02000002, 0x02000002, 0x02000200, 0x02000200, 0x02000202, 0x02000202,
+ 0x02000200, 0x02000200, 0x02000202, 0x02000202, 0x02020000, 0x02020000,
+ 0x02020002, 0x02020002, 0x02020000, 0x02020000, 0x02020002, 0x02020002,
+ 0x02020200, 0x02020200, 0x02020202, 0x02020202, 0x02020200, 0x02020200,
+ 0x02020202, 0x02020202, 0x02020000, 0x02020000, 0x02020002, 0x02020002,
+ 0x02020000, 0x02020000, 0x02020002, 0x02020002, 0x02020200, 0x02020200,
+ 0x02020202, 0x02020202, 0x02020200, 0x02020200, 0x02020202, 0x02020202,
+ 0x02000000, 0x02000000, 0x02000002, 0x02000002, 0x02000000, 0x02000000,
+ 0x02000002, 0x02000002, 0x02000200, 0x02000200, 0x02000202, 0x02000202,
+ 0x02000200, 0x02000200, 0x02000202, 0x02000202, 0x02000000, 0x02000000,
+ 0x02000002, 0x02000002, 0x02000000, 0x02000000, 0x02000002, 0x02000002,
+ 0x02000200, 0x02000200, 0x02000202, 0x02000202, 0x02000200, 0x02000200,
+ 0x02000202, 0x02000202, 0x02020000, 0x02020000, 0x02020002, 0x02020002,
+ 0x02020000, 0x02020000, 0x02020002, 0x02020002, 0x02020200, 0x02020200,
+ 0x02020202, 0x02020202, 0x02020200, 0x02020200, 0x02020202, 0x02020202,
+ 0x02020000, 0x02020000, 0x02020002, 0x02020002, 0x02020000, 0x02020000,
+ 0x02020002, 0x02020002, 0x02020200, 0x02020200, 0x02020202, 0x02020202,
+ 0x02020200, 0x02020200, 0x02020202, 0x02020202,
+ },
+ {
+ 0x00000000, 0x00000000, 0x00000004, 0x00000004, 0x00000000, 0x00000000,
+ 0x00000004, 0x00000004, 0x00000400, 0x00000400, 0x00000404, 0x00000404,
+ 0x00000400, 0x00000400, 0x00000404, 0x00000404, 0x00000000, 0x00000000,
+ 0x00000004, 0x00000004, 0x00000000, 0x00000000, 0x00000004, 0x00000004,
+ 0x00000400, 0x00000400, 0x00000404, 0x00000404, 0x00000400, 0x00000400,
+ 0x00000404, 0x00000404, 0x00040000, 0x00040000, 0x00040004, 0x00040004,
+ 0x00040000, 0x00040000, 0x00040004, 0x00040004, 0x00040400, 0x00040400,
+ 0x00040404, 0x00040404, 0x00040400, 0x00040400, 0x00040404, 0x00040404,
+ 0x00040000, 0x00040000, 0x00040004, 0x00040004, 0x00040000, 0x00040000,
+ 0x00040004, 0x00040004, 0x00040400, 0x00040400, 0x00040404, 0x00040404,
+ 0x00040400, 0x00040400, 0x00040404, 0x00040404, 0x00000000, 0x00000000,
+ 0x00000004, 0x00000004, 0x00000000, 0x00000000, 0x00000004, 0x00000004,
+ 0x00000400, 0x00000400, 0x00000404, 0x00000404, 0x00000400, 0x00000400,
+ 0x00000404, 0x00000404, 0x00000000, 0x00000000, 0x00000004, 0x00000004,
+ 0x00000000, 0x00000000, 0x00000004, 0x00000004, 0x00000400, 0x00000400,
+ 0x00000404, 0x00000404, 0x00000400, 0x00000400, 0x00000404, 0x00000404,
+ 0x00040000, 0x00040000, 0x00040004, 0x00040004, 0x00040000, 0x00040000,
+ 0x00040004, 0x00040004, 0x00040400, 0x00040400, 0x00040404, 0x00040404,
+ 0x00040400, 0x00040400, 0x00040404, 0x00040404, 0x00040000, 0x00040000,
+ 0x00040004, 0x00040004, 0x00040000, 0x00040000, 0x00040004, 0x00040004,
+ 0x00040400, 0x00040400, 0x00040404, 0x00040404, 0x00040400, 0x00040400,
+ 0x00040404, 0x00040404, 0x04000000, 0x04000000, 0x04000004, 0x04000004,
+ 0x04000000, 0x04000000, 0x04000004, 0x04000004, 0x04000400, 0x04000400,
+ 0x04000404, 0x04000404, 0x04000400, 0x04000400, 0x04000404, 0x04000404,
+ 0x04000000, 0x04000000, 0x04000004, 0x04000004, 0x04000000, 0x04000000,
+ 0x04000004, 0x04000004, 0x04000400, 0x04000400, 0x04000404, 0x04000404,
+ 0x04000400, 0x04000400, 0x04000404, 0x04000404, 0x04040000, 0x04040000,
+ 0x04040004, 0x04040004, 0x04040000, 0x04040000, 0x04040004, 0x04040004,
+ 0x04040400, 0x04040400, 0x04040404, 0x04040404, 0x04040400, 0x04040400,
+ 0x04040404, 0x04040404, 0x04040000, 0x04040000, 0x04040004, 0x04040004,
+ 0x04040000, 0x04040000, 0x04040004, 0x04040004, 0x04040400, 0x04040400,
+ 0x04040404, 0x04040404, 0x04040400, 0x04040400, 0x04040404, 0x04040404,
+ 0x04000000, 0x04000000, 0x04000004, 0x04000004, 0x04000000, 0x04000000,
+ 0x04000004, 0x04000004, 0x04000400, 0x04000400, 0x04000404, 0x04000404,
+ 0x04000400, 0x04000400, 0x04000404, 0x04000404, 0x04000000, 0x04000000,
+ 0x04000004, 0x04000004, 0x04000000, 0x04000000, 0x04000004, 0x04000004,
+ 0x04000400, 0x04000400, 0x04000404, 0x04000404, 0x04000400, 0x04000400,
+ 0x04000404, 0x04000404, 0x04040000, 0x04040000, 0x04040004, 0x04040004,
+ 0x04040000, 0x04040000, 0x04040004, 0x04040004, 0x04040400, 0x04040400,
+ 0x04040404, 0x04040404, 0x04040400, 0x04040400, 0x04040404, 0x04040404,
+ 0x04040000, 0x04040000, 0x04040004, 0x04040004, 0x04040000, 0x04040000,
+ 0x04040004, 0x04040004, 0x04040400, 0x04040400, 0x04040404, 0x04040404,
+ 0x04040400, 0x04040400, 0x04040404, 0x04040404,
+ },
+ {
+ 0x00000000, 0x00000000, 0x00000008, 0x00000008, 0x00000000, 0x00000000,
+ 0x00000008, 0x00000008, 0x00000800, 0x00000800, 0x00000808, 0x00000808,
+ 0x00000800, 0x00000800, 0x00000808, 0x00000808, 0x00000000, 0x00000000,
+ 0x00000008, 0x00000008, 0x00000000, 0x00000000, 0x00000008, 0x00000008,
+ 0x00000800, 0x00000800, 0x00000808, 0x00000808, 0x00000800, 0x00000800,
+ 0x00000808, 0x00000808, 0x00080000, 0x00080000, 0x00080008, 0x00080008,
+ 0x00080000, 0x00080000, 0x00080008, 0x00080008, 0x00080800, 0x00080800,
+ 0x00080808, 0x00080808, 0x00080800, 0x00080800, 0x00080808, 0x00080808,
+ 0x00080000, 0x00080000, 0x00080008, 0x00080008, 0x00080000, 0x00080000,
+ 0x00080008, 0x00080008, 0x00080800, 0x00080800, 0x00080808, 0x00080808,
+ 0x00080800, 0x00080800, 0x00080808, 0x00080808, 0x00000000, 0x00000000,
+ 0x00000008, 0x00000008, 0x00000000, 0x00000000, 0x00000008, 0x00000008,
+ 0x00000800, 0x00000800, 0x00000808, 0x00000808, 0x00000800, 0x00000800,
+ 0x00000808, 0x00000808, 0x00000000, 0x00000000, 0x00000008, 0x00000008,
+ 0x00000000, 0x00000000, 0x00000008, 0x00000008, 0x00000800, 0x00000800,
+ 0x00000808, 0x00000808, 0x00000800, 0x00000800, 0x00000808, 0x00000808,
+ 0x00080000, 0x00080000, 0x00080008, 0x00080008, 0x00080000, 0x00080000,
+ 0x00080008, 0x00080008, 0x00080800, 0x00080800, 0x00080808, 0x00080808,
+ 0x00080800, 0x00080800, 0x00080808, 0x00080808, 0x00080000, 0x00080000,
+ 0x00080008, 0x00080008, 0x00080000, 0x00080000, 0x00080008, 0x00080008,
+ 0x00080800, 0x00080800, 0x00080808, 0x00080808, 0x00080800, 0x00080800,
+ 0x00080808, 0x00080808, 0x08000000, 0x08000000, 0x08000008, 0x08000008,
+ 0x08000000, 0x08000000, 0x08000008, 0x08000008, 0x08000800, 0x08000800,
+ 0x08000808, 0x08000808, 0x08000800, 0x08000800, 0x08000808, 0x08000808,
+ 0x08000000, 0x08000000, 0x08000008, 0x08000008, 0x08000000, 0x08000000,
+ 0x08000008, 0x08000008, 0x08000800, 0x08000800, 0x08000808, 0x08000808,
+ 0x08000800, 0x08000800, 0x08000808, 0x08000808, 0x08080000, 0x08080000,
+ 0x08080008, 0x08080008, 0x08080000, 0x08080000, 0x08080008, 0x08080008,
+ 0x08080800, 0x08080800, 0x08080808, 0x08080808, 0x08080800, 0x08080800,
+ 0x08080808, 0x08080808, 0x08080000, 0x08080000, 0x08080008, 0x08080008,
+ 0x08080000, 0x08080000, 0x08080008, 0x08080008, 0x08080800, 0x08080800,
+ 0x08080808, 0x08080808, 0x08080800, 0x08080800, 0x08080808, 0x08080808,
+ 0x08000000, 0x08000000, 0x08000008, 0x08000008, 0x08000000, 0x08000000,
+ 0x08000008, 0x08000008, 0x08000800, 0x08000800, 0x08000808, 0x08000808,
+ 0x08000800, 0x08000800, 0x08000808, 0x08000808, 0x08000000, 0x08000000,
+ 0x08000008, 0x08000008, 0x08000000, 0x08000000, 0x08000008, 0x08000008,
+ 0x08000800, 0x08000800, 0x08000808, 0x08000808, 0x08000800, 0x08000800,
+ 0x08000808, 0x08000808, 0x08080000, 0x08080000, 0x08080008, 0x08080008,
+ 0x08080000, 0x08080000, 0x08080008, 0x08080008, 0x08080800, 0x08080800,
+ 0x08080808, 0x08080808, 0x08080800, 0x08080800, 0x08080808, 0x08080808,
+ 0x08080000, 0x08080000, 0x08080008, 0x08080008, 0x08080000, 0x08080000,
+ 0x08080008, 0x08080008, 0x08080800, 0x08080800, 0x08080808, 0x08080808,
+ 0x08080800, 0x08080800, 0x08080808, 0x08080808,
+ },
+ {
+ 0x00000000, 0x00000000, 0x00000010, 0x00000010, 0x00000000, 0x00000000,
+ 0x00000010, 0x00000010, 0x00001000, 0x00001000, 0x00001010, 0x00001010,
+ 0x00001000, 0x00001000, 0x00001010, 0x00001010, 0x00000000, 0x00000000,
+ 0x00000010, 0x00000010, 0x00000000, 0x00000000, 0x00000010, 0x00000010,
+ 0x00001000, 0x00001000, 0x00001010, 0x00001010, 0x00001000, 0x00001000,
+ 0x00001010, 0x00001010, 0x00100000, 0x00100000, 0x00100010, 0x00100010,
+ 0x00100000, 0x00100000, 0x00100010, 0x00100010, 0x00101000, 0x00101000,
+ 0x00101010, 0x00101010, 0x00101000, 0x00101000, 0x00101010, 0x00101010,
+ 0x00100000, 0x00100000, 0x00100010, 0x00100010, 0x00100000, 0x00100000,
+ 0x00100010, 0x00100010, 0x00101000, 0x00101000, 0x00101010, 0x00101010,
+ 0x00101000, 0x00101000, 0x00101010, 0x00101010, 0x00000000, 0x00000000,
+ 0x00000010, 0x00000010, 0x00000000, 0x00000000, 0x00000010, 0x00000010,
+ 0x00001000, 0x00001000, 0x00001010, 0x00001010, 0x00001000, 0x00001000,
+ 0x00001010, 0x00001010, 0x00000000, 0x00000000, 0x00000010, 0x00000010,
+ 0x00000000, 0x00000000, 0x00000010, 0x00000010, 0x00001000, 0x00001000,
+ 0x00001010, 0x00001010, 0x00001000, 0x00001000, 0x00001010, 0x00001010,
+ 0x00100000, 0x00100000, 0x00100010, 0x00100010, 0x00100000, 0x00100000,
+ 0x00100010, 0x00100010, 0x00101000, 0x00101000, 0x00101010, 0x00101010,
+ 0x00101000, 0x00101000, 0x00101010, 0x00101010, 0x00100000, 0x00100000,
+ 0x00100010, 0x00100010, 0x00100000, 0x00100000, 0x00100010, 0x00100010,
+ 0x00101000, 0x00101000, 0x00101010, 0x00101010, 0x00101000, 0x00101000,
+ 0x00101010, 0x00101010, 0x10000000, 0x10000000, 0x10000010, 0x10000010,
+ 0x10000000, 0x10000000, 0x10000010, 0x10000010, 0x10001000, 0x10001000,
+ 0x10001010, 0x10001010, 0x10001000, 0x10001000, 0x10001010, 0x10001010,
+ 0x10000000, 0x10000000, 0x10000010, 0x10000010, 0x10000000, 0x10000000,
+ 0x10000010, 0x10000010, 0x10001000, 0x10001000, 0x10001010, 0x10001010,
+ 0x10001000, 0x10001000, 0x10001010, 0x10001010, 0x10100000, 0x10100000,
+ 0x10100010, 0x10100010, 0x10100000, 0x10100000, 0x10100010, 0x10100010,
+ 0x10101000, 0x10101000, 0x10101010, 0x10101010, 0x10101000, 0x10101000,
+ 0x10101010, 0x10101010, 0x10100000, 0x10100000, 0x10100010, 0x10100010,
+ 0x10100000, 0x10100000, 0x10100010, 0x10100010, 0x10101000, 0x10101000,
+ 0x10101010, 0x10101010, 0x10101000, 0x10101000, 0x10101010, 0x10101010,
+ 0x10000000, 0x10000000, 0x10000010, 0x10000010, 0x10000000, 0x10000000,
+ 0x10000010, 0x10000010, 0x10001000, 0x10001000, 0x10001010, 0x10001010,
+ 0x10001000, 0x10001000, 0x10001010, 0x10001010, 0x10000000, 0x10000000,
+ 0x10000010, 0x10000010, 0x10000000, 0x10000000, 0x10000010, 0x10000010,
+ 0x10001000, 0x10001000, 0x10001010, 0x10001010, 0x10001000, 0x10001000,
+ 0x10001010, 0x10001010, 0x10100000, 0x10100000, 0x10100010, 0x10100010,
+ 0x10100000, 0x10100000, 0x10100010, 0x10100010, 0x10101000, 0x10101000,
+ 0x10101010, 0x10101010, 0x10101000, 0x10101000, 0x10101010, 0x10101010,
+ 0x10100000, 0x10100000, 0x10100010, 0x10100010, 0x10100000, 0x10100000,
+ 0x10100010, 0x10100010, 0x10101000, 0x10101000, 0x10101010, 0x10101010,
+ 0x10101000, 0x10101000, 0x10101010, 0x10101010,
+ },
+ {
+ 0x00000000, 0x00000000, 0x00000020, 0x00000020, 0x00000000, 0x00000000,
+ 0x00000020, 0x00000020, 0x00002000, 0x00002000, 0x00002020, 0x00002020,
+ 0x00002000, 0x00002000, 0x00002020, 0x00002020, 0x00000000, 0x00000000,
+ 0x00000020, 0x00000020, 0x00000000, 0x00000000, 0x00000020, 0x00000020,
+ 0x00002000, 0x00002000, 0x00002020, 0x00002020, 0x00002000, 0x00002000,
+ 0x00002020, 0x00002020, 0x00200000, 0x00200000, 0x00200020, 0x00200020,
+ 0x00200000, 0x00200000, 0x00200020, 0x00200020, 0x00202000, 0x00202000,
+ 0x00202020, 0x00202020, 0x00202000, 0x00202000, 0x00202020, 0x00202020,
+ 0x00200000, 0x00200000, 0x00200020, 0x00200020, 0x00200000, 0x00200000,
+ 0x00200020, 0x00200020, 0x00202000, 0x00202000, 0x00202020, 0x00202020,
+ 0x00202000, 0x00202000, 0x00202020, 0x00202020, 0x00000000, 0x00000000,
+ 0x00000020, 0x00000020, 0x00000000, 0x00000000, 0x00000020, 0x00000020,
+ 0x00002000, 0x00002000, 0x00002020, 0x00002020, 0x00002000, 0x00002000,
+ 0x00002020, 0x00002020, 0x00000000, 0x00000000, 0x00000020, 0x00000020,
+ 0x00000000, 0x00000000, 0x00000020, 0x00000020, 0x00002000, 0x00002000,
+ 0x00002020, 0x00002020, 0x00002000, 0x00002000, 0x00002020, 0x00002020,
+ 0x00200000, 0x00200000, 0x00200020, 0x00200020, 0x00200000, 0x00200000,
+ 0x00200020, 0x00200020, 0x00202000, 0x00202000, 0x00202020, 0x00202020,
+ 0x00202000, 0x00202000, 0x00202020, 0x00202020, 0x00200000, 0x00200000,
+ 0x00200020, 0x00200020, 0x00200000, 0x00200000, 0x00200020, 0x00200020,
+ 0x00202000, 0x00202000, 0x00202020, 0x00202020, 0x00202000, 0x00202000,
+ 0x00202020, 0x00202020, 0x20000000, 0x20000000, 0x20000020, 0x20000020,
+ 0x20000000, 0x20000000, 0x20000020, 0x20000020, 0x20002000, 0x20002000,
+ 0x20002020, 0x20002020, 0x20002000, 0x20002000, 0x20002020, 0x20002020,
+ 0x20000000, 0x20000000, 0x20000020, 0x20000020, 0x20000000, 0x20000000,
+ 0x20000020, 0x20000020, 0x20002000, 0x20002000, 0x20002020, 0x20002020,
+ 0x20002000, 0x20002000, 0x20002020, 0x20002020, 0x20200000, 0x20200000,
+ 0x20200020, 0x20200020, 0x20200000, 0x20200000, 0x20200020, 0x20200020,
+ 0x20202000, 0x20202000, 0x20202020, 0x20202020, 0x20202000, 0x20202000,
+ 0x20202020, 0x20202020, 0x20200000, 0x20200000, 0x20200020, 0x20200020,
+ 0x20200000, 0x20200000, 0x20200020, 0x20200020, 0x20202000, 0x20202000,
+ 0x20202020, 0x20202020, 0x20202000, 0x20202000, 0x20202020, 0x20202020,
+ 0x20000000, 0x20000000, 0x20000020, 0x20000020, 0x20000000, 0x20000000,
+ 0x20000020, 0x20000020, 0x20002000, 0x20002000, 0x20002020, 0x20002020,
+ 0x20002000, 0x20002000, 0x20002020, 0x20002020, 0x20000000, 0x20000000,
+ 0x20000020, 0x20000020, 0x20000000, 0x20000000, 0x20000020, 0x20000020,
+ 0x20002000, 0x20002000, 0x20002020, 0x20002020, 0x20002000, 0x20002000,
+ 0x20002020, 0x20002020, 0x20200000, 0x20200000, 0x20200020, 0x20200020,
+ 0x20200000, 0x20200000, 0x20200020, 0x20200020, 0x20202000, 0x20202000,
+ 0x20202020, 0x20202020, 0x20202000, 0x20202000, 0x20202020, 0x20202020,
+ 0x20200000, 0x20200000, 0x20200020, 0x20200020, 0x20200000, 0x20200000,
+ 0x20200020, 0x20200020, 0x20202000, 0x20202000, 0x20202020, 0x20202020,
+ 0x20202000, 0x20202000, 0x20202020, 0x20202020,
+ },
+ {
+ 0x00000000, 0x00000000, 0x00000040, 0x00000040, 0x00000000, 0x00000000,
+ 0x00000040, 0x00000040, 0x00004000, 0x00004000, 0x00004040, 0x00004040,
+ 0x00004000, 0x00004000, 0x00004040, 0x00004040, 0x00000000, 0x00000000,
+ 0x00000040, 0x00000040, 0x00000000, 0x00000000, 0x00000040, 0x00000040,
+ 0x00004000, 0x00004000, 0x00004040, 0x00004040, 0x00004000, 0x00004000,
+ 0x00004040, 0x00004040, 0x00400000, 0x00400000, 0x00400040, 0x00400040,
+ 0x00400000, 0x00400000, 0x00400040, 0x00400040, 0x00404000, 0x00404000,
+ 0x00404040, 0x00404040, 0x00404000, 0x00404000, 0x00404040, 0x00404040,
+ 0x00400000, 0x00400000, 0x00400040, 0x00400040, 0x00400000, 0x00400000,
+ 0x00400040, 0x00400040, 0x00404000, 0x00404000, 0x00404040, 0x00404040,
+ 0x00404000, 0x00404000, 0x00404040, 0x00404040, 0x00000000, 0x00000000,
+ 0x00000040, 0x00000040, 0x00000000, 0x00000000, 0x00000040, 0x00000040,
+ 0x00004000, 0x00004000, 0x00004040, 0x00004040, 0x00004000, 0x00004000,
+ 0x00004040, 0x00004040, 0x00000000, 0x00000000, 0x00000040, 0x00000040,
+ 0x00000000, 0x00000000, 0x00000040, 0x00000040, 0x00004000, 0x00004000,
+ 0x00004040, 0x00004040, 0x00004000, 0x00004000, 0x00004040, 0x00004040,
+ 0x00400000, 0x00400000, 0x00400040, 0x00400040, 0x00400000, 0x00400000,
+ 0x00400040, 0x00400040, 0x00404000, 0x00404000, 0x00404040, 0x00404040,
+ 0x00404000, 0x00404000, 0x00404040, 0x00404040, 0x00400000, 0x00400000,
+ 0x00400040, 0x00400040, 0x00400000, 0x00400000, 0x00400040, 0x00400040,
+ 0x00404000, 0x00404000, 0x00404040, 0x00404040, 0x00404000, 0x00404000,
+ 0x00404040, 0x00404040, 0x40000000, 0x40000000, 0x40000040, 0x40000040,
+ 0x40000000, 0x40000000, 0x40000040, 0x40000040, 0x40004000, 0x40004000,
+ 0x40004040, 0x40004040, 0x40004000, 0x40004000, 0x40004040, 0x40004040,
+ 0x40000000, 0x40000000, 0x40000040, 0x40000040, 0x40000000, 0x40000000,
+ 0x40000040, 0x40000040, 0x40004000, 0x40004000, 0x40004040, 0x40004040,
+ 0x40004000, 0x40004000, 0x40004040, 0x40004040, 0x40400000, 0x40400000,
+ 0x40400040, 0x40400040, 0x40400000, 0x40400000, 0x40400040, 0x40400040,
+ 0x40404000, 0x40404000, 0x40404040, 0x40404040, 0x40404000, 0x40404000,
+ 0x40404040, 0x40404040, 0x40400000, 0x40400000, 0x40400040, 0x40400040,
+ 0x40400000, 0x40400000, 0x40400040, 0x40400040, 0x40404000, 0x40404000,
+ 0x40404040, 0x40404040, 0x40404000, 0x40404000, 0x40404040, 0x40404040,
+ 0x40000000, 0x40000000, 0x40000040, 0x40000040, 0x40000000, 0x40000000,
+ 0x40000040, 0x40000040, 0x40004000, 0x40004000, 0x40004040, 0x40004040,
+ 0x40004000, 0x40004000, 0x40004040, 0x40004040, 0x40000000, 0x40000000,
+ 0x40000040, 0x40000040, 0x40000000, 0x40000000, 0x40000040, 0x40000040,
+ 0x40004000, 0x40004000, 0x40004040, 0x40004040, 0x40004000, 0x40004000,
+ 0x40004040, 0x40004040, 0x40400000, 0x40400000, 0x40400040, 0x40400040,
+ 0x40400000, 0x40400000, 0x40400040, 0x40400040, 0x40404000, 0x40404000,
+ 0x40404040, 0x40404040, 0x40404000, 0x40404000, 0x40404040, 0x40404040,
+ 0x40400000, 0x40400000, 0x40400040, 0x40400040, 0x40400000, 0x40400000,
+ 0x40400040, 0x40400040, 0x40404000, 0x40404000, 0x40404040, 0x40404040,
+ 0x40404000, 0x40404000, 0x40404040, 0x40404040,
+ },
+ {
+ 0x00000000, 0x00000000, 0x00000080, 0x00000080, 0x00000000, 0x00000000,
+ 0x00000080, 0x00000080, 0x00008000, 0x00008000, 0x00008080, 0x00008080,
+ 0x00008000, 0x00008000, 0x00008080, 0x00008080, 0x00000000, 0x00000000,
+ 0x00000080, 0x00000080, 0x00000000, 0x00000000, 0x00000080, 0x00000080,
+ 0x00008000, 0x00008000, 0x00008080, 0x00008080, 0x00008000, 0x00008000,
+ 0x00008080, 0x00008080, 0x00800000, 0x00800000, 0x00800080, 0x00800080,
+ 0x00800000, 0x00800000, 0x00800080, 0x00800080, 0x00808000, 0x00808000,
+ 0x00808080, 0x00808080, 0x00808000, 0x00808000, 0x00808080, 0x00808080,
+ 0x00800000, 0x00800000, 0x00800080, 0x00800080, 0x00800000, 0x00800000,
+ 0x00800080, 0x00800080, 0x00808000, 0x00808000, 0x00808080, 0x00808080,
+ 0x00808000, 0x00808000, 0x00808080, 0x00808080, 0x00000000, 0x00000000,
+ 0x00000080, 0x00000080, 0x00000000, 0x00000000, 0x00000080, 0x00000080,
+ 0x00008000, 0x00008000, 0x00008080, 0x00008080, 0x00008000, 0x00008000,
+ 0x00008080, 0x00008080, 0x00000000, 0x00000000, 0x00000080, 0x00000080,
+ 0x00000000, 0x00000000, 0x00000080, 0x00000080, 0x00008000, 0x00008000,
+ 0x00008080, 0x00008080, 0x00008000, 0x00008000, 0x00008080, 0x00008080,
+ 0x00800000, 0x00800000, 0x00800080, 0x00800080, 0x00800000, 0x00800000,
+ 0x00800080, 0x00800080, 0x00808000, 0x00808000, 0x00808080, 0x00808080,
+ 0x00808000, 0x00808000, 0x00808080, 0x00808080, 0x00800000, 0x00800000,
+ 0x00800080, 0x00800080, 0x00800000, 0x00800000, 0x00800080, 0x00800080,
+ 0x00808000, 0x00808000, 0x00808080, 0x00808080, 0x00808000, 0x00808000,
+ 0x00808080, 0x00808080, 0x80000000, 0x80000000, 0x80000080, 0x80000080,
+ 0x80000000, 0x80000000, 0x80000080, 0x80000080, 0x80008000, 0x80008000,
+ 0x80008080, 0x80008080, 0x80008000, 0x80008000, 0x80008080, 0x80008080,
+ 0x80000000, 0x80000000, 0x80000080, 0x80000080, 0x80000000, 0x80000000,
+ 0x80000080, 0x80000080, 0x80008000, 0x80008000, 0x80008080, 0x80008080,
+ 0x80008000, 0x80008000, 0x80008080, 0x80008080, 0x80800000, 0x80800000,
+ 0x80800080, 0x80800080, 0x80800000, 0x80800000, 0x80800080, 0x80800080,
+ 0x80808000, 0x80808000, 0x80808080, 0x80808080, 0x80808000, 0x80808000,
+ 0x80808080, 0x80808080, 0x80800000, 0x80800000, 0x80800080, 0x80800080,
+ 0x80800000, 0x80800000, 0x80800080, 0x80800080, 0x80808000, 0x80808000,
+ 0x80808080, 0x80808080, 0x80808000, 0x80808000, 0x80808080, 0x80808080,
+ 0x80000000, 0x80000000, 0x80000080, 0x80000080, 0x80000000, 0x80000000,
+ 0x80000080, 0x80000080, 0x80008000, 0x80008000, 0x80008080, 0x80008080,
+ 0x80008000, 0x80008000, 0x80008080, 0x80008080, 0x80000000, 0x80000000,
+ 0x80000080, 0x80000080, 0x80000000, 0x80000000, 0x80000080, 0x80000080,
+ 0x80008000, 0x80008000, 0x80008080, 0x80008080, 0x80008000, 0x80008000,
+ 0x80008080, 0x80008080, 0x80800000, 0x80800000, 0x80800080, 0x80800080,
+ 0x80800000, 0x80800000, 0x80800080, 0x80800080, 0x80808000, 0x80808000,
+ 0x80808080, 0x80808080, 0x80808000, 0x80808000, 0x80808080, 0x80808080,
+ 0x80800000, 0x80800000, 0x80800080, 0x80800080, 0x80800000, 0x80800000,
+ 0x80800080, 0x80800080, 0x80808000, 0x80808000, 0x80808080, 0x80808080,
+ 0x80808000, 0x80808000, 0x80808080, 0x80808080,
+ },
+};
+
+const uint32_t fp_maskl[8][256] = {
+ {
+ 0x00000000, 0x40000000, 0x00400000, 0x40400000, 0x00004000, 0x40004000,
+ 0x00404000, 0x40404000, 0x00000040, 0x40000040, 0x00400040, 0x40400040,
+ 0x00004040, 0x40004040, 0x00404040, 0x40404040, 0x00000000, 0x40000000,
+ 0x00400000, 0x40400000, 0x00004000, 0x40004000, 0x00404000, 0x40404000,
+ 0x00000040, 0x40000040, 0x00400040, 0x40400040, 0x00004040, 0x40004040,
+ 0x00404040, 0x40404040, 0x00000000, 0x40000000, 0x00400000, 0x40400000,
+ 0x00004000, 0x40004000, 0x00404000, 0x40404000, 0x00000040, 0x40000040,
+ 0x00400040, 0x40400040, 0x00004040, 0x40004040, 0x00404040, 0x40404040,
+ 0x00000000, 0x40000000, 0x00400000, 0x40400000, 0x00004000, 0x40004000,
+ 0x00404000, 0x40404000, 0x00000040, 0x40000040, 0x00400040, 0x40400040,
+ 0x00004040, 0x40004040, 0x00404040, 0x40404040, 0x00000000, 0x40000000,
+ 0x00400000, 0x40400000, 0x00004000, 0x40004000, 0x00404000, 0x40404000,
+ 0x00000040, 0x40000040, 0x00400040, 0x40400040, 0x00004040, 0x40004040,
+ 0x00404040, 0x40404040, 0x00000000, 0x40000000, 0x00400000, 0x40400000,
+ 0x00004000, 0x40004000, 0x00404000, 0x40404000, 0x00000040, 0x40000040,
+ 0x00400040, 0x40400040, 0x00004040, 0x40004040, 0x00404040, 0x40404040,
+ 0x00000000, 0x40000000, 0x00400000, 0x40400000, 0x00004000, 0x40004000,
+ 0x00404000, 0x40404000, 0x00000040, 0x40000040, 0x00400040, 0x40400040,
+ 0x00004040, 0x40004040, 0x00404040, 0x40404040, 0x00000000, 0x40000000,
+ 0x00400000, 0x40400000, 0x00004000, 0x40004000, 0x00404000, 0x40404000,
+ 0x00000040, 0x40000040, 0x00400040, 0x40400040, 0x00004040, 0x40004040,
+ 0x00404040, 0x40404040, 0x00000000, 0x40000000, 0x00400000, 0x40400000,
+ 0x00004000, 0x40004000, 0x00404000, 0x40404000, 0x00000040, 0x40000040,
+ 0x00400040, 0x40400040, 0x00004040, 0x40004040, 0x00404040, 0x40404040,
+ 0x00000000, 0x40000000, 0x00400000, 0x40400000, 0x00004000, 0x40004000,
+ 0x00404000, 0x40404000, 0x00000040, 0x40000040, 0x00400040, 0x40400040,
+ 0x00004040, 0x40004040, 0x00404040, 0x40404040, 0x00000000, 0x40000000,
+ 0x00400000, 0x40400000, 0x00004000, 0x40004000, 0x00404000, 0x40404000,
+ 0x00000040, 0x40000040, 0x00400040, 0x40400040, 0x00004040, 0x40004040,
+ 0x00404040, 0x40404040, 0x00000000, 0x40000000, 0x00400000, 0x40400000,
+ 0x00004000, 0x40004000, 0x00404000, 0x40404000, 0x00000040, 0x40000040,
+ 0x00400040, 0x40400040, 0x00004040, 0x40004040, 0x00404040, 0x40404040,
+ 0x00000000, 0x40000000, 0x00400000, 0x40400000, 0x00004000, 0x40004000,
+ 0x00404000, 0x40404000, 0x00000040, 0x40000040, 0x00400040, 0x40400040,
+ 0x00004040, 0x40004040, 0x00404040, 0x40404040, 0x00000000, 0x40000000,
+ 0x00400000, 0x40400000, 0x00004000, 0x40004000, 0x00404000, 0x40404000,
+ 0x00000040, 0x40000040, 0x00400040, 0x40400040, 0x00004040, 0x40004040,
+ 0x00404040, 0x40404040, 0x00000000, 0x40000000, 0x00400000, 0x40400000,
+ 0x00004000, 0x40004000, 0x00404000, 0x40404000, 0x00000040, 0x40000040,
+ 0x00400040, 0x40400040, 0x00004040, 0x40004040, 0x00404040, 0x40404040,
+ 0x00000000, 0x40000000, 0x00400000, 0x40400000, 0x00004000, 0x40004000,
+ 0x00404000, 0x40404000, 0x00000040, 0x40000040, 0x00400040, 0x40400040,
+ 0x00004040, 0x40004040, 0x00404040, 0x40404040,
+ },
+ {
+ 0x00000000, 0x10000000, 0x00100000, 0x10100000, 0x00001000, 0x10001000,
+ 0x00101000, 0x10101000, 0x00000010, 0x10000010, 0x00100010, 0x10100010,
+ 0x00001010, 0x10001010, 0x00101010, 0x10101010, 0x00000000, 0x10000000,
+ 0x00100000, 0x10100000, 0x00001000, 0x10001000, 0x00101000, 0x10101000,
+ 0x00000010, 0x10000010, 0x00100010, 0x10100010, 0x00001010, 0x10001010,
+ 0x00101010, 0x10101010, 0x00000000, 0x10000000, 0x00100000, 0x10100000,
+ 0x00001000, 0x10001000, 0x00101000, 0x10101000, 0x00000010, 0x10000010,
+ 0x00100010, 0x10100010, 0x00001010, 0x10001010, 0x00101010, 0x10101010,
+ 0x00000000, 0x10000000, 0x00100000, 0x10100000, 0x00001000, 0x10001000,
+ 0x00101000, 0x10101000, 0x00000010, 0x10000010, 0x00100010, 0x10100010,
+ 0x00001010, 0x10001010, 0x00101010, 0x10101010, 0x00000000, 0x10000000,
+ 0x00100000, 0x10100000, 0x00001000, 0x10001000, 0x00101000, 0x10101000,
+ 0x00000010, 0x10000010, 0x00100010, 0x10100010, 0x00001010, 0x10001010,
+ 0x00101010, 0x10101010, 0x00000000, 0x10000000, 0x00100000, 0x10100000,
+ 0x00001000, 0x10001000, 0x00101000, 0x10101000, 0x00000010, 0x10000010,
+ 0x00100010, 0x10100010, 0x00001010, 0x10001010, 0x00101010, 0x10101010,
+ 0x00000000, 0x10000000, 0x00100000, 0x10100000, 0x00001000, 0x10001000,
+ 0x00101000, 0x10101000, 0x00000010, 0x10000010, 0x00100010, 0x10100010,
+ 0x00001010, 0x10001010, 0x00101010, 0x10101010, 0x00000000, 0x10000000,
+ 0x00100000, 0x10100000, 0x00001000, 0x10001000, 0x00101000, 0x10101000,
+ 0x00000010, 0x10000010, 0x00100010, 0x10100010, 0x00001010, 0x10001010,
+ 0x00101010, 0x10101010, 0x00000000, 0x10000000, 0x00100000, 0x10100000,
+ 0x00001000, 0x10001000, 0x00101000, 0x10101000, 0x00000010, 0x10000010,
+ 0x00100010, 0x10100010, 0x00001010, 0x10001010, 0x00101010, 0x10101010,
+ 0x00000000, 0x10000000, 0x00100000, 0x10100000, 0x00001000, 0x10001000,
+ 0x00101000, 0x10101000, 0x00000010, 0x10000010, 0x00100010, 0x10100010,
+ 0x00001010, 0x10001010, 0x00101010, 0x10101010, 0x00000000, 0x10000000,
+ 0x00100000, 0x10100000, 0x00001000, 0x10001000, 0x00101000, 0x10101000,
+ 0x00000010, 0x10000010, 0x00100010, 0x10100010, 0x00001010, 0x10001010,
+ 0x00101010, 0x10101010, 0x00000000, 0x10000000, 0x00100000, 0x10100000,
+ 0x00001000, 0x10001000, 0x00101000, 0x10101000, 0x00000010, 0x10000010,
+ 0x00100010, 0x10100010, 0x00001010, 0x10001010, 0x00101010, 0x10101010,
+ 0x00000000, 0x10000000, 0x00100000, 0x10100000, 0x00001000, 0x10001000,
+ 0x00101000, 0x10101000, 0x00000010, 0x10000010, 0x00100010, 0x10100010,
+ 0x00001010, 0x10001010, 0x00101010, 0x10101010, 0x00000000, 0x10000000,
+ 0x00100000, 0x10100000, 0x00001000, 0x10001000, 0x00101000, 0x10101000,
+ 0x00000010, 0x10000010, 0x00100010, 0x10100010, 0x00001010, 0x10001010,
+ 0x00101010, 0x10101010, 0x00000000, 0x10000000, 0x00100000, 0x10100000,
+ 0x00001000, 0x10001000, 0x00101000, 0x10101000, 0x00000010, 0x10000010,
+ 0x00100010, 0x10100010, 0x00001010, 0x10001010, 0x00101010, 0x10101010,
+ 0x00000000, 0x10000000, 0x00100000, 0x10100000, 0x00001000, 0x10001000,
+ 0x00101000, 0x10101000, 0x00000010, 0x10000010, 0x00100010, 0x10100010,
+ 0x00001010, 0x10001010, 0x00101010, 0x10101010,
+ },
+ {
+ 0x00000000, 0x04000000, 0x00040000, 0x04040000, 0x00000400, 0x04000400,
+ 0x00040400, 0x04040400, 0x00000004, 0x04000004, 0x00040004, 0x04040004,
+ 0x00000404, 0x04000404, 0x00040404, 0x04040404, 0x00000000, 0x04000000,
+ 0x00040000, 0x04040000, 0x00000400, 0x04000400, 0x00040400, 0x04040400,
+ 0x00000004, 0x04000004, 0x00040004, 0x04040004, 0x00000404, 0x04000404,
+ 0x00040404, 0x04040404, 0x00000000, 0x04000000, 0x00040000, 0x04040000,
+ 0x00000400, 0x04000400, 0x00040400, 0x04040400, 0x00000004, 0x04000004,
+ 0x00040004, 0x04040004, 0x00000404, 0x04000404, 0x00040404, 0x04040404,
+ 0x00000000, 0x04000000, 0x00040000, 0x04040000, 0x00000400, 0x04000400,
+ 0x00040400, 0x04040400, 0x00000004, 0x04000004, 0x00040004, 0x04040004,
+ 0x00000404, 0x04000404, 0x00040404, 0x04040404, 0x00000000, 0x04000000,
+ 0x00040000, 0x04040000, 0x00000400, 0x04000400, 0x00040400, 0x04040400,
+ 0x00000004, 0x04000004, 0x00040004, 0x04040004, 0x00000404, 0x04000404,
+ 0x00040404, 0x04040404, 0x00000000, 0x04000000, 0x00040000, 0x04040000,
+ 0x00000400, 0x04000400, 0x00040400, 0x04040400, 0x00000004, 0x04000004,
+ 0x00040004, 0x04040004, 0x00000404, 0x04000404, 0x00040404, 0x04040404,
+ 0x00000000, 0x04000000, 0x00040000, 0x04040000, 0x00000400, 0x04000400,
+ 0x00040400, 0x04040400, 0x00000004, 0x04000004, 0x00040004, 0x04040004,
+ 0x00000404, 0x04000404, 0x00040404, 0x04040404, 0x00000000, 0x04000000,
+ 0x00040000, 0x04040000, 0x00000400, 0x04000400, 0x00040400, 0x04040400,
+ 0x00000004, 0x04000004, 0x00040004, 0x04040004, 0x00000404, 0x04000404,
+ 0x00040404, 0x04040404, 0x00000000, 0x04000000, 0x00040000, 0x04040000,
+ 0x00000400, 0x04000400, 0x00040400, 0x04040400, 0x00000004, 0x04000004,
+ 0x00040004, 0x04040004, 0x00000404, 0x04000404, 0x00040404, 0x04040404,
+ 0x00000000, 0x04000000, 0x00040000, 0x04040000, 0x00000400, 0x04000400,
+ 0x00040400, 0x04040400, 0x00000004, 0x04000004, 0x00040004, 0x04040004,
+ 0x00000404, 0x04000404, 0x00040404, 0x04040404, 0x00000000, 0x04000000,
+ 0x00040000, 0x04040000, 0x00000400, 0x04000400, 0x00040400, 0x04040400,
+ 0x00000004, 0x04000004, 0x00040004, 0x04040004, 0x00000404, 0x04000404,
+ 0x00040404, 0x04040404, 0x00000000, 0x04000000, 0x00040000, 0x04040000,
+ 0x00000400, 0x04000400, 0x00040400, 0x04040400, 0x00000004, 0x04000004,
+ 0x00040004, 0x04040004, 0x00000404, 0x04000404, 0x00040404, 0x04040404,
+ 0x00000000, 0x04000000, 0x00040000, 0x04040000, 0x00000400, 0x04000400,
+ 0x00040400, 0x04040400, 0x00000004, 0x04000004, 0x00040004, 0x04040004,
+ 0x00000404, 0x04000404, 0x00040404, 0x04040404, 0x00000000, 0x04000000,
+ 0x00040000, 0x04040000, 0x00000400, 0x04000400, 0x00040400, 0x04040400,
+ 0x00000004, 0x04000004, 0x00040004, 0x04040004, 0x00000404, 0x04000404,
+ 0x00040404, 0x04040404, 0x00000000, 0x04000000, 0x00040000, 0x04040000,
+ 0x00000400, 0x04000400, 0x00040400, 0x04040400, 0x00000004, 0x04000004,
+ 0x00040004, 0x04040004, 0x00000404, 0x04000404, 0x00040404, 0x04040404,
+ 0x00000000, 0x04000000, 0x00040000, 0x04040000, 0x00000400, 0x04000400,
+ 0x00040400, 0x04040400, 0x00000004, 0x04000004, 0x00040004, 0x04040004,
+ 0x00000404, 0x04000404, 0x00040404, 0x04040404,
+ },
+ {
+ 0x00000000, 0x01000000, 0x00010000, 0x01010000, 0x00000100, 0x01000100,
+ 0x00010100, 0x01010100, 0x00000001, 0x01000001, 0x00010001, 0x01010001,
+ 0x00000101, 0x01000101, 0x00010101, 0x01010101, 0x00000000, 0x01000000,
+ 0x00010000, 0x01010000, 0x00000100, 0x01000100, 0x00010100, 0x01010100,
+ 0x00000001, 0x01000001, 0x00010001, 0x01010001, 0x00000101, 0x01000101,
+ 0x00010101, 0x01010101, 0x00000000, 0x01000000, 0x00010000, 0x01010000,
+ 0x00000100, 0x01000100, 0x00010100, 0x01010100, 0x00000001, 0x01000001,
+ 0x00010001, 0x01010001, 0x00000101, 0x01000101, 0x00010101, 0x01010101,
+ 0x00000000, 0x01000000, 0x00010000, 0x01010000, 0x00000100, 0x01000100,
+ 0x00010100, 0x01010100, 0x00000001, 0x01000001, 0x00010001, 0x01010001,
+ 0x00000101, 0x01000101, 0x00010101, 0x01010101, 0x00000000, 0x01000000,
+ 0x00010000, 0x01010000, 0x00000100, 0x01000100, 0x00010100, 0x01010100,
+ 0x00000001, 0x01000001, 0x00010001, 0x01010001, 0x00000101, 0x01000101,
+ 0x00010101, 0x01010101, 0x00000000, 0x01000000, 0x00010000, 0x01010000,
+ 0x00000100, 0x01000100, 0x00010100, 0x01010100, 0x00000001, 0x01000001,
+ 0x00010001, 0x01010001, 0x00000101, 0x01000101, 0x00010101, 0x01010101,
+ 0x00000000, 0x01000000, 0x00010000, 0x01010000, 0x00000100, 0x01000100,
+ 0x00010100, 0x01010100, 0x00000001, 0x01000001, 0x00010001, 0x01010001,
+ 0x00000101, 0x01000101, 0x00010101, 0x01010101, 0x00000000, 0x01000000,
+ 0x00010000, 0x01010000, 0x00000100, 0x01000100, 0x00010100, 0x01010100,
+ 0x00000001, 0x01000001, 0x00010001, 0x01010001, 0x00000101, 0x01000101,
+ 0x00010101, 0x01010101, 0x00000000, 0x01000000, 0x00010000, 0x01010000,
+ 0x00000100, 0x01000100, 0x00010100, 0x01010100, 0x00000001, 0x01000001,
+ 0x00010001, 0x01010001, 0x00000101, 0x01000101, 0x00010101, 0x01010101,
+ 0x00000000, 0x01000000, 0x00010000, 0x01010000, 0x00000100, 0x01000100,
+ 0x00010100, 0x01010100, 0x00000001, 0x01000001, 0x00010001, 0x01010001,
+ 0x00000101, 0x01000101, 0x00010101, 0x01010101, 0x00000000, 0x01000000,
+ 0x00010000, 0x01010000, 0x00000100, 0x01000100, 0x00010100, 0x01010100,
+ 0x00000001, 0x01000001, 0x00010001, 0x01010001, 0x00000101, 0x01000101,
+ 0x00010101, 0x01010101, 0x00000000, 0x01000000, 0x00010000, 0x01010000,
+ 0x00000100, 0x01000100, 0x00010100, 0x01010100, 0x00000001, 0x01000001,
+ 0x00010001, 0x01010001, 0x00000101, 0x01000101, 0x00010101, 0x01010101,
+ 0x00000000, 0x01000000, 0x00010000, 0x01010000, 0x00000100, 0x01000100,
+ 0x00010100, 0x01010100, 0x00000001, 0x01000001, 0x00010001, 0x01010001,
+ 0x00000101, 0x01000101, 0x00010101, 0x01010101, 0x00000000, 0x01000000,
+ 0x00010000, 0x01010000, 0x00000100, 0x01000100, 0x00010100, 0x01010100,
+ 0x00000001, 0x01000001, 0x00010001, 0x01010001, 0x00000101, 0x01000101,
+ 0x00010101, 0x01010101, 0x00000000, 0x01000000, 0x00010000, 0x01010000,
+ 0x00000100, 0x01000100, 0x00010100, 0x01010100, 0x00000001, 0x01000001,
+ 0x00010001, 0x01010001, 0x00000101, 0x01000101, 0x00010101, 0x01010101,
+ 0x00000000, 0x01000000, 0x00010000, 0x01010000, 0x00000100, 0x01000100,
+ 0x00010100, 0x01010100, 0x00000001, 0x01000001, 0x00010001, 0x01010001,
+ 0x00000101, 0x01000101, 0x00010101, 0x01010101,
+ },
+ {
+ 0x00000000, 0x80000000, 0x00800000, 0x80800000, 0x00008000, 0x80008000,
+ 0x00808000, 0x80808000, 0x00000080, 0x80000080, 0x00800080, 0x80800080,
+ 0x00008080, 0x80008080, 0x00808080, 0x80808080, 0x00000000, 0x80000000,
+ 0x00800000, 0x80800000, 0x00008000, 0x80008000, 0x00808000, 0x80808000,
+ 0x00000080, 0x80000080, 0x00800080, 0x80800080, 0x00008080, 0x80008080,
+ 0x00808080, 0x80808080, 0x00000000, 0x80000000, 0x00800000, 0x80800000,
+ 0x00008000, 0x80008000, 0x00808000, 0x80808000, 0x00000080, 0x80000080,
+ 0x00800080, 0x80800080, 0x00008080, 0x80008080, 0x00808080, 0x80808080,
+ 0x00000000, 0x80000000, 0x00800000, 0x80800000, 0x00008000, 0x80008000,
+ 0x00808000, 0x80808000, 0x00000080, 0x80000080, 0x00800080, 0x80800080,
+ 0x00008080, 0x80008080, 0x00808080, 0x80808080, 0x00000000, 0x80000000,
+ 0x00800000, 0x80800000, 0x00008000, 0x80008000, 0x00808000, 0x80808000,
+ 0x00000080, 0x80000080, 0x00800080, 0x80800080, 0x00008080, 0x80008080,
+ 0x00808080, 0x80808080, 0x00000000, 0x80000000, 0x00800000, 0x80800000,
+ 0x00008000, 0x80008000, 0x00808000, 0x80808000, 0x00000080, 0x80000080,
+ 0x00800080, 0x80800080, 0x00008080, 0x80008080, 0x00808080, 0x80808080,
+ 0x00000000, 0x80000000, 0x00800000, 0x80800000, 0x00008000, 0x80008000,
+ 0x00808000, 0x80808000, 0x00000080, 0x80000080, 0x00800080, 0x80800080,
+ 0x00008080, 0x80008080, 0x00808080, 0x80808080, 0x00000000, 0x80000000,
+ 0x00800000, 0x80800000, 0x00008000, 0x80008000, 0x00808000, 0x80808000,
+ 0x00000080, 0x80000080, 0x00800080, 0x80800080, 0x00008080, 0x80008080,
+ 0x00808080, 0x80808080, 0x00000000, 0x80000000, 0x00800000, 0x80800000,
+ 0x00008000, 0x80008000, 0x00808000, 0x80808000, 0x00000080, 0x80000080,
+ 0x00800080, 0x80800080, 0x00008080, 0x80008080, 0x00808080, 0x80808080,
+ 0x00000000, 0x80000000, 0x00800000, 0x80800000, 0x00008000, 0x80008000,
+ 0x00808000, 0x80808000, 0x00000080, 0x80000080, 0x00800080, 0x80800080,
+ 0x00008080, 0x80008080, 0x00808080, 0x80808080, 0x00000000, 0x80000000,
+ 0x00800000, 0x80800000, 0x00008000, 0x80008000, 0x00808000, 0x80808000,
+ 0x00000080, 0x80000080, 0x00800080, 0x80800080, 0x00008080, 0x80008080,
+ 0x00808080, 0x80808080, 0x00000000, 0x80000000, 0x00800000, 0x80800000,
+ 0x00008000, 0x80008000, 0x00808000, 0x80808000, 0x00000080, 0x80000080,
+ 0x00800080, 0x80800080, 0x00008080, 0x80008080, 0x00808080, 0x80808080,
+ 0x00000000, 0x80000000, 0x00800000, 0x80800000, 0x00008000, 0x80008000,
+ 0x00808000, 0x80808000, 0x00000080, 0x80000080, 0x00800080, 0x80800080,
+ 0x00008080, 0x80008080, 0x00808080, 0x80808080, 0x00000000, 0x80000000,
+ 0x00800000, 0x80800000, 0x00008000, 0x80008000, 0x00808000, 0x80808000,
+ 0x00000080, 0x80000080, 0x00800080, 0x80800080, 0x00008080, 0x80008080,
+ 0x00808080, 0x80808080, 0x00000000, 0x80000000, 0x00800000, 0x80800000,
+ 0x00008000, 0x80008000, 0x00808000, 0x80808000, 0x00000080, 0x80000080,
+ 0x00800080, 0x80800080, 0x00008080, 0x80008080, 0x00808080, 0x80808080,
+ 0x00000000, 0x80000000, 0x00800000, 0x80800000, 0x00008000, 0x80008000,
+ 0x00808000, 0x80808000, 0x00000080, 0x80000080, 0x00800080, 0x80800080,
+ 0x00008080, 0x80008080, 0x00808080, 0x80808080,
+ },
+ {
+ 0x00000000, 0x20000000, 0x00200000, 0x20200000, 0x00002000, 0x20002000,
+ 0x00202000, 0x20202000, 0x00000020, 0x20000020, 0x00200020, 0x20200020,
+ 0x00002020, 0x20002020, 0x00202020, 0x20202020, 0x00000000, 0x20000000,
+ 0x00200000, 0x20200000, 0x00002000, 0x20002000, 0x00202000, 0x20202000,
+ 0x00000020, 0x20000020, 0x00200020, 0x20200020, 0x00002020, 0x20002020,
+ 0x00202020, 0x20202020, 0x00000000, 0x20000000, 0x00200000, 0x20200000,
+ 0x00002000, 0x20002000, 0x00202000, 0x20202000, 0x00000020, 0x20000020,
+ 0x00200020, 0x20200020, 0x00002020, 0x20002020, 0x00202020, 0x20202020,
+ 0x00000000, 0x20000000, 0x00200000, 0x20200000, 0x00002000, 0x20002000,
+ 0x00202000, 0x20202000, 0x00000020, 0x20000020, 0x00200020, 0x20200020,
+ 0x00002020, 0x20002020, 0x00202020, 0x20202020, 0x00000000, 0x20000000,
+ 0x00200000, 0x20200000, 0x00002000, 0x20002000, 0x00202000, 0x20202000,
+ 0x00000020, 0x20000020, 0x00200020, 0x20200020, 0x00002020, 0x20002020,
+ 0x00202020, 0x20202020, 0x00000000, 0x20000000, 0x00200000, 0x20200000,
+ 0x00002000, 0x20002000, 0x00202000, 0x20202000, 0x00000020, 0x20000020,
+ 0x00200020, 0x20200020, 0x00002020, 0x20002020, 0x00202020, 0x20202020,
+ 0x00000000, 0x20000000, 0x00200000, 0x20200000, 0x00002000, 0x20002000,
+ 0x00202000, 0x20202000, 0x00000020, 0x20000020, 0x00200020, 0x20200020,
+ 0x00002020, 0x20002020, 0x00202020, 0x20202020, 0x00000000, 0x20000000,
+ 0x00200000, 0x20200000, 0x00002000, 0x20002000, 0x00202000, 0x20202000,
+ 0x00000020, 0x20000020, 0x00200020, 0x20200020, 0x00002020, 0x20002020,
+ 0x00202020, 0x20202020, 0x00000000, 0x20000000, 0x00200000, 0x20200000,
+ 0x00002000, 0x20002000, 0x00202000, 0x20202000, 0x00000020, 0x20000020,
+ 0x00200020, 0x20200020, 0x00002020, 0x20002020, 0x00202020, 0x20202020,
+ 0x00000000, 0x20000000, 0x00200000, 0x20200000, 0x00002000, 0x20002000,
+ 0x00202000, 0x20202000, 0x00000020, 0x20000020, 0x00200020, 0x20200020,
+ 0x00002020, 0x20002020, 0x00202020, 0x20202020, 0x00000000, 0x20000000,
+ 0x00200000, 0x20200000, 0x00002000, 0x20002000, 0x00202000, 0x20202000,
+ 0x00000020, 0x20000020, 0x00200020, 0x20200020, 0x00002020, 0x20002020,
+ 0x00202020, 0x20202020, 0x00000000, 0x20000000, 0x00200000, 0x20200000,
+ 0x00002000, 0x20002000, 0x00202000, 0x20202000, 0x00000020, 0x20000020,
+ 0x00200020, 0x20200020, 0x00002020, 0x20002020, 0x00202020, 0x20202020,
+ 0x00000000, 0x20000000, 0x00200000, 0x20200000, 0x00002000, 0x20002000,
+ 0x00202000, 0x20202000, 0x00000020, 0x20000020, 0x00200020, 0x20200020,
+ 0x00002020, 0x20002020, 0x00202020, 0x20202020, 0x00000000, 0x20000000,
+ 0x00200000, 0x20200000, 0x00002000, 0x20002000, 0x00202000, 0x20202000,
+ 0x00000020, 0x20000020, 0x00200020, 0x20200020, 0x00002020, 0x20002020,
+ 0x00202020, 0x20202020, 0x00000000, 0x20000000, 0x00200000, 0x20200000,
+ 0x00002000, 0x20002000, 0x00202000, 0x20202000, 0x00000020, 0x20000020,
+ 0x00200020, 0x20200020, 0x00002020, 0x20002020, 0x00202020, 0x20202020,
+ 0x00000000, 0x20000000, 0x00200000, 0x20200000, 0x00002000, 0x20002000,
+ 0x00202000, 0x20202000, 0x00000020, 0x20000020, 0x00200020, 0x20200020,
+ 0x00002020, 0x20002020, 0x00202020, 0x20202020,
+ },
+ {
+ 0x00000000, 0x08000000, 0x00080000, 0x08080000, 0x00000800, 0x08000800,
+ 0x00080800, 0x08080800, 0x00000008, 0x08000008, 0x00080008, 0x08080008,
+ 0x00000808, 0x08000808, 0x00080808, 0x08080808, 0x00000000, 0x08000000,
+ 0x00080000, 0x08080000, 0x00000800, 0x08000800, 0x00080800, 0x08080800,
+ 0x00000008, 0x08000008, 0x00080008, 0x08080008, 0x00000808, 0x08000808,
+ 0x00080808, 0x08080808, 0x00000000, 0x08000000, 0x00080000, 0x08080000,
+ 0x00000800, 0x08000800, 0x00080800, 0x08080800, 0x00000008, 0x08000008,
+ 0x00080008, 0x08080008, 0x00000808, 0x08000808, 0x00080808, 0x08080808,
+ 0x00000000, 0x08000000, 0x00080000, 0x08080000, 0x00000800, 0x08000800,
+ 0x00080800, 0x08080800, 0x00000008, 0x08000008, 0x00080008, 0x08080008,
+ 0x00000808, 0x08000808, 0x00080808, 0x08080808, 0x00000000, 0x08000000,
+ 0x00080000, 0x08080000, 0x00000800, 0x08000800, 0x00080800, 0x08080800,
+ 0x00000008, 0x08000008, 0x00080008, 0x08080008, 0x00000808, 0x08000808,
+ 0x00080808, 0x08080808, 0x00000000, 0x08000000, 0x00080000, 0x08080000,
+ 0x00000800, 0x08000800, 0x00080800, 0x08080800, 0x00000008, 0x08000008,
+ 0x00080008, 0x08080008, 0x00000808, 0x08000808, 0x00080808, 0x08080808,
+ 0x00000000, 0x08000000, 0x00080000, 0x08080000, 0x00000800, 0x08000800,
+ 0x00080800, 0x08080800, 0x00000008, 0x08000008, 0x00080008, 0x08080008,
+ 0x00000808, 0x08000808, 0x00080808, 0x08080808, 0x00000000, 0x08000000,
+ 0x00080000, 0x08080000, 0x00000800, 0x08000800, 0x00080800, 0x08080800,
+ 0x00000008, 0x08000008, 0x00080008, 0x08080008, 0x00000808, 0x08000808,
+ 0x00080808, 0x08080808, 0x00000000, 0x08000000, 0x00080000, 0x08080000,
+ 0x00000800, 0x08000800, 0x00080800, 0x08080800, 0x00000008, 0x08000008,
+ 0x00080008, 0x08080008, 0x00000808, 0x08000808, 0x00080808, 0x08080808,
+ 0x00000000, 0x08000000, 0x00080000, 0x08080000, 0x00000800, 0x08000800,
+ 0x00080800, 0x08080800, 0x00000008, 0x08000008, 0x00080008, 0x08080008,
+ 0x00000808, 0x08000808, 0x00080808, 0x08080808, 0x00000000, 0x08000000,
+ 0x00080000, 0x08080000, 0x00000800, 0x08000800, 0x00080800, 0x08080800,
+ 0x00000008, 0x08000008, 0x00080008, 0x08080008, 0x00000808, 0x08000808,
+ 0x00080808, 0x08080808, 0x00000000, 0x08000000, 0x00080000, 0x08080000,
+ 0x00000800, 0x08000800, 0x00080800, 0x08080800, 0x00000008, 0x08000008,
+ 0x00080008, 0x08080008, 0x00000808, 0x08000808, 0x00080808, 0x08080808,
+ 0x00000000, 0x08000000, 0x00080000, 0x08080000, 0x00000800, 0x08000800,
+ 0x00080800, 0x08080800, 0x00000008, 0x08000008, 0x00080008, 0x08080008,
+ 0x00000808, 0x08000808, 0x00080808, 0x08080808, 0x00000000, 0x08000000,
+ 0x00080000, 0x08080000, 0x00000800, 0x08000800, 0x00080800, 0x08080800,
+ 0x00000008, 0x08000008, 0x00080008, 0x08080008, 0x00000808, 0x08000808,
+ 0x00080808, 0x08080808, 0x00000000, 0x08000000, 0x00080000, 0x08080000,
+ 0x00000800, 0x08000800, 0x00080800, 0x08080800, 0x00000008, 0x08000008,
+ 0x00080008, 0x08080008, 0x00000808, 0x08000808, 0x00080808, 0x08080808,
+ 0x00000000, 0x08000000, 0x00080000, 0x08080000, 0x00000800, 0x08000800,
+ 0x00080800, 0x08080800, 0x00000008, 0x08000008, 0x00080008, 0x08080008,
+ 0x00000808, 0x08000808, 0x00080808, 0x08080808,
+ },
+ {
+ 0x00000000, 0x02000000, 0x00020000, 0x02020000, 0x00000200, 0x02000200,
+ 0x00020200, 0x02020200, 0x00000002, 0x02000002, 0x00020002, 0x02020002,
+ 0x00000202, 0x02000202, 0x00020202, 0x02020202, 0x00000000, 0x02000000,
+ 0x00020000, 0x02020000, 0x00000200, 0x02000200, 0x00020200, 0x02020200,
+ 0x00000002, 0x02000002, 0x00020002, 0x02020002, 0x00000202, 0x02000202,
+ 0x00020202, 0x02020202, 0x00000000, 0x02000000, 0x00020000, 0x02020000,
+ 0x00000200, 0x02000200, 0x00020200, 0x02020200, 0x00000002, 0x02000002,
+ 0x00020002, 0x02020002, 0x00000202, 0x02000202, 0x00020202, 0x02020202,
+ 0x00000000, 0x02000000, 0x00020000, 0x02020000, 0x00000200, 0x02000200,
+ 0x00020200, 0x02020200, 0x00000002, 0x02000002, 0x00020002, 0x02020002,
+ 0x00000202, 0x02000202, 0x00020202, 0x02020202, 0x00000000, 0x02000000,
+ 0x00020000, 0x02020000, 0x00000200, 0x02000200, 0x00020200, 0x02020200,
+ 0x00000002, 0x02000002, 0x00020002, 0x02020002, 0x00000202, 0x02000202,
+ 0x00020202, 0x02020202, 0x00000000, 0x02000000, 0x00020000, 0x02020000,
+ 0x00000200, 0x02000200, 0x00020200, 0x02020200, 0x00000002, 0x02000002,
+ 0x00020002, 0x02020002, 0x00000202, 0x02000202, 0x00020202, 0x02020202,
+ 0x00000000, 0x02000000, 0x00020000, 0x02020000, 0x00000200, 0x02000200,
+ 0x00020200, 0x02020200, 0x00000002, 0x02000002, 0x00020002, 0x02020002,
+ 0x00000202, 0x02000202, 0x00020202, 0x02020202, 0x00000000, 0x02000000,
+ 0x00020000, 0x02020000, 0x00000200, 0x02000200, 0x00020200, 0x02020200,
+ 0x00000002, 0x02000002, 0x00020002, 0x02020002, 0x00000202, 0x02000202,
+ 0x00020202, 0x02020202, 0x00000000, 0x02000000, 0x00020000, 0x02020000,
+ 0x00000200, 0x02000200, 0x00020200, 0x02020200, 0x00000002, 0x02000002,
+ 0x00020002, 0x02020002, 0x00000202, 0x02000202, 0x00020202, 0x02020202,
+ 0x00000000, 0x02000000, 0x00020000, 0x02020000, 0x00000200, 0x02000200,
+ 0x00020200, 0x02020200, 0x00000002, 0x02000002, 0x00020002, 0x02020002,
+ 0x00000202, 0x02000202, 0x00020202, 0x02020202, 0x00000000, 0x02000000,
+ 0x00020000, 0x02020000, 0x00000200, 0x02000200, 0x00020200, 0x02020200,
+ 0x00000002, 0x02000002, 0x00020002, 0x02020002, 0x00000202, 0x02000202,
+ 0x00020202, 0x02020202, 0x00000000, 0x02000000, 0x00020000, 0x02020000,
+ 0x00000200, 0x02000200, 0x00020200, 0x02020200, 0x00000002, 0x02000002,
+ 0x00020002, 0x02020002, 0x00000202, 0x02000202, 0x00020202, 0x02020202,
+ 0x00000000, 0x02000000, 0x00020000, 0x02020000, 0x00000200, 0x02000200,
+ 0x00020200, 0x02020200, 0x00000002, 0x02000002, 0x00020002, 0x02020002,
+ 0x00000202, 0x02000202, 0x00020202, 0x02020202, 0x00000000, 0x02000000,
+ 0x00020000, 0x02020000, 0x00000200, 0x02000200, 0x00020200, 0x02020200,
+ 0x00000002, 0x02000002, 0x00020002, 0x02020002, 0x00000202, 0x02000202,
+ 0x00020202, 0x02020202, 0x00000000, 0x02000000, 0x00020000, 0x02020000,
+ 0x00000200, 0x02000200, 0x00020200, 0x02020200, 0x00000002, 0x02000002,
+ 0x00020002, 0x02020002, 0x00000202, 0x02000202, 0x00020202, 0x02020202,
+ 0x00000000, 0x02000000, 0x00020000, 0x02020000, 0x00000200, 0x02000200,
+ 0x00020200, 0x02020200, 0x00000002, 0x02000002, 0x00020002, 0x02020002,
+ 0x00000202, 0x02000202, 0x00020202, 0x02020202,
+ },
+};
+
+const uint32_t fp_maskr[8][256] = {
+ {
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x40000000, 0x40000000,
+ 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
+ 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
+ 0x40000000, 0x40000000, 0x00400000, 0x00400000, 0x00400000, 0x00400000,
+ 0x00400000, 0x00400000, 0x00400000, 0x00400000, 0x00400000, 0x00400000,
+ 0x00400000, 0x00400000, 0x00400000, 0x00400000, 0x00400000, 0x00400000,
+ 0x40400000, 0x40400000, 0x40400000, 0x40400000, 0x40400000, 0x40400000,
+ 0x40400000, 0x40400000, 0x40400000, 0x40400000, 0x40400000, 0x40400000,
+ 0x40400000, 0x40400000, 0x40400000, 0x40400000, 0x00004000, 0x00004000,
+ 0x00004000, 0x00004000, 0x00004000, 0x00004000, 0x00004000, 0x00004000,
+ 0x00004000, 0x00004000, 0x00004000, 0x00004000, 0x00004000, 0x00004000,
+ 0x00004000, 0x00004000, 0x40004000, 0x40004000, 0x40004000, 0x40004000,
+ 0x40004000, 0x40004000, 0x40004000, 0x40004000, 0x40004000, 0x40004000,
+ 0x40004000, 0x40004000, 0x40004000, 0x40004000, 0x40004000, 0x40004000,
+ 0x00404000, 0x00404000, 0x00404000, 0x00404000, 0x00404000, 0x00404000,
+ 0x00404000, 0x00404000, 0x00404000, 0x00404000, 0x00404000, 0x00404000,
+ 0x00404000, 0x00404000, 0x00404000, 0x00404000, 0x40404000, 0x40404000,
+ 0x40404000, 0x40404000, 0x40404000, 0x40404000, 0x40404000, 0x40404000,
+ 0x40404000, 0x40404000, 0x40404000, 0x40404000, 0x40404000, 0x40404000,
+ 0x40404000, 0x40404000, 0x00000040, 0x00000040, 0x00000040, 0x00000040,
+ 0x00000040, 0x00000040, 0x00000040, 0x00000040, 0x00000040, 0x00000040,
+ 0x00000040, 0x00000040, 0x00000040, 0x00000040, 0x00000040, 0x00000040,
+ 0x40000040, 0x40000040, 0x40000040, 0x40000040, 0x40000040, 0x40000040,
+ 0x40000040, 0x40000040, 0x40000040, 0x40000040, 0x40000040, 0x40000040,
+ 0x40000040, 0x40000040, 0x40000040, 0x40000040, 0x00400040, 0x00400040,
+ 0x00400040, 0x00400040, 0x00400040, 0x00400040, 0x00400040, 0x00400040,
+ 0x00400040, 0x00400040, 0x00400040, 0x00400040, 0x00400040, 0x00400040,
+ 0x00400040, 0x00400040, 0x40400040, 0x40400040, 0x40400040, 0x40400040,
+ 0x40400040, 0x40400040, 0x40400040, 0x40400040, 0x40400040, 0x40400040,
+ 0x40400040, 0x40400040, 0x40400040, 0x40400040, 0x40400040, 0x40400040,
+ 0x00004040, 0x00004040, 0x00004040, 0x00004040, 0x00004040, 0x00004040,
+ 0x00004040, 0x00004040, 0x00004040, 0x00004040, 0x00004040, 0x00004040,
+ 0x00004040, 0x00004040, 0x00004040, 0x00004040, 0x40004040, 0x40004040,
+ 0x40004040, 0x40004040, 0x40004040, 0x40004040, 0x40004040, 0x40004040,
+ 0x40004040, 0x40004040, 0x40004040, 0x40004040, 0x40004040, 0x40004040,
+ 0x40004040, 0x40004040, 0x00404040, 0x00404040, 0x00404040, 0x00404040,
+ 0x00404040, 0x00404040, 0x00404040, 0x00404040, 0x00404040, 0x00404040,
+ 0x00404040, 0x00404040, 0x00404040, 0x00404040, 0x00404040, 0x00404040,
+ 0x40404040, 0x40404040, 0x40404040, 0x40404040, 0x40404040, 0x40404040,
+ 0x40404040, 0x40404040, 0x40404040, 0x40404040, 0x40404040, 0x40404040,
+ 0x40404040, 0x40404040, 0x40404040, 0x40404040,
+ },
+ {
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x10000000, 0x10000000,
+ 0x10000000, 0x10000000, 0x10000000, 0x10000000, 0x10000000, 0x10000000,
+ 0x10000000, 0x10000000, 0x10000000, 0x10000000, 0x10000000, 0x10000000,
+ 0x10000000, 0x10000000, 0x00100000, 0x00100000, 0x00100000, 0x00100000,
+ 0x00100000, 0x00100000, 0x00100000, 0x00100000, 0x00100000, 0x00100000,
+ 0x00100000, 0x00100000, 0x00100000, 0x00100000, 0x00100000, 0x00100000,
+ 0x10100000, 0x10100000, 0x10100000, 0x10100000, 0x10100000, 0x10100000,
+ 0x10100000, 0x10100000, 0x10100000, 0x10100000, 0x10100000, 0x10100000,
+ 0x10100000, 0x10100000, 0x10100000, 0x10100000, 0x00001000, 0x00001000,
+ 0x00001000, 0x00001000, 0x00001000, 0x00001000, 0x00001000, 0x00001000,
+ 0x00001000, 0x00001000, 0x00001000, 0x00001000, 0x00001000, 0x00001000,
+ 0x00001000, 0x00001000, 0x10001000, 0x10001000, 0x10001000, 0x10001000,
+ 0x10001000, 0x10001000, 0x10001000, 0x10001000, 0x10001000, 0x10001000,
+ 0x10001000, 0x10001000, 0x10001000, 0x10001000, 0x10001000, 0x10001000,
+ 0x00101000, 0x00101000, 0x00101000, 0x00101000, 0x00101000, 0x00101000,
+ 0x00101000, 0x00101000, 0x00101000, 0x00101000, 0x00101000, 0x00101000,
+ 0x00101000, 0x00101000, 0x00101000, 0x00101000, 0x10101000, 0x10101000,
+ 0x10101000, 0x10101000, 0x10101000, 0x10101000, 0x10101000, 0x10101000,
+ 0x10101000, 0x10101000, 0x10101000, 0x10101000, 0x10101000, 0x10101000,
+ 0x10101000, 0x10101000, 0x00000010, 0x00000010, 0x00000010, 0x00000010,
+ 0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000010,
+ 0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000010,
+ 0x10000010, 0x10000010, 0x10000010, 0x10000010, 0x10000010, 0x10000010,
+ 0x10000010, 0x10000010, 0x10000010, 0x10000010, 0x10000010, 0x10000010,
+ 0x10000010, 0x10000010, 0x10000010, 0x10000010, 0x00100010, 0x00100010,
+ 0x00100010, 0x00100010, 0x00100010, 0x00100010, 0x00100010, 0x00100010,
+ 0x00100010, 0x00100010, 0x00100010, 0x00100010, 0x00100010, 0x00100010,
+ 0x00100010, 0x00100010, 0x10100010, 0x10100010, 0x10100010, 0x10100010,
+ 0x10100010, 0x10100010, 0x10100010, 0x10100010, 0x10100010, 0x10100010,
+ 0x10100010, 0x10100010, 0x10100010, 0x10100010, 0x10100010, 0x10100010,
+ 0x00001010, 0x00001010, 0x00001010, 0x00001010, 0x00001010, 0x00001010,
+ 0x00001010, 0x00001010, 0x00001010, 0x00001010, 0x00001010, 0x00001010,
+ 0x00001010, 0x00001010, 0x00001010, 0x00001010, 0x10001010, 0x10001010,
+ 0x10001010, 0x10001010, 0x10001010, 0x10001010, 0x10001010, 0x10001010,
+ 0x10001010, 0x10001010, 0x10001010, 0x10001010, 0x10001010, 0x10001010,
+ 0x10001010, 0x10001010, 0x00101010, 0x00101010, 0x00101010, 0x00101010,
+ 0x00101010, 0x00101010, 0x00101010, 0x00101010, 0x00101010, 0x00101010,
+ 0x00101010, 0x00101010, 0x00101010, 0x00101010, 0x00101010, 0x00101010,
+ 0x10101010, 0x10101010, 0x10101010, 0x10101010, 0x10101010, 0x10101010,
+ 0x10101010, 0x10101010, 0x10101010, 0x10101010, 0x10101010, 0x10101010,
+ 0x10101010, 0x10101010, 0x10101010, 0x10101010,
+ },
+ {
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x04000000, 0x04000000,
+ 0x04000000, 0x04000000, 0x04000000, 0x04000000, 0x04000000, 0x04000000,
+ 0x04000000, 0x04000000, 0x04000000, 0x04000000, 0x04000000, 0x04000000,
+ 0x04000000, 0x04000000, 0x00040000, 0x00040000, 0x00040000, 0x00040000,
+ 0x00040000, 0x00040000, 0x00040000, 0x00040000, 0x00040000, 0x00040000,
+ 0x00040000, 0x00040000, 0x00040000, 0x00040000, 0x00040000, 0x00040000,
+ 0x04040000, 0x04040000, 0x04040000, 0x04040000, 0x04040000, 0x04040000,
+ 0x04040000, 0x04040000, 0x04040000, 0x04040000, 0x04040000, 0x04040000,
+ 0x04040000, 0x04040000, 0x04040000, 0x04040000, 0x00000400, 0x00000400,
+ 0x00000400, 0x00000400, 0x00000400, 0x00000400, 0x00000400, 0x00000400,
+ 0x00000400, 0x00000400, 0x00000400, 0x00000400, 0x00000400, 0x00000400,
+ 0x00000400, 0x00000400, 0x04000400, 0x04000400, 0x04000400, 0x04000400,
+ 0x04000400, 0x04000400, 0x04000400, 0x04000400, 0x04000400, 0x04000400,
+ 0x04000400, 0x04000400, 0x04000400, 0x04000400, 0x04000400, 0x04000400,
+ 0x00040400, 0x00040400, 0x00040400, 0x00040400, 0x00040400, 0x00040400,
+ 0x00040400, 0x00040400, 0x00040400, 0x00040400, 0x00040400, 0x00040400,
+ 0x00040400, 0x00040400, 0x00040400, 0x00040400, 0x04040400, 0x04040400,
+ 0x04040400, 0x04040400, 0x04040400, 0x04040400, 0x04040400, 0x04040400,
+ 0x04040400, 0x04040400, 0x04040400, 0x04040400, 0x04040400, 0x04040400,
+ 0x04040400, 0x04040400, 0x00000004, 0x00000004, 0x00000004, 0x00000004,
+ 0x00000004, 0x00000004, 0x00000004, 0x00000004, 0x00000004, 0x00000004,
+ 0x00000004, 0x00000004, 0x00000004, 0x00000004, 0x00000004, 0x00000004,
+ 0x04000004, 0x04000004, 0x04000004, 0x04000004, 0x04000004, 0x04000004,
+ 0x04000004, 0x04000004, 0x04000004, 0x04000004, 0x04000004, 0x04000004,
+ 0x04000004, 0x04000004, 0x04000004, 0x04000004, 0x00040004, 0x00040004,
+ 0x00040004, 0x00040004, 0x00040004, 0x00040004, 0x00040004, 0x00040004,
+ 0x00040004, 0x00040004, 0x00040004, 0x00040004, 0x00040004, 0x00040004,
+ 0x00040004, 0x00040004, 0x04040004, 0x04040004, 0x04040004, 0x04040004,
+ 0x04040004, 0x04040004, 0x04040004, 0x04040004, 0x04040004, 0x04040004,
+ 0x04040004, 0x04040004, 0x04040004, 0x04040004, 0x04040004, 0x04040004,
+ 0x00000404, 0x00000404, 0x00000404, 0x00000404, 0x00000404, 0x00000404,
+ 0x00000404, 0x00000404, 0x00000404, 0x00000404, 0x00000404, 0x00000404,
+ 0x00000404, 0x00000404, 0x00000404, 0x00000404, 0x04000404, 0x04000404,
+ 0x04000404, 0x04000404, 0x04000404, 0x04000404, 0x04000404, 0x04000404,
+ 0x04000404, 0x04000404, 0x04000404, 0x04000404, 0x04000404, 0x04000404,
+ 0x04000404, 0x04000404, 0x00040404, 0x00040404, 0x00040404, 0x00040404,
+ 0x00040404, 0x00040404, 0x00040404, 0x00040404, 0x00040404, 0x00040404,
+ 0x00040404, 0x00040404, 0x00040404, 0x00040404, 0x00040404, 0x00040404,
+ 0x04040404, 0x04040404, 0x04040404, 0x04040404, 0x04040404, 0x04040404,
+ 0x04040404, 0x04040404, 0x04040404, 0x04040404, 0x04040404, 0x04040404,
+ 0x04040404, 0x04040404, 0x04040404, 0x04040404,
+ },
+ {
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x01000000, 0x01000000,
+ 0x01000000, 0x01000000, 0x01000000, 0x01000000, 0x01000000, 0x01000000,
+ 0x01000000, 0x01000000, 0x01000000, 0x01000000, 0x01000000, 0x01000000,
+ 0x01000000, 0x01000000, 0x00010000, 0x00010000, 0x00010000, 0x00010000,
+ 0x00010000, 0x00010000, 0x00010000, 0x00010000, 0x00010000, 0x00010000,
+ 0x00010000, 0x00010000, 0x00010000, 0x00010000, 0x00010000, 0x00010000,
+ 0x01010000, 0x01010000, 0x01010000, 0x01010000, 0x01010000, 0x01010000,
+ 0x01010000, 0x01010000, 0x01010000, 0x01010000, 0x01010000, 0x01010000,
+ 0x01010000, 0x01010000, 0x01010000, 0x01010000, 0x00000100, 0x00000100,
+ 0x00000100, 0x00000100, 0x00000100, 0x00000100, 0x00000100, 0x00000100,
+ 0x00000100, 0x00000100, 0x00000100, 0x00000100, 0x00000100, 0x00000100,
+ 0x00000100, 0x00000100, 0x01000100, 0x01000100, 0x01000100, 0x01000100,
+ 0x01000100, 0x01000100, 0x01000100, 0x01000100, 0x01000100, 0x01000100,
+ 0x01000100, 0x01000100, 0x01000100, 0x01000100, 0x01000100, 0x01000100,
+ 0x00010100, 0x00010100, 0x00010100, 0x00010100, 0x00010100, 0x00010100,
+ 0x00010100, 0x00010100, 0x00010100, 0x00010100, 0x00010100, 0x00010100,
+ 0x00010100, 0x00010100, 0x00010100, 0x00010100, 0x01010100, 0x01010100,
+ 0x01010100, 0x01010100, 0x01010100, 0x01010100, 0x01010100, 0x01010100,
+ 0x01010100, 0x01010100, 0x01010100, 0x01010100, 0x01010100, 0x01010100,
+ 0x01010100, 0x01010100, 0x00000001, 0x00000001, 0x00000001, 0x00000001,
+ 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001,
+ 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001,
+ 0x01000001, 0x01000001, 0x01000001, 0x01000001, 0x01000001, 0x01000001,
+ 0x01000001, 0x01000001, 0x01000001, 0x01000001, 0x01000001, 0x01000001,
+ 0x01000001, 0x01000001, 0x01000001, 0x01000001, 0x00010001, 0x00010001,
+ 0x00010001, 0x00010001, 0x00010001, 0x00010001, 0x00010001, 0x00010001,
+ 0x00010001, 0x00010001, 0x00010001, 0x00010001, 0x00010001, 0x00010001,
+ 0x00010001, 0x00010001, 0x01010001, 0x01010001, 0x01010001, 0x01010001,
+ 0x01010001, 0x01010001, 0x01010001, 0x01010001, 0x01010001, 0x01010001,
+ 0x01010001, 0x01010001, 0x01010001, 0x01010001, 0x01010001, 0x01010001,
+ 0x00000101, 0x00000101, 0x00000101, 0x00000101, 0x00000101, 0x00000101,
+ 0x00000101, 0x00000101, 0x00000101, 0x00000101, 0x00000101, 0x00000101,
+ 0x00000101, 0x00000101, 0x00000101, 0x00000101, 0x01000101, 0x01000101,
+ 0x01000101, 0x01000101, 0x01000101, 0x01000101, 0x01000101, 0x01000101,
+ 0x01000101, 0x01000101, 0x01000101, 0x01000101, 0x01000101, 0x01000101,
+ 0x01000101, 0x01000101, 0x00010101, 0x00010101, 0x00010101, 0x00010101,
+ 0x00010101, 0x00010101, 0x00010101, 0x00010101, 0x00010101, 0x00010101,
+ 0x00010101, 0x00010101, 0x00010101, 0x00010101, 0x00010101, 0x00010101,
+ 0x01010101, 0x01010101, 0x01010101, 0x01010101, 0x01010101, 0x01010101,
+ 0x01010101, 0x01010101, 0x01010101, 0x01010101, 0x01010101, 0x01010101,
+ 0x01010101, 0x01010101, 0x01010101, 0x01010101,
+ },
+ {
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x80000000, 0x80000000,
+ 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000,
+ 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000,
+ 0x80000000, 0x80000000, 0x00800000, 0x00800000, 0x00800000, 0x00800000,
+ 0x00800000, 0x00800000, 0x00800000, 0x00800000, 0x00800000, 0x00800000,
+ 0x00800000, 0x00800000, 0x00800000, 0x00800000, 0x00800000, 0x00800000,
+ 0x80800000, 0x80800000, 0x80800000, 0x80800000, 0x80800000, 0x80800000,
+ 0x80800000, 0x80800000, 0x80800000, 0x80800000, 0x80800000, 0x80800000,
+ 0x80800000, 0x80800000, 0x80800000, 0x80800000, 0x00008000, 0x00008000,
+ 0x00008000, 0x00008000, 0x00008000, 0x00008000, 0x00008000, 0x00008000,
+ 0x00008000, 0x00008000, 0x00008000, 0x00008000, 0x00008000, 0x00008000,
+ 0x00008000, 0x00008000, 0x80008000, 0x80008000, 0x80008000, 0x80008000,
+ 0x80008000, 0x80008000, 0x80008000, 0x80008000, 0x80008000, 0x80008000,
+ 0x80008000, 0x80008000, 0x80008000, 0x80008000, 0x80008000, 0x80008000,
+ 0x00808000, 0x00808000, 0x00808000, 0x00808000, 0x00808000, 0x00808000,
+ 0x00808000, 0x00808000, 0x00808000, 0x00808000, 0x00808000, 0x00808000,
+ 0x00808000, 0x00808000, 0x00808000, 0x00808000, 0x80808000, 0x80808000,
+ 0x80808000, 0x80808000, 0x80808000, 0x80808000, 0x80808000, 0x80808000,
+ 0x80808000, 0x80808000, 0x80808000, 0x80808000, 0x80808000, 0x80808000,
+ 0x80808000, 0x80808000, 0x00000080, 0x00000080, 0x00000080, 0x00000080,
+ 0x00000080, 0x00000080, 0x00000080, 0x00000080, 0x00000080, 0x00000080,
+ 0x00000080, 0x00000080, 0x00000080, 0x00000080, 0x00000080, 0x00000080,
+ 0x80000080, 0x80000080, 0x80000080, 0x80000080, 0x80000080, 0x80000080,
+ 0x80000080, 0x80000080, 0x80000080, 0x80000080, 0x80000080, 0x80000080,
+ 0x80000080, 0x80000080, 0x80000080, 0x80000080, 0x00800080, 0x00800080,
+ 0x00800080, 0x00800080, 0x00800080, 0x00800080, 0x00800080, 0x00800080,
+ 0x00800080, 0x00800080, 0x00800080, 0x00800080, 0x00800080, 0x00800080,
+ 0x00800080, 0x00800080, 0x80800080, 0x80800080, 0x80800080, 0x80800080,
+ 0x80800080, 0x80800080, 0x80800080, 0x80800080, 0x80800080, 0x80800080,
+ 0x80800080, 0x80800080, 0x80800080, 0x80800080, 0x80800080, 0x80800080,
+ 0x00008080, 0x00008080, 0x00008080, 0x00008080, 0x00008080, 0x00008080,
+ 0x00008080, 0x00008080, 0x00008080, 0x00008080, 0x00008080, 0x00008080,
+ 0x00008080, 0x00008080, 0x00008080, 0x00008080, 0x80008080, 0x80008080,
+ 0x80008080, 0x80008080, 0x80008080, 0x80008080, 0x80008080, 0x80008080,
+ 0x80008080, 0x80008080, 0x80008080, 0x80008080, 0x80008080, 0x80008080,
+ 0x80008080, 0x80008080, 0x00808080, 0x00808080, 0x00808080, 0x00808080,
+ 0x00808080, 0x00808080, 0x00808080, 0x00808080, 0x00808080, 0x00808080,
+ 0x00808080, 0x00808080, 0x00808080, 0x00808080, 0x00808080, 0x00808080,
+ 0x80808080, 0x80808080, 0x80808080, 0x80808080, 0x80808080, 0x80808080,
+ 0x80808080, 0x80808080, 0x80808080, 0x80808080, 0x80808080, 0x80808080,
+ 0x80808080, 0x80808080, 0x80808080, 0x80808080,
+ },
+ {
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x20000000, 0x20000000,
+ 0x20000000, 0x20000000, 0x20000000, 0x20000000, 0x20000000, 0x20000000,
+ 0x20000000, 0x20000000, 0x20000000, 0x20000000, 0x20000000, 0x20000000,
+ 0x20000000, 0x20000000, 0x00200000, 0x00200000, 0x00200000, 0x00200000,
+ 0x00200000, 0x00200000, 0x00200000, 0x00200000, 0x00200000, 0x00200000,
+ 0x00200000, 0x00200000, 0x00200000, 0x00200000, 0x00200000, 0x00200000,
+ 0x20200000, 0x20200000, 0x20200000, 0x20200000, 0x20200000, 0x20200000,
+ 0x20200000, 0x20200000, 0x20200000, 0x20200000, 0x20200000, 0x20200000,
+ 0x20200000, 0x20200000, 0x20200000, 0x20200000, 0x00002000, 0x00002000,
+ 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000,
+ 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000,
+ 0x00002000, 0x00002000, 0x20002000, 0x20002000, 0x20002000, 0x20002000,
+ 0x20002000, 0x20002000, 0x20002000, 0x20002000, 0x20002000, 0x20002000,
+ 0x20002000, 0x20002000, 0x20002000, 0x20002000, 0x20002000, 0x20002000,
+ 0x00202000, 0x00202000, 0x00202000, 0x00202000, 0x00202000, 0x00202000,
+ 0x00202000, 0x00202000, 0x00202000, 0x00202000, 0x00202000, 0x00202000,
+ 0x00202000, 0x00202000, 0x00202000, 0x00202000, 0x20202000, 0x20202000,
+ 0x20202000, 0x20202000, 0x20202000, 0x20202000, 0x20202000, 0x20202000,
+ 0x20202000, 0x20202000, 0x20202000, 0x20202000, 0x20202000, 0x20202000,
+ 0x20202000, 0x20202000, 0x00000020, 0x00000020, 0x00000020, 0x00000020,
+ 0x00000020, 0x00000020, 0x00000020, 0x00000020, 0x00000020, 0x00000020,
+ 0x00000020, 0x00000020, 0x00000020, 0x00000020, 0x00000020, 0x00000020,
+ 0x20000020, 0x20000020, 0x20000020, 0x20000020, 0x20000020, 0x20000020,
+ 0x20000020, 0x20000020, 0x20000020, 0x20000020, 0x20000020, 0x20000020,
+ 0x20000020, 0x20000020, 0x20000020, 0x20000020, 0x00200020, 0x00200020,
+ 0x00200020, 0x00200020, 0x00200020, 0x00200020, 0x00200020, 0x00200020,
+ 0x00200020, 0x00200020, 0x00200020, 0x00200020, 0x00200020, 0x00200020,
+ 0x00200020, 0x00200020, 0x20200020, 0x20200020, 0x20200020, 0x20200020,
+ 0x20200020, 0x20200020, 0x20200020, 0x20200020, 0x20200020, 0x20200020,
+ 0x20200020, 0x20200020, 0x20200020, 0x20200020, 0x20200020, 0x20200020,
+ 0x00002020, 0x00002020, 0x00002020, 0x00002020, 0x00002020, 0x00002020,
+ 0x00002020, 0x00002020, 0x00002020, 0x00002020, 0x00002020, 0x00002020,
+ 0x00002020, 0x00002020, 0x00002020, 0x00002020, 0x20002020, 0x20002020,
+ 0x20002020, 0x20002020, 0x20002020, 0x20002020, 0x20002020, 0x20002020,
+ 0x20002020, 0x20002020, 0x20002020, 0x20002020, 0x20002020, 0x20002020,
+ 0x20002020, 0x20002020, 0x00202020, 0x00202020, 0x00202020, 0x00202020,
+ 0x00202020, 0x00202020, 0x00202020, 0x00202020, 0x00202020, 0x00202020,
+ 0x00202020, 0x00202020, 0x00202020, 0x00202020, 0x00202020, 0x00202020,
+ 0x20202020, 0x20202020, 0x20202020, 0x20202020, 0x20202020, 0x20202020,
+ 0x20202020, 0x20202020, 0x20202020, 0x20202020, 0x20202020, 0x20202020,
+ 0x20202020, 0x20202020, 0x20202020, 0x20202020,
+ },
+ {
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x08000000, 0x08000000,
+ 0x08000000, 0x08000000, 0x08000000, 0x08000000, 0x08000000, 0x08000000,
+ 0x08000000, 0x08000000, 0x08000000, 0x08000000, 0x08000000, 0x08000000,
+ 0x08000000, 0x08000000, 0x00080000, 0x00080000, 0x00080000, 0x00080000,
+ 0x00080000, 0x00080000, 0x00080000, 0x00080000, 0x00080000, 0x00080000,
+ 0x00080000, 0x00080000, 0x00080000, 0x00080000, 0x00080000, 0x00080000,
+ 0x08080000, 0x08080000, 0x08080000, 0x08080000, 0x08080000, 0x08080000,
+ 0x08080000, 0x08080000, 0x08080000, 0x08080000, 0x08080000, 0x08080000,
+ 0x08080000, 0x08080000, 0x08080000, 0x08080000, 0x00000800, 0x00000800,
+ 0x00000800, 0x00000800, 0x00000800, 0x00000800, 0x00000800, 0x00000800,
+ 0x00000800, 0x00000800, 0x00000800, 0x00000800, 0x00000800, 0x00000800,
+ 0x00000800, 0x00000800, 0x08000800, 0x08000800, 0x08000800, 0x08000800,
+ 0x08000800, 0x08000800, 0x08000800, 0x08000800, 0x08000800, 0x08000800,
+ 0x08000800, 0x08000800, 0x08000800, 0x08000800, 0x08000800, 0x08000800,
+ 0x00080800, 0x00080800, 0x00080800, 0x00080800, 0x00080800, 0x00080800,
+ 0x00080800, 0x00080800, 0x00080800, 0x00080800, 0x00080800, 0x00080800,
+ 0x00080800, 0x00080800, 0x00080800, 0x00080800, 0x08080800, 0x08080800,
+ 0x08080800, 0x08080800, 0x08080800, 0x08080800, 0x08080800, 0x08080800,
+ 0x08080800, 0x08080800, 0x08080800, 0x08080800, 0x08080800, 0x08080800,
+ 0x08080800, 0x08080800, 0x00000008, 0x00000008, 0x00000008, 0x00000008,
+ 0x00000008, 0x00000008, 0x00000008, 0x00000008, 0x00000008, 0x00000008,
+ 0x00000008, 0x00000008, 0x00000008, 0x00000008, 0x00000008, 0x00000008,
+ 0x08000008, 0x08000008, 0x08000008, 0x08000008, 0x08000008, 0x08000008,
+ 0x08000008, 0x08000008, 0x08000008, 0x08000008, 0x08000008, 0x08000008,
+ 0x08000008, 0x08000008, 0x08000008, 0x08000008, 0x00080008, 0x00080008,
+ 0x00080008, 0x00080008, 0x00080008, 0x00080008, 0x00080008, 0x00080008,
+ 0x00080008, 0x00080008, 0x00080008, 0x00080008, 0x00080008, 0x00080008,
+ 0x00080008, 0x00080008, 0x08080008, 0x08080008, 0x08080008, 0x08080008,
+ 0x08080008, 0x08080008, 0x08080008, 0x08080008, 0x08080008, 0x08080008,
+ 0x08080008, 0x08080008, 0x08080008, 0x08080008, 0x08080008, 0x08080008,
+ 0x00000808, 0x00000808, 0x00000808, 0x00000808, 0x00000808, 0x00000808,
+ 0x00000808, 0x00000808, 0x00000808, 0x00000808, 0x00000808, 0x00000808,
+ 0x00000808, 0x00000808, 0x00000808, 0x00000808, 0x08000808, 0x08000808,
+ 0x08000808, 0x08000808, 0x08000808, 0x08000808, 0x08000808, 0x08000808,
+ 0x08000808, 0x08000808, 0x08000808, 0x08000808, 0x08000808, 0x08000808,
+ 0x08000808, 0x08000808, 0x00080808, 0x00080808, 0x00080808, 0x00080808,
+ 0x00080808, 0x00080808, 0x00080808, 0x00080808, 0x00080808, 0x00080808,
+ 0x00080808, 0x00080808, 0x00080808, 0x00080808, 0x00080808, 0x00080808,
+ 0x08080808, 0x08080808, 0x08080808, 0x08080808, 0x08080808, 0x08080808,
+ 0x08080808, 0x08080808, 0x08080808, 0x08080808, 0x08080808, 0x08080808,
+ 0x08080808, 0x08080808, 0x08080808, 0x08080808,
+ },
+ {
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x02000000, 0x02000000,
+ 0x02000000, 0x02000000, 0x02000000, 0x02000000, 0x02000000, 0x02000000,
+ 0x02000000, 0x02000000, 0x02000000, 0x02000000, 0x02000000, 0x02000000,
+ 0x02000000, 0x02000000, 0x00020000, 0x00020000, 0x00020000, 0x00020000,
+ 0x00020000, 0x00020000, 0x00020000, 0x00020000, 0x00020000, 0x00020000,
+ 0x00020000, 0x00020000, 0x00020000, 0x00020000, 0x00020000, 0x00020000,
+ 0x02020000, 0x02020000, 0x02020000, 0x02020000, 0x02020000, 0x02020000,
+ 0x02020000, 0x02020000, 0x02020000, 0x02020000, 0x02020000, 0x02020000,
+ 0x02020000, 0x02020000, 0x02020000, 0x02020000, 0x00000200, 0x00000200,
+ 0x00000200, 0x00000200, 0x00000200, 0x00000200, 0x00000200, 0x00000200,
+ 0x00000200, 0x00000200, 0x00000200, 0x00000200, 0x00000200, 0x00000200,
+ 0x00000200, 0x00000200, 0x02000200, 0x02000200, 0x02000200, 0x02000200,
+ 0x02000200, 0x02000200, 0x02000200, 0x02000200, 0x02000200, 0x02000200,
+ 0x02000200, 0x02000200, 0x02000200, 0x02000200, 0x02000200, 0x02000200,
+ 0x00020200, 0x00020200, 0x00020200, 0x00020200, 0x00020200, 0x00020200,
+ 0x00020200, 0x00020200, 0x00020200, 0x00020200, 0x00020200, 0x00020200,
+ 0x00020200, 0x00020200, 0x00020200, 0x00020200, 0x02020200, 0x02020200,
+ 0x02020200, 0x02020200, 0x02020200, 0x02020200, 0x02020200, 0x02020200,
+ 0x02020200, 0x02020200, 0x02020200, 0x02020200, 0x02020200, 0x02020200,
+ 0x02020200, 0x02020200, 0x00000002, 0x00000002, 0x00000002, 0x00000002,
+ 0x00000002, 0x00000002, 0x00000002, 0x00000002, 0x00000002, 0x00000002,
+ 0x00000002, 0x00000002, 0x00000002, 0x00000002, 0x00000002, 0x00000002,
+ 0x02000002, 0x02000002, 0x02000002, 0x02000002, 0x02000002, 0x02000002,
+ 0x02000002, 0x02000002, 0x02000002, 0x02000002, 0x02000002, 0x02000002,
+ 0x02000002, 0x02000002, 0x02000002, 0x02000002, 0x00020002, 0x00020002,
+ 0x00020002, 0x00020002, 0x00020002, 0x00020002, 0x00020002, 0x00020002,
+ 0x00020002, 0x00020002, 0x00020002, 0x00020002, 0x00020002, 0x00020002,
+ 0x00020002, 0x00020002, 0x02020002, 0x02020002, 0x02020002, 0x02020002,
+ 0x02020002, 0x02020002, 0x02020002, 0x02020002, 0x02020002, 0x02020002,
+ 0x02020002, 0x02020002, 0x02020002, 0x02020002, 0x02020002, 0x02020002,
+ 0x00000202, 0x00000202, 0x00000202, 0x00000202, 0x00000202, 0x00000202,
+ 0x00000202, 0x00000202, 0x00000202, 0x00000202, 0x00000202, 0x00000202,
+ 0x00000202, 0x00000202, 0x00000202, 0x00000202, 0x02000202, 0x02000202,
+ 0x02000202, 0x02000202, 0x02000202, 0x02000202, 0x02000202, 0x02000202,
+ 0x02000202, 0x02000202, 0x02000202, 0x02000202, 0x02000202, 0x02000202,
+ 0x02000202, 0x02000202, 0x00020202, 0x00020202, 0x00020202, 0x00020202,
+ 0x00020202, 0x00020202, 0x00020202, 0x00020202, 0x00020202, 0x00020202,
+ 0x00020202, 0x00020202, 0x00020202, 0x00020202, 0x00020202, 0x00020202,
+ 0x02020202, 0x02020202, 0x02020202, 0x02020202, 0x02020202, 0x02020202,
+ 0x02020202, 0x02020202, 0x02020202, 0x02020202, 0x02020202, 0x02020202,
+ 0x02020202, 0x02020202, 0x02020202, 0x02020202,
+ },
+};
+
+const uint32_t key_perm_maskl[8][128] = {
+ {
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000010, 0x00000010,
+ 0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000010,
+ 0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000010,
+ 0x00000010, 0x00000010, 0x00001000, 0x00001000, 0x00001000, 0x00001000,
+ 0x00001000, 0x00001000, 0x00001000, 0x00001000, 0x00001000, 0x00001000,
+ 0x00001000, 0x00001000, 0x00001000, 0x00001000, 0x00001000, 0x00001000,
+ 0x00001010, 0x00001010, 0x00001010, 0x00001010, 0x00001010, 0x00001010,
+ 0x00001010, 0x00001010, 0x00001010, 0x00001010, 0x00001010, 0x00001010,
+ 0x00001010, 0x00001010, 0x00001010, 0x00001010, 0x00100000, 0x00100000,
+ 0x00100000, 0x00100000, 0x00100000, 0x00100000, 0x00100000, 0x00100000,
+ 0x00100000, 0x00100000, 0x00100000, 0x00100000, 0x00100000, 0x00100000,
+ 0x00100000, 0x00100000, 0x00100010, 0x00100010, 0x00100010, 0x00100010,
+ 0x00100010, 0x00100010, 0x00100010, 0x00100010, 0x00100010, 0x00100010,
+ 0x00100010, 0x00100010, 0x00100010, 0x00100010, 0x00100010, 0x00100010,
+ 0x00101000, 0x00101000, 0x00101000, 0x00101000, 0x00101000, 0x00101000,
+ 0x00101000, 0x00101000, 0x00101000, 0x00101000, 0x00101000, 0x00101000,
+ 0x00101000, 0x00101000, 0x00101000, 0x00101000, 0x00101010, 0x00101010,
+ 0x00101010, 0x00101010, 0x00101010, 0x00101010, 0x00101010, 0x00101010,
+ 0x00101010, 0x00101010, 0x00101010, 0x00101010, 0x00101010, 0x00101010,
+ 0x00101010, 0x00101010,
+ },
+ {
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000020, 0x00000020,
+ 0x00000020, 0x00000020, 0x00000020, 0x00000020, 0x00000020, 0x00000020,
+ 0x00000020, 0x00000020, 0x00000020, 0x00000020, 0x00000020, 0x00000020,
+ 0x00000020, 0x00000020, 0x00002000, 0x00002000, 0x00002000, 0x00002000,
+ 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000,
+ 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000,
+ 0x00002020, 0x00002020, 0x00002020, 0x00002020, 0x00002020, 0x00002020,
+ 0x00002020, 0x00002020, 0x00002020, 0x00002020, 0x00002020, 0x00002020,
+ 0x00002020, 0x00002020, 0x00002020, 0x00002020, 0x00200000, 0x00200000,
+ 0x00200000, 0x00200000, 0x00200000, 0x00200000, 0x00200000, 0x00200000,
+ 0x00200000, 0x00200000, 0x00200000, 0x00200000, 0x00200000, 0x00200000,
+ 0x00200000, 0x00200000, 0x00200020, 0x00200020, 0x00200020, 0x00200020,
+ 0x00200020, 0x00200020, 0x00200020, 0x00200020, 0x00200020, 0x00200020,
+ 0x00200020, 0x00200020, 0x00200020, 0x00200020, 0x00200020, 0x00200020,
+ 0x00202000, 0x00202000, 0x00202000, 0x00202000, 0x00202000, 0x00202000,
+ 0x00202000, 0x00202000, 0x00202000, 0x00202000, 0x00202000, 0x00202000,
+ 0x00202000, 0x00202000, 0x00202000, 0x00202000, 0x00202020, 0x00202020,
+ 0x00202020, 0x00202020, 0x00202020, 0x00202020, 0x00202020, 0x00202020,
+ 0x00202020, 0x00202020, 0x00202020, 0x00202020, 0x00202020, 0x00202020,
+ 0x00202020, 0x00202020,
+ },
+ {
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000040, 0x00000040,
+ 0x00000040, 0x00000040, 0x00000040, 0x00000040, 0x00000040, 0x00000040,
+ 0x00000040, 0x00000040, 0x00000040, 0x00000040, 0x00000040, 0x00000040,
+ 0x00000040, 0x00000040, 0x00004000, 0x00004000, 0x00004000, 0x00004000,
+ 0x00004000, 0x00004000, 0x00004000, 0x00004000, 0x00004000, 0x00004000,
+ 0x00004000, 0x00004000, 0x00004000, 0x00004000, 0x00004000, 0x00004000,
+ 0x00004040, 0x00004040, 0x00004040, 0x00004040, 0x00004040, 0x00004040,
+ 0x00004040, 0x00004040, 0x00004040, 0x00004040, 0x00004040, 0x00004040,
+ 0x00004040, 0x00004040, 0x00004040, 0x00004040, 0x00400000, 0x00400000,
+ 0x00400000, 0x00400000, 0x00400000, 0x00400000, 0x00400000, 0x00400000,
+ 0x00400000, 0x00400000, 0x00400000, 0x00400000, 0x00400000, 0x00400000,
+ 0x00400000, 0x00400000, 0x00400040, 0x00400040, 0x00400040, 0x00400040,
+ 0x00400040, 0x00400040, 0x00400040, 0x00400040, 0x00400040, 0x00400040,
+ 0x00400040, 0x00400040, 0x00400040, 0x00400040, 0x00400040, 0x00400040,
+ 0x00404000, 0x00404000, 0x00404000, 0x00404000, 0x00404000, 0x00404000,
+ 0x00404000, 0x00404000, 0x00404000, 0x00404000, 0x00404000, 0x00404000,
+ 0x00404000, 0x00404000, 0x00404000, 0x00404000, 0x00404040, 0x00404040,
+ 0x00404040, 0x00404040, 0x00404040, 0x00404040, 0x00404040, 0x00404040,
+ 0x00404040, 0x00404040, 0x00404040, 0x00404040, 0x00404040, 0x00404040,
+ 0x00404040, 0x00404040,
+ },
+ {
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000080, 0x00000080,
+ 0x00000080, 0x00000080, 0x00000080, 0x00000080, 0x00000080, 0x00000080,
+ 0x00000080, 0x00000080, 0x00000080, 0x00000080, 0x00000080, 0x00000080,
+ 0x00000080, 0x00000080, 0x00008000, 0x00008000, 0x00008000, 0x00008000,
+ 0x00008000, 0x00008000, 0x00008000, 0x00008000, 0x00008000, 0x00008000,
+ 0x00008000, 0x00008000, 0x00008000, 0x00008000, 0x00008000, 0x00008000,
+ 0x00008080, 0x00008080, 0x00008080, 0x00008080, 0x00008080, 0x00008080,
+ 0x00008080, 0x00008080, 0x00008080, 0x00008080, 0x00008080, 0x00008080,
+ 0x00008080, 0x00008080, 0x00008080, 0x00008080, 0x00800000, 0x00800000,
+ 0x00800000, 0x00800000, 0x00800000, 0x00800000, 0x00800000, 0x00800000,
+ 0x00800000, 0x00800000, 0x00800000, 0x00800000, 0x00800000, 0x00800000,
+ 0x00800000, 0x00800000, 0x00800080, 0x00800080, 0x00800080, 0x00800080,
+ 0x00800080, 0x00800080, 0x00800080, 0x00800080, 0x00800080, 0x00800080,
+ 0x00800080, 0x00800080, 0x00800080, 0x00800080, 0x00800080, 0x00800080,
+ 0x00808000, 0x00808000, 0x00808000, 0x00808000, 0x00808000, 0x00808000,
+ 0x00808000, 0x00808000, 0x00808000, 0x00808000, 0x00808000, 0x00808000,
+ 0x00808000, 0x00808000, 0x00808000, 0x00808000, 0x00808080, 0x00808080,
+ 0x00808080, 0x00808080, 0x00808080, 0x00808080, 0x00808080, 0x00808080,
+ 0x00808080, 0x00808080, 0x00808080, 0x00808080, 0x00808080, 0x00808080,
+ 0x00808080, 0x00808080,
+ },
+ {
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00000001,
+ 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000100, 0x00000100,
+ 0x00000100, 0x00000100, 0x00000100, 0x00000100, 0x00000100, 0x00000100,
+ 0x00000101, 0x00000101, 0x00000101, 0x00000101, 0x00000101, 0x00000101,
+ 0x00000101, 0x00000101, 0x00010000, 0x00010000, 0x00010000, 0x00010000,
+ 0x00010000, 0x00010000, 0x00010000, 0x00010000, 0x00010001, 0x00010001,
+ 0x00010001, 0x00010001, 0x00010001, 0x00010001, 0x00010001, 0x00010001,
+ 0x00010100, 0x00010100, 0x00010100, 0x00010100, 0x00010100, 0x00010100,
+ 0x00010100, 0x00010100, 0x00010101, 0x00010101, 0x00010101, 0x00010101,
+ 0x00010101, 0x00010101, 0x00010101, 0x00010101, 0x01000000, 0x01000000,
+ 0x01000000, 0x01000000, 0x01000000, 0x01000000, 0x01000000, 0x01000000,
+ 0x01000001, 0x01000001, 0x01000001, 0x01000001, 0x01000001, 0x01000001,
+ 0x01000001, 0x01000001, 0x01000100, 0x01000100, 0x01000100, 0x01000100,
+ 0x01000100, 0x01000100, 0x01000100, 0x01000100, 0x01000101, 0x01000101,
+ 0x01000101, 0x01000101, 0x01000101, 0x01000101, 0x01000101, 0x01000101,
+ 0x01010000, 0x01010000, 0x01010000, 0x01010000, 0x01010000, 0x01010000,
+ 0x01010000, 0x01010000, 0x01010001, 0x01010001, 0x01010001, 0x01010001,
+ 0x01010001, 0x01010001, 0x01010001, 0x01010001, 0x01010100, 0x01010100,
+ 0x01010100, 0x01010100, 0x01010100, 0x01010100, 0x01010100, 0x01010100,
+ 0x01010101, 0x01010101, 0x01010101, 0x01010101, 0x01010101, 0x01010101,
+ 0x01010101, 0x01010101,
+ },
+ {
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000002, 0x00000002, 0x00000002, 0x00000002,
+ 0x00000002, 0x00000002, 0x00000002, 0x00000002, 0x00000200, 0x00000200,
+ 0x00000200, 0x00000200, 0x00000200, 0x00000200, 0x00000200, 0x00000200,
+ 0x00000202, 0x00000202, 0x00000202, 0x00000202, 0x00000202, 0x00000202,
+ 0x00000202, 0x00000202, 0x00020000, 0x00020000, 0x00020000, 0x00020000,
+ 0x00020000, 0x00020000, 0x00020000, 0x00020000, 0x00020002, 0x00020002,
+ 0x00020002, 0x00020002, 0x00020002, 0x00020002, 0x00020002, 0x00020002,
+ 0x00020200, 0x00020200, 0x00020200, 0x00020200, 0x00020200, 0x00020200,
+ 0x00020200, 0x00020200, 0x00020202, 0x00020202, 0x00020202, 0x00020202,
+ 0x00020202, 0x00020202, 0x00020202, 0x00020202, 0x02000000, 0x02000000,
+ 0x02000000, 0x02000000, 0x02000000, 0x02000000, 0x02000000, 0x02000000,
+ 0x02000002, 0x02000002, 0x02000002, 0x02000002, 0x02000002, 0x02000002,
+ 0x02000002, 0x02000002, 0x02000200, 0x02000200, 0x02000200, 0x02000200,
+ 0x02000200, 0x02000200, 0x02000200, 0x02000200, 0x02000202, 0x02000202,
+ 0x02000202, 0x02000202, 0x02000202, 0x02000202, 0x02000202, 0x02000202,
+ 0x02020000, 0x02020000, 0x02020000, 0x02020000, 0x02020000, 0x02020000,
+ 0x02020000, 0x02020000, 0x02020002, 0x02020002, 0x02020002, 0x02020002,
+ 0x02020002, 0x02020002, 0x02020002, 0x02020002, 0x02020200, 0x02020200,
+ 0x02020200, 0x02020200, 0x02020200, 0x02020200, 0x02020200, 0x02020200,
+ 0x02020202, 0x02020202, 0x02020202, 0x02020202, 0x02020202, 0x02020202,
+ 0x02020202, 0x02020202,
+ },
+ {
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000004, 0x00000004, 0x00000004, 0x00000004,
+ 0x00000004, 0x00000004, 0x00000004, 0x00000004, 0x00000400, 0x00000400,
+ 0x00000400, 0x00000400, 0x00000400, 0x00000400, 0x00000400, 0x00000400,
+ 0x00000404, 0x00000404, 0x00000404, 0x00000404, 0x00000404, 0x00000404,
+ 0x00000404, 0x00000404, 0x00040000, 0x00040000, 0x00040000, 0x00040000,
+ 0x00040000, 0x00040000, 0x00040000, 0x00040000, 0x00040004, 0x00040004,
+ 0x00040004, 0x00040004, 0x00040004, 0x00040004, 0x00040004, 0x00040004,
+ 0x00040400, 0x00040400, 0x00040400, 0x00040400, 0x00040400, 0x00040400,
+ 0x00040400, 0x00040400, 0x00040404, 0x00040404, 0x00040404, 0x00040404,
+ 0x00040404, 0x00040404, 0x00040404, 0x00040404, 0x04000000, 0x04000000,
+ 0x04000000, 0x04000000, 0x04000000, 0x04000000, 0x04000000, 0x04000000,
+ 0x04000004, 0x04000004, 0x04000004, 0x04000004, 0x04000004, 0x04000004,
+ 0x04000004, 0x04000004, 0x04000400, 0x04000400, 0x04000400, 0x04000400,
+ 0x04000400, 0x04000400, 0x04000400, 0x04000400, 0x04000404, 0x04000404,
+ 0x04000404, 0x04000404, 0x04000404, 0x04000404, 0x04000404, 0x04000404,
+ 0x04040000, 0x04040000, 0x04040000, 0x04040000, 0x04040000, 0x04040000,
+ 0x04040000, 0x04040000, 0x04040004, 0x04040004, 0x04040004, 0x04040004,
+ 0x04040004, 0x04040004, 0x04040004, 0x04040004, 0x04040400, 0x04040400,
+ 0x04040400, 0x04040400, 0x04040400, 0x04040400, 0x04040400, 0x04040400,
+ 0x04040404, 0x04040404, 0x04040404, 0x04040404, 0x04040404, 0x04040404,
+ 0x04040404, 0x04040404,
+ },
+ {
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000008, 0x00000008, 0x00000008, 0x00000008,
+ 0x00000008, 0x00000008, 0x00000008, 0x00000008, 0x00000800, 0x00000800,
+ 0x00000800, 0x00000800, 0x00000800, 0x00000800, 0x00000800, 0x00000800,
+ 0x00000808, 0x00000808, 0x00000808, 0x00000808, 0x00000808, 0x00000808,
+ 0x00000808, 0x00000808, 0x00080000, 0x00080000, 0x00080000, 0x00080000,
+ 0x00080000, 0x00080000, 0x00080000, 0x00080000, 0x00080008, 0x00080008,
+ 0x00080008, 0x00080008, 0x00080008, 0x00080008, 0x00080008, 0x00080008,
+ 0x00080800, 0x00080800, 0x00080800, 0x00080800, 0x00080800, 0x00080800,
+ 0x00080800, 0x00080800, 0x00080808, 0x00080808, 0x00080808, 0x00080808,
+ 0x00080808, 0x00080808, 0x00080808, 0x00080808, 0x08000000, 0x08000000,
+ 0x08000000, 0x08000000, 0x08000000, 0x08000000, 0x08000000, 0x08000000,
+ 0x08000008, 0x08000008, 0x08000008, 0x08000008, 0x08000008, 0x08000008,
+ 0x08000008, 0x08000008, 0x08000800, 0x08000800, 0x08000800, 0x08000800,
+ 0x08000800, 0x08000800, 0x08000800, 0x08000800, 0x08000808, 0x08000808,
+ 0x08000808, 0x08000808, 0x08000808, 0x08000808, 0x08000808, 0x08000808,
+ 0x08080000, 0x08080000, 0x08080000, 0x08080000, 0x08080000, 0x08080000,
+ 0x08080000, 0x08080000, 0x08080008, 0x08080008, 0x08080008, 0x08080008,
+ 0x08080008, 0x08080008, 0x08080008, 0x08080008, 0x08080800, 0x08080800,
+ 0x08080800, 0x08080800, 0x08080800, 0x08080800, 0x08080800, 0x08080800,
+ 0x08080808, 0x08080808, 0x08080808, 0x08080808, 0x08080808, 0x08080808,
+ 0x08080808, 0x08080808,
+ },
+};
+
+const uint32_t key_perm_maskr[8][128] = {
+ {
+ 0x00000000, 0x00100000, 0x00001000, 0x00101000, 0x00000010, 0x00100010,
+ 0x00001010, 0x00101010, 0x00000001, 0x00100001, 0x00001001, 0x00101001,
+ 0x00000011, 0x00100011, 0x00001011, 0x00101011, 0x00000000, 0x00100000,
+ 0x00001000, 0x00101000, 0x00000010, 0x00100010, 0x00001010, 0x00101010,
+ 0x00000001, 0x00100001, 0x00001001, 0x00101001, 0x00000011, 0x00100011,
+ 0x00001011, 0x00101011, 0x00000000, 0x00100000, 0x00001000, 0x00101000,
+ 0x00000010, 0x00100010, 0x00001010, 0x00101010, 0x00000001, 0x00100001,
+ 0x00001001, 0x00101001, 0x00000011, 0x00100011, 0x00001011, 0x00101011,
+ 0x00000000, 0x00100000, 0x00001000, 0x00101000, 0x00000010, 0x00100010,
+ 0x00001010, 0x00101010, 0x00000001, 0x00100001, 0x00001001, 0x00101001,
+ 0x00000011, 0x00100011, 0x00001011, 0x00101011, 0x00000000, 0x00100000,
+ 0x00001000, 0x00101000, 0x00000010, 0x00100010, 0x00001010, 0x00101010,
+ 0x00000001, 0x00100001, 0x00001001, 0x00101001, 0x00000011, 0x00100011,
+ 0x00001011, 0x00101011, 0x00000000, 0x00100000, 0x00001000, 0x00101000,
+ 0x00000010, 0x00100010, 0x00001010, 0x00101010, 0x00000001, 0x00100001,
+ 0x00001001, 0x00101001, 0x00000011, 0x00100011, 0x00001011, 0x00101011,
+ 0x00000000, 0x00100000, 0x00001000, 0x00101000, 0x00000010, 0x00100010,
+ 0x00001010, 0x00101010, 0x00000001, 0x00100001, 0x00001001, 0x00101001,
+ 0x00000011, 0x00100011, 0x00001011, 0x00101011, 0x00000000, 0x00100000,
+ 0x00001000, 0x00101000, 0x00000010, 0x00100010, 0x00001010, 0x00101010,
+ 0x00000001, 0x00100001, 0x00001001, 0x00101001, 0x00000011, 0x00100011,
+ 0x00001011, 0x00101011,
+ },
+ {
+ 0x00000000, 0x00200000, 0x00002000, 0x00202000, 0x00000020, 0x00200020,
+ 0x00002020, 0x00202020, 0x00000002, 0x00200002, 0x00002002, 0x00202002,
+ 0x00000022, 0x00200022, 0x00002022, 0x00202022, 0x00000000, 0x00200000,
+ 0x00002000, 0x00202000, 0x00000020, 0x00200020, 0x00002020, 0x00202020,
+ 0x00000002, 0x00200002, 0x00002002, 0x00202002, 0x00000022, 0x00200022,
+ 0x00002022, 0x00202022, 0x00000000, 0x00200000, 0x00002000, 0x00202000,
+ 0x00000020, 0x00200020, 0x00002020, 0x00202020, 0x00000002, 0x00200002,
+ 0x00002002, 0x00202002, 0x00000022, 0x00200022, 0x00002022, 0x00202022,
+ 0x00000000, 0x00200000, 0x00002000, 0x00202000, 0x00000020, 0x00200020,
+ 0x00002020, 0x00202020, 0x00000002, 0x00200002, 0x00002002, 0x00202002,
+ 0x00000022, 0x00200022, 0x00002022, 0x00202022, 0x00000000, 0x00200000,
+ 0x00002000, 0x00202000, 0x00000020, 0x00200020, 0x00002020, 0x00202020,
+ 0x00000002, 0x00200002, 0x00002002, 0x00202002, 0x00000022, 0x00200022,
+ 0x00002022, 0x00202022, 0x00000000, 0x00200000, 0x00002000, 0x00202000,
+ 0x00000020, 0x00200020, 0x00002020, 0x00202020, 0x00000002, 0x00200002,
+ 0x00002002, 0x00202002, 0x00000022, 0x00200022, 0x00002022, 0x00202022,
+ 0x00000000, 0x00200000, 0x00002000, 0x00202000, 0x00000020, 0x00200020,
+ 0x00002020, 0x00202020, 0x00000002, 0x00200002, 0x00002002, 0x00202002,
+ 0x00000022, 0x00200022, 0x00002022, 0x00202022, 0x00000000, 0x00200000,
+ 0x00002000, 0x00202000, 0x00000020, 0x00200020, 0x00002020, 0x00202020,
+ 0x00000002, 0x00200002, 0x00002002, 0x00202002, 0x00000022, 0x00200022,
+ 0x00002022, 0x00202022,
+ },
+ {
+ 0x00000000, 0x00400000, 0x00004000, 0x00404000, 0x00000040, 0x00400040,
+ 0x00004040, 0x00404040, 0x00000004, 0x00400004, 0x00004004, 0x00404004,
+ 0x00000044, 0x00400044, 0x00004044, 0x00404044, 0x00000000, 0x00400000,
+ 0x00004000, 0x00404000, 0x00000040, 0x00400040, 0x00004040, 0x00404040,
+ 0x00000004, 0x00400004, 0x00004004, 0x00404004, 0x00000044, 0x00400044,
+ 0x00004044, 0x00404044, 0x00000000, 0x00400000, 0x00004000, 0x00404000,
+ 0x00000040, 0x00400040, 0x00004040, 0x00404040, 0x00000004, 0x00400004,
+ 0x00004004, 0x00404004, 0x00000044, 0x00400044, 0x00004044, 0x00404044,
+ 0x00000000, 0x00400000, 0x00004000, 0x00404000, 0x00000040, 0x00400040,
+ 0x00004040, 0x00404040, 0x00000004, 0x00400004, 0x00004004, 0x00404004,
+ 0x00000044, 0x00400044, 0x00004044, 0x00404044, 0x00000000, 0x00400000,
+ 0x00004000, 0x00404000, 0x00000040, 0x00400040, 0x00004040, 0x00404040,
+ 0x00000004, 0x00400004, 0x00004004, 0x00404004, 0x00000044, 0x00400044,
+ 0x00004044, 0x00404044, 0x00000000, 0x00400000, 0x00004000, 0x00404000,
+ 0x00000040, 0x00400040, 0x00004040, 0x00404040, 0x00000004, 0x00400004,
+ 0x00004004, 0x00404004, 0x00000044, 0x00400044, 0x00004044, 0x00404044,
+ 0x00000000, 0x00400000, 0x00004000, 0x00404000, 0x00000040, 0x00400040,
+ 0x00004040, 0x00404040, 0x00000004, 0x00400004, 0x00004004, 0x00404004,
+ 0x00000044, 0x00400044, 0x00004044, 0x00404044, 0x00000000, 0x00400000,
+ 0x00004000, 0x00404000, 0x00000040, 0x00400040, 0x00004040, 0x00404040,
+ 0x00000004, 0x00400004, 0x00004004, 0x00404004, 0x00000044, 0x00400044,
+ 0x00004044, 0x00404044,
+ },
+ {
+ 0x00000000, 0x00800000, 0x00008000, 0x00808000, 0x00000080, 0x00800080,
+ 0x00008080, 0x00808080, 0x00000008, 0x00800008, 0x00008008, 0x00808008,
+ 0x00000088, 0x00800088, 0x00008088, 0x00808088, 0x00000000, 0x00800000,
+ 0x00008000, 0x00808000, 0x00000080, 0x00800080, 0x00008080, 0x00808080,
+ 0x00000008, 0x00800008, 0x00008008, 0x00808008, 0x00000088, 0x00800088,
+ 0x00008088, 0x00808088, 0x00000000, 0x00800000, 0x00008000, 0x00808000,
+ 0x00000080, 0x00800080, 0x00008080, 0x00808080, 0x00000008, 0x00800008,
+ 0x00008008, 0x00808008, 0x00000088, 0x00800088, 0x00008088, 0x00808088,
+ 0x00000000, 0x00800000, 0x00008000, 0x00808000, 0x00000080, 0x00800080,
+ 0x00008080, 0x00808080, 0x00000008, 0x00800008, 0x00008008, 0x00808008,
+ 0x00000088, 0x00800088, 0x00008088, 0x00808088, 0x00000000, 0x00800000,
+ 0x00008000, 0x00808000, 0x00000080, 0x00800080, 0x00008080, 0x00808080,
+ 0x00000008, 0x00800008, 0x00008008, 0x00808008, 0x00000088, 0x00800088,
+ 0x00008088, 0x00808088, 0x00000000, 0x00800000, 0x00008000, 0x00808000,
+ 0x00000080, 0x00800080, 0x00008080, 0x00808080, 0x00000008, 0x00800008,
+ 0x00008008, 0x00808008, 0x00000088, 0x00800088, 0x00008088, 0x00808088,
+ 0x00000000, 0x00800000, 0x00008000, 0x00808000, 0x00000080, 0x00800080,
+ 0x00008080, 0x00808080, 0x00000008, 0x00800008, 0x00008008, 0x00808008,
+ 0x00000088, 0x00800088, 0x00008088, 0x00808088, 0x00000000, 0x00800000,
+ 0x00008000, 0x00808000, 0x00000080, 0x00800080, 0x00008080, 0x00808080,
+ 0x00000008, 0x00800008, 0x00008008, 0x00808008, 0x00000088, 0x00800088,
+ 0x00008088, 0x00808088,
+ },
+ {
+ 0x00000000, 0x01000000, 0x00010000, 0x01010000, 0x00000100, 0x01000100,
+ 0x00010100, 0x01010100, 0x00000000, 0x01000000, 0x00010000, 0x01010000,
+ 0x00000100, 0x01000100, 0x00010100, 0x01010100, 0x00000000, 0x01000000,
+ 0x00010000, 0x01010000, 0x00000100, 0x01000100, 0x00010100, 0x01010100,
+ 0x00000000, 0x01000000, 0x00010000, 0x01010000, 0x00000100, 0x01000100,
+ 0x00010100, 0x01010100, 0x00000000, 0x01000000, 0x00010000, 0x01010000,
+ 0x00000100, 0x01000100, 0x00010100, 0x01010100, 0x00000000, 0x01000000,
+ 0x00010000, 0x01010000, 0x00000100, 0x01000100, 0x00010100, 0x01010100,
+ 0x00000000, 0x01000000, 0x00010000, 0x01010000, 0x00000100, 0x01000100,
+ 0x00010100, 0x01010100, 0x00000000, 0x01000000, 0x00010000, 0x01010000,
+ 0x00000100, 0x01000100, 0x00010100, 0x01010100, 0x00000000, 0x01000000,
+ 0x00010000, 0x01010000, 0x00000100, 0x01000100, 0x00010100, 0x01010100,
+ 0x00000000, 0x01000000, 0x00010000, 0x01010000, 0x00000100, 0x01000100,
+ 0x00010100, 0x01010100, 0x00000000, 0x01000000, 0x00010000, 0x01010000,
+ 0x00000100, 0x01000100, 0x00010100, 0x01010100, 0x00000000, 0x01000000,
+ 0x00010000, 0x01010000, 0x00000100, 0x01000100, 0x00010100, 0x01010100,
+ 0x00000000, 0x01000000, 0x00010000, 0x01010000, 0x00000100, 0x01000100,
+ 0x00010100, 0x01010100, 0x00000000, 0x01000000, 0x00010000, 0x01010000,
+ 0x00000100, 0x01000100, 0x00010100, 0x01010100, 0x00000000, 0x01000000,
+ 0x00010000, 0x01010000, 0x00000100, 0x01000100, 0x00010100, 0x01010100,
+ 0x00000000, 0x01000000, 0x00010000, 0x01010000, 0x00000100, 0x01000100,
+ 0x00010100, 0x01010100,
+ },
+ {
+ 0x00000000, 0x02000000, 0x00020000, 0x02020000, 0x00000200, 0x02000200,
+ 0x00020200, 0x02020200, 0x00000000, 0x02000000, 0x00020000, 0x02020000,
+ 0x00000200, 0x02000200, 0x00020200, 0x02020200, 0x00000000, 0x02000000,
+ 0x00020000, 0x02020000, 0x00000200, 0x02000200, 0x00020200, 0x02020200,
+ 0x00000000, 0x02000000, 0x00020000, 0x02020000, 0x00000200, 0x02000200,
+ 0x00020200, 0x02020200, 0x00000000, 0x02000000, 0x00020000, 0x02020000,
+ 0x00000200, 0x02000200, 0x00020200, 0x02020200, 0x00000000, 0x02000000,
+ 0x00020000, 0x02020000, 0x00000200, 0x02000200, 0x00020200, 0x02020200,
+ 0x00000000, 0x02000000, 0x00020000, 0x02020000, 0x00000200, 0x02000200,
+ 0x00020200, 0x02020200, 0x00000000, 0x02000000, 0x00020000, 0x02020000,
+ 0x00000200, 0x02000200, 0x00020200, 0x02020200, 0x00000000, 0x02000000,
+ 0x00020000, 0x02020000, 0x00000200, 0x02000200, 0x00020200, 0x02020200,
+ 0x00000000, 0x02000000, 0x00020000, 0x02020000, 0x00000200, 0x02000200,
+ 0x00020200, 0x02020200, 0x00000000, 0x02000000, 0x00020000, 0x02020000,
+ 0x00000200, 0x02000200, 0x00020200, 0x02020200, 0x00000000, 0x02000000,
+ 0x00020000, 0x02020000, 0x00000200, 0x02000200, 0x00020200, 0x02020200,
+ 0x00000000, 0x02000000, 0x00020000, 0x02020000, 0x00000200, 0x02000200,
+ 0x00020200, 0x02020200, 0x00000000, 0x02000000, 0x00020000, 0x02020000,
+ 0x00000200, 0x02000200, 0x00020200, 0x02020200, 0x00000000, 0x02000000,
+ 0x00020000, 0x02020000, 0x00000200, 0x02000200, 0x00020200, 0x02020200,
+ 0x00000000, 0x02000000, 0x00020000, 0x02020000, 0x00000200, 0x02000200,
+ 0x00020200, 0x02020200,
+ },
+ {
+ 0x00000000, 0x04000000, 0x00040000, 0x04040000, 0x00000400, 0x04000400,
+ 0x00040400, 0x04040400, 0x00000000, 0x04000000, 0x00040000, 0x04040000,
+ 0x00000400, 0x04000400, 0x00040400, 0x04040400, 0x00000000, 0x04000000,
+ 0x00040000, 0x04040000, 0x00000400, 0x04000400, 0x00040400, 0x04040400,
+ 0x00000000, 0x04000000, 0x00040000, 0x04040000, 0x00000400, 0x04000400,
+ 0x00040400, 0x04040400, 0x00000000, 0x04000000, 0x00040000, 0x04040000,
+ 0x00000400, 0x04000400, 0x00040400, 0x04040400, 0x00000000, 0x04000000,
+ 0x00040000, 0x04040000, 0x00000400, 0x04000400, 0x00040400, 0x04040400,
+ 0x00000000, 0x04000000, 0x00040000, 0x04040000, 0x00000400, 0x04000400,
+ 0x00040400, 0x04040400, 0x00000000, 0x04000000, 0x00040000, 0x04040000,
+ 0x00000400, 0x04000400, 0x00040400, 0x04040400, 0x00000000, 0x04000000,
+ 0x00040000, 0x04040000, 0x00000400, 0x04000400, 0x00040400, 0x04040400,
+ 0x00000000, 0x04000000, 0x00040000, 0x04040000, 0x00000400, 0x04000400,
+ 0x00040400, 0x04040400, 0x00000000, 0x04000000, 0x00040000, 0x04040000,
+ 0x00000400, 0x04000400, 0x00040400, 0x04040400, 0x00000000, 0x04000000,
+ 0x00040000, 0x04040000, 0x00000400, 0x04000400, 0x00040400, 0x04040400,
+ 0x00000000, 0x04000000, 0x00040000, 0x04040000, 0x00000400, 0x04000400,
+ 0x00040400, 0x04040400, 0x00000000, 0x04000000, 0x00040000, 0x04040000,
+ 0x00000400, 0x04000400, 0x00040400, 0x04040400, 0x00000000, 0x04000000,
+ 0x00040000, 0x04040000, 0x00000400, 0x04000400, 0x00040400, 0x04040400,
+ 0x00000000, 0x04000000, 0x00040000, 0x04040000, 0x00000400, 0x04000400,
+ 0x00040400, 0x04040400,
+ },
+ {
+ 0x00000000, 0x08000000, 0x00080000, 0x08080000, 0x00000800, 0x08000800,
+ 0x00080800, 0x08080800, 0x00000000, 0x08000000, 0x00080000, 0x08080000,
+ 0x00000800, 0x08000800, 0x00080800, 0x08080800, 0x00000000, 0x08000000,
+ 0x00080000, 0x08080000, 0x00000800, 0x08000800, 0x00080800, 0x08080800,
+ 0x00000000, 0x08000000, 0x00080000, 0x08080000, 0x00000800, 0x08000800,
+ 0x00080800, 0x08080800, 0x00000000, 0x08000000, 0x00080000, 0x08080000,
+ 0x00000800, 0x08000800, 0x00080800, 0x08080800, 0x00000000, 0x08000000,
+ 0x00080000, 0x08080000, 0x00000800, 0x08000800, 0x00080800, 0x08080800,
+ 0x00000000, 0x08000000, 0x00080000, 0x08080000, 0x00000800, 0x08000800,
+ 0x00080800, 0x08080800, 0x00000000, 0x08000000, 0x00080000, 0x08080000,
+ 0x00000800, 0x08000800, 0x00080800, 0x08080800, 0x00000000, 0x08000000,
+ 0x00080000, 0x08080000, 0x00000800, 0x08000800, 0x00080800, 0x08080800,
+ 0x00000000, 0x08000000, 0x00080000, 0x08080000, 0x00000800, 0x08000800,
+ 0x00080800, 0x08080800, 0x00000000, 0x08000000, 0x00080000, 0x08080000,
+ 0x00000800, 0x08000800, 0x00080800, 0x08080800, 0x00000000, 0x08000000,
+ 0x00080000, 0x08080000, 0x00000800, 0x08000800, 0x00080800, 0x08080800,
+ 0x00000000, 0x08000000, 0x00080000, 0x08080000, 0x00000800, 0x08000800,
+ 0x00080800, 0x08080800, 0x00000000, 0x08000000, 0x00080000, 0x08080000,
+ 0x00000800, 0x08000800, 0x00080800, 0x08080800, 0x00000000, 0x08000000,
+ 0x00080000, 0x08080000, 0x00000800, 0x08000800, 0x00080800, 0x08080800,
+ 0x00000000, 0x08000000, 0x00080000, 0x08080000, 0x00000800, 0x08000800,
+ 0x00080800, 0x08080800,
+ },
+};
+
+const uint32_t comp_maskl[8][128] = {
+ {
+ 0x00000000, 0x00000010, 0x00004000, 0x00004010, 0x00040000, 0x00040010,
+ 0x00044000, 0x00044010, 0x00000100, 0x00000110, 0x00004100, 0x00004110,
+ 0x00040100, 0x00040110, 0x00044100, 0x00044110, 0x00020000, 0x00020010,
+ 0x00024000, 0x00024010, 0x00060000, 0x00060010, 0x00064000, 0x00064010,
+ 0x00020100, 0x00020110, 0x00024100, 0x00024110, 0x00060100, 0x00060110,
+ 0x00064100, 0x00064110, 0x00000001, 0x00000011, 0x00004001, 0x00004011,
+ 0x00040001, 0x00040011, 0x00044001, 0x00044011, 0x00000101, 0x00000111,
+ 0x00004101, 0x00004111, 0x00040101, 0x00040111, 0x00044101, 0x00044111,
+ 0x00020001, 0x00020011, 0x00024001, 0x00024011, 0x00060001, 0x00060011,
+ 0x00064001, 0x00064011, 0x00020101, 0x00020111, 0x00024101, 0x00024111,
+ 0x00060101, 0x00060111, 0x00064101, 0x00064111, 0x00080000, 0x00080010,
+ 0x00084000, 0x00084010, 0x000c0000, 0x000c0010, 0x000c4000, 0x000c4010,
+ 0x00080100, 0x00080110, 0x00084100, 0x00084110, 0x000c0100, 0x000c0110,
+ 0x000c4100, 0x000c4110, 0x000a0000, 0x000a0010, 0x000a4000, 0x000a4010,
+ 0x000e0000, 0x000e0010, 0x000e4000, 0x000e4010, 0x000a0100, 0x000a0110,
+ 0x000a4100, 0x000a4110, 0x000e0100, 0x000e0110, 0x000e4100, 0x000e4110,
+ 0x00080001, 0x00080011, 0x00084001, 0x00084011, 0x000c0001, 0x000c0011,
+ 0x000c4001, 0x000c4011, 0x00080101, 0x00080111, 0x00084101, 0x00084111,
+ 0x000c0101, 0x000c0111, 0x000c4101, 0x000c4111, 0x000a0001, 0x000a0011,
+ 0x000a4001, 0x000a4011, 0x000e0001, 0x000e0011, 0x000e4001, 0x000e4011,
+ 0x000a0101, 0x000a0111, 0x000a4101, 0x000a4111, 0x000e0101, 0x000e0111,
+ 0x000e4101, 0x000e4111,
+ },
+ {
+ 0x00000000, 0x00800000, 0x00000002, 0x00800002, 0x00000200, 0x00800200,
+ 0x00000202, 0x00800202, 0x00200000, 0x00a00000, 0x00200002, 0x00a00002,
+ 0x00200200, 0x00a00200, 0x00200202, 0x00a00202, 0x00001000, 0x00801000,
+ 0x00001002, 0x00801002, 0x00001200, 0x00801200, 0x00001202, 0x00801202,
+ 0x00201000, 0x00a01000, 0x00201002, 0x00a01002, 0x00201200, 0x00a01200,
+ 0x00201202, 0x00a01202, 0x00000000, 0x00800000, 0x00000002, 0x00800002,
+ 0x00000200, 0x00800200, 0x00000202, 0x00800202, 0x00200000, 0x00a00000,
+ 0x00200002, 0x00a00002, 0x00200200, 0x00a00200, 0x00200202, 0x00a00202,
+ 0x00001000, 0x00801000, 0x00001002, 0x00801002, 0x00001200, 0x00801200,
+ 0x00001202, 0x00801202, 0x00201000, 0x00a01000, 0x00201002, 0x00a01002,
+ 0x00201200, 0x00a01200, 0x00201202, 0x00a01202, 0x00000040, 0x00800040,
+ 0x00000042, 0x00800042, 0x00000240, 0x00800240, 0x00000242, 0x00800242,
+ 0x00200040, 0x00a00040, 0x00200042, 0x00a00042, 0x00200240, 0x00a00240,
+ 0x00200242, 0x00a00242, 0x00001040, 0x00801040, 0x00001042, 0x00801042,
+ 0x00001240, 0x00801240, 0x00001242, 0x00801242, 0x00201040, 0x00a01040,
+ 0x00201042, 0x00a01042, 0x00201240, 0x00a01240, 0x00201242, 0x00a01242,
+ 0x00000040, 0x00800040, 0x00000042, 0x00800042, 0x00000240, 0x00800240,
+ 0x00000242, 0x00800242, 0x00200040, 0x00a00040, 0x00200042, 0x00a00042,
+ 0x00200240, 0x00a00240, 0x00200242, 0x00a00242, 0x00001040, 0x00801040,
+ 0x00001042, 0x00801042, 0x00001240, 0x00801240, 0x00001242, 0x00801242,
+ 0x00201040, 0x00a01040, 0x00201042, 0x00a01042, 0x00201240, 0x00a01240,
+ 0x00201242, 0x00a01242,
+ },
+ {
+ 0x00000000, 0x00002000, 0x00000004, 0x00002004, 0x00000400, 0x00002400,
+ 0x00000404, 0x00002404, 0x00000000, 0x00002000, 0x00000004, 0x00002004,
+ 0x00000400, 0x00002400, 0x00000404, 0x00002404, 0x00400000, 0x00402000,
+ 0x00400004, 0x00402004, 0x00400400, 0x00402400, 0x00400404, 0x00402404,
+ 0x00400000, 0x00402000, 0x00400004, 0x00402004, 0x00400400, 0x00402400,
+ 0x00400404, 0x00402404, 0x00000020, 0x00002020, 0x00000024, 0x00002024,
+ 0x00000420, 0x00002420, 0x00000424, 0x00002424, 0x00000020, 0x00002020,
+ 0x00000024, 0x00002024, 0x00000420, 0x00002420, 0x00000424, 0x00002424,
+ 0x00400020, 0x00402020, 0x00400024, 0x00402024, 0x00400420, 0x00402420,
+ 0x00400424, 0x00402424, 0x00400020, 0x00402020, 0x00400024, 0x00402024,
+ 0x00400420, 0x00402420, 0x00400424, 0x00402424, 0x00008000, 0x0000a000,
+ 0x00008004, 0x0000a004, 0x00008400, 0x0000a400, 0x00008404, 0x0000a404,
+ 0x00008000, 0x0000a000, 0x00008004, 0x0000a004, 0x00008400, 0x0000a400,
+ 0x00008404, 0x0000a404, 0x00408000, 0x0040a000, 0x00408004, 0x0040a004,
+ 0x00408400, 0x0040a400, 0x00408404, 0x0040a404, 0x00408000, 0x0040a000,
+ 0x00408004, 0x0040a004, 0x00408400, 0x0040a400, 0x00408404, 0x0040a404,
+ 0x00008020, 0x0000a020, 0x00008024, 0x0000a024, 0x00008420, 0x0000a420,
+ 0x00008424, 0x0000a424, 0x00008020, 0x0000a020, 0x00008024, 0x0000a024,
+ 0x00008420, 0x0000a420, 0x00008424, 0x0000a424, 0x00408020, 0x0040a020,
+ 0x00408024, 0x0040a024, 0x00408420, 0x0040a420, 0x00408424, 0x0040a424,
+ 0x00408020, 0x0040a020, 0x00408024, 0x0040a024, 0x00408420, 0x0040a420,
+ 0x00408424, 0x0040a424,
+ },
+ {
+ 0x00000000, 0x00010000, 0x00000008, 0x00010008, 0x00000080, 0x00010080,
+ 0x00000088, 0x00010088, 0x00000000, 0x00010000, 0x00000008, 0x00010008,
+ 0x00000080, 0x00010080, 0x00000088, 0x00010088, 0x00100000, 0x00110000,
+ 0x00100008, 0x00110008, 0x00100080, 0x00110080, 0x00100088, 0x00110088,
+ 0x00100000, 0x00110000, 0x00100008, 0x00110008, 0x00100080, 0x00110080,
+ 0x00100088, 0x00110088, 0x00000800, 0x00010800, 0x00000808, 0x00010808,
+ 0x00000880, 0x00010880, 0x00000888, 0x00010888, 0x00000800, 0x00010800,
+ 0x00000808, 0x00010808, 0x00000880, 0x00010880, 0x00000888, 0x00010888,
+ 0x00100800, 0x00110800, 0x00100808, 0x00110808, 0x00100880, 0x00110880,
+ 0x00100888, 0x00110888, 0x00100800, 0x00110800, 0x00100808, 0x00110808,
+ 0x00100880, 0x00110880, 0x00100888, 0x00110888, 0x00000000, 0x00010000,
+ 0x00000008, 0x00010008, 0x00000080, 0x00010080, 0x00000088, 0x00010088,
+ 0x00000000, 0x00010000, 0x00000008, 0x00010008, 0x00000080, 0x00010080,
+ 0x00000088, 0x00010088, 0x00100000, 0x00110000, 0x00100008, 0x00110008,
+ 0x00100080, 0x00110080, 0x00100088, 0x00110088, 0x00100000, 0x00110000,
+ 0x00100008, 0x00110008, 0x00100080, 0x00110080, 0x00100088, 0x00110088,
+ 0x00000800, 0x00010800, 0x00000808, 0x00010808, 0x00000880, 0x00010880,
+ 0x00000888, 0x00010888, 0x00000800, 0x00010800, 0x00000808, 0x00010808,
+ 0x00000880, 0x00010880, 0x00000888, 0x00010888, 0x00100800, 0x00110800,
+ 0x00100808, 0x00110808, 0x00100880, 0x00110880, 0x00100888, 0x00110888,
+ 0x00100800, 0x00110800, 0x00100808, 0x00110808, 0x00100880, 0x00110880,
+ 0x00100888, 0x00110888,
+ },
+ {
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000,
+ },
+ {
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000,
+ },
+ {
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000,
+ },
+ {
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000,
+ },
+};
+
+const uint32_t comp_maskr[8][128] = {
+ {
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000,
+ },
+ {
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000,
+ },
+ {
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000,
+ },
+ {
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000,
+ },
+ {
+ 0x00000000, 0x00000000, 0x00000080, 0x00000080, 0x00002000, 0x00002000,
+ 0x00002080, 0x00002080, 0x00000001, 0x00000001, 0x00000081, 0x00000081,
+ 0x00002001, 0x00002001, 0x00002081, 0x00002081, 0x00200000, 0x00200000,
+ 0x00200080, 0x00200080, 0x00202000, 0x00202000, 0x00202080, 0x00202080,
+ 0x00200001, 0x00200001, 0x00200081, 0x00200081, 0x00202001, 0x00202001,
+ 0x00202081, 0x00202081, 0x00020000, 0x00020000, 0x00020080, 0x00020080,
+ 0x00022000, 0x00022000, 0x00022080, 0x00022080, 0x00020001, 0x00020001,
+ 0x00020081, 0x00020081, 0x00022001, 0x00022001, 0x00022081, 0x00022081,
+ 0x00220000, 0x00220000, 0x00220080, 0x00220080, 0x00222000, 0x00222000,
+ 0x00222080, 0x00222080, 0x00220001, 0x00220001, 0x00220081, 0x00220081,
+ 0x00222001, 0x00222001, 0x00222081, 0x00222081, 0x00000002, 0x00000002,
+ 0x00000082, 0x00000082, 0x00002002, 0x00002002, 0x00002082, 0x00002082,
+ 0x00000003, 0x00000003, 0x00000083, 0x00000083, 0x00002003, 0x00002003,
+ 0x00002083, 0x00002083, 0x00200002, 0x00200002, 0x00200082, 0x00200082,
+ 0x00202002, 0x00202002, 0x00202082, 0x00202082, 0x00200003, 0x00200003,
+ 0x00200083, 0x00200083, 0x00202003, 0x00202003, 0x00202083, 0x00202083,
+ 0x00020002, 0x00020002, 0x00020082, 0x00020082, 0x00022002, 0x00022002,
+ 0x00022082, 0x00022082, 0x00020003, 0x00020003, 0x00020083, 0x00020083,
+ 0x00022003, 0x00022003, 0x00022083, 0x00022083, 0x00220002, 0x00220002,
+ 0x00220082, 0x00220082, 0x00222002, 0x00222002, 0x00222082, 0x00222082,
+ 0x00220003, 0x00220003, 0x00220083, 0x00220083, 0x00222003, 0x00222003,
+ 0x00222083, 0x00222083,
+ },
+ {
+ 0x00000000, 0x00000010, 0x00800000, 0x00800010, 0x00010000, 0x00010010,
+ 0x00810000, 0x00810010, 0x00000200, 0x00000210, 0x00800200, 0x00800210,
+ 0x00010200, 0x00010210, 0x00810200, 0x00810210, 0x00000000, 0x00000010,
+ 0x00800000, 0x00800010, 0x00010000, 0x00010010, 0x00810000, 0x00810010,
+ 0x00000200, 0x00000210, 0x00800200, 0x00800210, 0x00010200, 0x00010210,
+ 0x00810200, 0x00810210, 0x00100000, 0x00100010, 0x00900000, 0x00900010,
+ 0x00110000, 0x00110010, 0x00910000, 0x00910010, 0x00100200, 0x00100210,
+ 0x00900200, 0x00900210, 0x00110200, 0x00110210, 0x00910200, 0x00910210,
+ 0x00100000, 0x00100010, 0x00900000, 0x00900010, 0x00110000, 0x00110010,
+ 0x00910000, 0x00910010, 0x00100200, 0x00100210, 0x00900200, 0x00900210,
+ 0x00110200, 0x00110210, 0x00910200, 0x00910210, 0x00000004, 0x00000014,
+ 0x00800004, 0x00800014, 0x00010004, 0x00010014, 0x00810004, 0x00810014,
+ 0x00000204, 0x00000214, 0x00800204, 0x00800214, 0x00010204, 0x00010214,
+ 0x00810204, 0x00810214, 0x00000004, 0x00000014, 0x00800004, 0x00800014,
+ 0x00010004, 0x00010014, 0x00810004, 0x00810014, 0x00000204, 0x00000214,
+ 0x00800204, 0x00800214, 0x00010204, 0x00010214, 0x00810204, 0x00810214,
+ 0x00100004, 0x00100014, 0x00900004, 0x00900014, 0x00110004, 0x00110014,
+ 0x00910004, 0x00910014, 0x00100204, 0x00100214, 0x00900204, 0x00900214,
+ 0x00110204, 0x00110214, 0x00910204, 0x00910214, 0x00100004, 0x00100014,
+ 0x00900004, 0x00900014, 0x00110004, 0x00110014, 0x00910004, 0x00910014,
+ 0x00100204, 0x00100214, 0x00900204, 0x00900214, 0x00110204, 0x00110214,
+ 0x00910204, 0x00910214,
+ },
+ {
+ 0x00000000, 0x00000400, 0x00001000, 0x00001400, 0x00080000, 0x00080400,
+ 0x00081000, 0x00081400, 0x00000020, 0x00000420, 0x00001020, 0x00001420,
+ 0x00080020, 0x00080420, 0x00081020, 0x00081420, 0x00004000, 0x00004400,
+ 0x00005000, 0x00005400, 0x00084000, 0x00084400, 0x00085000, 0x00085400,
+ 0x00004020, 0x00004420, 0x00005020, 0x00005420, 0x00084020, 0x00084420,
+ 0x00085020, 0x00085420, 0x00000800, 0x00000c00, 0x00001800, 0x00001c00,
+ 0x00080800, 0x00080c00, 0x00081800, 0x00081c00, 0x00000820, 0x00000c20,
+ 0x00001820, 0x00001c20, 0x00080820, 0x00080c20, 0x00081820, 0x00081c20,
+ 0x00004800, 0x00004c00, 0x00005800, 0x00005c00, 0x00084800, 0x00084c00,
+ 0x00085800, 0x00085c00, 0x00004820, 0x00004c20, 0x00005820, 0x00005c20,
+ 0x00084820, 0x00084c20, 0x00085820, 0x00085c20, 0x00000000, 0x00000400,
+ 0x00001000, 0x00001400, 0x00080000, 0x00080400, 0x00081000, 0x00081400,
+ 0x00000020, 0x00000420, 0x00001020, 0x00001420, 0x00080020, 0x00080420,
+ 0x00081020, 0x00081420, 0x00004000, 0x00004400, 0x00005000, 0x00005400,
+ 0x00084000, 0x00084400, 0x00085000, 0x00085400, 0x00004020, 0x00004420,
+ 0x00005020, 0x00005420, 0x00084020, 0x00084420, 0x00085020, 0x00085420,
+ 0x00000800, 0x00000c00, 0x00001800, 0x00001c00, 0x00080800, 0x00080c00,
+ 0x00081800, 0x00081c00, 0x00000820, 0x00000c20, 0x00001820, 0x00001c20,
+ 0x00080820, 0x00080c20, 0x00081820, 0x00081c20, 0x00004800, 0x00004c00,
+ 0x00005800, 0x00005c00, 0x00084800, 0x00084c00, 0x00085800, 0x00085c00,
+ 0x00004820, 0x00004c20, 0x00005820, 0x00005c20, 0x00084820, 0x00084c20,
+ 0x00085820, 0x00085c20,
+ },
+ {
+ 0x00000000, 0x00000100, 0x00040000, 0x00040100, 0x00000000, 0x00000100,
+ 0x00040000, 0x00040100, 0x00000040, 0x00000140, 0x00040040, 0x00040140,
+ 0x00000040, 0x00000140, 0x00040040, 0x00040140, 0x00400000, 0x00400100,
+ 0x00440000, 0x00440100, 0x00400000, 0x00400100, 0x00440000, 0x00440100,
+ 0x00400040, 0x00400140, 0x00440040, 0x00440140, 0x00400040, 0x00400140,
+ 0x00440040, 0x00440140, 0x00008000, 0x00008100, 0x00048000, 0x00048100,
+ 0x00008000, 0x00008100, 0x00048000, 0x00048100, 0x00008040, 0x00008140,
+ 0x00048040, 0x00048140, 0x00008040, 0x00008140, 0x00048040, 0x00048140,
+ 0x00408000, 0x00408100, 0x00448000, 0x00448100, 0x00408000, 0x00408100,
+ 0x00448000, 0x00448100, 0x00408040, 0x00408140, 0x00448040, 0x00448140,
+ 0x00408040, 0x00408140, 0x00448040, 0x00448140, 0x00000008, 0x00000108,
+ 0x00040008, 0x00040108, 0x00000008, 0x00000108, 0x00040008, 0x00040108,
+ 0x00000048, 0x00000148, 0x00040048, 0x00040148, 0x00000048, 0x00000148,
+ 0x00040048, 0x00040148, 0x00400008, 0x00400108, 0x00440008, 0x00440108,
+ 0x00400008, 0x00400108, 0x00440008, 0x00440108, 0x00400048, 0x00400148,
+ 0x00440048, 0x00440148, 0x00400048, 0x00400148, 0x00440048, 0x00440148,
+ 0x00008008, 0x00008108, 0x00048008, 0x00048108, 0x00008008, 0x00008108,
+ 0x00048008, 0x00048108, 0x00008048, 0x00008148, 0x00048048, 0x00048148,
+ 0x00008048, 0x00008148, 0x00048048, 0x00048148, 0x00408008, 0x00408108,
+ 0x00448008, 0x00448108, 0x00408008, 0x00408108, 0x00448008, 0x00448108,
+ 0x00408048, 0x00408148, 0x00448048, 0x00448148, 0x00408048, 0x00408148,
+ 0x00448048, 0x00448148,
+ },
+};
+
+const uint32_t psbox[4][256] = {
+ {
+ 0x00000000, 0x00004000, 0x40000000, 0x40004000, 0x00000010, 0x00004010,
+ 0x40000010, 0x40004010, 0x00080000, 0x00084000, 0x40080000, 0x40084000,
+ 0x00080010, 0x00084010, 0x40080010, 0x40084010, 0x00000002, 0x00004002,
+ 0x40000002, 0x40004002, 0x00000012, 0x00004012, 0x40000012, 0x40004012,
+ 0x00080002, 0x00084002, 0x40080002, 0x40084002, 0x00080012, 0x00084012,
+ 0x40080012, 0x40084012, 0x00000200, 0x00004200, 0x40000200, 0x40004200,
+ 0x00000210, 0x00004210, 0x40000210, 0x40004210, 0x00080200, 0x00084200,
+ 0x40080200, 0x40084200, 0x00080210, 0x00084210, 0x40080210, 0x40084210,
+ 0x00000202, 0x00004202, 0x40000202, 0x40004202, 0x00000212, 0x00004212,
+ 0x40000212, 0x40004212, 0x00080202, 0x00084202, 0x40080202, 0x40084202,
+ 0x00080212, 0x00084212, 0x40080212, 0x40084212, 0x00008000, 0x0000c000,
+ 0x40008000, 0x4000c000, 0x00008010, 0x0000c010, 0x40008010, 0x4000c010,
+ 0x00088000, 0x0008c000, 0x40088000, 0x4008c000, 0x00088010, 0x0008c010,
+ 0x40088010, 0x4008c010, 0x00008002, 0x0000c002, 0x40008002, 0x4000c002,
+ 0x00008012, 0x0000c012, 0x40008012, 0x4000c012, 0x00088002, 0x0008c002,
+ 0x40088002, 0x4008c002, 0x00088012, 0x0008c012, 0x40088012, 0x4008c012,
+ 0x00008200, 0x0000c200, 0x40008200, 0x4000c200, 0x00008210, 0x0000c210,
+ 0x40008210, 0x4000c210, 0x00088200, 0x0008c200, 0x40088200, 0x4008c200,
+ 0x00088210, 0x0008c210, 0x40088210, 0x4008c210, 0x00008202, 0x0000c202,
+ 0x40008202, 0x4000c202, 0x00008212, 0x0000c212, 0x40008212, 0x4000c212,
+ 0x00088202, 0x0008c202, 0x40088202, 0x4008c202, 0x00088212, 0x0008c212,
+ 0x40088212, 0x4008c212, 0x00800000, 0x00804000, 0x40800000, 0x40804000,
+ 0x00800010, 0x00804010, 0x40800010, 0x40804010, 0x00880000, 0x00884000,
+ 0x40880000, 0x40884000, 0x00880010, 0x00884010, 0x40880010, 0x40884010,
+ 0x00800002, 0x00804002, 0x40800002, 0x40804002, 0x00800012, 0x00804012,
+ 0x40800012, 0x40804012, 0x00880002, 0x00884002, 0x40880002, 0x40884002,
+ 0x00880012, 0x00884012, 0x40880012, 0x40884012, 0x00800200, 0x00804200,
+ 0x40800200, 0x40804200, 0x00800210, 0x00804210, 0x40800210, 0x40804210,
+ 0x00880200, 0x00884200, 0x40880200, 0x40884200, 0x00880210, 0x00884210,
+ 0x40880210, 0x40884210, 0x00800202, 0x00804202, 0x40800202, 0x40804202,
+ 0x00800212, 0x00804212, 0x40800212, 0x40804212, 0x00880202, 0x00884202,
+ 0x40880202, 0x40884202, 0x00880212, 0x00884212, 0x40880212, 0x40884212,
+ 0x00808000, 0x0080c000, 0x40808000, 0x4080c000, 0x00808010, 0x0080c010,
+ 0x40808010, 0x4080c010, 0x00888000, 0x0088c000, 0x40888000, 0x4088c000,
+ 0x00888010, 0x0088c010, 0x40888010, 0x4088c010, 0x00808002, 0x0080c002,
+ 0x40808002, 0x4080c002, 0x00808012, 0x0080c012, 0x40808012, 0x4080c012,
+ 0x00888002, 0x0088c002, 0x40888002, 0x4088c002, 0x00888012, 0x0088c012,
+ 0x40888012, 0x4088c012, 0x00808200, 0x0080c200, 0x40808200, 0x4080c200,
+ 0x00808210, 0x0080c210, 0x40808210, 0x4080c210, 0x00888200, 0x0088c200,
+ 0x40888200, 0x4088c200, 0x00888210, 0x0088c210, 0x40888210, 0x4088c210,
+ 0x00808202, 0x0080c202, 0x40808202, 0x4080c202, 0x00808212, 0x0080c212,
+ 0x40808212, 0x4080c212, 0x00888202, 0x0088c202, 0x40888202, 0x4088c202,
+ 0x00888212, 0x0088c212, 0x40888212, 0x4088c212,
+ },
+ {
+ 0x00000000, 0x80000000, 0x00400000, 0x80400000, 0x00001000, 0x80001000,
+ 0x00401000, 0x80401000, 0x00000040, 0x80000040, 0x00400040, 0x80400040,
+ 0x00001040, 0x80001040, 0x00401040, 0x80401040, 0x04000000, 0x84000000,
+ 0x04400000, 0x84400000, 0x04001000, 0x84001000, 0x04401000, 0x84401000,
+ 0x04000040, 0x84000040, 0x04400040, 0x84400040, 0x04001040, 0x84001040,
+ 0x04401040, 0x84401040, 0x00000004, 0x80000004, 0x00400004, 0x80400004,
+ 0x00001004, 0x80001004, 0x00401004, 0x80401004, 0x00000044, 0x80000044,
+ 0x00400044, 0x80400044, 0x00001044, 0x80001044, 0x00401044, 0x80401044,
+ 0x04000004, 0x84000004, 0x04400004, 0x84400004, 0x04001004, 0x84001004,
+ 0x04401004, 0x84401004, 0x04000044, 0x84000044, 0x04400044, 0x84400044,
+ 0x04001044, 0x84001044, 0x04401044, 0x84401044, 0x00010000, 0x80010000,
+ 0x00410000, 0x80410000, 0x00011000, 0x80011000, 0x00411000, 0x80411000,
+ 0x00010040, 0x80010040, 0x00410040, 0x80410040, 0x00011040, 0x80011040,
+ 0x00411040, 0x80411040, 0x04010000, 0x84010000, 0x04410000, 0x84410000,
+ 0x04011000, 0x84011000, 0x04411000, 0x84411000, 0x04010040, 0x84010040,
+ 0x04410040, 0x84410040, 0x04011040, 0x84011040, 0x04411040, 0x84411040,
+ 0x00010004, 0x80010004, 0x00410004, 0x80410004, 0x00011004, 0x80011004,
+ 0x00411004, 0x80411004, 0x00010044, 0x80010044, 0x00410044, 0x80410044,
+ 0x00011044, 0x80011044, 0x00411044, 0x80411044, 0x04010004, 0x84010004,
+ 0x04410004, 0x84410004, 0x04011004, 0x84011004, 0x04411004, 0x84411004,
+ 0x04010044, 0x84010044, 0x04410044, 0x84410044, 0x04011044, 0x84011044,
+ 0x04411044, 0x84411044, 0x00000100, 0x80000100, 0x00400100, 0x80400100,
+ 0x00001100, 0x80001100, 0x00401100, 0x80401100, 0x00000140, 0x80000140,
+ 0x00400140, 0x80400140, 0x00001140, 0x80001140, 0x00401140, 0x80401140,
+ 0x04000100, 0x84000100, 0x04400100, 0x84400100, 0x04001100, 0x84001100,
+ 0x04401100, 0x84401100, 0x04000140, 0x84000140, 0x04400140, 0x84400140,
+ 0x04001140, 0x84001140, 0x04401140, 0x84401140, 0x00000104, 0x80000104,
+ 0x00400104, 0x80400104, 0x00001104, 0x80001104, 0x00401104, 0x80401104,
+ 0x00000144, 0x80000144, 0x00400144, 0x80400144, 0x00001144, 0x80001144,
+ 0x00401144, 0x80401144, 0x04000104, 0x84000104, 0x04400104, 0x84400104,
+ 0x04001104, 0x84001104, 0x04401104, 0x84401104, 0x04000144, 0x84000144,
+ 0x04400144, 0x84400144, 0x04001144, 0x84001144, 0x04401144, 0x84401144,
+ 0x00010100, 0x80010100, 0x00410100, 0x80410100, 0x00011100, 0x80011100,
+ 0x00411100, 0x80411100, 0x00010140, 0x80010140, 0x00410140, 0x80410140,
+ 0x00011140, 0x80011140, 0x00411140, 0x80411140, 0x04010100, 0x84010100,
+ 0x04410100, 0x84410100, 0x04011100, 0x84011100, 0x04411100, 0x84411100,
+ 0x04010140, 0x84010140, 0x04410140, 0x84410140, 0x04011140, 0x84011140,
+ 0x04411140, 0x84411140, 0x00010104, 0x80010104, 0x00410104, 0x80410104,
+ 0x00011104, 0x80011104, 0x00411104, 0x80411104, 0x00010144, 0x80010144,
+ 0x00410144, 0x80410144, 0x00011144, 0x80011144, 0x00411144, 0x80411144,
+ 0x04010104, 0x84010104, 0x04410104, 0x84410104, 0x04011104, 0x84011104,
+ 0x04411104, 0x84411104, 0x04010144, 0x84010144, 0x04410144, 0x84410144,
+ 0x04011144, 0x84011144, 0x04411144, 0x84411144,
+ },
+ {
+ 0x00000000, 0x00002000, 0x00200000, 0x00202000, 0x00000008, 0x00002008,
+ 0x00200008, 0x00202008, 0x10000000, 0x10002000, 0x10200000, 0x10202000,
+ 0x10000008, 0x10002008, 0x10200008, 0x10202008, 0x20000000, 0x20002000,
+ 0x20200000, 0x20202000, 0x20000008, 0x20002008, 0x20200008, 0x20202008,
+ 0x30000000, 0x30002000, 0x30200000, 0x30202000, 0x30000008, 0x30002008,
+ 0x30200008, 0x30202008, 0x00000080, 0x00002080, 0x00200080, 0x00202080,
+ 0x00000088, 0x00002088, 0x00200088, 0x00202088, 0x10000080, 0x10002080,
+ 0x10200080, 0x10202080, 0x10000088, 0x10002088, 0x10200088, 0x10202088,
+ 0x20000080, 0x20002080, 0x20200080, 0x20202080, 0x20000088, 0x20002088,
+ 0x20200088, 0x20202088, 0x30000080, 0x30002080, 0x30200080, 0x30202080,
+ 0x30000088, 0x30002088, 0x30200088, 0x30202088, 0x00040000, 0x00042000,
+ 0x00240000, 0x00242000, 0x00040008, 0x00042008, 0x00240008, 0x00242008,
+ 0x10040000, 0x10042000, 0x10240000, 0x10242000, 0x10040008, 0x10042008,
+ 0x10240008, 0x10242008, 0x20040000, 0x20042000, 0x20240000, 0x20242000,
+ 0x20040008, 0x20042008, 0x20240008, 0x20242008, 0x30040000, 0x30042000,
+ 0x30240000, 0x30242000, 0x30040008, 0x30042008, 0x30240008, 0x30242008,
+ 0x00040080, 0x00042080, 0x00240080, 0x00242080, 0x00040088, 0x00042088,
+ 0x00240088, 0x00242088, 0x10040080, 0x10042080, 0x10240080, 0x10242080,
+ 0x10040088, 0x10042088, 0x10240088, 0x10242088, 0x20040080, 0x20042080,
+ 0x20240080, 0x20242080, 0x20040088, 0x20042088, 0x20240088, 0x20242088,
+ 0x30040080, 0x30042080, 0x30240080, 0x30242080, 0x30040088, 0x30042088,
+ 0x30240088, 0x30242088, 0x01000000, 0x01002000, 0x01200000, 0x01202000,
+ 0x01000008, 0x01002008, 0x01200008, 0x01202008, 0x11000000, 0x11002000,
+ 0x11200000, 0x11202000, 0x11000008, 0x11002008, 0x11200008, 0x11202008,
+ 0x21000000, 0x21002000, 0x21200000, 0x21202000, 0x21000008, 0x21002008,
+ 0x21200008, 0x21202008, 0x31000000, 0x31002000, 0x31200000, 0x31202000,
+ 0x31000008, 0x31002008, 0x31200008, 0x31202008, 0x01000080, 0x01002080,
+ 0x01200080, 0x01202080, 0x01000088, 0x01002088, 0x01200088, 0x01202088,
+ 0x11000080, 0x11002080, 0x11200080, 0x11202080, 0x11000088, 0x11002088,
+ 0x11200088, 0x11202088, 0x21000080, 0x21002080, 0x21200080, 0x21202080,
+ 0x21000088, 0x21002088, 0x21200088, 0x21202088, 0x31000080, 0x31002080,
+ 0x31200080, 0x31202080, 0x31000088, 0x31002088, 0x31200088, 0x31202088,
+ 0x01040000, 0x01042000, 0x01240000, 0x01242000, 0x01040008, 0x01042008,
+ 0x01240008, 0x01242008, 0x11040000, 0x11042000, 0x11240000, 0x11242000,
+ 0x11040008, 0x11042008, 0x11240008, 0x11242008, 0x21040000, 0x21042000,
+ 0x21240000, 0x21242000, 0x21040008, 0x21042008, 0x21240008, 0x21242008,
+ 0x31040000, 0x31042000, 0x31240000, 0x31242000, 0x31040008, 0x31042008,
+ 0x31240008, 0x31242008, 0x01040080, 0x01042080, 0x01240080, 0x01242080,
+ 0x01040088, 0x01042088, 0x01240088, 0x01242088, 0x11040080, 0x11042080,
+ 0x11240080, 0x11242080, 0x11040088, 0x11042088, 0x11240088, 0x11242088,
+ 0x21040080, 0x21042080, 0x21240080, 0x21242080, 0x21040088, 0x21042088,
+ 0x21240088, 0x21242088, 0x31040080, 0x31042080, 0x31240080, 0x31242080,
+ 0x31040088, 0x31042088, 0x31240088, 0x31242088,
+ },
+ {
+ 0x00000000, 0x00000800, 0x00020000, 0x00020800, 0x00000020, 0x00000820,
+ 0x00020020, 0x00020820, 0x08000000, 0x08000800, 0x08020000, 0x08020800,
+ 0x08000020, 0x08000820, 0x08020020, 0x08020820, 0x02000000, 0x02000800,
+ 0x02020000, 0x02020800, 0x02000020, 0x02000820, 0x02020020, 0x02020820,
+ 0x0a000000, 0x0a000800, 0x0a020000, 0x0a020800, 0x0a000020, 0x0a000820,
+ 0x0a020020, 0x0a020820, 0x00000400, 0x00000c00, 0x00020400, 0x00020c00,
+ 0x00000420, 0x00000c20, 0x00020420, 0x00020c20, 0x08000400, 0x08000c00,
+ 0x08020400, 0x08020c00, 0x08000420, 0x08000c20, 0x08020420, 0x08020c20,
+ 0x02000400, 0x02000c00, 0x02020400, 0x02020c00, 0x02000420, 0x02000c20,
+ 0x02020420, 0x02020c20, 0x0a000400, 0x0a000c00, 0x0a020400, 0x0a020c00,
+ 0x0a000420, 0x0a000c20, 0x0a020420, 0x0a020c20, 0x00100000, 0x00100800,
+ 0x00120000, 0x00120800, 0x00100020, 0x00100820, 0x00120020, 0x00120820,
+ 0x08100000, 0x08100800, 0x08120000, 0x08120800, 0x08100020, 0x08100820,
+ 0x08120020, 0x08120820, 0x02100000, 0x02100800, 0x02120000, 0x02120800,
+ 0x02100020, 0x02100820, 0x02120020, 0x02120820, 0x0a100000, 0x0a100800,
+ 0x0a120000, 0x0a120800, 0x0a100020, 0x0a100820, 0x0a120020, 0x0a120820,
+ 0x00100400, 0x00100c00, 0x00120400, 0x00120c00, 0x00100420, 0x00100c20,
+ 0x00120420, 0x00120c20, 0x08100400, 0x08100c00, 0x08120400, 0x08120c00,
+ 0x08100420, 0x08100c20, 0x08120420, 0x08120c20, 0x02100400, 0x02100c00,
+ 0x02120400, 0x02120c00, 0x02100420, 0x02100c20, 0x02120420, 0x02120c20,
+ 0x0a100400, 0x0a100c00, 0x0a120400, 0x0a120c00, 0x0a100420, 0x0a100c20,
+ 0x0a120420, 0x0a120c20, 0x00000001, 0x00000801, 0x00020001, 0x00020801,
+ 0x00000021, 0x00000821, 0x00020021, 0x00020821, 0x08000001, 0x08000801,
+ 0x08020001, 0x08020801, 0x08000021, 0x08000821, 0x08020021, 0x08020821,
+ 0x02000001, 0x02000801, 0x02020001, 0x02020801, 0x02000021, 0x02000821,
+ 0x02020021, 0x02020821, 0x0a000001, 0x0a000801, 0x0a020001, 0x0a020801,
+ 0x0a000021, 0x0a000821, 0x0a020021, 0x0a020821, 0x00000401, 0x00000c01,
+ 0x00020401, 0x00020c01, 0x00000421, 0x00000c21, 0x00020421, 0x00020c21,
+ 0x08000401, 0x08000c01, 0x08020401, 0x08020c01, 0x08000421, 0x08000c21,
+ 0x08020421, 0x08020c21, 0x02000401, 0x02000c01, 0x02020401, 0x02020c01,
+ 0x02000421, 0x02000c21, 0x02020421, 0x02020c21, 0x0a000401, 0x0a000c01,
+ 0x0a020401, 0x0a020c01, 0x0a000421, 0x0a000c21, 0x0a020421, 0x0a020c21,
+ 0x00100001, 0x00100801, 0x00120001, 0x00120801, 0x00100021, 0x00100821,
+ 0x00120021, 0x00120821, 0x08100001, 0x08100801, 0x08120001, 0x08120801,
+ 0x08100021, 0x08100821, 0x08120021, 0x08120821, 0x02100001, 0x02100801,
+ 0x02120001, 0x02120801, 0x02100021, 0x02100821, 0x02120021, 0x02120821,
+ 0x0a100001, 0x0a100801, 0x0a120001, 0x0a120801, 0x0a100021, 0x0a100821,
+ 0x0a120021, 0x0a120821, 0x00100401, 0x00100c01, 0x00120401, 0x00120c01,
+ 0x00100421, 0x00100c21, 0x00120421, 0x00120c21, 0x08100401, 0x08100c01,
+ 0x08120401, 0x08120c01, 0x08100421, 0x08100c21, 0x08120421, 0x08120c21,
+ 0x02100401, 0x02100c01, 0x02120401, 0x02120c01, 0x02100421, 0x02100c21,
+ 0x02120421, 0x02120c21, 0x0a100401, 0x0a100c01, 0x0a120401, 0x0a120c01,
+ 0x0a100421, 0x0a100c21, 0x0a120421, 0x0a120c21,
+ },
+};
diff --git a/configure.ac b/configure.ac
index 9846e3f..f843b51 100644
--- a/configure.ac
+++ b/configure.ac
@@ -24,7 +24,6 @@ AH_BOTTOM(
# Checks for programs.
AC_CANONICAL_HOST
AC_PROG_CC
-AX_PROG_CC_FOR_BUILD
# Dependencies
PKG_PROG_PKG_CONFIG
diff --git a/gen-des-tables.c b/gen-des-tables.c
index cf2b76f..ee18cd4 100644
--- a/gen-des-tables.c
+++ b/gen-des-tables.c
@@ -40,6 +40,12 @@
* by David Burren <davidb@werj.com.au>.
*/
+/*
+ * This program can regenerate the tables in alg-des-tables.c.
+ * It is preserved as documentation, but it should no longer be
+ * necessary to run it.
+ */
+
#include "crypt-port.h"
#include <inttypes.h>
@@ -341,11 +347,6 @@ main(void)
{
des_init();
- puts("/* Generated by gen-des-tables. DO NOT EDIT. */\n"
- "\n"
- "#include \"crypt-port.h\"\n"
- "#include \"alg-des.h\"");
-
write_table_u8(4, 4096, &m_sbox_[0][0], "m_sbox");
write_table_u32(8, 256, &ip_maskl_[0][0], "ip_maskl");
diff --git a/m4/ax_prog_cc_for_build.m4 b/m4/ax_prog_cc_for_build.m4
deleted file mode 100644
index ac6043a..0000000
--- a/m4/ax_prog_cc_for_build.m4
+++ /dev/null
@@ -1,158 +0,0 @@
-# ===========================================================================
-# https://www.gnu.org/software/autoconf-archive/ax_prog_cc_for_build.html
-# ===========================================================================
-#
-# SYNOPSIS
-#
-# AX_PROG_CC_FOR_BUILD
-#
-# DESCRIPTION
-#
-# This macro searches for a C compiler that generates native executables,
-# that is a C compiler that surely is not a cross-compiler. This can be
-# useful if you have to generate source code at compile-time like for
-# example GCC does.
-#
-# The macro sets the CC_FOR_BUILD and CPP_FOR_BUILD macros to anything
-# needed to compile or link (CC_FOR_BUILD) and preprocess (CPP_FOR_BUILD).
-# The value of these variables can be overridden by the user by specifying
-# a compiler with an environment variable (like you do for standard CC).
-#
-# It also sets BUILD_EXEEXT and BUILD_OBJEXT to the executable and object
-# file extensions for the build platform, and GCC_FOR_BUILD to `yes' if
-# the compiler we found is GCC. All these variables but GCC_FOR_BUILD are
-# substituted in the Makefile.
-#
-# LICENSE
-#
-# Copyright (c) 2008 Paolo Bonzini <bonzini@gnu.org>
-#
-# Copying and distribution of this file, with or without modification, are
-# permitted in any medium without royalty provided the copyright notice
-# and this notice are preserved. This file is offered as-is, without any
-# warranty.
-
-#serial 9
-
-AU_ALIAS([AC_PROG_CC_FOR_BUILD], [AX_PROG_CC_FOR_BUILD])
-AC_DEFUN([AX_PROG_CC_FOR_BUILD], [dnl
-AC_REQUIRE([AC_PROG_CC])dnl
-AC_REQUIRE([AC_PROG_CPP])dnl
-AC_REQUIRE([AC_EXEEXT])dnl
-AC_REQUIRE([AC_CANONICAL_HOST])dnl
-
-dnl Use the standard macros, but make them use other variable names
-dnl
-pushdef([_AC_LANG_ABBREV], [build_c])dnl
-pushdef([ac_cv_prog_CPP], ac_cv_build_prog_CPP)dnl
-pushdef([ac_cv_prog_gcc], ac_cv_build_prog_gcc)dnl
-pushdef([ac_cv_prog_cc_works], ac_cv_build_prog_cc_works)dnl
-pushdef([ac_cv_prog_cc_cross], ac_cv_build_prog_cc_cross)dnl
-pushdef([ac_cv_prog_cc_g], ac_cv_build_prog_cc_g)dnl
-pushdef([ac_cv_prog_cc_stdc], ac_cv_build_prog_cc_stdc)dnl
-pushdef([ac_cv_prog_cc_c11], ac_cv_build_prog_cc_c11)dnl
-pushdef([ac_cv_prog_cc_c99], ac_cv_build_prog_cc_c99)dnl
-pushdef([ac_prog_cc_stdc], ac_build_prog_cc_stdc)dnl
-pushdef([am_cv_CC_dependencies_compiler_type],
- am_cv_build_CC_depencies_compiler_type)dnl
-pushdef([am_cv_prog_cc_c_o], am_cv_build_prog_cc_c_o)dnl
-pushdef([ac_cv_exeext], ac_cv_build_exeext)dnl
-pushdef([ac_cv_objext], ac_cv_build_objext)dnl
-pushdef([ac_exeext], ac_build_exeext)dnl
-pushdef([ac_objext], ac_build_objext)dnl
-pushdef([CC], CC_FOR_BUILD)dnl
-pushdef([CPP], CPP_FOR_BUILD)dnl
-pushdef([CFLAGS], CFLAGS_FOR_BUILD)dnl
-pushdef([CPPFLAGS], CPPFLAGS_FOR_BUILD)dnl
-pushdef([LDFLAGS], LDFLAGS_FOR_BUILD)dnl
-pushdef([host], build)dnl
-pushdef([host_alias], build_alias)dnl
-pushdef([host_cpu], build_cpu)dnl
-pushdef([host_vendor], build_vendor)dnl
-pushdef([host_os], build_os)dnl
-pushdef([ac_cv_host], ac_cv_build)dnl
-pushdef([ac_cv_host_alias], ac_cv_build_alias)dnl
-pushdef([ac_cv_host_cpu], ac_cv_build_cpu)dnl
-pushdef([ac_cv_host_vendor], ac_cv_build_vendor)dnl
-pushdef([ac_cv_host_os], ac_cv_build_os)dnl
-pushdef([ac_cpp], ac_build_cpp)dnl
-pushdef([ac_compile], ac_build_compile)dnl
-pushdef([ac_link], ac_build_link)dnl
-
-dnl Shim the shell functions used by AC_COMPILE_IFELSE etc.
-AC_REQUIRE_SHELL_FN([ac_fn_build_c_try_cpp],
- [# Forward ac_fn_build_c_* to ac_fn_c_*.],
- [ac_fn_c_try_cpp "$][@"])
-AC_REQUIRE_SHELL_FN([ac_fn_build_c_try_compile],,[ac_fn_c_try_compile "$][@"])
-AC_REQUIRE_SHELL_FN([ac_fn_build_c_try_link],,[ac_fn_c_try_link "$][@"])
-AC_REQUIRE_SHELL_FN([ac_fn_build_c_try_run],,[ac_fn_c_try_run "$][@"])
-AC_REQUIRE_SHELL_FN([ac_fn_build_c_check_decl],,[ac_fn_c_check_decl "$][@"])
-AC_REQUIRE_SHELL_FN([ac_fn_build_c_check_func],,[ac_fn_c_check_func "$][@"])
-AC_REQUIRE_SHELL_FN([ac_fn_build_c_check_header_mongrel],,[ac_fn_c_check_header_mongrel "$][@"])
-AC_REQUIRE_SHELL_FN([ac_fn_build_c_check_header_compile],,[ac_fn_c_check_header_compile "$][@"])
-AC_REQUIRE_SHELL_FN([ac_fn_build_c_check_header_preproc],,[ac_fn_c_check_header_preproc "$][@"])
-AC_REQUIRE_SHELL_FN([ac_fn_build_c_check_member],,[ac_fn_c_check_member "$][@"])
-AC_REQUIRE_SHELL_FN([ac_fn_build_c_check_type],,[ac_fn_c_check_type "$][@"])
-AC_REQUIRE_SHELL_FN([ac_fn_build_c_compute_int],,[ac_fn_c_compute_int "$][@"])
-AC_REQUIRE_SHELL_FN([ac_fn_build_c_find_intX_t],,[ac_fn_c_find_intX_t "$][@"])
-AC_REQUIRE_SHELL_FN([ac_fn_build_c_find_uintX_t],,[ac_fn_c_find_uintX_t "$][@"])
-
-save_cross_compiling=$cross_compiling
-save_ac_tool_prefix=$ac_tool_prefix
-cross_compiling=no
-ac_tool_prefix=
-
-AC_PROG_CC
-AC_PROG_CPP
-AC_EXEEXT
-
-ac_tool_prefix=$save_ac_tool_prefix
-cross_compiling=$save_cross_compiling
-
-dnl Restore the old definitions
-dnl
-popdef([ac_link])dnl
-popdef([ac_compile])dnl
-popdef([ac_cpp])dnl
-popdef([ac_cv_host_os])dnl
-popdef([ac_cv_host_vendor])dnl
-popdef([ac_cv_host_cpu])dnl
-popdef([ac_cv_host_alias])dnl
-popdef([ac_cv_host])dnl
-popdef([host_os])dnl
-popdef([host_vendor])dnl
-popdef([host_cpu])dnl
-popdef([host_alias])dnl
-popdef([host])dnl
-popdef([LDFLAGS])dnl
-popdef([CPPFLAGS])dnl
-popdef([CFLAGS])dnl
-popdef([CPP])dnl
-popdef([CC])dnl
-popdef([ac_objext])dnl
-popdef([ac_exeext])dnl
-popdef([ac_cv_objext])dnl
-popdef([ac_cv_exeext])dnl
-popdef([am_cv_prog_cc_c_o])dnl
-popdef([am_cv_CC_dependencies_compiler_type])dnl
-popdef([ac_prog_cc_stdc])dnl
-popdef([ac_cv_prog_cc_c99])dnl
-popdef([ac_cv_prog_cc_c11])dnl
-popdef([ac_cv_prog_cc_stdc])dnl
-popdef([ac_cv_prog_cc_g])dnl
-popdef([ac_cv_prog_cc_cross])dnl
-popdef([ac_cv_prog_cc_works])dnl
-popdef([ac_cv_prog_gcc])dnl
-popdef([ac_cv_prog_CPP])dnl
-popdef([_AC_LANG_ABBREV])dnl
-
-dnl Finally, set Makefile variables
-dnl
-BUILD_EXEEXT=$ac_build_exeext
-BUILD_OBJEXT=$ac_build_objext
-AC_SUBST(BUILD_EXEEXT)dnl
-AC_SUBST(BUILD_OBJEXT)dnl
-AC_SUBST([CFLAGS_FOR_BUILD])dnl
-AC_SUBST([CPPFLAGS_FOR_BUILD])dnl
-AC_SUBST([LDFLAGS_FOR_BUILD])dnl
-])
From ed4be6afa7b34fe0d827cc3f7f9608de0d9325cd Mon Sep 17 00:00:00 2001
From: Zack Weinberg <zackw@panix.com>
Date: Wed, 4 Jul 2018 21:42:36 -0400
Subject: [PATCH 15/38] Make it possible to disable individual hashes at
configure time.
The table of supported hash algorithms now lives in hashes.lst.
The configure script accepts an option --enable-hashes which takes a
comma-separated list of hash algorithms to include. We generate a
header that defines INCLUDE_ macros for each hash that is enabled,
and all of the code is conditionalized appropriately.
The default is --enable-hashes=all. --enable-hashes=strong is the
equivalent of the old --disable-weak-hashes. You could even do
--enable-hashes=bcrypt,des to get a binary-compatible libcrypt.so.1
that still supports almost nothing other than bcrypt.
---
.gitignore | 1 +
Makefile.am | 63 +++++++++----------
README.md | 12 ++--
alg-des-tables.c | 4 ++
alg-des.c | 5 ++
alg-hmac-sha1.c | 4 ++
alg-md4.c | 4 ++
alg-md5.c | 3 +
alg-sha1.c | 3 +
alg-sha256.c | 3 +
alg-sha512.c | 3 +
configure.ac | 59 ++++++++---------
crypt-bcrypt.c | 4 ++
crypt-des.c | 61 ++++++++++--------
crypt-gensalt.c | 4 ++
crypt-md5.c | 3 +
crypt-nthash.c | 4 ++
crypt-pbkdf1-sha1.c | 4 ++
crypt-port.h | 74 +++++++++++-----------
crypt-private.h | 82 ------------------------
crypt-sha256.c | 3 +
crypt-sha512.c | 3 +
crypt-sunmd5.c | 5 ++
crypt.c | 94 +++++++++-------------------
gen-hashes.awk | 160 +++++++++++++++++++++++++++++++++++++++++++++++
hashes.lst | 40 ++++++++++++
sel-hashes.awk | 89 ++++++++++++++++++++++++++
test-alg-des.c | 12 ++++
test-alg-hmac-sha1.c | 12 ++++
test-alg-md4.c | 12 ++++
test-alg-md5.c | 12 ++++
test-alg-sha1.c | 12 ++++
test-alg-sha256.c | 12 ++++
test-alg-sha512.c | 12 ++++
test-crypt-badsalt.c | 2 +
test-crypt-bcrypt.c | 12 ++++
test-crypt-des.c | 18 +++++-
test-crypt-md5.c | 12 ++++
test-crypt-nthash.c | 12 ++++
test-crypt-pbkdf1-sha1.c | 12 ++++
test-crypt-sha256.c | 12 ++++
test-crypt-sha512.c | 12 ++++
test-crypt-sunmd5.c | 12 ++++
test-gensalt.c | 61 +++++++++++++-----
44 files changed, 745 insertions(+), 298 deletions(-)
create mode 100644 gen-hashes.awk
create mode 100644 hashes.lst
create mode 100644 sel-hashes.awk
diff --git a/.gitignore b/.gitignore
index 5e998dd..9f443bd 100644
--- a/.gitignore
+++ b/.gitignore
@@ -43,6 +43,7 @@
*.so
*.trs
/crypt.h
+/crypt-hashes.h
/crypt-symbol-vers.h
/libcrypt.map
/test-alg-des
diff --git a/Makefile.am b/Makefile.am
index 71fbd62..040d719 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -12,12 +12,14 @@ AM_CFLAGS = $(WARN_CFLAGS)
EXTRA_DIST = \
LICENSING THANKS \
libcrypt.map.in libcrypt.minver \
- gen-map.awk gen-vers.awk gen-crypt-h.awk
+ gen-map.awk gen-vers.awk gen-crypt-h.awk \
+ gen-hashes.awk sel-hashes.awk hashes.lst
notrans_dist_man3_MANS = crypt_rn.3 crypt_gensalt.3
notrans_dist_man5_MANS = crypt.5
nodist_include_HEADERS = crypt.h
+nodist_noinst_HEADERS = crypt-hashes.h
noinst_HEADERS = \
alg-des.h alg-hmac-sha1.h alg-md4.h alg-md5.h \
alg-sha1.h alg-sha256.h alg-sha512.h byteorder.h \
@@ -26,9 +28,12 @@ noinst_HEADERS = \
lib_LTLIBRARIES = libcrypt.la
libcrypt_la_SOURCES = \
- crypt.c crypt-static.c crypt-gensalt.c crypt-gensalt-static.c \
- crypt-bcrypt.c crypt-sha512.c crypt-sha256.c \
- alg-sha512.c alg-sha256.c randombytes.c
+ alg-des.c alg-des-tables.c alg-hmac-sha1.c alg-md4.c alg-md5.c \
+ alg-sha1.c alg-sha256.c alg-sha512.c \
+ crypt.c crypt-bcrypt.c crypt-des.c crypt-gensalt-static.c \
+ crypt-gensalt.c crypt-md5.c crypt-nthash.c crypt-pbkdf1-sha1.c \
+ crypt-sha256.c crypt-sha512.c crypt-static.c crypt-sunmd5.c \
+ randombytes.c
pkgconfig_DATA = libxcrypt.pc
@@ -49,6 +54,7 @@ CONFIG_STATUS_DEPENDENCIES = libcrypt.minver
EXTRA_libcrypt_la_DEPENDENCIES = libcrypt.map
CLEANFILES = libcrypt.map libcrypt.map.T \
crypt-symbol-vers.h crypt-symbol-vers.h.T \
+ crypt-hashes.h crypt-hashes.h.T \
crypt.h crypt.h.T
libcrypt.map: libcrypt.map.in gen-map.awk Makefile
@@ -70,6 +76,12 @@ crypt.h: crypt-base.h gen-crypt-h.awk config.h
> crypt.h.T
$(AM_V_at)mv -f crypt.h.T crypt.h
+crypt-hashes.h: hashes.lst gen-hashes.awk Makefile
+ $(AM_V_GEN)LC_ALL=C $(AWK) -f $(srcdir)/gen-hashes.awk \
+ -v ENABLED_HASHES=$(hashes_enabled) \
+ $(srcdir)/hashes.lst > crypt-hashes.h.T
+ $(AM_V_at)mv -f crypt-hashes.h.T crypt-hashes.h
+
# When we are being binary compatible, also install symbolic links to
# mimic SUSE's libowcrypt; any program that uses -lowcrypt in its
# build, or already has a NEEDED entry for libowcrypt.so.1, will be
@@ -108,30 +120,13 @@ endif
endif
check_PROGRAMS = \
- test-alg-sha256 test-alg-sha512 \
- test-crypt-sha256 test-crypt-sha512 test-crypt-bcrypt \
- test-crypt-nonnull test-byteorder test-gensalt
-
-if ENABLE_WEAK_HASHES
-libcrypt_la_SOURCES += \
- crypt-des.c crypt-md5.c alg-des.c alg-des-tables.c alg-md5.c
-
-if ENABLE_WEAK_NON_GLIBC_HASHES
-libcrypt_la_SOURCES += \
- crypt-nthash.c crypt-pbkdf1-sha1.c crypt-sunmd5.c \
- alg-hmac-sha1.c alg-md4.c alg-sha1.c
-endif
-
-check_PROGRAMS += \
- test-alg-des test-alg-md5 test-crypt-des test-crypt-md5 \
- test-crypt-badsalt
-
-if ENABLE_WEAK_NON_GLIBC_HASHES
-check_PROGRAMS += \
- test-alg-hmac-sha1 test-alg-md4 test-alg-sha1 \
- test-crypt-nthash test-crypt-sunmd5 test-crypt-pbkdf1-sha1
-endif
-endif
+ test-alg-des test-alg-hmac-sha1 test-alg-md4 test-alg-md5 \
+ test-alg-sha1 test-alg-sha256 test-alg-sha512 \
+ test-crypt-badsalt test-crypt-bcrypt test-crypt-des \
+ test-crypt-md5 test-crypt-nonnull test-crypt-nthash \
+ test-crypt-pbkdf1-sha1 test-crypt-sha256 test-crypt-sha512 \
+ test-crypt-sunmd5 \
+ test-byteorder test-gensalt
if ENABLE_OBSOLETE_API
libcrypt_la_SOURCES += crypt-des-obsolete.c
@@ -187,7 +182,11 @@ test_alg_sha256_LDADD = alg-sha256.lo
test_alg_sha512_LDADD = alg-sha512.lo
-# Every object file in the library depends on crypt-symbol-vers.h,
-# which is a generated file, so automatic dependency generation will
-# not detect it.
-$(libcrypt_la_OBJECTS): crypt-symbol-vers.h
+# Every object file depends on crypt-symbol-vers.h and crypt-hashes.h,
+# which are generated files, so automatic dependency generation is not
+# sufficient. Most of the test programs depend on either libcrypt.la
+# or one of its components, so they do not need an explicit dependency
+# (after the first *successful* build, automatic dependency generation
+# will reveal the direct dependency) but a few don't.
+$(libcrypt_la_OBJECTS): crypt-symbol-vers.h crypt-hashes.h
+$(test_byteorder_OBJECTS): crypt-symbol-vers.h crypt-hashes.h
diff --git a/README.md b/README.md
index 869d46f..9211a33 100644
--- a/README.md
+++ b/README.md
@@ -92,11 +92,13 @@ Linux. We are willing to consider adding binary backward
compatibility for other operating systems' existing libcrypts, but we
don't currently plan to do that work ourselves.
-It is also possible to remove support for DES, MD5, NTHASH and SUNMD5
-password hashes, by supplying the `--disable-weak-hashes` switch to
-`configure`. This option implies `--disable-obsolete-api`. It should
-only be used in contexts where there are definitely no user accounts
-that are old enough to have stored their password with an old hash.
+Individual hash functions may be enabled or disabled by use of the
+`--enable-hashes` switch to `configure`. The default is to enable all
+supported hashes. Disabling the traditional 'des' hash algorithm
+implies `--disable-obsolete-api`. Security-conscious environments
+without backward compatibility constraints are encouraged to use
+`--enable-hashes=strong`, which enables only the hash functions that
+are strong enough to be safe for newly hashed passwords.
The original implementation of the SUNMD5 hashing algorithm has a bug,
which is mimicked by libxcrypt to be fully compatible with hashes
diff --git a/alg-des-tables.c b/alg-des-tables.c
index 0bf9c88..c46d1c4 100644
--- a/alg-des-tables.c
+++ b/alg-des-tables.c
@@ -49,6 +49,8 @@
#include "crypt-port.h"
#include "alg-des.h"
+#if INCLUDE_des || INCLUDE_des_xbsd || INCLUDE_des_big
+
const uint8_t m_sbox[4][4096] = {
{
0xef, 0xe3, 0xe1, 0xed, 0xe8, 0xe4, 0xee, 0xe7, 0xe6, 0xef, 0xeb, 0xe2,
@@ -3842,3 +3844,5 @@ const uint32_t psbox[4][256] = {
0x0a100421, 0x0a100c21, 0x0a120421, 0x0a120c21,
},
};
+
+#endif
diff --git a/alg-des.c b/alg-des.c
index 3e62fe2..959d0f7 100644
--- a/alg-des.c
+++ b/alg-des.c
@@ -59,6 +59,9 @@
*/
#include "crypt-port.h"
+
+#if INCLUDE_des || INCLUDE_des_big || INCLUDE_des_xbsd
+
#include "alg-des.h"
#include "byteorder.h"
@@ -261,3 +264,5 @@ des_crypt_block (struct des_ctx *restrict ctx,
cpu_to_be32 (out, l_out);
cpu_to_be32 (out + 4, r_out);
}
+
+#endif
diff --git a/alg-hmac-sha1.c b/alg-hmac-sha1.c
index 2940774..0b22163 100644
--- a/alg-hmac-sha1.c
+++ b/alg-hmac-sha1.c
@@ -37,6 +37,8 @@
#include <stdlib.h>
+#if INCLUDE_sha1
+
/* Don't change these */
#define HMAC_IPAD 0x36
#define HMAC_OPAD 0x5c
@@ -125,3 +127,5 @@ hmac_sha1_process_data (const uint8_t *text, size_t text_len,
sha1_process_bytes (resbuf, &ctx, HASH_LENGTH);
sha1_finish_ctx(&ctx, resbuf);
}
+
+#endif
diff --git a/alg-md4.c b/alg-md4.c
index 56367df..ce62490 100644
--- a/alg-md4.c
+++ b/alg-md4.c
@@ -19,6 +19,8 @@
#include "alg-md4.h"
#include "byteorder.h"
+#if INCLUDE_nthash
+
/*
* The basic MD4 functions.
*/
@@ -250,3 +252,5 @@ md4_finish_ctx (struct md4_ctx *ctx, void *resbuf)
return md4_read_ctx (ctx, resbuf);
}
+
+#endif
diff --git a/alg-md5.c b/alg-md5.c
index e9b3412..df49fc6 100644
--- a/alg-md5.c
+++ b/alg-md5.c
@@ -23,6 +23,7 @@
#include "alg-md5.h"
#include "byteorder.h"
+#if INCLUDE_md5 || INCLUDE_sunmd5
static void md5_process_block (const void *buffer, size_t len,
struct md5_ctx *ctx);
@@ -303,3 +304,5 @@ md5_process_block (const void *buffer, size_t len, struct md5_ctx *ctx)
ctx->C = C;
ctx->D = D;
}
+
+#endif
diff --git a/alg-sha1.c b/alg-sha1.c
index 13ff75a..421ffbd 100644
--- a/alg-sha1.c
+++ b/alg-sha1.c
@@ -72,6 +72,7 @@ modified for use with libxcrypt
#include "crypt-port.h"
#include "alg-sha1.h"
+#if INCLUDE_sha1
#define SHA1_DIGEST_SIZE 20
@@ -278,3 +279,5 @@ sha1_finish_ctx (struct sha1_ctx *ctx, void *resbuf)
return resbuf;
}
+
+#endif
diff --git a/alg-sha256.c b/alg-sha256.c
index d4921a5..713385d 100644
--- a/alg-sha256.c
+++ b/alg-sha256.c
@@ -22,6 +22,7 @@
#include "alg-sha256.h"
#include "byteorder.h"
+#if INCLUDE_sha256
/* Constants for SHA256 from FIPS 180-2:4.2.2. */
static const uint32_t K[64] =
@@ -251,3 +252,5 @@ sha256_process_bytes (const void *buffer, size_t len, struct sha256_ctx *ctx)
ctx->buflen = (uint32_t)left_over;
}
}
+
+#endif
diff --git a/alg-sha512.c b/alg-sha512.c
index 5010bc4..6a6aab2 100644
--- a/alg-sha512.c
+++ b/alg-sha512.c
@@ -22,6 +22,7 @@
#include "alg-sha512.h"
#include "byteorder.h"
+#if INCLUDE_sha512
/* Constants for SHA512 from FIPS 180-2:4.2.3. */
static const uint64_t K[80] =
@@ -284,3 +285,5 @@ sha512_process_bytes (const void *buffer, size_t len, struct sha512_ctx *ctx)
ctx->buflen = (uint32_t)left_over;
}
}
+
+#endif
diff --git a/configure.ac b/configure.ac
index f843b51..119f171 100644
--- a/configure.ac
+++ b/configure.ac
@@ -201,35 +201,35 @@ AC_ARG_ENABLE([obsolete-api],
[enable_obsolete_api=1]
)
-AC_ARG_ENABLE([weak-hashes],
+AC_ARG_ENABLE([hashes],
AS_HELP_STRING(
- [--enable-weak-hashes[=ARG]],
- [When set to "yes", all of the hashing methods documented in crypt(5)
- are supported for authenticating existing password hashes, including
- several that are too weak to use for new passwords.
-
- When set to "glibc", only the weak hashes supported by historic
- versions of GNU libc are supported: traditional DES and FreeBSD-style
- MD5, but not bigcrypt-DES, BSDi extended DES, SHA1, SUNMD5, or NTHASH.
-
- When set to "no", only bcrypt, SHA512, and SHA256 are supported.
- This mode implies --disable-obsolete-api and breaks binary
- compatibility with glibc's libcrypt.
-
- [default=yes]]
+ [--enable-hashes=HASHES],
+ [Select hash algorithms to support. Acceptable values are
+ 'all' or a comma-separated list of names from the file
+ 'hashes.lst' and/or the keywords 'strong' and 'glibc', which
+ select groups of hashes as described in that file. The
+ default is 'all'. Note: if binary compatibility with glibc's
+ libcrypt is desired, the 'des' hash must be enabled.]
),
- [case "${enableval}" in
- yes) enable_weak_hashes=1; enable_weak_non_glibc_hashes=1 ;;
- glibc) enable_weak_hashes=1; enable_weak_non_glibc_hashes=0 ;;
- no) enable_weak_hashes=0; enable_weak_non_glibc_hashes=0 ;;
- *) AC_MSG_ERROR([bad value ${enableval} for --enable-weak-hashes]) ;;
- esac],
- [enable_weak_hashes=1; enable_weak_non_glibc_hashes=1]
+ [hashes_selected=$enableval],
+ [hashes_selected=all]
)
+# This code must run after AC_PROG_AWK.
+hashes_enabled=$(
+ $AWK -f ${srcdir}/sel-hashes.awk -v SELECTED_HASHES="$hashes_selected" \
+ ${srcdir}/hashes.lst
+)
+if test x"$hashes_enabled" = x || test x"$hashes_enabled" = x,; then
+ AC_MSG_ERROR([bad value '${hashes_selected}' for --enable-hashes])
+fi
+AC_SUBST([hashes_enabled])
-# If weak hashes are disabled, then the obsolete APIs won't work anyway
-# (they're all DES-specific).
-if test $enable_weak_hashes = 0; then enable_obsolete_api=0; fi
+# If the traditional DES hash is disabled, then the obsolete APIs are
+# implicitly disabled.
+case "$hashes_enabled" in
+ *,des,*) ;;
+ *) enable_obsolete_api=0 ;;
+esac
# The obsolete APIs are unconditionally excluded from the static library,
# so if we are not building the shared library, we are effectively not
@@ -298,15 +298,6 @@ AC_DEFINE_UNQUOTED([ENABLE_OBSOLETE_API], [$enable_obsolete_api],
should be included, 0 otherwise.])
AM_CONDITIONAL([ENABLE_OBSOLETE_API], [test $enable_obsolete_api = 1])
-AC_DEFINE_UNQUOTED([ENABLE_WEAK_HASHES], [$enable_weak_hashes],
- [Define as 1 if weak hashes (DES, MD5) should be included, 0 otherwise.
- If this is 0, ENABLE_OBSOLETE_API must also be 0.])
-AM_CONDITIONAL([ENABLE_WEAK_HASHES], [test $enable_weak_hashes = 1])
-
-AC_DEFINE_UNQUOTED([ENABLE_WEAK_NON_GLIBC_HASHES], [$enable_weak_non_glibc_hashes],
- [Define as 1 if weak hashes not supported by glibc should be included, 0 otherwise.])
-AM_CONDITIONAL([ENABLE_WEAK_NON_GLIBC_HASHES], [test $enable_weak_non_glibc_hashes = 1])
-
# The Makefile needs to know which versions of the library we are building.
AM_CONDITIONAL([ENABLE_STATIC], [test $enable_static = yes])
AM_CONDITIONAL([ENABLE_SHARED], [test $enable_shared = yes])
diff --git a/crypt-bcrypt.c b/crypt-bcrypt.c
index f41a893..d468399 100644
--- a/crypt-bcrypt.c
+++ b/crypt-bcrypt.c
@@ -50,6 +50,8 @@
#include <errno.h>
#include <stdio.h>
+#if INCLUDE_bcrypt
+
#if defined(__i386__) || defined(__x86_64__) || \
defined(__alpha__) || defined(__hppa__)
#define BF_SCALE 1
@@ -1007,3 +1009,5 @@ gensalt_bcrypt_y_rn (unsigned long count,
{
BF_gensalt ('y', count, rbytes, nrbytes, output, o_size);
}
+
+#endif
diff --git a/crypt-des.c b/crypt-des.c
index 79b3144..3d8bc2e 100644
--- a/crypt-des.c
+++ b/crypt-des.c
@@ -49,6 +49,8 @@
#include <errno.h>
+#if INCLUDE_des || INCLUDE_des_xbsd || INCLUDE_des_big
+
#define DES_TRD_OUTPUT_LEN 14 /* SShhhhhhhhhhh0 */
#define DES_EXT_OUTPUT_LEN 21 /* _CCCCSSSShhhhhhhhhhh0 */
#define DES_BIG_OUTPUT_LEN ((16*11) + 2 + 1) /* SS (hhhhhhhhhhh){1,16} 0 */
@@ -142,15 +144,14 @@ des_gen_hash (struct des_ctx *ctx, uint32_t count, uint8_t *output,
while (sptr < end);
*output = '\0';
}
+#endif
+#if INCLUDE_des
/* The original UNIX DES-based password hash, no extensions. */
-#if ENABLE_WEAK_NON_GLIBC_HASHES
-static
-#endif
void
-crypt_des_trd_rn (const char *phrase, const char *setting,
- uint8_t *output, size_t o_size,
- void *scratch, size_t s_size)
+crypt_des_rn (const char *phrase, const char *setting,
+ uint8_t *output, size_t o_size,
+ void *scratch, size_t s_size)
{
/* This shouldn't ever happen, but... */
if (o_size < DES_TRD_OUTPUT_LEN || s_size < sizeof (struct des_buffer))
@@ -194,8 +195,9 @@ crypt_des_trd_rn (const char *phrase, const char *setting,
des_set_salt (ctx, salt);
des_gen_hash (ctx, 25, cp, pkbuf);
}
+#endif
-#if ENABLE_WEAK_NON_GLIBC_HASHES
+#if INCLUDE_des_big
/* This algorithm is algorithm 0 (default) shipped with the C2 secure
implementation of Digital UNIX.
@@ -212,11 +214,23 @@ crypt_des_trd_rn (const char *phrase, const char *setting,
(that is, the password can be no more than 128 characters long).
Andy Phillips <atp@mssl.ucl.ac.uk> */
-static void
+void
crypt_des_big_rn (const char *phrase, const char *setting,
uint8_t *output, size_t o_size,
void *scratch, size_t s_size)
{
+#if INCLUDE_des
+ /* For backward compatibility, if the setting string is short enough
+ to have been generated by the traditional DES algorithm, forward
+ to traditional DES (which means that only the first 8 characters
+ of 'phrase' are significant). */
+ if (strlen (setting) <= 13)
+ {
+ crypt_des_rn (phrase, setting, output, o_size, scratch, s_size);
+ return;
+ }
+#endif
+
/* This shouldn't ever happen, but... */
if (o_size < DES_BIG_OUTPUT_LEN || s_size < sizeof (struct des_buffer))
{
@@ -264,19 +278,9 @@ crypt_des_big_rn (const char *phrase, const char *setting,
cp += 11;
}
}
+#endif
-/* crypt_rn() entry point for both the original UNIX password hash,
- with its 8-character length limit, and the Digital UNIX "bigcrypt"
- extension to permit longer passwords. */
-void
-crypt_des_trd_or_big_rn (const char *phrase, const char *setting,
- uint8_t *output, size_t o_size,
- void *scratch, size_t s_size)
-{
- (strlen (setting) > 13 ? crypt_des_big_rn : crypt_des_trd_rn)
- (phrase, setting, output, o_size, scratch, s_size);
-}
-
+#if INCLUDE_des_xbsd
/* crypt_rn() entry point for BSD-style extended DES hashes. These
permit long passwords and have more salt and a controllable iteration
count, but are still unacceptably weak by modern standards. */
@@ -346,12 +350,13 @@ crypt_des_xbsd_rn (const char *phrase, const char *setting,
des_set_salt (ctx, salt);
des_gen_hash (ctx, count, cp, pkbuf);
}
-#endif /* ENABLE_WEAK_NON_GLIBC_HASHES */
+#endif
+#if INCLUDE_des || INCLUDE_des_big
void
-gensalt_des_trd_rn (unsigned long count,
- const uint8_t *rbytes, size_t nrbytes,
- uint8_t *output, size_t output_size)
+gensalt_des_rn (unsigned long count,
+ const uint8_t *rbytes, size_t nrbytes,
+ uint8_t *output, size_t output_size)
{
if (output_size < 3)
{
@@ -369,8 +374,12 @@ gensalt_des_trd_rn (unsigned long count,
output[1] = ascii64[(unsigned int) rbytes[1] & 0x3f];
output[2] = '\0';
}
+#if INCLUDE_des_big
+strong_alias (gensalt_des_rn, gensalt_des_big_rn);
+#endif
+#endif
-#if ENABLE_WEAK_NON_GLIBC_HASHES
+#if INCLUDE_des_xbsd
void
gensalt_des_xbsd_rn (unsigned long count,
const uint8_t *rbytes, size_t nrbytes,
@@ -412,4 +421,4 @@ gensalt_des_xbsd_rn (unsigned long count,
output[9] = '\0';
}
-#endif /* ENABLE_WEAK_NON_GLIBC_HASHES */
+#endif
diff --git a/crypt-gensalt.c b/crypt-gensalt.c
index cfd596c..fb5b12c 100644
--- a/crypt-gensalt.c
+++ b/crypt-gensalt.c
@@ -14,6 +14,8 @@
#include <errno.h>
#include <stdio.h>
+#if INCLUDE_sha256 || INCLUDE_sha512
+
static const unsigned char _xcrypt_itoa64[64 + 1] =
"./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
@@ -90,3 +92,5 @@ gensalt_sha_rn (char tag, size_t maxsalt, unsigned long defcount,
output[written] = '\0';
}
+
+#endif
diff --git a/crypt-md5.c b/crypt-md5.c
index 9ae22da..1a9139a 100644
--- a/crypt-md5.c
+++ b/crypt-md5.c
@@ -23,6 +23,7 @@
#include <errno.h>
+#if INCLUDE_md5
/* Define our magic string to mark salt for MD5 "encryption"
replacement. This is meant to be the same as for other MD5 based
@@ -216,3 +217,5 @@ gensalt_md5_rn (unsigned long count,
gensalt_sha_rn ('1', 8, 1000, 1000, 1000,
count, rbytes, nrbytes, output, output_size);
}
+
+#endif
diff --git a/crypt-nthash.c b/crypt-nthash.c
index 9d43232..f9fee7b 100644
--- a/crypt-nthash.c
+++ b/crypt-nthash.c
@@ -42,6 +42,8 @@
#include <stdlib.h>
#include <netinet/in.h>
+#if INCLUDE_nthash
+
/*
* NT HASH = md4(str2unicode(phrase))
*/
@@ -145,3 +147,5 @@ gensalt_nthash_rn (unsigned long count,
memcpy (output, salt, 15);
memcpy (output + 15, hashstr, 14);
}
+
+#endif
diff --git a/crypt-pbkdf1-sha1.c b/crypt-pbkdf1-sha1.c
index b55d233..544d890 100644
--- a/crypt-pbkdf1-sha1.c
+++ b/crypt-pbkdf1-sha1.c
@@ -35,6 +35,8 @@
#include <stdio.h>
#include <stdlib.h>
+#if INCLUDE_sha1
+
/*
* The default iterations - should take >0s on a fast CPU
* but not be insane for a slow CPU.
@@ -258,3 +260,5 @@ gensalt_sha1_rn (unsigned long count,
output[n + (c * enclen)] = '$';
output[n + (c * enclen) + 1] = '\0';
}
+
+#endif
diff --git a/crypt-port.h b/crypt-port.h
index 8b21f56..6d94b09 100644
--- a/crypt-port.h
+++ b/crypt-port.h
@@ -191,69 +191,67 @@ void _xcrypt_secure_memset (void *s, size_t len)
#define symver_ref(extname, intname, version) \
symver_set(extname, intname, version, "@")
+/* Get the set of hash algorithms to be included and some related
+ definitions. */
+#include "crypt-hashes.h"
+
+
/* Rename all of the internal-but-global symbols with a _crypt_ prefix
so that they do not interfere with other people's code when linking
statically. This list cannot be autogenerated, but is validated by
test-symbols.sh. */
-#define crypt_bcrypt_rn _crypt_crypt_bcrypt_rn
-#define gensalt_bcrypt_a_rn _crypt_gensalt_bcrypt_a_rn
-#define gensalt_bcrypt_b_rn _crypt_gensalt_bcrypt_b_rn
-#define gensalt_bcrypt_x_rn _crypt_gensalt_bcrypt_x_rn
-#define gensalt_bcrypt_y_rn _crypt_gensalt_bcrypt_y_rn
-#define gensalt_sha_rn _crypt_gensalt_sha_rn
-#define gensalt_sha256_rn _crypt_gensalt_sha256_rn
-#define gensalt_sha512_rn _crypt_gensalt_sha512_rn
#define get_random_bytes _crypt_get_random_bytes
-#define crypt_sha256_rn _crypt_crypt_sha256_rn
-#define crypt_sha512_rn _crypt_crypt_sha512_rn
-#define sha256_finish_ctx _crypt_sha256_finish_ctx
-#define sha256_init_ctx _crypt_sha256_init_ctx
-#define sha256_process_bytes _crypt_sha256_process_bytes
-#define sha512_finish_ctx _crypt_sha512_finish_ctx
-#define sha512_init_ctx _crypt_sha512_init_ctx
-#define sha512_process_bytes _crypt_sha512_process_bytes
-#if ENABLE_WEAK_HASHES
-#define comp_maskl _crypt_comp_maskl
-#define comp_maskr _crypt_comp_maskr
-#if ENABLE_WEAK_NON_GLIBC_HASHES
-#define crypt_des_trd_or_big_rn _crypt_crypt_des_trd_or_big_rn
-#else
-#define crypt_des_trd_rn _crypt_crypt_des_trd_rn
-#endif
-#define crypt_des_xbsd_rn _crypt_crypt_des_xbsd_rn
-#define crypt_md5_rn _crypt_crypt_md5_rn
-#define crypt_nthash_rn _crypt_crypt_nthash_rn
-#define crypt_sha1_rn _crypt_crypt_sha1_rn
-#define crypt_sunmd5_rn _crypt_crypt_sunmd5_rn
+#if INCLUDE_des || INCLUDE_des_xbsd || INCLUDE_des_big
#define des_crypt_block _crypt_des_crypt_block
#define des_set_key _crypt_des_set_key
#define des_set_salt _crypt_des_set_salt
+#define comp_maskl _crypt_comp_maskl
+#define comp_maskr _crypt_comp_maskr
#define fp_maskl _crypt_fp_maskl
#define fp_maskr _crypt_fp_maskr
-#define gensalt_des_trd_rn _crypt_gensalt_des_trd_rn
-#define gensalt_des_xbsd_rn _crypt_gensalt_des_xbsd_rn
-#define gensalt_md5_rn _crypt_gensalt_md5_rn
-#define gensalt_nthash_rn _crypt_gensalt_nthash_rn
-#define gensalt_sha1_rn _crypt_gensalt_sha1_rn
-#define gensalt_sunmd5_rn _crypt_gensalt_sunmd5_rn
#define ip_maskl _crypt_ip_maskl
#define ip_maskr _crypt_ip_maskr
#define key_perm_maskl _crypt_key_perm_maskl
#define key_perm_maskr _crypt_key_perm_maskr
-#define hmac_sha1_process_data _crypt_hmac_sha1_process_data
+#define m_sbox _crypt_m_sbox
+#define psbox _crypt_psbox
+#endif
+
+#if INCLUDE_nthash
#define md4_finish_ctx _crypt_md4_finish_ctx
#define md4_init_ctx _crypt_md4_init_ctx
#define md4_process_bytes _crypt_md4_process_bytes
+#endif
+
+#if INCLUDE_md5 || INCLUDE_sunmd5
#define md5_finish_ctx _crypt_md5_finish_ctx
#define md5_init_ctx _crypt_md5_init_ctx
#define md5_process_bytes _crypt_md5_process_bytes
-#define m_sbox _crypt_m_sbox
-#define psbox _crypt_psbox
+#endif
+
+#if INCLUDE_sha1
+#define hmac_sha1_process_data _crypt_hmac_sha1_process_data
#define sha1_finish_ctx _crypt_sha1_finish_ctx
#define sha1_init_ctx _crypt_sha1_init_ctx
#define sha1_process_bytes _crypt_sha1_process_bytes
#endif
+#if INCLUDE_sha256
+#define sha256_finish_ctx _crypt_sha256_finish_ctx
+#define sha256_init_ctx _crypt_sha256_init_ctx
+#define sha256_process_bytes _crypt_sha256_process_bytes
+#endif
+
+#if INCLUDE_sha512
+#define sha512_finish_ctx _crypt_sha512_finish_ctx
+#define sha512_init_ctx _crypt_sha512_init_ctx
+#define sha512_process_bytes _crypt_sha512_process_bytes
+#endif
+
+#if INCLUDE_sha256 || INCLUDE_sha512
+#define gensalt_sha_rn _crypt_gensalt_sha_rn
+#endif
+
#endif /* crypt-port.h */
diff --git a/crypt-private.h b/crypt-private.h
index c5db3bd..7b2b232 100644
--- a/crypt-private.h
+++ b/crypt-private.h
@@ -36,86 +36,4 @@ extern void gensalt_sha_rn (char tag, size_t maxsalt, unsigned long defcount,
this big. */
#define ALG_SPECIFIC_SIZE 8192
-/* Individual hash functions */
-
-#if ENABLE_WEAK_HASHES
-extern void crypt_md5_rn (const char *phrase, const char *setting,
- uint8_t *output, size_t o_size,
- void *scratch, size_t s_size);
-#if ENABLE_WEAK_NON_GLIBC_HASHES
-extern void crypt_des_trd_or_big_rn (const char *phrase, const char *setting,
- uint8_t *output, size_t o_size,
- void *scratch, size_t s_size);
-extern void crypt_des_xbsd_rn (const char *phrase, const char *setting,
- uint8_t *output, size_t o_size,
- void *scratch, size_t s_size);
-extern void crypt_nthash_rn (const char *phrase, const char *setting,
- uint8_t *output, size_t o_size,
- void *scratch, size_t s_size);
-extern void crypt_sha1_rn (const char *phrase, const char *setting,
- uint8_t *output, size_t o_size,
- void *scratch, size_t s_size);
-extern void crypt_sunmd5_rn (const char *phrase, const char *setting,
- uint8_t *output, size_t o_size,
- void *scratch, size_t s_size);
-#else
-extern void crypt_des_trd_rn (const char *phrase, const char *setting,
- uint8_t *output, size_t o_size,
- void *scratch, size_t s_size);
-#endif
-#endif
-
-extern void crypt_sha256_rn (const char *phrase, const char *setting,
- uint8_t *output, size_t o_size,
- void *scratch, size_t s_size);
-extern void crypt_sha512_rn (const char *phrase, const char *setting,
- uint8_t *output, size_t o_size,
- void *scratch, size_t s_size);
-extern void crypt_bcrypt_rn (const char *phrase, const char *setting,
- uint8_t *output, size_t o_size,
- void *scratch, size_t s_size);
-
-#if ENABLE_WEAK_HASHES
-extern void gensalt_des_trd_rn (unsigned long count,
- const uint8_t *rbytes, size_t nrbytes,
- uint8_t *output, size_t o_size);
-extern void gensalt_md5_rn (unsigned long count,
- const uint8_t *rbytes, size_t nrbytes,
- uint8_t *output, size_t o_size);
-#if ENABLE_WEAK_NON_GLIBC_HASHES
-extern void gensalt_des_xbsd_rn (unsigned long count,
- const uint8_t *rbytes, size_t nrbytes,
- uint8_t *output, size_t o_size);
-extern void gensalt_nthash_rn (unsigned long count,
- const uint8_t *rbytes, size_t nrbytes,
- uint8_t *output, size_t o_size);
-extern void gensalt_sha1_rn (unsigned long count,
- const uint8_t *rbytes, size_t nrbytes,
- uint8_t *output, size_t o_size);
-extern void gensalt_sunmd5_rn (unsigned long count,
- const uint8_t *rbytes, size_t nrbytes,
- uint8_t *output, size_t o_size);
-#endif
-#endif
-
-extern void gensalt_sha256_rn (unsigned long count,
- const uint8_t *rbytes, size_t nrbytes,
- uint8_t *output, size_t o_size);
-extern void gensalt_sha512_rn (unsigned long count,
- const uint8_t *rbytes, size_t nrbytes,
- uint8_t *output, size_t o_size);
-
-extern void gensalt_bcrypt_a_rn (unsigned long count,
- const uint8_t *rbytes, size_t nrbytes,
- uint8_t *output, size_t o_size);
-extern void gensalt_bcrypt_b_rn (unsigned long count,
- const uint8_t *rbytes, size_t nrbytes,
- uint8_t *output, size_t o_size);
-extern void gensalt_bcrypt_x_rn (unsigned long count,
- const uint8_t *rbytes, size_t nrbytes,
- uint8_t *output, size_t o_size);
-extern void gensalt_bcrypt_y_rn (unsigned long count,
- const uint8_t *rbytes, size_t nrbytes,
- uint8_t *output, size_t o_size);
-
#endif /* crypt-private.h */
diff --git a/crypt-sha256.c b/crypt-sha256.c
index 9fc70e1..8b4ba67 100644
--- a/crypt-sha256.c
+++ b/crypt-sha256.c
@@ -24,6 +24,7 @@
#include <stdio.h>
#include <stdlib.h>
+#if INCLUDE_sha256
/* Define our magic string to mark salt for SHA256 "encryption"
replacement. */
@@ -283,3 +284,5 @@ gensalt_sha256_rn (unsigned long count,
gensalt_sha_rn ('5', SALT_LEN_MAX, ROUNDS_DEFAULT, ROUNDS_MIN, ROUNDS_MAX,
count, rbytes, nrbytes, output, output_size);
}
+
+#endif
diff --git a/crypt-sha512.c b/crypt-sha512.c
index b4473da..28e4f1c 100644
--- a/crypt-sha512.c
+++ b/crypt-sha512.c
@@ -24,6 +24,7 @@
#include <stdio.h>
#include <stdlib.h>
+#if INCLUDE_sha512
/* Define our magic string to mark salt for SHA512 "encryption"
replacement. */
@@ -297,3 +298,5 @@ gensalt_sha512_rn (unsigned long count,
gensalt_sha_rn ('6', SALT_LEN_MAX, ROUNDS_DEFAULT, ROUNDS_MIN, ROUNDS_MAX,
count, rbytes, nrbytes, output, output_size);
}
+
+#endif
diff --git a/crypt-sunmd5.c b/crypt-sunmd5.c
index 43054b9..fcd3984 100644
--- a/crypt-sunmd5.c
+++ b/crypt-sunmd5.c
@@ -32,6 +32,9 @@
#include <stdlib.h>
#include <stdio.h>
+#if INCLUDE_sunmd5
+
+
#define CRYPT_ALGNAME "md5"
/* minimum number of rounds we do, not including the per-user ones */
@@ -419,3 +422,5 @@ crypt_sunmd5_rn (const char *phrase, const char *setting,
p += 2;
*p = '\0';
}
+
+#endif
diff --git a/crypt.c b/crypt.c
index 12d50fd..e1bfc5b 100644
--- a/crypt.c
+++ b/crypt.c
@@ -70,6 +70,7 @@ typedef void (*gensalt_fn) (unsigned long count,
struct hashfn
{
const char *prefix;
+ size_t plen;
crypt_fn crypt;
gensalt_fn gensalt;
/* The type of this field is unsigned char to ensure that it cannot
@@ -77,54 +78,12 @@ struct hashfn
unsigned char nrbytes;
};
-/* This table should always begin with the algorithm that should be used
- for new encryptions. */
-static const struct hashfn tagged_hashes[] =
+static const struct hashfn hash_algorithms[] =
{
- /* bcrypt */
- { "$2b$", crypt_bcrypt_rn, gensalt_bcrypt_b_rn, 16 },
- { "$2a$", crypt_bcrypt_rn, gensalt_bcrypt_a_rn, 16 },
- { "$2x$", crypt_bcrypt_rn, gensalt_bcrypt_x_rn, 16 },
- { "$2y$", crypt_bcrypt_rn, gensalt_bcrypt_y_rn, 16 },
-
- /* legacy hashes */
-#if ENABLE_WEAK_HASHES
- { "$1$", crypt_md5_rn, gensalt_md5_rn, 9 },
-#if ENABLE_WEAK_NON_GLIBC_HASHES
- { "$3$", crypt_nthash_rn, gensalt_nthash_rn, 16 },
- { "$md5", crypt_sunmd5_rn, gensalt_sunmd5_rn, 8 },
- { "$sha1", crypt_sha1_rn, gensalt_sha1_rn, 48 },
-#endif
-#endif
- { "$5$", crypt_sha256_rn, gensalt_sha256_rn, 15 },
- { "$6$", crypt_sha512_rn, gensalt_sha512_rn, 15 },
- { 0, 0, 0, 0 }
-};
-
-#if ENABLE_WEAK_HASHES
-#if ENABLE_WEAK_NON_GLIBC_HASHES
-/* BSD-style extended DES */
-static const struct hashfn bsdi_extended_hash =
-{
- "_", crypt_des_xbsd_rn, gensalt_des_xbsd_rn, 3
-};
-
-/* Traditional DES or bigcrypt-style extended DES */
-static const struct hashfn traditional_hash =
-{
- "", crypt_des_trd_or_big_rn, gensalt_des_trd_rn, 2
+ HASH_ALGORITHM_TABLE_ENTRIES
};
-#else
-
-/* Traditional DES */
-static const struct hashfn traditional_hash =
-{
- "", crypt_des_trd_rn, gensalt_des_trd_rn, 2
-};
-
-#endif
-
+#if INCLUDE_des || INCLUDE_des_big
static int
is_des_salt_char (char c)
{
@@ -133,30 +92,29 @@ is_des_salt_char (char c)
(c >= '0' && c <= '9') ||
c == '.' || c == '/');
}
-#endif /* ENABLE_WEAK_HASHES */
+#endif
static const struct hashfn *
get_hashfn (const char *setting)
{
- if (setting[0] == '$')
+ const struct hashfn *h;
+ for (h = hash_algorithms; h->prefix; h++)
{
- const struct hashfn *h;
- for (h = tagged_hashes; h->prefix; h++)
- if (!strncmp (setting, h->prefix, strlen (h->prefix)))
- return h;
- return 0;
- }
-#if ENABLE_WEAK_HASHES
-#if ENABLE_WEAK_NON_GLIBC_HASHES
- else if (setting[0] == '_')
- return &bsdi_extended_hash;
-#endif
- else if (setting[0] == '\0' ||
- (is_des_salt_char (setting[0]) && is_des_salt_char (setting[1])))
- return &traditional_hash;
+ if (h->plen > 0)
+ {
+ if (!strncmp (setting, h->prefix, h->plen))
+ return h;
+ }
+#if INCLUDE_des || INCLUDE_des_big
+ else
+ {
+ if (setting[0] == '\0' ||
+ (is_des_salt_char (setting[0]) && is_des_salt_char (setting[1])))
+ return h;
+ }
#endif
- else
- return 0;
+ }
+ return 0;
}
/* For historical reasons, crypt and crypt_r are not expected ever to
@@ -392,9 +350,15 @@ crypt_gensalt_rn (const char *prefix, unsigned long count,
/* If the prefix is 0, that means to use the current best default.
Note that this is different from the behavior when the prefix is
- "", which selects DES. */
+ "", which selects DES. HASH_ALGORITHM_DEFAULT is null when the
+ current default algorithm was disabled at configure time. */
if (!prefix)
- prefix = tagged_hashes[0].prefix;
+ prefix = HASH_ALGORITHM_DEFAULT;
+ if (!prefix)
+ {
+ errno = EINVAL;
+ return 0;
+ }
const struct hashfn *h = get_hashfn (prefix);
if (!h)
diff --git a/gen-hashes.awk b/gen-hashes.awk
new file mode 100644
index 0000000..39faf8e
--- /dev/null
+++ b/gen-hashes.awk
@@ -0,0 +1,160 @@
+# Generate crypt-hashes.h from hashes.lst and configure settings.
+#
+# Copyright 2018 Zack Weinberg
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public License
+# as published by the Free Software Foundation; either version 2.1 of
+# the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, see
+# <https://www.gnu.org/licenses/>.
+
+BEGIN {
+ default_prefix = ":"
+ next_output = 0
+ error = 0
+}
+
+/^#/ {
+ next
+}
+
+{
+ if (!($1 in hash_enabled)) {
+ output_order[next_output++] = $1
+ hash_enabled[$1] = 0
+ }
+ if ($1 == ":") {
+ printf("%s:%d: name cannot be blank\n", FILENAME, NR)
+ error = 1
+ }
+ if ($4 !~ /^[0-9]+$/ || $4 == 0) {
+ printf("%s:%d: nrbytes must be a positive integer\n", FILENAME, NR)
+ error = 1
+ }
+ if ($2 == ":") $2 = ""
+ if ($3 == ":") $3 = ""
+ if ($5 == ":") $5 = ""
+
+ crypt_fn = "crypt_" $1 "_rn"
+ gensalt_fn = "gensalt_" $1 $2 "_rn"
+
+ if (!(crypt_fn in prototyped)) {
+ prototyped[crypt_fn] = 1
+ renames[$1] = renames[$1] \
+ "#define " crypt_fn " _crypt_" crypt_fn "\n"
+ prototypes[$1] = prototypes[$1] \
+ "extern void " crypt_fn "\n " \
+ "(const char *, const char *, uint8_t *, size_t, void *, size_t);\n"
+ }
+ if (!(gensalt_fn in prototyped)) {
+ prototyped[gensalt_fn] = 1
+ renames[$1] = renames[$1] \
+ "#define " gensalt_fn " _crypt_" gensalt_fn "\n"
+ prototypes[$1] = prototypes[$1] \
+ "extern void " gensalt_fn "\n " \
+ "(unsigned long, const uint8_t *, size_t, uint8_t *, size_t);\n"
+ }
+
+ entry = sprintf(" { \"%s\", %d, %s, %s, %d }, \\\n",
+ $3, length($3), crypt_fn, gensalt_fn, $4)
+ table_entries[$1] = table_entries[$1] entry
+
+ split($5, flags, ",")
+ for (i in flags) {
+ flag = flags[i]
+ if (flag == "DEFAULT") {
+ if (default_prefix == ":") {
+ default_hash = $1
+ default_prefix = $3
+ default_prefix_line = NR
+ } else {
+ printf("%s:%d: error: 'DEFAULT' specified twice\n",
+ FILENAME, NR) > "/dev/stderr"
+ printf("%s:%d: note: previous 'DEFAULT' was here\n",
+ FILENAME, default_prefix_line) > "/dev/stderr"
+ error = 1
+ }
+ } else if (flag == "STRONG" || flag == "GLIBC") {
+ # handled in sel-hashes.awk
+ } else {
+ printf("%s:%d: unrecognized flag %s\n", FILENAME, NR, flag) \
+ > "/dev/stderr"
+ error = 1
+ }
+ }
+}
+
+
+END {
+ if (error) {
+ exit 1
+ }
+
+ # ENABLED_HASHES is set on the command line.
+ split(ENABLED_HASHES, enabled_hashes_list, ",")
+ for (i in enabled_hashes_list) {
+ h = enabled_hashes_list[i]
+ if (h != "") {
+ hash_enabled[h] = 1
+ }
+ }
+
+ if (default_prefix == ":") {
+ print "error: no default hash selected" > "/dev/stderr"
+ exit 1
+ }
+
+ print "/* Generated by genhashes.awk from hashes.lst. DO NOT EDIT. */"
+ print ""
+ print "#ifndef _CRYPT_HASHES_H"
+ print "#define _CRYPT_HASHES_H 1"
+
+ print ""
+ for (i in output_order) {
+ hash = output_order[i]
+ printf("#define INCLUDE_%-8s %d\n", hash, hash_enabled[hash])
+ }
+
+ print ""
+ print "/* Internal symbol renames for static linkage, see crypt-port.h. */"
+ for (i in output_order) {
+ hash = output_order[i]
+ if (hash_enabled[hash]) {
+ print renames[hash]
+ }
+ }
+
+ print "/* Prototypes for hash algorithm entry points. */"
+ for (i in output_order) {
+ hash = output_order[i]
+ if (hash_enabled[hash]) {
+ print prototypes[hash]
+ }
+ }
+
+ print "#define HASH_ALGORITHM_TABLE_ENTRIES \\"
+ for (i in output_order) {
+ hash = output_order[i]
+ if (hash_enabled[hash]) {
+ printf("%s", table_entries[hash])
+ }
+ }
+ print " { 0, 0, 0, 0, 0 }"
+
+ print ""
+ if (hash_enabled[default_hash]) {
+ print "#define HASH_ALGORITHM_DEFAULT \"" default_prefix "\""
+ } else {
+ print "#define HASH_ALGORITHM_DEFAULT 0"
+ }
+ print ""
+ print "#endif /* crypt-hashes.h */"
+}
diff --git a/hashes.lst b/hashes.lst
new file mode 100644
index 0000000..488768f
--- /dev/null
+++ b/hashes.lst
@@ -0,0 +1,40 @@
+# This file is read by genhashes.awk and by the configure script.
+#
+# It lists, for each supported hash algorithm, the name to be used to
+# enable or disable it at configure time, which is also part of the
+# name used for the 'crypt_fn' and 'gensalt_fn' entry points to the
+# relevant algorithm module; an optional suffix on the name of the
+# 'gensalt_fn'; the prefix used to identify the algorithm in hash
+# strings; the number of bytes of random data required to generate a
+# salt; and a set of flags. Currently there are three flags: DEFAULT
+# means this is the hash to use when no prefix was supplied to
+# crypt_gensalt, STRONG means the hash is still considered strong
+# enough to use for newly hashed passwords, and GLIBC means the hash
+# was historically supported by GNU libc's libcrypt.
+#
+# Fields are separated by whitespace. Lines beginning with # are
+# ignored; # is not otherwise significant. Multiple flags are
+# separated by commas. A field whose contents are a single colon (:)
+# is actually understood as an empty string; colon is used for this
+# purpose because it cannot be part of a hash prefix or a C identifier.
+#
+# Note: All entries with the same name should be consecutive.
+#
+# Note: crypt() checks prefixes in the order they appear in this file,
+# and the first match wins. Therefore, the empty prefix (traditional
+# DES) must be last.
+#
+#name gs_suffix h_prefix nrbytes flags
+bcrypt _b $2b$ 16 STRONG,DEFAULT
+bcrypt _a $2a$ 16 STRONG
+bcrypt _x $2x$ 16 STRONG
+bcrypt _y $2y$ 16 STRONG
+sha512 : $6$ 15 STRONG,GLIBC
+sha256 : $5$ 15 STRONG,GLIBC
+md5 : $1$ 9 GLIBC
+sunmd5 : $md5 8 :
+sha1 : $sha1 48 :
+nthash : $3$ 16 :
+des_xbsd : _ 3 :
+des_big : : 2 :
+des : : 2 GLIBC
diff --git a/sel-hashes.awk b/sel-hashes.awk
new file mode 100644
index 0000000..c4edcbb
--- /dev/null
+++ b/sel-hashes.awk
@@ -0,0 +1,89 @@
+# Expand a list of selected hashes to a list of enabled hashes, using
+# the information in hashes.lst.
+#
+# Copyright 2018 Zack Weinberg
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public License
+# as published by the Free Software Foundation; either version 2.1 of
+# the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, see
+# <https://www.gnu.org/licenses/>.
+
+BEGIN {
+ enable_all = 0
+ enable_strong = 0
+ enable_glibc = 0
+ enable_some = 0
+ error = 0
+ split(SELECTED_HASHES, selected_hashes_list, ",")
+ for (i in selected_hashes_list) {
+ h = selected_hashes_list[i]
+ if (h == "all") {
+ enable_all = 1
+ } else if (h == "strong") {
+ enable_strong = 1
+ } else if (h == "glibc") {
+ enable_glibc = 1
+ } else {
+ enable_some = 1
+ selected_hashes[h] = 1
+ }
+ }
+ if (enable_all && (enable_strong || enable_glibc || enable_some)) {
+ error = 1
+ exit 1
+ }
+}
+
+/^#/ {
+ next
+}
+
+{
+ if (enable_all || $1 in selected_hashes) {
+ enabled_hashes[$1] = 1
+ } else {
+ enabled_hashes[$1] = 0
+
+ split($5, flags, ",")
+ for (i in flags) {
+ flag = flags[i]
+ if (flag == "STRONG" && enable_strong) {
+ enabled_hashes[$1] = 1
+ } else if (flag == "GLIBC" && enable_glibc) {
+ enabled_hashes[$1] = 1
+ }
+ }
+ }
+}
+
+
+END {
+ if (error) {
+ exit 1
+ }
+
+ # Check for individual selected hashes that didn't appear in
+ # hashes.lst.
+ for (h in selected_hashes) {
+ if (!(h in enabled_hashes)) {
+ exit 1
+ }
+ }
+
+ enabled_hash_list = ","
+ for (i in enabled_hashes) {
+ if (enabled_hashes[i]) {
+ enabled_hash_list = enabled_hash_list i ","
+ }
+ }
+ print enabled_hash_list
+}
diff --git a/test-alg-des.c b/test-alg-des.c
index 2f42870..d00fdb5 100644
--- a/test-alg-des.c
+++ b/test-alg-des.c
@@ -11,6 +11,8 @@
#include <stdio.h>
+#if INCLUDE_des || INCLUDE_des_xbsd || INCLUDE_des_big
+
static void
v_print (const unsigned char v[8])
{
@@ -66,3 +68,13 @@ main (void)
return status;
}
+
+#else
+
+int
+main (void)
+{
+ return 77; /* UNSUPPORTED */
+}
+
+#endif
diff --git a/test-alg-hmac-sha1.c b/test-alg-hmac-sha1.c
index 777ac86..21ef281 100644
--- a/test-alg-hmac-sha1.c
+++ b/test-alg-hmac-sha1.c
@@ -33,6 +33,8 @@
#include <stdio.h>
#include <stdlib.h>
+#if INCLUDE_sha1
+
#define HASH_LENGTH 20
static char *
@@ -166,3 +168,13 @@ main (void)
}
return n;
}
+
+#else
+
+int
+main (void)
+{
+ return 77; /* UNSUPPORTED */
+}
+
+#endif
diff --git a/test-alg-md4.c b/test-alg-md4.c
index ab6ad87..1b1b828 100644
--- a/test-alg-md4.c
+++ b/test-alg-md4.c
@@ -3,6 +3,8 @@
#include <stdio.h>
+#if INCLUDE_nthash
+
static const struct
{
const char *input;
@@ -97,3 +99,13 @@ main (void)
return result;
}
+
+#else
+
+int
+main (void)
+{
+ return 77; /* UNSUPPORTED */
+}
+
+#endif
diff --git a/test-alg-md5.c b/test-alg-md5.c
index 9908ab8..dabc6ba 100644
--- a/test-alg-md5.c
+++ b/test-alg-md5.c
@@ -3,6 +3,8 @@
#include <stdio.h>
+#if INCLUDE_md5 || INCLUDE_sunmd5
+
static const struct
{
const char *input;
@@ -120,3 +122,13 @@ main (void)
return result;
}
+
+#else
+
+int
+main (void)
+{
+ return 77; /* UNSUPPORTED */
+}
+
+#endif
diff --git a/test-alg-sha1.c b/test-alg-sha1.c
index 04ce456..594d192 100644
--- a/test-alg-sha1.c
+++ b/test-alg-sha1.c
@@ -9,6 +9,8 @@
#include <stdio.h>
+#if INCLUDE_sha1
+
/* Test Vectors (from FIPS PUB 180-1) */
const char *test_data[3] =
{
@@ -80,3 +82,13 @@ main (void)
/* success */
return retval;
}
+
+#else
+
+int
+main (void)
+{
+ return 77; /* UNSUPPORTED */
+}
+
+#endif
diff --git a/test-alg-sha256.c b/test-alg-sha256.c
index 45345e2..06354ac 100644
--- a/test-alg-sha256.c
+++ b/test-alg-sha256.c
@@ -3,6 +3,8 @@
#include <stdio.h>
+#if INCLUDE_sha256
+
static const struct
{
const char *input;
@@ -129,3 +131,13 @@ main (void)
return result;
}
+
+#else
+
+int
+main (void)
+{
+ return 77; /* UNSUPPORTED */
+}
+
+#endif
diff --git a/test-alg-sha512.c b/test-alg-sha512.c
index 0e24ad5..b6d4fc6 100644
--- a/test-alg-sha512.c
+++ b/test-alg-sha512.c
@@ -3,6 +3,8 @@
#include <stdio.h>
+#if INCLUDE_sha512
+
static const struct
{
const char *input;
@@ -159,3 +161,13 @@ main (void)
return result;
}
+
+#else
+
+int
+main (void)
+{
+ return 77; /* UNSUPPORTED */
+}
+
+#endif
diff --git a/test-crypt-badsalt.c b/test-crypt-badsalt.c
index a5e0e01..8ce7401 100644
--- a/test-crypt-badsalt.c
+++ b/test-crypt-badsalt.c
@@ -25,7 +25,9 @@
static const char *tests[][3] =
{
+#if INCLUDE_des || INCLUDE_des_big
{ "no salt", "", "..ogcgXxFhnjI" /* valid setting */ },
+#endif
{ "single char", "/", "*0" /* invalid setting */ },
{ "first char bad", "!x", "*0" /* invalid setting */ },
{ "second char bad", "Z%", "*0" /* invalid setting */ },
diff --git a/test-crypt-bcrypt.c b/test-crypt-bcrypt.c
index 02a2f07..c984e4d 100644
--- a/test-crypt-bcrypt.c
+++ b/test-crypt-bcrypt.c
@@ -21,6 +21,8 @@
#include <stdio.h>
#include <stdlib.h>
+#if INCLUDE_bcrypt
+
static const char *tests[][3] =
{
{
@@ -259,3 +261,13 @@ main (void)
free (data);
return status;
}
+
+#else
+
+int
+main (void)
+{
+ return 77; /* UNSUPPORTED */
+}
+
+#endif
diff --git a/test-crypt-des.c b/test-crypt-des.c
index e541885..1b5463e 100644
--- a/test-crypt-des.c
+++ b/test-crypt-des.c
@@ -3,6 +3,8 @@
#include <stdio.h>
+#if INCLUDE_des || INCLUDE_des_xbsd || INCLUDE_des_big
+
static const struct
{
const char *salt;
@@ -10,6 +12,7 @@ static const struct
const char *input;
} tests[] =
{
+#if INCLUDE_des
/* traditional-DES test vectors from John the Ripper */
{ "CC", "CCNf8Sbh3HDfQ", "U*U*U*U*" },
{ "CC", "CCNf8Sbh3HDfQ", "U*U*U*U*ignored" },
@@ -19,8 +22,9 @@ static const struct
{ "CC", "CC4rMpbg9AMZ.", "\xd5\xaa\xd5\xaa\xaa\xaa\xd5\xaa" },
{ "XX", "XXxzOu6maQKqQ", "*U*U*U*U" },
{ "SD", "SDbsugeBiC58A", "" },
+#endif
-#if ENABLE_WEAK_NON_GLIBC_HASHES
+#if INCLUDE_des_xbsd
/* BSDI-extended-DES, ditto */
{ "_J9..CCCC", "_J9..CCCCXBrJUJV154M", "U*U*U*U*" },
{ "_J9..CCCC", "_J9..CCCCXUhOBTXzaiE", "U*U***U" },
@@ -38,7 +42,9 @@ static const struct
{ "_J9..SDiz", "_J9..SDizxmRI1GjnQuE", "zxyDPWgydbQjgq" },
{ "_K9..Salt", "_K9..SaltNrQgIYUAeoY", "726 even" },
{ "_J9..SDSD", "_J9..SDSD5YGyRCr4W4c", "" },
+#endif
+#if INCLUDE_des_big
/* 10 bigcrypt test vectors from pw-fake-unix.gz from the openwall
wiki. All have two blocks. The salt is padded with dots because
crypt_r will only use bigcrypt if the setting string begins with
@@ -100,3 +106,13 @@ main (void)
return result;
}
+
+#else
+
+int
+main (void)
+{
+ return 77; /* UNSUPPORTED */
+}
+
+#endif
diff --git a/test-crypt-md5.c b/test-crypt-md5.c
index 235c250..3035c39 100644
--- a/test-crypt-md5.c
+++ b/test-crypt-md5.c
@@ -1,6 +1,8 @@
#include "crypt-port.h"
#include "crypt-base.h"
+#if INCLUDE_md5
+
int
main (void)
{
@@ -17,3 +19,13 @@ main (void)
return result;
}
+
+#else
+
+int
+main (void)
+{
+ return 77; /* UNSUPPORTED */
+}
+
+#endif
diff --git a/test-crypt-nthash.c b/test-crypt-nthash.c
index 6f897fe..9bf7d28 100644
--- a/test-crypt-nthash.c
+++ b/test-crypt-nthash.c
@@ -3,6 +3,8 @@
#include <stdio.h>
+#if INCLUDE_nthash
+
static const struct
{
const char *input;
@@ -160,3 +162,13 @@ main (void)
return result;
}
+
+#else
+
+int
+main (void)
+{
+ return 77; /* UNSUPPORTED */
+}
+
+#endif
diff --git a/test-crypt-pbkdf1-sha1.c b/test-crypt-pbkdf1-sha1.c
index aadc0fe..677e5bf 100644
--- a/test-crypt-pbkdf1-sha1.c
+++ b/test-crypt-pbkdf1-sha1.c
@@ -5,6 +5,8 @@
#include <stdio.h>
#include <stdlib.h>
+#if INCLUDE_sha1
+
const char *password = "zyxwvuts";
const char *tests[][2] =
{
@@ -92,3 +94,13 @@ main (void)
free (previous);
return result;
}
+
+#else
+
+int
+main (void)
+{
+ return 77; /* UNSUPPORTED */
+}
+
+#endif
diff --git a/test-crypt-sha256.c b/test-crypt-sha256.c
index 23da81c..7c42398 100644
--- a/test-crypt-sha256.c
+++ b/test-crypt-sha256.c
@@ -3,6 +3,8 @@
#include <stdio.h>
+#if INCLUDE_sha256
+
static const struct
{
const char *salt;
@@ -73,3 +75,13 @@ main (void)
return result;
}
+
+#else
+
+int
+main (void)
+{
+ return 77; /* UNSUPPORTED */
+}
+
+#endif
diff --git a/test-crypt-sha512.c b/test-crypt-sha512.c
index 1aa0b71..c2a1973 100644
--- a/test-crypt-sha512.c
+++ b/test-crypt-sha512.c
@@ -3,6 +3,8 @@
#include <stdio.h>
+#if INCLUDE_sha512
+
static const struct
{
const char *salt;
@@ -73,3 +75,13 @@ main (void)
return result;
}
+
+#else
+
+int
+main (void)
+{
+ return 77; /* UNSUPPORTED */
+}
+
+#endif
diff --git a/test-crypt-sunmd5.c b/test-crypt-sunmd5.c
index d67781b..2c9731a 100644
--- a/test-crypt-sunmd5.c
+++ b/test-crypt-sunmd5.c
@@ -4,6 +4,8 @@
#include <stdio.h>
#include <stdlib.h>
+#if INCLUDE_sunmd5
+
const char *password = "abcdefg";
const char *tests[][3] =
{
@@ -128,3 +130,13 @@ main (void)
free (previous);
return result;
}
+
+#else
+
+int
+main (void)
+{
+ return 77; /* UNSUPPORTED */
+}
+
+#endif
diff --git a/test-gensalt.c b/test-gensalt.c
index 2705671..b81fcf0 100644
--- a/test-gensalt.c
+++ b/test-gensalt.c
@@ -14,43 +14,56 @@ static const char *const entropy[] =
0
};
-#if ENABLE_WEAK_HASHES
+#if INCLUDE_des || INCLUDE_des_big
static const char *const des_expected_output[] = { "Mp", "Pp", "ZH", "Uh"};
-static const char *const md5_expected_output[] = {
- "$1$MJHnaAke",
- "$1$PKXc3hCO",
- "$1$ZAFlICwY",
- "$1$UqGBkVu0"
-};
-#if ENABLE_WEAK_NON_GLIBC_HASHES
+#endif
+#if INCLUDE_des_xbsd
static const char *const bsdi_expected_output[] = {
"_J9..MJHn",
"_J9..PKXc",
"_J9..ZAFl",
"_J9..UqGB"
};
+#endif
+#if INCLUDE_md5
+static const char *const md5_expected_output[] = {
+ "$1$MJHnaAke",
+ "$1$PKXc3hCO",
+ "$1$ZAFlICwY",
+ "$1$UqGBkVu0"
+};
+#endif
+#if INCLUDE_nthash
static const char *const nthash_expected_output[] = {
"$3$__not_used__c809a450df09a3",
"$3$__not_used__30d0d6f834c0c3",
"$3$__not_used__0eeeebb83d6fe4",
"$3$__not_used__1c690d6a9ef88c"
};
+#endif
+#if INCLUDE_sunmd5
#define sunmd5_expected_output 0 /* output is not deterministic */
-#define pbkdf_expected_output 0 /* output is not deterministic */
#endif
+#if INCLUDE_sha1
+#define pbkdf_expected_output 0 /* output is not deterministic */
#endif
+#if INCLUDE_sha256
static const char *const sha256_expected_output[] = {
"$5$MJHnaAkegEVYHsFK",
"$5$PKXc3hCOSyMqdaEQ",
"$5$ZAFlICwYRETzIzIj",
"$5$UqGBkVu01rurVZqg"
};
+#endif
+#if INCLUDE_sha512
static const char *const sha512_expected_output[] = {
"$6$MJHnaAkegEVYHsFK",
"$6$PKXc3hCOSyMqdaEQ",
"$6$ZAFlICwYRETzIzIj",
"$6$UqGBkVu01rurVZqg"
};
+#endif
+#if INCLUDE_bcrypt
static const char *const bcrypt_a_expected_output[] = {
"$2a$05$UBVLHeMpJ/QQCv3XqJx8zO",
"$2a$05$kxUgPcrmlm9XoOjvxCyfP.",
@@ -75,6 +88,7 @@ static const char *const bcrypt_y_expected_output[] = {
"$2y$05$HPNDjKMRFdR7zC87CMSmA.",
"$2y$05$mAyzaIeJu41dWUkxEbn8hO"
};
+#endif
struct testcase
{
@@ -86,22 +100,36 @@ struct testcase
static const struct testcase testcases[] =
{
-#if ENABLE_WEAK_HASHES
+#if INCLUDE_des || INCLUDE_des_big
{ "", des_expected_output, 2, 0 }, // DES
- { "$1$", md5_expected_output, 11, 0 }, // MD5
-#if ENABLE_WEAK_NON_GLIBC_HASHES
+#endif
+#if INCLUDE_des_xbsd
{ "_", bsdi_expected_output, 9, 0 }, // BSDi extended DES
+#endif
+#if INCLUDE_md5
+ { "$1$", md5_expected_output, 11, 0 }, // MD5
+#endif
+#if INCLUDE_nthash
{ "$3$", nthash_expected_output, 29, 0 }, // NTHASH
+#endif
+#if INCLUDE_sunmd5
{ "$md5", sunmd5_expected_output, 27, 0 }, // SUNMD5
- { "$sha1", pbkdf_expected_output, 34, 74 }, // PBKDF with SHA1
#endif
+#if INCLUDE_sha1
+ { "$sha1", pbkdf_expected_output, 34, 74 }, // PBKDF with SHA1
#endif
+#if INCLUDE_sha256
{ "$5$", sha256_expected_output, 19, 0 }, // SHA-2-256
+#endif
+#if INCLUDE_sha512
{ "$6$", sha512_expected_output, 19, 0 }, // SHA-2-512
+#endif
+#if INCLUDE_bcrypt
{ "$2a$", bcrypt_a_expected_output, 29, 0 }, // bcrypt mode A
{ "$2b$", bcrypt_b_expected_output, 29, 0 }, // bcrypt mode B
{ "$2x$", bcrypt_x_expected_output, 29, 0 }, // bcrypt mode X
{ "$2y$", bcrypt_y_expected_output, 29, 0 }, // bcrypt mode Y
+#endif
{ 0, 0, 0, 0 }
};
@@ -184,7 +212,9 @@ main (void)
char *setting1, *setting2;
setting1 = crypt_gensalt_ra ("$2b$", 0, entropy[0], 16);
setting2 = crypt_gensalt_ra (0, 0, entropy[0], 16);
- if (strcmp (setting1, setting2))
+ if ((setting1 == 0 && setting2 != 0) ||
+ (setting1 != 0 && setting2 == 0) ||
+ (setting1 != 0 && setting2 != 0 && strcmp (setting1, setting2)))
{
printf ("FAILED: crypt_gensalt defaulting to $2b$\n"
" $2b$ -> %s\n"
@@ -196,6 +226,7 @@ main (void)
free (setting2);
}
+#if INCLUDE_bcrypt
/* FIXME: This test is a little too specific. It used to be in
test-bcrypt.c and I'm not sure what it's meant to be testing. */
{
@@ -225,6 +256,6 @@ main (void)
free (setting1);
free (setting2);
}
-
+#endif
return status;
}
From 15b30b6d7da6d5470de65f9a2a4d676f82423ceb Mon Sep 17 00:00:00 2001
From: Zack Weinberg <zackw@panix.com>
Date: Wed, 4 Jul 2018 22:31:02 -0400
Subject: [PATCH 16/38] .travis.yml: Use --enable-hashes instead of
--enable-weak-hashes.
---
.travis.yml | 26 +++++++++++++-------------
1 file changed, 13 insertions(+), 13 deletions(-)
diff --git a/.travis.yml b/.travis.yml
index 7e892b2..ffca408 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -19,80 +19,80 @@ matrix:
os: linux
services: docker
env:
- - CONF="--enable-obsolete-api --enable-weak-hashes"
+ - CONF="--enable-obsolete-api --enable-hashes=all"
- FCVER="rawhide"
- CODECOV=1
- compiler: gcc
os: linux
services: docker
env:
- - CONF="--enable-obsolete-api --enable-weak-hashes"
+ - CONF="--enable-obsolete-api --enable-hashes=all"
- FCVER="rawhide"
- compiler: clang
os: linux
services: docker
env:
- - CONF="--enable-obsolete-api --enable-weak-hashes"
+ - CONF="--enable-obsolete-api --enable-hashes=all"
- FCVER="rawhide"
- compiler: gcc
os: linux
services: docker
env:
- - CONF="--enable-obsolete-api --enable-weak-hashes"
+ - CONF="--enable-obsolete-api --enable-hashes=all"
- FCVER="latest"
- compiler: clang
os: linux
services: docker
env:
- - CONF="--enable-obsolete-api --enable-weak-hashes"
+ - CONF="--enable-obsolete-api --enable-hashes=all"
- FCVER="latest"
- compiler: gcc
os: linux
services: docker
env:
- - CONF="--disable-obsolete-api --enable-weak-hashes"
+ - CONF="--disable-obsolete-api --enable-hashes=all"
- FCVER="rawhide"
- compiler: clang
os: linux
services: docker
env:
- - CONF="--disable-obsolete-api --enable-weak-hashes"
+ - CONF="--disable-obsolete-api --enable-hashes=all"
- FCVER="rawhide"
- compiler: gcc
os: linux
services: docker
env:
- - CONF="--disable-obsolete-api --enable-weak-hashes"
+ - CONF="--disable-obsolete-api --enable-hashes=all"
- FCVER="latest"
- compiler: clang
os: linux
services: docker
env:
- - CONF="--disable-obsolete-api --enable-weak-hashes"
+ - CONF="--disable-obsolete-api --enable-hashes=all"
- FCVER="latest"
- compiler: gcc
os: linux
services: docker
env:
- - CONF="--disable-obsolete-api --disable-weak-hashes"
+ - CONF="--disable-obsolete-api --enable-hashes=strong"
- FCVER="rawhide"
- compiler: clang
os: linux
services: docker
env:
- - CONF="--disable-obsolete-api --disable-weak-hashes"
+ - CONF="--disable-obsolete-api --enable-hashes=strong"
- FCVER="rawhide"
- compiler: gcc
os: linux
services: docker
env:
- - CONF="--disable-obsolete-api --disable-weak-hashes"
+ - CONF="--disable-obsolete-api --enable-hashes=strong"
- FCVER="latest"
- compiler: clang
os: linux
services: docker
env:
- - CONF="--disable-obsolete-api --disable-weak-hashes"
+ - CONF="--disable-obsolete-api --enable-hashes=strong"
- FCVER="latest"
before_install:
From a33d95ea613256c46f0b05fa2345080d47193c9e Mon Sep 17 00:00:00 2001
From: "Dmitry V. Levin" <ldv@altlinux.org>
Date: Wed, 4 Jul 2018 15:59:40 +0000
Subject: [PATCH 17/38] .travis.yml: add --enable-hashes=glibc to the test
matrix
---
.travis.yml | 24 ++++++++++++++++++++++++
1 file changed, 24 insertions(+)
diff --git a/.travis.yml b/.travis.yml
index ffca408..b8a7ecf 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -94,6 +94,30 @@ matrix:
env:
- CONF="--disable-obsolete-api --enable-hashes=strong"
- FCVER="latest"
+ - compiler: gcc
+ os: linux
+ services: docker
+ env:
+ - CONF="--enable-obsolete-api --enable-hashes=glibc"
+ - FCVER="rawhide"
+ - compiler: clang
+ os: linux
+ services: docker
+ env:
+ - CONF="--enable-obsolete-api --enable-hashes=glibc"
+ - FCVER="rawhide"
+ - compiler: gcc
+ os: linux
+ services: docker
+ env:
+ - CONF="--enable-obsolete-api --enable-hashes=glibc"
+ - FCVER="latest"
+ - compiler: clang
+ os: linux
+ services: docker
+ env:
+ - CONF="--enable-obsolete-api --enable-hashes=glibc"
+ - FCVER="latest"
before_install:
- for i in `seq 0 99`; do docker pull fedora:$FCVER && i= && break || sleep 1; done; [ -z "$i" ]
From a7f9df50cecec46bb8176382faa685ce35ca72be Mon Sep 17 00:00:00 2001
From: Zack Weinberg <zackw@panix.com>
Date: Thu, 5 Jul 2018 15:20:05 -0400
Subject: [PATCH 18/38] Make salt validation pickier.
This started out as a patch to fold together test-crypt-badsalt.c and
test-crypt-nonnull.c (which were almost the same program) and extend
their testing from DES to all of the supported hashes. That revealed
that many of the supported hash functions do not validate the contents
of their salt strings very carefully.
This patch has a low but nonzero backward compatibility risk, because
now we reject certain calls to crypt*() that we would previously have
accepted. In particular, setting strings of the form
$5$xxxxxxx*xxxxxxxx$
where x stands for any "itoa64" character and * for any non-"itoa64"
character, would formerly be accepted but are now rejected. Some of
the hash algorithms that were lenient about the contents of the salt
would echo back the salt verbatim, and others would convert it to the
base64 alphabet somehow. I think it's unlikely that this occurs in
real password files but I don't have a lot of data to base that on.
---
.gitignore | 3 +-
.travis.yml | 2 +-
Makefile.am | 9 +-
alg-des-tables.c | 30 +++--
crypt-des.c | 80 ++++++++---
crypt-md5.c | 9 +-
crypt-pbkdf1-sha1.c | 37 +++---
crypt-sha256.c | 11 +-
crypt-sha512.c | 11 +-
crypt-sunmd5.c | 72 +++++-----
crypt.c | 17 +--
test-badsalt.c | 367 +++++++++++++++++++++++++++++++++++++++++++++++++++
test-crypt-badsalt.c | 139 -------------------
test-crypt-nonnull.c | 97 --------------
test-gensalt.c | 31 +++--
15 files changed, 558 insertions(+), 357 deletions(-)
create mode 100644 test-badsalt.c
delete mode 100644 test-crypt-badsalt.c
delete mode 100644 test-crypt-nonnull.c
diff --git a/.gitignore b/.gitignore
index 9f443bd..bb7f15c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -53,13 +53,12 @@
/test-alg-sha1
/test-alg-sha256
/test-alg-sha512
+/test-badsalt
/test-bigcrypt
/test-byteorder
-/test-crypt-badsalt
/test-crypt-bcrypt
/test-crypt-des
/test-crypt-md5
-/test-crypt-nonnull
/test-crypt-nthash
/test-crypt-pbkdf1-sha1
/test-crypt-sha256
diff --git a/.travis.yml b/.travis.yml
index b8a7ecf..31c50fa 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -156,4 +156,4 @@ script:
- docker exec -t buildenv /bin/sh -c "(make -C /opt/libxcrypt -j$((`nproc --all` * 2)) check || (cat /opt/libxcrypt/test-suite.log && exit 1))"
after_success:
- - if [[ "$CODECOV" == "1" ]] ; then docker exec -t buildenv /bin/sh -c "cd /opt/libxcrypt ; lcov --directory . --capture --output-file all_coverage.info ; lcov --remove all_coverage.info '/usr/*' '*test*' > coverage.info ; rm -f all_coverage.info ; codecov -X gcov" ; fi
+ - if [[ "$CODECOV" == "1" ]] ; then docker exec -t buildenv /bin/sh -c "make -C /opt/libxcrypt check && cd /opt/libxcrypt && lcov --directory . --capture --output-file all_coverage.info && lcov --remove all_coverage.info '/usr/*' '*test*' > coverage.info && rm all_coverage.info && codecov -X gcov" ; fi
diff --git a/Makefile.am b/Makefile.am
index 040d719..79d59d7 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -122,11 +122,11 @@ endif
check_PROGRAMS = \
test-alg-des test-alg-hmac-sha1 test-alg-md4 test-alg-md5 \
test-alg-sha1 test-alg-sha256 test-alg-sha512 \
- test-crypt-badsalt test-crypt-bcrypt test-crypt-des \
- test-crypt-md5 test-crypt-nonnull test-crypt-nthash \
+ test-crypt-bcrypt test-crypt-des \
+ test-crypt-md5 test-crypt-nthash \
test-crypt-pbkdf1-sha1 test-crypt-sha256 test-crypt-sha512 \
test-crypt-sunmd5 \
- test-byteorder test-gensalt
+ test-byteorder test-badsalt test-gensalt
if ENABLE_OBSOLETE_API
libcrypt_la_SOURCES += crypt-des-obsolete.c
@@ -157,16 +157,15 @@ LOG_COMPILER = m4/skip-if-exec-format-error
endif
EXTRA_DIST += m4/skip-if-exec-format-error
-test_crypt_badsalt_LDADD = libcrypt.la
test_crypt_bcrypt_LDADD = libcrypt.la
test_crypt_des_LDADD = libcrypt.la
test_crypt_md5_LDADD = libcrypt.la
-test_crypt_nonnull_LDADD = libcrypt.la
test_crypt_nthash_LDADD = libcrypt.la
test_crypt_pbkdf1_sha1_LDADD = libcrypt.la
test_crypt_sha256_LDADD = libcrypt.la
test_crypt_sha512_LDADD = libcrypt.la
test_crypt_sunmd5_LDADD = libcrypt.la
+test_badsalt_LDADD = libcrypt.la
test_gensalt_LDADD = libcrypt.la
test_des_obsolete_LDADD = libcrypt.la
test_des_obsolete_r_LDADD = libcrypt.la
diff --git a/alg-des-tables.c b/alg-des-tables.c
index c46d1c4..4204a37 100644
--- a/alg-des-tables.c
+++ b/alg-des-tables.c
@@ -51,7 +51,8 @@
#if INCLUDE_des || INCLUDE_des_xbsd || INCLUDE_des_big
-const uint8_t m_sbox[4][4096] = {
+const uint8_t m_sbox[4][4096] =
+{
{
0xef, 0xe3, 0xe1, 0xed, 0xe8, 0xe4, 0xee, 0xe7, 0xe6, 0xef, 0xeb, 0xe2,
0xe3, 0xe8, 0xe4, 0xee, 0xe9, 0xec, 0xe7, 0xe0, 0xe2, 0xe1, 0xed, 0xea,
@@ -1430,7 +1431,8 @@ const uint8_t m_sbox[4][4096] = {
},
};
-const uint32_t ip_maskl[8][256] = {
+const uint32_t ip_maskl[8][256] =
+{
{
0x00000000, 0x00000001, 0x00000000, 0x00000001, 0x00000100, 0x00000101,
0x00000100, 0x00000101, 0x00000000, 0x00000001, 0x00000000, 0x00000001,
@@ -1793,7 +1795,8 @@ const uint32_t ip_maskl[8][256] = {
},
};
-const uint32_t ip_maskr[8][256] = {
+const uint32_t ip_maskr[8][256] =
+{
{
0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000000, 0x00000000,
0x00000001, 0x00000001, 0x00000100, 0x00000100, 0x00000101, 0x00000101,
@@ -2156,7 +2159,8 @@ const uint32_t ip_maskr[8][256] = {
},
};
-const uint32_t fp_maskl[8][256] = {
+const uint32_t fp_maskl[8][256] =
+{
{
0x00000000, 0x40000000, 0x00400000, 0x40400000, 0x00004000, 0x40004000,
0x00404000, 0x40404000, 0x00000040, 0x40000040, 0x00400040, 0x40400040,
@@ -2519,7 +2523,8 @@ const uint32_t fp_maskl[8][256] = {
},
};
-const uint32_t fp_maskr[8][256] = {
+const uint32_t fp_maskr[8][256] =
+{
{
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
@@ -2882,7 +2887,8 @@ const uint32_t fp_maskr[8][256] = {
},
};
-const uint32_t key_perm_maskl[8][128] = {
+const uint32_t key_perm_maskl[8][128] =
+{
{
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
@@ -3077,7 +3083,8 @@ const uint32_t key_perm_maskl[8][128] = {
},
};
-const uint32_t key_perm_maskr[8][128] = {
+const uint32_t key_perm_maskr[8][128] =
+{
{
0x00000000, 0x00100000, 0x00001000, 0x00101000, 0x00000010, 0x00100010,
0x00001010, 0x00101010, 0x00000001, 0x00100001, 0x00001001, 0x00101001,
@@ -3272,7 +3279,8 @@ const uint32_t key_perm_maskr[8][128] = {
},
};
-const uint32_t comp_maskl[8][128] = {
+const uint32_t comp_maskl[8][128] =
+{
{
0x00000000, 0x00000010, 0x00004000, 0x00004010, 0x00040000, 0x00040010,
0x00044000, 0x00044010, 0x00000100, 0x00000110, 0x00004100, 0x00004110,
@@ -3467,7 +3475,8 @@ const uint32_t comp_maskl[8][128] = {
},
};
-const uint32_t comp_maskr[8][128] = {
+const uint32_t comp_maskr[8][128] =
+{
{
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
@@ -3662,7 +3671,8 @@ const uint32_t comp_maskr[8][128] = {
},
};
-const uint32_t psbox[4][256] = {
+const uint32_t psbox[4][256] =
+{
{
0x00000000, 0x00004000, 0x40000000, 0x40004000, 0x00000010, 0x00004010,
0x40000010, 0x40004010, 0x00080000, 0x00084000, 0x40080000, 0x40084000,
diff --git a/crypt-des.c b/crypt-des.c
index 3d8bc2e..b197dcd 100644
--- a/crypt-des.c
+++ b/crypt-des.c
@@ -80,22 +80,22 @@ static const uint8_t ascii64[] =
/* 0000000000111111111122222222223333333333444444444455555555556666 */
/* 0123456789012345678901234567890123456789012345678901234567890123 */
-static inline unsigned int
+static inline int
ascii_to_bin(char ch)
{
if (ch > 'z')
- return 0;
+ return -1;
if (ch >= 'a')
- return (unsigned int)(ch - 'a' + 38);
+ return ch - 'a' + 38;
if (ch > 'Z')
- return 0;
+ return -1;
if (ch >= 'A')
- return (unsigned int)(ch - 'A' + 12);
+ return ch - 'A' + 12;
if (ch > '9')
- return 0;
+ return -1;
if (ch >= '.')
- return (unsigned int)(ch - '.');
- return 0;
+ return ch - '.';
+ return -1;
}
/* Generate an 11-character DES password hash into the buffer at
@@ -169,10 +169,21 @@ crypt_des_rn (const char *phrase, const char *setting,
/* "old"-style: setting - 2 bytes of salt, phrase - up to 8 characters.
Note: ascii_to_bin maps all byte values outside the ascii64
- alphabet to zero. Do not read past the end of the string. */
- salt = ascii_to_bin (setting[0]);
- if (setting[0])
- salt |= ascii_to_bin (setting[1]) << 6;
+ alphabet to -1. Do not read past the end of the string. */
+ i = ascii_to_bin (setting[0]);
+ if (i < 0)
+ {
+ errno = EINVAL;
+ return;
+ }
+ salt = (unsigned int)i;
+ i = ascii_to_bin (setting[1]);
+ if (i < 0)
+ {
+ errno = EINVAL;
+ return;
+ }
+ salt |= ((unsigned int)i << 6);
/* Write the canonical form of the salt to the output buffer. We do
this instead of copying from the setting because the setting
@@ -247,9 +258,20 @@ crypt_des_big_rn (const char *phrase, const char *setting,
/* The setting string is exactly the same as for a traditional DES
hash. */
- salt = ascii_to_bin (setting[0]);
- if (setting[0])
- salt |= ascii_to_bin (setting[1]) << 6;
+ i = ascii_to_bin (setting[0]);
+ if (i < 0)
+ {
+ errno = EINVAL;
+ return;
+ }
+ salt = (unsigned int)i;
+ i = ascii_to_bin (setting[1]);
+ if (i < 0)
+ {
+ errno = EINVAL;
+ return;
+ }
+ salt |= ((unsigned int)i << 6);
*cp++ = ascii64[salt & 0x3f];
*cp++ = ascii64[(salt >> 6) & 0x3f];
@@ -272,9 +294,9 @@ crypt_des_big_rn (const char *phrase, const char *setting,
break;
/* change the salt (1st 2 chars of previous block) - this was found
- by dowsing */
- salt = ascii_to_bin ((char)cp[0]);
- salt |= ascii_to_bin ((char)cp[1]) << 6;
+ by dowsing - no need to check for invalid characters here */
+ salt = (unsigned int)ascii_to_bin ((char)cp[0]);
+ salt |= (unsigned int)ascii_to_bin ((char)cp[1]) << 6;
cp += 11;
}
}
@@ -309,17 +331,33 @@ crypt_des_xbsd_rn (const char *phrase, const char *setting,
uint32_t count = 0, salt = 0;
uint8_t *keybuf = buf->keybuf, *pkbuf = buf->pkbuf;
uint8_t *cp = output;
- int i;
+ int i, x;
/* "new"-style DES hash:
setting - underscore, 4 bytes of count, 4 bytes of salt
phrase - unlimited characters
*/
for (i = 1; i < 5; i++)
- count |= ascii_to_bin(setting[i]) << ((i - 1) * 6);
+ {
+ x = ascii_to_bin(setting[i]);
+ if (x < 0)
+ {
+ errno = EINVAL;
+ return;
+ }
+ count |= (unsigned int)x << ((i - 1) * 6);
+ }
for (i = 5; i < 9; i++)
- salt |= ascii_to_bin(setting[i]) << ((i - 5) * 6);
+ {
+ x = ascii_to_bin(setting[i]);
+ if (x < 0)
+ {
+ errno = EINVAL;
+ return;
+ }
+ salt |= (unsigned int)x << ((i - 5) * 6);
+ }
memcpy (cp, setting, 9);
cp += 9;
diff --git a/crypt-md5.c b/crypt-md5.c
index 1a9139a..f051794 100644
--- a/crypt-md5.c
+++ b/crypt-md5.c
@@ -31,7 +31,7 @@
static const char md5_salt_prefix[] = "$1$";
/* Table with characters for base64 transformation. */
-static const char b64t[64] =
+static const char b64t[] =
"./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
/* The maximum length of an MD5 salt string (just the actual salt, not
@@ -88,7 +88,12 @@ crypt_md5_rn (const char *phrase, const char *setting,
/* Skip salt prefix. */
salt += sizeof (md5_salt_prefix) - 1;
- salt_len = strcspn (salt, "$");
+ salt_len = strspn (salt, b64t);
+ if (salt[salt_len] && salt[salt_len] != '$')
+ {
+ errno = EINVAL;
+ return;
+ }
if (salt_len > SALT_LEN_MAX)
salt_len = SALT_LEN_MAX;
phrase_len = strlen (phrase);
diff --git a/crypt-pbkdf1-sha1.c b/crypt-pbkdf1-sha1.c
index 544d890..6bacc21 100644
--- a/crypt-pbkdf1-sha1.c
+++ b/crypt-pbkdf1-sha1.c
@@ -148,30 +148,33 @@ crypt_sha1_rn (const char *phrase, const char *setting,
/*
* Salt format is
* $<tag>$<iterations>$salt[$]
- * If it does not start with $ we use our default iterations.
*/
- /* If it starts with the magic string, then skip that */
- if (!strncmp (setting, magic, strlen (magic)))
+ /* If the string doesn't starts with the magic prefix, we shouldn't have been called */
+ if (strncmp (setting, magic, strlen (magic)))
{
- setting += strlen (magic);
- /* and get the iteration count */
- iterations = (unsigned long)strtoul (setting, (char **)&ep, 10);
- if (*ep != '$')
- {
- errno = EINVAL;
- return; /* invalid input */
- }
- setting = (char *)ep + 1; /* skip over the '$' */
+ errno = EINVAL;
+ return;
}
- else
+
+ setting += strlen (magic);
+ /* get the iteration count */
+ iterations = (unsigned long)strtoul (setting, (char **)&ep, 10);
+ if (*ep != '$')
{
- iterations = (unsigned long)crypt_sha1_iterations (0);
+ errno = EINVAL;
+ return; /* invalid input */
}
+ setting = (char *)ep + 1; /* skip over the '$' */
- /* It stops at the next '$', max CRYPT_SHA1_ITERATIONS chars */
- for (sp = setting; *sp && *sp != '$' && sp < (setting + CRYPT_SHA1_ITERATIONS); sp++)
- continue;
+ /* The next 1..CRYPT_SHA1_SALT_LENGTH bytes should be itoa64 characters,
+ followed by another '$' (or end of string). */
+ sp = setting + strspn (setting, (const char *)itoa64);
+ if (sp == setting || (*sp && *sp != '$'))
+ {
+ errno = EINVAL;
+ return;
+ }
/* Get the length of the actual salt */
sl = (size_t)(sp - setting);
diff --git a/crypt-sha256.c b/crypt-sha256.c
index 8b4ba67..b8640b8 100644
--- a/crypt-sha256.c
+++ b/crypt-sha256.c
@@ -70,7 +70,7 @@ static_assert (sizeof (struct sha256_buffer) <= ALG_SPECIFIC_SIZE,
/* Table with characters for base64 transformation. */
-static const char b64t[64] =
+static const char b64t[] =
"./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
/* Subroutine of _xcrypt_crypt_sha256_rn: Feed CTX with LEN bytes of a
@@ -133,7 +133,14 @@ crypt_sha256_rn (const char *phrase, const char *setting,
}
}
- salt_len = MIN (strcspn (salt, "$"), SALT_LEN_MAX);
+ salt_len = strspn (salt, b64t);
+ if (salt[salt_len] && salt[salt_len] != '$')
+ {
+ errno = EINVAL;
+ return;
+ }
+ if (salt_len > SALT_LEN_MAX)
+ salt_len = SALT_LEN_MAX;
phrase_len = strlen (phrase);
/* Compute alternate SHA256 sum with input PHRASE, SALT, and PHRASE. The
diff --git a/crypt-sha512.c b/crypt-sha512.c
index 28e4f1c..1a651e0 100644
--- a/crypt-sha512.c
+++ b/crypt-sha512.c
@@ -70,7 +70,7 @@ static_assert (sizeof (struct sha512_buffer) <= ALG_SPECIFIC_SIZE,
/* Table with characters for base64 transformation. */
-static const char b64t[64] =
+static const char b64t[] =
"./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
/* Subroutine of _xcrypt_crypt_sha512_rn: Feed CTX with LEN bytes of a
@@ -133,7 +133,14 @@ crypt_sha512_rn (const char *phrase, const char *setting,
}
}
- salt_len = MIN (strcspn (salt, "$"), SALT_LEN_MAX);
+ salt_len = strspn (salt, b64t);
+ if (salt[salt_len] && salt[salt_len] != '$')
+ {
+ errno = EINVAL;
+ return;
+ }
+ if (salt_len > SALT_LEN_MAX)
+ salt_len = SALT_LEN_MAX;
phrase_len = strlen (phrase);
/* Compute alternate SHA512 sum with input PHRASE, SALT, and PHRASE. The
diff --git a/crypt-sunmd5.c b/crypt-sunmd5.c
index fcd3984..f3c84a8 100644
--- a/crypt-sunmd5.c
+++ b/crypt-sunmd5.c
@@ -115,41 +115,51 @@ to64 (char *s, uint64_t v, int n)
}
}
-#define ROUNDS "rounds="
+#define ROUNDS ",rounds="
#define ROUNDSLEN (sizeof (ROUNDS) - 1)
/*
- * get the integer value after rounds= where ever it occurs in the string.
- * if the last char after the int is a , or $ that is fine anything else is an
- * error.
+ * get the integer value after ,rounds= if present
+ * s should point immediately after $md5
+ * set *puresalt one character after the dollar sign after
+ * the number of rounds (if present) or to NULL if the syntax
+ * is invalid
*/
static uint32_t
-getrounds (const char *s)
+getrounds (const char *s, const char **puresalt)
{
- char *r, *p, *e;
+ const char *p;
+ char *e;
long val;
+ *puresalt = 0;
+
if (s == NULL)
return (0);
- if ((r = strstr (s, ROUNDS)) == NULL)
- return (0);
+ if (*s == '$')
+ {
+ *puresalt = s + 1;
+ return (0);
+ }
- if (strncmp (r, ROUNDS, ROUNDSLEN) != 0)
+ if (strncmp (s, ROUNDS, ROUNDSLEN) != 0)
return (0);
- p = r + ROUNDSLEN;
+ p = s + ROUNDSLEN;
errno = 0;
val = strtol (p, &e, 10);
/*
* An error occured or there is non-numeric stuff at the end
* which isn't one of the crypt(3c) special chars ',' or '$'
*/
- if (errno != 0 || val < 0 ||
- !(*e == '\0' || *e == ',' || *e == '$'))
- {
- return (0);
- }
+ if (errno != 0 || val < 0 || p == e || (*e != '\0' && *e != '$'))
+ return (0);
+
+ if (*e == '$')
+ *puresalt = e + 1;
+ else
+ *puresalt = e;
return ((uint32_t)val);
}
@@ -189,7 +199,7 @@ gensalt_sunmd5_rn (unsigned long count,
/* Generated salt is at least 27 bytes
and a maximum of 32 bytes long. */
snprintf ((char *)output, o_size,
- "$" CRYPT_ALGNAME "," ROUNDS "%u$%s$",
+ "$" CRYPT_ALGNAME ROUNDS "%u$%s$",
(unsigned int)count, rndstr);
}
@@ -245,22 +255,27 @@ crypt_sunmd5_rn (const char *phrase, const char *setting,
int round;
uint32_t maxrounds = BASIC_ROUND_COUNT;
uint32_t l;
- char *puresalt;
- char *saltend;
- char *p;
+ const char *ps = 0;
+ const char *saltend = 0;
+ char *p, *puresalt;
struct sunmd5_ctx *data = scratch;
/*
- * Extract the puresalt (if it exists) from the existing salt string
+ * Extract the rounds (if it exists) and puresalt from the salt string
* $md5[,rounds=%d]$<puresalt>$<optional existing encoding>
*/
- saltend = strrchr (setting, '$');
-
- if (saltend == NULL || saltend == setting)
+ maxrounds += getrounds (setting + sizeof ("$" CRYPT_ALGNAME) - 1, &ps);
+ if (ps)
+ saltend = ps + strspn (ps, (char *)itoa64);
+ if (!saltend || saltend == ps || saltend[0] != '$')
{
errno = EINVAL;
return;
}
+ /* For bug-compatibility with the original implementation, if saltend
+ points at "$$", advance it to point at the second dollar sign. */
+ if (saltend[0] == '$' && saltend[1] == '$')
+ saltend += 1;
if (saltend[1] != '\0')
{
@@ -289,17 +304,6 @@ crypt_sunmd5_rn (const char *phrase, const char *setting,
}
}
- /* There must not be any dollar sign '$', but
- the last character before the terminating
- '\0' in the string containing the salt. */
- if (puresalt[strlen (puresalt) - 2] == '$')
- {
- errno = EINVAL;
- return;
- }
-
- maxrounds += getrounds (setting);
-
/* initialise the context */
md5_init_ctx (&(data->context));
diff --git a/crypt.c b/crypt.c
index e1bfc5b..387b69a 100644
--- a/crypt.c
+++ b/crypt.c
@@ -83,17 +83,6 @@ static const struct hashfn hash_algorithms[] =
HASH_ALGORITHM_TABLE_ENTRIES
};
-#if INCLUDE_des || INCLUDE_des_big
-static int
-is_des_salt_char (char c)
-{
- return ((c >= 'a' && c <= 'z') ||
- (c >= 'A' && c <= 'Z') ||
- (c >= '0' && c <= '9') ||
- c == '.' || c == '/');
-}
-#endif
-
static const struct hashfn *
get_hashfn (const char *setting)
{
@@ -109,7 +98,7 @@ get_hashfn (const char *setting)
else
{
if (setting[0] == '\0' ||
- (is_des_salt_char (setting[0]) && is_des_salt_char (setting[1])))
+ (setting[0] != '$' && setting[0] != '*'))
return h;
}
#endif
@@ -265,8 +254,8 @@ do_crypt (const char *phrase, const char *setting, struct crypt_data *data)
}
#else
h->crypt (phrase, setting,
- (unsigned char *)data->output, sizeof data->output,
- cint->alg_specific, sizeof cint->alg_specific);
+ (unsigned char *)data->output, sizeof data->output,
+ cint->alg_specific, sizeof cint->alg_specific);
#endif
}
diff --git a/test-badsalt.c b/test-badsalt.c
new file mode 100644
index 0000000..41d164a
--- /dev/null
+++ b/test-badsalt.c
@@ -0,0 +1,367 @@
+/* Test rejection of ill-formed password hashes.
+ Copyright (C) 2012-2018 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include "crypt-port.h"
+#include <crypt.h>
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/mman.h>
+#include <unistd.h>
+
+static const char phrase[] = "values of β will give rise to dom!";
+
+struct testcase
+{
+ const char *label;
+ size_t plen;
+ const char *setting;
+};
+static const struct testcase testcases[] =
+{
+ /* These strings are invalid regardless of the algorithm. */
+ { "*too short", 1, "/" },
+ { "*invalid char :", 1, ":" },
+ { "*invalid char ;", 1, ";" },
+ { "*invalid char *", 1, "*" },
+ { "*invalid char !", 1, "!" },
+ { "*invalid char \\", 1, "\\" },
+ { "*invalid white 1", 1, " " },
+ { "*invalid white 2", 1, "\t" },
+ { "*invalid white 3", 1, "\r" },
+ { "*invalid white 4", 1, "\n" },
+ { "*invalid white 5", 1, "\f" },
+ { "*invalid ctrl 1", 1, "\1" },
+ { "*invalid ctrl 2", 1, "\177" },
+ { "*failure token 1", 2, "*0" },
+ { "*failure token 2", 2, "*1" },
+
+ /* Each of these is a valid setting string for some algorithm,
+ from which we will derive many invalid setting strings.
+ This is an expensive test, so where possible, the number of
+ "rounds" of the hash function has been set abnormally low. */
+#if INCLUDE_des
+ { "DES (trad.)", 2, "Mp" },
+ { "*DES (trad.), 1st char invalid -", 2, "-p" },
+ { "*DES (trad.), 2nd char invalid -", 2, "M-" },
+ { "*DES (trad.), 1st char invalid :", 2, ":p" },
+ { "*DES (trad.), 2nd char invalid :", 2, "M:" },
+ { "*DES (trad.), 1st char invalid [", 2, "[p" },
+ { "*DES (trad.), 2nd char invalid [", 2, "M[" },
+ { "*DES (trad.), 1st char invalid {", 2, "{p" },
+ { "*DES (trad.), 2nd char invalid {", 2, "M{" },
+#endif
+#if INCLUDE_des_big
+ { "DES (bigcrypt)", 2, "Mp............" },
+ { "*DES (bigcrypt), 1st char invalid -", 2, "-p............" },
+ { "*DES (bigcrypt), 2nd char invalid -", 2, "M-............" },
+ { "*DES (bigcrypt), 1st char invalid :", 2, ":p............" },
+ { "*DES (bigcrypt), 2nd char invalid :", 2, "M:............" },
+ { "*DES (bigcrypt), 1st char invalid [", 2, "[p............" },
+ { "*DES (bigcrypt), 2nd char invalid [", 2, "M[............" },
+ { "*DES (bigcrypt), 1st char invalid {", 2, "{p............" },
+ { "*DES (bigcrypt), 2nd char invalid {", 2, "M{............" },
+#endif
+#if INCLUDE_des_xbsd
+ { "DES (BSDi)", 9, "_J9..MJHn" },
+ { "*DES (BSDi), 1st char invalid -", 9, "_-9..MJHn" },
+ { "*DES (BSDi), 2nd char invalid -", 9, "_J-..MJHn" },
+ { "*DES (BSDi), 3rd char invalid -", 9, "_J9-.MJHn" },
+ { "*DES (BSDi), 4th char invalid -", 9, "_J9.-MJHn" },
+ { "*DES (BSDi), 5th char invalid -", 9, "_J9..-JHn" },
+ { "*DES (BSDi), 6th char invalid -", 9, "_J9..M-Hn" },
+ { "*DES (BSDi), 7th char invalid -", 9, "_J9..MJ-n" },
+ { "*DES (BSDi), 8th char invalid -", 9, "_J9..MJH-" },
+ { "*DES (BSDi), 1st char invalid :", 9, "_:9..MJHn" },
+ { "*DES (BSDi), 2nd char invalid :", 9, "_J:..MJHn" },
+ { "*DES (BSDi), 3rd char invalid :", 9, "_J9:.MJHn" },
+ { "*DES (BSDi), 4th char invalid :", 9, "_J9.:MJHn" },
+ { "*DES (BSDi), 5th char invalid :", 9, "_J9..:JHn" },
+ { "*DES (BSDi), 6th char invalid :", 9, "_J9..M:Hn" },
+ { "*DES (BSDi), 7th char invalid :", 9, "_J9..MJ:n" },
+ { "*DES (BSDi), 8th char invalid :", 9, "_J9..MJH:" },
+ { "*DES (BSDi), 1st char invalid [", 9, "_[9..MJHn" },
+ { "*DES (BSDi), 2nd char invalid [", 9, "_J[..MJHn" },
+ { "*DES (BSDi), 3rd char invalid [", 9, "_J9[.MJHn" },
+ { "*DES (BSDi), 4th char invalid [", 9, "_J9.[MJHn" },
+ { "*DES (BSDi), 5th char invalid [", 9, "_J9..[JHn" },
+ { "*DES (BSDi), 6th char invalid [", 9, "_J9..M[Hn" },
+ { "*DES (BSDi), 7th char invalid [", 9, "_J9..MJ[n" },
+ { "*DES (BSDi), 8th char invalid [", 9, "_J9..MJH[" },
+ { "*DES (BSDi), 1st char invalid {", 9, "_{9..MJHn" },
+ { "*DES (BSDi), 2nd char invalid {", 9, "_J{..MJHn" },
+ { "*DES (BSDi), 3rd char invalid {", 9, "_J9{.MJHn" },
+ { "*DES (BSDi), 4th char invalid {", 9, "_J9.{MJHn" },
+ { "*DES (BSDi), 5th char invalid {", 9, "_J9..{JHn" },
+ { "*DES (BSDi), 6th char invalid {", 9, "_J9..M{Hn" },
+ { "*DES (BSDi), 7th char invalid {", 9, "_J9..MJ{n" },
+ { "*DES (BSDi), 8th char invalid {", 9, "_J9..MJH{" },
+#endif
+#if INCLUDE_md5
+ { "MD5 (FreeBSD)", 12, "$1$MJHnaAke$" },
+#endif
+#if INCLUDE_sunmd5
+ { "MD5 (Sun, plain)", 14, "$md5$1xMeE.at$" },
+ { "MD5 (Sun, rounds)", 25, "$md5,rounds=123$1xMeE.at$" },
+#endif
+#if INCLUDE_nthash
+ { "NTHASH (bare)", 3, "$3$" },
+ { "NTHASH (fake salt)", 3, "$3$__not_used__c809a450df09a3" },
+#endif
+#if INCLUDE_sha1
+ { "HMAC-SHA1", 27, "$sha1$123$GGXpNqoJvglVTkGU$" },
+#endif
+#if INCLUDE_sha256
+ { "SHA-256 (plain)", 20, "$5$MJHnaAkegEVYHsFK$" },
+ { "SHA-256 (rounds)", 32, "$5$rounds=1000$MJHnaAkegEVYHsFK$" },
+#endif
+#if INCLUDE_sha512
+ { "SHA-512 (plain)", 20, "$6$MJHnaAkegEVYHsFK$" },
+ { "SHA-512 (rounds)", 32, "$6$rounds=1000$MJHnaAkegEVYHsFK$" },
+#endif
+#if INCLUDE_bcrypt
+ { "bcrypt (a04)", 29, "$2a$04$UBVLHeMpJ/QQCv3XqJx8zO" },
+ { "bcrypt (b04)", 29, "$2b$04$UBVLHeMpJ/QQCv3XqJx8zO" },
+ { "bcrypt (x04)", 29, "$2x$04$UBVLHeMpJ/QQCv3XqJx8zO" },
+ { "bcrypt (y04)", 29, "$2y$04$UBVLHeMpJ/QQCv3XqJx8zO" },
+#endif
+};
+
+static bool
+check_results (const char *label, const char *fn,
+ const char *retval, const char *setting,
+ bool expected_to_succeed)
+{
+ size_t l_setting = strlen (setting);
+ if (expected_to_succeed)
+ {
+ if (retval[0] == '*' ||
+ strncmp (retval, setting,
+ (setting[l_setting - 1] == '*') ? l_setting - 1 : l_setting))
+ {
+ printf ("FAIL: %s/%s/%s: expected success, got non-matching %s\n",
+ label, setting, fn, retval);
+ return false;
+ }
+ }
+ else
+ {
+ if (retval[0] != '*' ||
+ (l_setting >= 2 && !strncmp (retval, setting, l_setting)))
+ {
+ printf ("FAIL: %s/%s/%s: expected failure, got %s\n",
+ label, setting, fn, retval);
+ return false;
+ }
+ }
+ return true;
+}
+
+static bool
+check_crypt (const char *label, const char *fn,
+ const char *retval, const char *setting,
+ bool expected_to_succeed)
+{
+ /* crypt/crypt_r should never return null */
+ if (!retval)
+ {
+ printf ("FAIL: %s/%s/%s: returned NULL\n", label, setting, fn);
+ return false;
+ }
+ if (!check_results (label, fn, retval, setting,
+ expected_to_succeed))
+ return false;
+ return true;
+}
+
+static bool
+check_crypt_rn (const char *label, const char *fn,
+ const char *retval, const char *output,
+ const char *setting, bool expected_to_succeed)
+{
+ bool ok = true;
+ if (expected_to_succeed)
+ {
+ if (!retval)
+ {
+ printf ("FAIL: %s/%s/%s: returned NULL\n", label, setting, fn);
+ ok = false;
+ }
+ else if (retval != output)
+ {
+ printf ("FAIL: %s/%s/%s: returned %p but output is %p\n",
+ label, setting, fn,
+ (const void *)retval, (const void *)output);
+ ok = false;
+ }
+ }
+ else
+ {
+ if (retval)
+ {
+ printf ("FAIL: %s/%s/%s: returned %p (output is %p), "
+ "should be NULL\n",
+ label, setting, fn,
+ (const void *)retval, (const void *)output);
+ ok = false;
+ }
+ }
+ if (!check_results (label, fn, output, setting,
+ expected_to_succeed))
+ ok = false;
+ return ok;
+}
+
+static bool
+test_one_setting (const char *label, const char *setting,
+ struct crypt_data *cd, bool expected_to_succeed)
+{
+ bool ok = true;
+ const char *retval;
+ int cdsize = (int) sizeof (struct crypt_data);
+#ifdef VERBOSE
+ printf ("%s: testing %s (expect: %s)\n", label, setting,
+ expected_to_succeed ? "succeed" : "fail");
+#endif
+ retval = crypt (phrase, setting);
+ if (!check_crypt (label, "crypt", retval, setting, expected_to_succeed))
+ ok = false;
+
+ retval = crypt_r (phrase, setting, cd);
+ if (!check_crypt (label, "crypt_r", retval, setting, expected_to_succeed))
+ ok = false;
+
+ retval = crypt_rn (phrase, setting, cd, cdsize);
+ if (!check_crypt_rn (label, "crypt_rn", retval, cd->output,
+ setting, expected_to_succeed))
+ ok = false;
+
+ retval = crypt_ra (phrase, setting, (void **)&cd, &cdsize);
+ if (!check_crypt_rn (label, "crypt_ra", retval, cd->output,
+ setting, expected_to_succeed))
+ ok = false;
+ return ok;
+}
+
+static bool
+test_one_case (const struct testcase *t,
+ char *page, size_t pagesize,
+ struct crypt_data *cd)
+{
+ memset (page, 'a', pagesize);
+
+ size_t l_setting = strlen (t->setting);
+ assert (l_setting <= pagesize);
+ if (t->label[0] == '*')
+ {
+ /* Hashing with this setting is expected to fail already.
+ We still want to verify that we do not read past the end of
+ the string. */
+ char *p = page + pagesize - (l_setting + 1);
+ memcpy (p, t->setting, l_setting + 1);
+ if (!test_one_setting (t->label + 1, p, cd, false))
+ return false;
+ printf ("PASS: %s\n", t->label + 1);
+ return true;
+ }
+ else
+ {
+ /* Hashing with this setting is expected to succeed. */
+ char goodhash[CRYPT_OUTPUT_SIZE];
+ char *result = crypt_rn (phrase, t->setting, cd,
+ sizeof (struct crypt_data));
+ if (!result)
+ {
+ printf ("FAIL: %s: initial hash returned NULL/%s (%s)\n",
+ t->label, cd->output, strerror (errno));
+ return 1;
+ }
+
+ size_t l_hash = strlen (result);
+ assert (l_hash + 1 <= CRYPT_OUTPUT_SIZE);
+
+ memcpy (goodhash, result, l_hash + 1);
+
+ char *p = page + pagesize - (l_hash + 1);
+ memcpy (p, goodhash, l_hash + 1);
+
+ /* Rechecking the hash with the full output should succeed. */
+ if (!test_one_setting (t->label, p, cd, true))
+ return false;
+
+ /* Recomputing the hash with its own prefix should produce a
+ hash with the same prefix. */
+ p = page + pagesize - (t->plen + 1);
+ memcpy (p, goodhash, t->plen);
+ p[t->plen] = '\0';
+ if (!test_one_setting (t->label, p, cd, true))
+ return false;
+
+ /* An invalid character after the prefix should not affect the
+ result of the hash computation. */
+ p = page + pagesize - (t->plen + 2);
+ memcpy (p, goodhash, t->plen);
+ p[t->plen] = '*';
+ p[t->plen+1] = '\0';
+ if (!test_one_setting (t->label, p, cd, true))
+ return false;
+
+ /* However, an invalid character anywhere within the prefix should
+ cause hashing to fail. */
+ for (size_t i = 1; i < t->plen; i++)
+ {
+ p = page + pagesize - (t->plen + 2 - i);
+ memcpy (p, goodhash, t->plen - i);
+ if (!test_one_setting (t->label, p, cd, false))
+ return false;
+ }
+ printf ("PASS: %s\n", t->label);
+ return true;
+ }
+}
+
+int
+main (void)
+{
+ /* Set up a two-page region whose first page is read-write and
+ whose second page is inaccessible. */
+ size_t pagesize = (size_t) sysconf (_SC_PAGESIZE);
+ char *page = mmap (0, pagesize * 2, PROT_READ|PROT_WRITE,
+ MAP_PRIVATE|MAP_ANON, -1, 0);
+ if (page == MAP_FAILED)
+ {
+ perror ("mmap");
+ return 1;
+ }
+ memset (page, 'x', pagesize * 2);
+ if (mprotect (page + pagesize, pagesize, PROT_NONE))
+ {
+ perror ("mprotect");
+ return 1;
+ }
+
+ struct crypt_data cd;
+ memset (&cd, 0, sizeof cd);
+
+ bool ok = true;
+ for (size_t i = 0; i < ARRAY_SIZE (testcases); i++)
+ if (!test_one_case (&testcases[i], page, pagesize, &cd))
+ ok = false;
+
+ return ok ? 0 : 1;
+}
diff --git a/test-crypt-badsalt.c b/test-crypt-badsalt.c
deleted file mode 100644
index 8ce7401..0000000
--- a/test-crypt-badsalt.c
+++ /dev/null
@@ -1,139 +0,0 @@
-/* Test program for bad DES salt detection in crypt.
- Copyright (C) 2012-2017 Free Software Foundation, Inc.
- This file is part of the GNU C Library.
-
- The GNU C Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
-
- The GNU C Library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with the GNU C Library; if not, see
- <http://www.gnu.org/licenses/>. */
-
-#include "crypt-port.h"
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-#include <sys/mman.h>
-#include <crypt.h>
-
-static const char *tests[][3] =
-{
-#if INCLUDE_des || INCLUDE_des_big
- { "no salt", "", "..ogcgXxFhnjI" /* valid setting */ },
-#endif
- { "single char", "/", "*0" /* invalid setting */ },
- { "first char bad", "!x", "*0" /* invalid setting */ },
- { "second char bad", "Z%", "*0" /* invalid setting */ },
- { "both chars bad", ":@", "*0" /* invalid setting */ },
- { "un$upported algorithm", "$2$", "*0" /* invalid setting */ },
- { "un$upported $etting", "$2a$", "*0" /* invalid setting */ },
- { "un$upported $etting", "$2b$", "*0" /* invalid setting */ },
- { "un$upported $etting", "$2x$", "*0" /* invalid setting */ },
- { "bad salt for BSDi", "_1", "*0" /* invalid setting */ },
- { "end of page", NULL, "*0" /* invalid setting */ }
-};
-
-int
-main (void)
-{
- int cdsize = sizeof (struct crypt_data);
- int result = 0;
- struct crypt_data cd;
- struct crypt_data *cdptr = &cd;
- size_t n = ARRAY_SIZE (tests);
- size_t pagesize = (size_t) sysconf (_SC_PAGESIZE);
- char *page, *retval;
- const char *saltstr, *special = "%";
-
- /* Check that crypt won't look at the second character if the first
- one is invalid. */
- page = mmap (NULL, pagesize * 2, PROT_READ | PROT_WRITE,
- MAP_PRIVATE | MAP_ANON, -1, 0);
- if (page == MAP_FAILED)
- {
- perror ("mmap");
- n--;
- }
- else
- {
- if (mmap (page + pagesize, pagesize, 0,
- MAP_PRIVATE | MAP_ANON | MAP_FIXED,
- -1, 0) != page + pagesize)
- perror ("mmap 2");
- page[pagesize - 1] = special[0];
- tests[n - 1][1] = &page[pagesize - 1];
- }
-
- /* Mark cd as initialized before first call to crypt_r. */
- cd.initialized = 0;
-
- for (size_t i = 0; i < n; i++)
- {
- retval = crypt (tests[i][0], tests[i][1]);
- if (strcmp (tests[i][2], retval))
- {
- result++;
- if (memcmp (&page[pagesize - 1], tests[i][1], 1) != 0)
- saltstr = tests[i][1];
- else
- saltstr = special;
- printf ("%s: crypt returned wrong magic value with salt \"%s\".\n",
- tests[i][0], saltstr);
- printf (" expected: \"%s\"\n got: \"%s\"\n\n",
- tests[i][2], retval);
- }
-
- retval = crypt_r (tests[i][0], tests[i][1], &cd);
- if (strcmp (tests[i][2], retval))
- {
- result++;
- if (memcmp (&page[pagesize - 1], tests[i][1], 1) != 0)
- saltstr = tests[i][1];
- else
- saltstr = special;
- printf ("%s: crypt_r returned wrong magic value with salt \"%s\".\n",
- tests[i][0], saltstr);
- printf (" expected: \"%s\"\n got: \"%s\"\n\n",
- tests[i][2], retval);
- }
-
- crypt_rn (tests[i][0], tests[i][1], cdptr, cdsize);
- retval = cd.output;
- if (strcmp (tests[i][2], retval))
- {
- result++;
- if (memcmp (&page[pagesize - 1], tests[i][1], 1) != 0)
- saltstr = tests[i][1];
- else
- saltstr = special;
- printf ("%s: crypt_rn returned wrong magic value with salt \"%s\".\n",
- tests[i][0], saltstr);
- printf (" expected: \"%s\"\n got: \"%s\"\n\n",
- tests[i][2], retval);
- }
-
- crypt_ra (tests[i][0], tests[i][1], (void **)&cdptr, &cdsize);
- retval = cd.output;
- if (strcmp (tests[i][2], retval))
- {
- result++;
- if (memcmp (&page[pagesize - 1], tests[i][1], 1) != 0)
- saltstr = tests[i][1];
- else
- saltstr = special;
- printf ("%s: crypt_ra returned wrong magic value with salt \"%s\".\n",
- tests[i][0], saltstr);
- printf (" expected: \"%s\"\n got: \"%s\"\n\n",
- tests[i][2], retval);
- }
- }
-
- return result;
-}
diff --git a/test-crypt-nonnull.c b/test-crypt-nonnull.c
deleted file mode 100644
index e4738ff..0000000
--- a/test-crypt-nonnull.c
+++ /dev/null
@@ -1,97 +0,0 @@
-/* Test program for bad DES salt detection in crypt.
- Copyright (C) 2012-2017 Free Software Foundation, Inc.
- This file is part of the GNU C Library.
-
- The GNU C Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
-
- The GNU C Library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with the GNU C Library; if not, see
- <http://www.gnu.org/licenses/>. */
-
-#include "crypt-port.h"
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-#include <sys/mman.h>
-#include <crypt.h>
-
-static const char *tests[][3] =
-{
- { "single char", "/" },
- { "first char bad", "!x" },
- { "second char bad", "Z%" },
- { "both chars bad", ":@" },
- { "un$upported algorithm", "$2$" },
- { "un$upported $etting", "$2a$" },
- { "un$upported $etting", "$2b$" },
- { "un$upported $etting", "$2x$" },
- { "bad salt for BSDi", "_1" },
- { "end of page", NULL }
-};
-
-int
-main (void)
-{
- int cdsize = sizeof (struct crypt_data);
- int result = 0;
- struct crypt_data cd;
- struct crypt_data *cdptr = &cd;
- size_t n = ARRAY_SIZE (tests);
- size_t pagesize = (size_t) sysconf (_SC_PAGESIZE);
- char *page;
- const char *saltstr, *special = "%";
-
- /* Check that crypt won't look at the second character if the first
- one is invalid. */
- page = mmap (NULL, pagesize * 2, PROT_READ | PROT_WRITE,
- MAP_PRIVATE | MAP_ANON, -1, 0);
- if (page == MAP_FAILED)
- {
- perror ("mmap");
- n--;
- }
- else
- {
- if (mmap (page + pagesize, pagesize, 0,
- MAP_PRIVATE | MAP_ANON | MAP_FIXED,
- -1, 0) != page + pagesize)
- perror ("mmap 2");
- page[pagesize - 1] = special[0];
- tests[n - 1][1] = &page[pagesize - 1];
- }
-
- for (size_t i = 0; i < n; i++)
- {
- if (crypt_rn (tests[i][0], tests[i][1], cdptr, cdsize))
- {
- result++;
- if (memcmp (&page[pagesize - 1], tests[i][1], 1) != 0)
- saltstr = tests[i][1];
- else
- saltstr = special;
- printf ("%s: crypt_rn returned non-NULL with salt \"%s\"\n",
- tests[i][0], saltstr);
- }
-
- if (crypt_ra (tests[i][0], tests[i][1], (void **)&cdptr, &cdsize))
- {
- result++;
- if (memcmp (&page[pagesize - 1], tests[i][1], 1) != 0)
- saltstr = tests[i][1];
- else
- saltstr = special;
- printf ("%s: crypt_ra returned non-NULL with salt \"%s\"\n",
- tests[i][0], saltstr);
- }
- }
-
- return result;
-}
diff --git a/test-gensalt.c b/test-gensalt.c
index b81fcf0..5b9d64c 100644
--- a/test-gensalt.c
+++ b/test-gensalt.c
@@ -18,7 +18,8 @@ static const char *const entropy[] =
static const char *const des_expected_output[] = { "Mp", "Pp", "ZH", "Uh"};
#endif
#if INCLUDE_des_xbsd
-static const char *const bsdi_expected_output[] = {
+static const char *const bsdi_expected_output[] =
+{
"_J9..MJHn",
"_J9..PKXc",
"_J9..ZAFl",
@@ -26,7 +27,8 @@ static const char *const bsdi_expected_output[] = {
};
#endif
#if INCLUDE_md5
-static const char *const md5_expected_output[] = {
+static const char *const md5_expected_output[] =
+{
"$1$MJHnaAke",
"$1$PKXc3hCO",
"$1$ZAFlICwY",
@@ -34,7 +36,8 @@ static const char *const md5_expected_output[] = {
};
#endif
#if INCLUDE_nthash
-static const char *const nthash_expected_output[] = {
+static const char *const nthash_expected_output[] =
+{
"$3$__not_used__c809a450df09a3",
"$3$__not_used__30d0d6f834c0c3",
"$3$__not_used__0eeeebb83d6fe4",
@@ -48,7 +51,8 @@ static const char *const nthash_expected_output[] = {
#define pbkdf_expected_output 0 /* output is not deterministic */
#endif
#if INCLUDE_sha256
-static const char *const sha256_expected_output[] = {
+static const char *const sha256_expected_output[] =
+{
"$5$MJHnaAkegEVYHsFK",
"$5$PKXc3hCOSyMqdaEQ",
"$5$ZAFlICwYRETzIzIj",
@@ -56,7 +60,8 @@ static const char *const sha256_expected_output[] = {
};
#endif
#if INCLUDE_sha512
-static const char *const sha512_expected_output[] = {
+static const char *const sha512_expected_output[] =
+{
"$6$MJHnaAkegEVYHsFK",
"$6$PKXc3hCOSyMqdaEQ",
"$6$ZAFlICwYRETzIzIj",
@@ -64,25 +69,29 @@ static const char *const sha512_expected_output[] = {
};
#endif
#if INCLUDE_bcrypt
-static const char *const bcrypt_a_expected_output[] = {
+static const char *const bcrypt_a_expected_output[] =
+{
"$2a$05$UBVLHeMpJ/QQCv3XqJx8zO",
"$2a$05$kxUgPcrmlm9XoOjvxCyfP.",
"$2a$05$HPNDjKMRFdR7zC87CMSmA.",
"$2a$05$mAyzaIeJu41dWUkxEbn8hO"
};
-static const char *const bcrypt_b_expected_output[] = {
+static const char *const bcrypt_b_expected_output[] =
+{
"$2b$05$UBVLHeMpJ/QQCv3XqJx8zO",
"$2b$05$kxUgPcrmlm9XoOjvxCyfP.",
"$2b$05$HPNDjKMRFdR7zC87CMSmA.",
"$2b$05$mAyzaIeJu41dWUkxEbn8hO"
};
-static const char *const bcrypt_x_expected_output[] = {
+static const char *const bcrypt_x_expected_output[] =
+{
"$2x$05$UBVLHeMpJ/QQCv3XqJx8zO",
"$2x$05$kxUgPcrmlm9XoOjvxCyfP.",
"$2x$05$HPNDjKMRFdR7zC87CMSmA.",
"$2x$05$mAyzaIeJu41dWUkxEbn8hO"
};
-static const char *const bcrypt_y_expected_output[] = {
+static const char *const bcrypt_y_expected_output[] =
+{
"$2y$05$UBVLHeMpJ/QQCv3XqJx8zO",
"$2y$05$kxUgPcrmlm9XoOjvxCyfP.",
"$2y$05$HPNDjKMRFdR7zC87CMSmA.",
@@ -167,8 +176,8 @@ main (void)
}
size_t slen = strlen (salt);
unsigned int expected_len =
- (!entropy[ent] && tcase->expected_auto_len) ?
- tcase->expected_auto_len : tcase->expected_len;
+ (!entropy[ent] && tcase->expected_auto_len) ?
+ tcase->expected_auto_len : tcase->expected_len;
if (slen != expected_len)
{
fprintf (stderr,
From 58ac83090e107aa628a5be252931a2b8b0f286cf Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bj=C3=B6rn=20Esser?= <besser82@fedoraproject.org>
Date: Sun, 8 Jul 2018 23:59:53 +0200
Subject: [PATCH 19/38] Fix Werror=stringop-truncation
---
test-gensalt.c | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/test-gensalt.c b/test-gensalt.c
index 5b9d64c..c08627e 100644
--- a/test-gensalt.c
+++ b/test-gensalt.c
@@ -208,9 +208,8 @@ main (void)
fprintf (stderr, " ok: %s/%u -> %s\n",
tcase->prefix, ent, salt);
- /* Note: strncpy's somewhat odd fill-to-size-with-NULs behavior
- is specifically wanted in this case. */
- strncpy (prev_output, salt, CRYPT_GENSALT_OUTPUT_SIZE);
+ XCRYPT_SECURE_MEMSET (prev_output, CRYPT_GENSALT_OUTPUT_SIZE);
+ strncpy (prev_output, salt, CRYPT_GENSALT_OUTPUT_SIZE -1 );
}
}
From 98043c5be0ed8a09dfd49ad04b179c017ac78677 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bj=C3=B6rn=20Esser?= <besser82@fedoraproject.org>
Date: Mon, 9 Jul 2018 00:49:19 +0200
Subject: [PATCH 20/38] Fix DNF config for DNF v3.x
---
.travis.dnf.conf.rawhide_latest | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/.travis.dnf.conf.rawhide_latest b/.travis.dnf.conf.rawhide_latest
index ee4370a..52b55b0 100644
--- a/.travis.dnf.conf.rawhide_latest
+++ b/.travis.dnf.conf.rawhide_latest
@@ -1,5 +1,5 @@
-[latest_$basearch]
-name=Fedora - Rawhide Build - Fresh builds served by Koji - $basearch
+[latest_native]
+name=Fedora - Rawhide Build - Fresh builds served by Koji - native
failovermethod=priority
baseurl=https://kojipkgs.fedoraproject.org/repos/rawhide/latest/$basearch
enabled=1
From c14b7ae156e4dfb21c4c2506eb6d44e98eaa6f29 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bj=C3=B6rn=20Esser?= <besser82@fedoraproject.org>
Date: Mon, 9 Jul 2018 11:42:05 +0200
Subject: [PATCH 21/38] Extend badsalt tests and fix invalid pass
---
test-badsalt.c | 53 +++++++++++++++++++++++++++++++++++++----------------
1 file changed, 37 insertions(+), 16 deletions(-)
diff --git a/test-badsalt.c b/test-badsalt.c
index 41d164a..6d57b14 100644
--- a/test-badsalt.c
+++ b/test-badsalt.c
@@ -35,21 +35,24 @@ struct testcase
static const struct testcase testcases[] =
{
/* These strings are invalid regardless of the algorithm. */
- { "*too short", 1, "/" },
- { "*invalid char :", 1, ":" },
- { "*invalid char ;", 1, ";" },
- { "*invalid char *", 1, "*" },
- { "*invalid char !", 1, "!" },
- { "*invalid char \\", 1, "\\" },
- { "*invalid white 1", 1, " " },
- { "*invalid white 2", 1, "\t" },
- { "*invalid white 3", 1, "\r" },
- { "*invalid white 4", 1, "\n" },
- { "*invalid white 5", 1, "\f" },
- { "*invalid ctrl 1", 1, "\1" },
- { "*invalid ctrl 2", 1, "\177" },
- { "*failure token 1", 2, "*0" },
- { "*failure token 2", 2, "*1" },
+ { "*too short", 1, "/" },
+ { "*invalid char :", 1, ":" },
+ { "*invalid char ;", 1, ";" },
+ { "*invalid char *", 1, "*" },
+ { "*invalid char !", 1, "!" },
+ { "*invalid char \\", 1, "\\" },
+ { "*invalid white 1", 1, " " },
+ { "*invalid white 2", 1, "\t" },
+ { "*invalid white 3", 1, "\r" },
+ { "*invalid white 4", 1, "\n" },
+ { "*invalid white 5", 1, "\f" },
+ { "*invalid ctrl 1", 1, "\1" },
+ { "*invalid ctrl 2", 1, "\177" },
+ { "*failure token 1", 2, "*0" },
+ { "*failure token 2", 2, "*1" },
+ { "*bcrypt invalid salt", 3, "$2$" },
+ { "*unsupported algorithm", 13, "$un$upp0rt3d$" },
+ { "*empty string", 1, "\0" },
/* Each of these is a valid setting string for some algorithm,
from which we will derive many invalid setting strings.
@@ -114,10 +117,14 @@ static const struct testcase testcases[] =
#endif
#if INCLUDE_md5
{ "MD5 (FreeBSD)", 12, "$1$MJHnaAke$" },
+ { "*MD5 (FreeBSD) invalid char", 12, "$1$:JHnaAke$" },
#endif
#if INCLUDE_sunmd5
{ "MD5 (Sun, plain)", 14, "$md5$1xMeE.at$" },
+ { "*MD5 (Sun, plain) invalid char", 14, "$md5$:xMeE.at$" },
{ "MD5 (Sun, rounds)", 25, "$md5,rounds=123$1xMeE.at$" },
+ { "*MD5 (Sun, rounds) invalid char", 25, "$md5,rounds=123$:xMeE.at$" },
+ { "*MD5 (Sun, rounds) invalid rounds", 25, "$md5,rounds=:23$1xMeE.at$" },
#endif
#if INCLUDE_nthash
{ "NTHASH (bare)", 3, "$3$" },
@@ -125,20 +132,34 @@ static const struct testcase testcases[] =
#endif
#if INCLUDE_sha1
{ "HMAC-SHA1", 27, "$sha1$123$GGXpNqoJvglVTkGU$" },
+ { "*HMAC-SHA1 invalid char", 27, "$sha1$123$:GXpNqoJvglVTkGU$" },
+ { "*HMAC-SHA1 invalid rounds", 27, "$sha1$:23$GGXpNqoJvglVTkGU$" },
#endif
#if INCLUDE_sha256
{ "SHA-256 (plain)", 20, "$5$MJHnaAkegEVYHsFK$" },
+ { "*SHA-256 (plain) invalid char", 20, "$5$:JHnaAkegEVYHsFK$" },
{ "SHA-256 (rounds)", 32, "$5$rounds=1000$MJHnaAkegEVYHsFK$" },
+ { "*SHA-256 (rounds) invalid rounds", 32, "$5$rounds=:000$MJHnaAkegEVYHsFK$" },
#endif
#if INCLUDE_sha512
{ "SHA-512 (plain)", 20, "$6$MJHnaAkegEVYHsFK$" },
+ { "*SHA-512 (plain) invalid char", 20, "$6$:JHnaAkegEVYHsFK$" },
{ "SHA-512 (rounds)", 32, "$6$rounds=1000$MJHnaAkegEVYHsFK$" },
+ { "*SHA-512 (rounds) invalid rounds", 32, "$6$rounds=:000$MJHnaAkegEVYHsFK$" },
#endif
#if INCLUDE_bcrypt
{ "bcrypt (a04)", 29, "$2a$04$UBVLHeMpJ/QQCv3XqJx8zO" },
+ { "*bcrypt (a04) invalid char", 29, "$2a$04$:BVLHeMpJ/QQCv3XqJx8zO" },
+ { "*bcrypt (a04) invalid rounds", 29, "$2a$:4$UBVLHeMpJ/QQCv3XqJx8zO" },
{ "bcrypt (b04)", 29, "$2b$04$UBVLHeMpJ/QQCv3XqJx8zO" },
+ { "*bcrypt (b04) invalid char", 29, "$2b$04$:BVLHeMpJ/QQCv3XqJx8zO" },
+ { "*bcrypt (b04) invalid rounds", 29, "$2b$:4$UBVLHeMpJ/QQCv3XqJx8zO" },
{ "bcrypt (x04)", 29, "$2x$04$UBVLHeMpJ/QQCv3XqJx8zO" },
+ { "*bcrypt (x04) invalid char", 29, "$2x$04$:BVLHeMpJ/QQCv3XqJx8zO" },
+ { "*bcrypt (x04) invalid rounds", 29, "$2x$:4$UBVLHeMpJ/QQCv3XqJx8zO" },
{ "bcrypt (y04)", 29, "$2y$04$UBVLHeMpJ/QQCv3XqJx8zO" },
+ { "*bcrypt (y04) invalid char", 29, "$2y$04$:BVLHeMpJ/QQCv3XqJx8zO" },
+ { "*bcrypt (y04) invalid rounds", 29, "$2y$:4$UBVLHeMpJ/QQCv3XqJx8zO" },
#endif
};
@@ -289,7 +310,7 @@ test_one_case (const struct testcase *t,
{
printf ("FAIL: %s: initial hash returned NULL/%s (%s)\n",
t->label, cd->output, strerror (errno));
- return 1;
+ return false;
}
size_t l_hash = strlen (result);
From 820e5b242e648347e9c9e4110e75842b3d6531e5 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bj=C3=B6rn=20Esser?= <besser82@fedoraproject.org>
Date: Mon, 9 Jul 2018 15:25:54 +0200
Subject: [PATCH 22/38] Add test for short output buffers
---
Makefile.am | 3 ++-
test-short-outbuf.c | 72 +++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 74 insertions(+), 1 deletion(-)
create mode 100644 test-short-outbuf.c
diff --git a/Makefile.am b/Makefile.am
index 79d59d7..fec069e 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -126,7 +126,7 @@ check_PROGRAMS = \
test-crypt-md5 test-crypt-nthash \
test-crypt-pbkdf1-sha1 test-crypt-sha256 test-crypt-sha512 \
test-crypt-sunmd5 \
- test-byteorder test-badsalt test-gensalt
+ test-byteorder test-badsalt test-gensalt test-short-outbuf
if ENABLE_OBSOLETE_API
libcrypt_la_SOURCES += crypt-des-obsolete.c
@@ -169,6 +169,7 @@ test_badsalt_LDADD = libcrypt.la
test_gensalt_LDADD = libcrypt.la
test_des_obsolete_LDADD = libcrypt.la
test_des_obsolete_r_LDADD = libcrypt.la
+test_short_outbuf_LDADD = libcrypt.la
# These tests call internal APIs that may not be accessible from the
# fully linked shared library.
diff --git a/test-short-outbuf.c b/test-short-outbuf.c
new file mode 100644
index 0000000..7ab9d11
--- /dev/null
+++ b/test-short-outbuf.c
@@ -0,0 +1,72 @@
+#include "crypt-port.h"
+#include <crypt.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+struct testcase
+{
+ const char *exp_rn;
+ const char *exp_ra;
+};
+
+static const struct testcase testcases[] =
+{
+ { "", "*0" },
+ { "*", "*0" },
+ { "*0", "*0" },
+};
+
+int
+main (void)
+{
+ bool ok = true;
+ char **outbuf = malloc (sizeof (char*));
+ char result[5];
+
+ for (size_t i = 0; i < ARRAY_SIZE (testcases); i++)
+ {
+ size_t *j = malloc (sizeof (size_t));
+
+ *j = i + 1;
+
+ *outbuf = malloc (sizeof (char*) * *j);
+
+ crypt_rn ("@@", "@@", *outbuf, (int) *j);
+
+ if (!strncmp (testcases[i].exp_rn, *outbuf, *j))
+ {
+ strcpy (result, "PASS");
+ }
+ else
+ {
+ strcpy (result, "FAIL");
+ ok = false;
+ }
+
+ printf ("Test %lu.0: %s, expected: \"%-2s\", got: \"%-2s\"\n",
+ i + 1, result, testcases[i].exp_rn, *outbuf);
+
+ crypt_ra ("@@", "@@", (void **) outbuf, (int *) j);
+
+ if (!strncmp (testcases[i].exp_ra, *outbuf, strlen(*outbuf)))
+ {
+ strcpy (result, "PASS");
+ }
+ else
+ {
+ strcpy (result, "FAIL");
+ ok = false;
+ }
+
+ printf ("Test %lu.1: %s, expected: \"%-2s\", got: \"%-2s\"\n",
+ i + 1, result, testcases[i].exp_ra, *outbuf);
+
+ free (j);
+ free (*outbuf);
+ }
+
+ free (outbuf);
+
+ return ok ? 0 : 1;
+}
From 9197a77826124683e39ef123f5e57058e358e225 Mon Sep 17 00:00:00 2001
From: Zack Weinberg <zackw@panix.com>
Date: Tue, 10 Jul 2018 12:06:10 -0400
Subject: [PATCH 23/38] Replace crypt-sunmd5.c with BSD-licensed cleanroom
reimplementation.
This eliminates all CDDL-licensed code from the library, as requested
in issue #7 because of GPL incompatibility.
The new implementation was based exclusively on the prose description
of the algorithm in the Passlib v1.7.1 documentation, which should be
adequately arms-length for copyright purposes. (N.B. the lengthy
quotation from _Hamlet_ is used as input to MD5, so it must remain
byte-for-byte identical to achieve interoperability with the original;
also, the play itself is in the public domain.)
The new implementation is also fully deterministic (that is, its
gensalt procedure draws randomness only from its rbytes argument) and
does not call malloc.
---
LICENSING | 2 +-
crypt-sunmd5.c | 543 +++++++++++++++++++++++----------------------------------
test-gensalt.c | 8 +-
3 files changed, 225 insertions(+), 328 deletions(-)
diff --git a/LICENSING b/LICENSING
index b6f5168..b9df920 100644
--- a/LICENSING
+++ b/LICENSING
@@ -28,7 +28,7 @@ source tree. For specific licensing terms consult the files themselves.
* Copyright Michael Bretterklieber, Björn Esser et al.; 2-clause BSD:
crypt-nthash.c
- * Copyright Sun Microsystems, Inc., Björn Esser; CDDL-1.0:
+ * Copyright Zack Weinberg; 2-clause BSD:
crypt-sunmd5.c
* Public domain, written by Steve Reid et al.:
diff --git a/crypt-sunmd5.c b/crypt-sunmd5.c
index f3c84a8..9107052 100644
--- a/crypt-sunmd5.c
+++ b/crypt-sunmd5.c
@@ -1,27 +1,31 @@
-/*
- * CDDL HEADER START
+/* Copyright (c) 2018 Zack Weinberg.
+ * All rights reserved.
*
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * 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.
*
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
*
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
+ * This is a clean-room reimplementation of the Sun-MD5 password hash,
+ * based on the prose description of the algorithm in the Passlib v1.7.1
+ * documentation:
+ * https://passlib.readthedocs.io/en/stable/lib/passlib.hash.sun_md5_crypt.html
*/
#include "crypt-port.h"
@@ -34,21 +38,21 @@
#if INCLUDE_sunmd5
-
-#define CRYPT_ALGNAME "md5"
-
-/* minimum number of rounds we do, not including the per-user ones */
-#define BASIC_ROUND_COUNT 4096 /* enough to make things interesting */
-#define DIGEST_LEN 16
-#define ROUND_BUFFER_LEN 64
-
-/*
- * Public domain quotation courtesy of Project Gutenberg.
- * ftp://metalab.unc.edu/pub/docs/books/gutenberg/etext98/2ws2610.txt
- * Hamlet III.ii - 1517 bytes, including trailing NUL
- * ANSI-C string constant concatenation is a requirement here.
- */
-static const char constant_phrase[] =
+#define SUNMD5_PREFIX "$md5"
+#define SUNMD5_PREFIX_LEN 4
+#define SUNMD5_SALT_LEN 8
+#define SUNMD5_MAX_SETTING_LEN 32 /* $md5,rounds=4294963199$12345678$ */
+#define SUNMD5_BARE_OUTPUT_LEN 22 /* not counting the setting or the NUL */
+#define SUNMD5_MAX_ROUNDS (0xFFFFFFFF - 4096)
+
+/* At each round of the algorithm, this string (including the trailing
+ NUL) may or may not be included in the input to MD5, depending on a
+ pseudorandom coin toss. It is Hamlet's famous soliloquy from the
+ play of the same name, which is in the public domain. Text from
+ <https://www.gutenberg.org/files/1524/old/2ws2610.tex> with double
+ blank lines replaced with `\n`. Note that more recent Project
+ Gutenberg editions of _Hamlet_ are punctuated differently. */
+static const char hamlet_quotation[] =
"To be, or not to be,--that is the question:--\n"
"Whether 'tis nobler in the mind to suffer\n"
"The slings and arrows of outrageous fortune\n"
@@ -85,346 +89,233 @@ static const char constant_phrase[] =
"The fair Ophelia!--Nymph, in thy orisons\n"
"Be all my sins remember'd.\n";
-/* ------------------------------------------------------------------ */
-
-static int
-md5bit (uint8_t *digest, int bit_num)
+/* Decide, pseudorandomly, whether or not to include the above quotation
+ in the input to MD5. */
+static inline bool
+get_nth_bit (const uint8_t digest[16], unsigned int n)
{
- int byte_off;
- int bit_off;
-
- bit_num %= 128; /* keep this bounded for convenience */
- byte_off = bit_num / 8;
- bit_off = bit_num % 8;
-
- /* return the value of bit N from the digest */
- return ((digest[byte_off] & (0x01 << bit_off)) ? 1 : 0);
+ unsigned int byte = (n % 128) / 8;
+ unsigned int bit = (n % 128) % 8;
+ return !!(digest[byte] & (1 << bit));
}
-/* 0 ... 63 => ascii - 64 */
-static unsigned char itoa64[] =
- "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
-
-static void
-to64 (char *s, uint64_t v, int n)
+static bool
+muffet_coin_toss (const uint8_t prev_digest[16], unsigned int round_count)
{
- while (--n >= 0)
+ unsigned int x, y, a, b, r, v, i;
+ for (i = 0, x = 0, y = 0; i < 8; i++)
{
- *s++ = (char)itoa64[v&0x3f];
- v >>= 6;
+ a = prev_digest[(i + 0) % 16];
+ b = prev_digest[(i + 3) % 16];
+ r = a >> (b % 5);
+ v = prev_digest[r % 16];
+ if (b & (1u << (a % 8)))
+ v /= 2;
+ x |= ((unsigned int) +get_nth_bit (prev_digest, v)) << i;
+
+ a = prev_digest[(i + 8) % 16];
+ b = prev_digest[(i + 11) % 16];
+ r = a >> (b % 5);
+ v = prev_digest[r % 16];
+ if (b & (1u << (a % 8)))
+ v /= 2;
+ y |= ((unsigned int) +get_nth_bit (prev_digest, v)) << i;
}
-}
-#define ROUNDS ",rounds="
-#define ROUNDSLEN (sizeof (ROUNDS) - 1)
+ if (get_nth_bit (prev_digest, round_count))
+ x /= 2;
+ if (get_nth_bit (prev_digest, round_count + 64))
+ y /= 2;
-/*
- * get the integer value after ,rounds= if present
- * s should point immediately after $md5
- * set *puresalt one character after the dollar sign after
- * the number of rounds (if present) or to NULL if the syntax
- * is invalid
- */
-static uint32_t
-getrounds (const char *s, const char **puresalt)
-{
- const char *p;
- char *e;
- long val;
-
- *puresalt = 0;
-
- if (s == NULL)
- return (0);
+ return !!(get_nth_bit (prev_digest, x) ^ get_nth_bit (prev_digest, y));
+}
- if (*s == '$')
- {
- *puresalt = s + 1;
- return (0);
- }
+/* itoa64 output utilities. */
+static const unsigned char itoa64[] =
+ "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
- if (strncmp (s, ROUNDS, ROUNDSLEN) != 0)
- return (0);
-
- p = s + ROUNDSLEN;
- errno = 0;
- val = strtol (p, &e, 10);
- /*
- * An error occured or there is non-numeric stuff at the end
- * which isn't one of the crypt(3c) special chars ',' or '$'
- */
- if (errno != 0 || val < 0 || p == e || (*e != '\0' && *e != '$'))
- return (0);
-
- if (*e == '$')
- *puresalt = e + 1;
- else
- *puresalt = e;
-
- return ((uint32_t)val);
+static inline void
+write_itoa64_4 (uint8_t *output,
+ unsigned int b0, unsigned int b1, unsigned int b2)
+{
+ unsigned int value = (b0 << 0) | (b1 << 8) | (b2 << 16);
+ output[0] = itoa64[value & 0x3f];
+ output[1] = itoa64[(value >> 6) & 0x3f];
+ output[2] = itoa64[(value >> 12) & 0x3f];
+ output[3] = itoa64[(value >> 18) & 0x3f];
}
-void
-gensalt_sunmd5_rn (unsigned long count,
- const uint8_t *rbytes, size_t nrbytes,
- uint8_t *output, size_t o_size)
+/* used only for the last two bytes of crypt_sunmd5_rn output */
+static inline void
+write_itoa64_2 (uint8_t *output,
+ unsigned int b0, unsigned int b1, unsigned int b2)
{
- /* This should not happen, but. */
- if ((nrbytes < sizeof (uint64_t)) || (o_size < 33))
- {
- errno = ERANGE;
- return;
- }
-
- uint64_t rndval;
- char rndstr[sizeof (rndval) + 1]; /* rndval as a base64 string */
- const uint8_t minrounds = 15; /* Min. number of rounds = 2^X */
-
- /* Set count to a reasonable random value,
- if count was not set high enough by the
- caller. */
- if (count < (unsigned long)(1 << minrounds))
- {
- uint64_t rand1, rand2;
- get_random_bytes(&rand1, sizeof (uint64_t));
- get_random_bytes(&rand2, sizeof (uint64_t));
- count = (long unsigned int)(1 << ((rand1 % 2) + minrounds));
- count += (long unsigned int)(rand2 % (uint64_t)((1 << (minrounds - 1)) + 1));
- }
-
- memcpy (&rndval, rbytes, sizeof (rndval));
- to64 ((char *)&rndstr, rndval, sizeof (rndval));
- rndstr[sizeof (rndstr) - 1] = '\0';
-
- /* Generated salt is at least 27 bytes
- and a maximum of 32 bytes long. */
- snprintf ((char *)output, o_size,
- "$" CRYPT_ALGNAME ROUNDS "%u$%s$",
- (unsigned int)count, rndstr);
+ unsigned int value = (b0 << 0) | (b1 << 8) | (b2 << 16);
+ output[0] = itoa64[value & 0x3f];
+ output[1] = itoa64[(value >> 6) & 0x3f];
}
+/* Module entry points. */
+
void
-crypt_sunmd5_rn (const char *phrase, const char *setting,
- uint8_t *output, size_t o_size,
- void *scratch, size_t s_size)
+crypt_sunmd5_rn (const char *phrase,
+ const char *setting,
+ uint8_t *output,
+ size_t o_size,
+ void *scratch,
+ size_t s_size)
{
- /* put all the sensitive data in a struct */
- struct sunmd5_ctx
+ struct crypt_sunmd5_scratch
{
- struct md5_ctx context; /* working buffer for MD5 algorithm */
- uint8_t digest[DIGEST_LEN]; /* where the MD5 digest is stored */
-
- int indirect_4[16]; /* extracted array of 4bit values */
- int shift_4[16]; /* shift schedule, vals 0..4 */
-
- int s7shift; /* shift for shift_7 creation, vals 0..7 */
- int indirect_7[16]; /* extracted array of 7bit values */
- int shift_7[16]; /* shift schedule, vals 0..1 */
-
- int indirect_a; /* 7bit index into digest */
- int shift_a; /* shift schedule, vals 0..1 */
-
- int indirect_b; /* 7bit index into digest */
- int shift_b; /* shift schedule, vals 0..1 */
-
- int bit_a; /* single bit for cointoss */
- int bit_b; /* single bit for cointoss */
-
- char roundascii[ROUND_BUFFER_LEN]; /* ascii rep of roundcount */
+ struct md5_ctx ctx;
+ uint8_t dg[16];
+ char rn[16];
};
- /* Scratch space needs to be large enough
- to fit struct sunmd5_ctx. Output must
- be able to fit up to 32 bytes for the
- setting + '$' + 22 bytes of hash. */
- if (s_size < sizeof (struct sunmd5_ctx) || (o_size < 32 + 1 + 22))
+ /* If 'setting' doesn't start with the prefix, we should not have
+ been called in the first place. */
+ if (strncmp (setting, SUNMD5_PREFIX, SUNMD5_PREFIX_LEN)
+ || (setting[SUNMD5_PREFIX_LEN] != '$'
+ && setting[SUNMD5_PREFIX_LEN] != ','))
{
- errno = ERANGE;
+ errno = EINVAL;
return;
}
- /* If the magic does not match, this
- should not have been called. */
- if (!strncmp ("$" CRYPT_ALGNAME, setting, sizeof ("$" CRYPT_ALGNAME)))
+ /* For bug-compatibility with the original implementation, we allow
+ 'rounds=' to follow either '$md5,' or '$md5$'. */
+ const char *p = setting + SUNMD5_PREFIX_LEN + 1;
+ unsigned int nrounds = 4096;
+ if (!strncmp (p, "rounds=", sizeof "rounds=" - 1))
{
- errno = EINVAL;
- return;
+ p += sizeof "rounds=" - 1;
+ /* Do not allow an explicit setting of zero additional rounds,
+ nor leading zeroes on the number of rounds. */
+ if (!(*p >= '1' && *p <= '9'))
+ {
+ errno = EINVAL;
+ return;
+ }
+
+ errno = 0;
+ char *endp;
+ unsigned long arounds = strtoul (p, &endp, 10);
+ if (endp == p || arounds > SUNMD5_MAX_ROUNDS || errno)
+ {
+ errno = EINVAL;
+ return;
+ }
+ nrounds += (unsigned int)arounds;
+ p = endp;
+ if (*p != '$')
+ {
+ errno = EINVAL;
+ return;
+ }
+ p += 1;
}
- int i;
- int round;
- uint32_t maxrounds = BASIC_ROUND_COUNT;
- uint32_t l;
- const char *ps = 0;
- const char *saltend = 0;
- char *p, *puresalt;
- struct sunmd5_ctx *data = scratch;
-
- /*
- * Extract the rounds (if it exists) and puresalt from the salt string
- * $md5[,rounds=%d]$<puresalt>$<optional existing encoding>
- */
- maxrounds += getrounds (setting + sizeof ("$" CRYPT_ALGNAME) - 1, &ps);
- if (ps)
- saltend = ps + strspn (ps, (char *)itoa64);
- if (!saltend || saltend == ps || saltend[0] != '$')
+ /* p now points to the beginning of the actual salt. */
+ p += strspn (p, (const char *)itoa64);
+ if (*p != '\0' && *p != '$')
{
errno = EINVAL;
return;
}
- /* For bug-compatibility with the original implementation, if saltend
- points at "$$", advance it to point at the second dollar sign. */
- if (saltend[0] == '$' && saltend[1] == '$')
- saltend += 1;
-
- if (saltend[1] != '\0')
- {
- size_t len = (size_t)(saltend - setting + 1);
-
- if ((puresalt = malloc (len)) == NULL)
- /* malloc() is supposed to set errno == ENOMEM. */
- return;
-
- /* The original implementation used strlcpy(),
- which is not portable. Since strlcpy()
- always terminated a C string properly after
- copying len - 1 bytes of data, we need to
- do that manually. */
- (void)strncpy (puresalt, setting, len);
- puresalt[len - 1] = '\0';
- }
- else
+ /* For bug-compatibility with the original implementation, if p
+ points to a '$' and the following character is either another '$'
+ or NUL, the first '$' should be included in the salt. */
+ if (p[0] == '$' && (p[1] == '$' || p[1] == '\0'))
+ p += 1;
+
+ size_t saltlen = (size_t) (p - setting);
+ /* Do we have enough space? */
+ if (s_size < sizeof (struct crypt_sunmd5_scratch)
+ || o_size < saltlen + SUNMD5_BARE_OUTPUT_LEN + 2)
{
- puresalt = strdup(setting);
-
- if (puresalt == NULL)
- {
- /* strdup() is supposed to set errno == ENOMEM. */
- return;
- }
+ errno = ERANGE;
+ return;
}
- /* initialise the context */
- md5_init_ctx (&(data->context));
-
- /* update with the (hopefully entropic) plaintext */
- md5_process_bytes ((const unsigned char *)phrase, strlen (phrase), &(data->context));
-
- /* update with the (publically known) salt */
- md5_process_bytes ((unsigned char *)puresalt, strlen (puresalt), &(data->context));
-
-
- /* compute the digest */
- md5_finish_ctx (&(data->context), &(data->digest));
+ struct crypt_sunmd5_scratch *s = scratch;
- /*
- * now to delay high-speed md5 implementations that have stuff
- * like code inlining, loops unrolled and table lookup
- */
+ /* Initial round. */
+ md5_init_ctx (&s->ctx);
+ md5_process_bytes (phrase, strlen (phrase), &s->ctx);
+ md5_process_bytes (setting, saltlen, &s->ctx);
+ md5_finish_ctx (&s->ctx, s->dg);
- for (round = 0; (uint32_t)round < maxrounds; round++)
+ /* Stretching rounds. */
+ for (unsigned int i = 0; i < nrounds; i++)
{
- /* re-initialise the context */
- md5_init_ctx (&(data->context));
+ md5_init_ctx (&s->ctx);
- /* update with the previous digest */
- md5_process_bytes (&(data->digest), sizeof (data->digest), &(data->context));
+ md5_process_bytes (s->dg, sizeof s->dg, &s->ctx);
- /* populate the shift schedules for use later */
- for (i = 0; i < 16; i++)
- {
- int j;
-
- /* offset 3 -> occasionally span more than 1 int32 fetch */
- j = (i + 3) % 16;
- data->s7shift = data->digest[i] % 8;
- data->shift_4[i] = data->digest[j] % 5;
- data->shift_7[i] = (data->digest[j] >> data->s7shift) & 0x01;
- }
-
- data->shift_a = md5bit (data->digest, round);
- data->shift_b = md5bit (data->digest, round + 64);
-
- /* populate indirect_4 with 4bit values extracted from digest */
- for (i = 0; i < 16; i++)
- /* shift the digest byte and extract four bits */
- data->indirect_4[i] = (data->digest[i] >> data->shift_4[i]) & 0x0f;
-
- /*
- * populate indirect_7 with 7bit values from digest
- * indexed via indirect_4
- */
+ /* The trailing nul is intentionally included. */
+ if (muffet_coin_toss (s->dg, i))
+ md5_process_bytes (hamlet_quotation, sizeof hamlet_quotation, &s->ctx);
- for (i = 0; i < 16; i++)
- /* shift the digest byte and extract seven bits */
- data->indirect_7[i] = (data->digest[data->indirect_4[i]]
- >> data->shift_7[i]) & 0x7f;
+ int nwritten = snprintf (s->rn, sizeof s->rn, "%u", i);
+ assert (nwritten >= 1 && (unsigned int)nwritten + 1 <= sizeof s->rn);
+ md5_process_bytes (s->rn, (unsigned int)nwritten, &s->ctx);
- /*
- * use the 7bit values to indirect into digest,
- * and create two 8bit values from the results.
- */
- data->indirect_a = data->indirect_b = 0;
+ md5_finish_ctx (&s->ctx, s->dg);
+ }
- for (i = 0; i < 8; i++)
- {
- data->indirect_a |= (md5bit (data->digest,
- data->indirect_7[i]) << i);
+ memcpy (output, setting, saltlen);
+ *(output + saltlen + 0) = '$';
+ /* This is the same permuted order used by BSD md5-crypt ($1$). */
+ write_itoa64_4 (output + saltlen + 1, s->dg[12], s->dg[ 6], s->dg[0]);
+ write_itoa64_4 (output + saltlen + 5, s->dg[13], s->dg[ 7], s->dg[1]);
+ write_itoa64_4 (output + saltlen + 9, s->dg[14], s->dg[ 8], s->dg[2]);
+ write_itoa64_4 (output + saltlen + 13, s->dg[15], s->dg[ 9], s->dg[3]);
+ write_itoa64_4 (output + saltlen + 17, s->dg[ 5], s->dg[10], s->dg[4]);
+ write_itoa64_2 (output + saltlen + 21, s->dg[11], 0, 0);
+ *(output + saltlen + 23) = '\0';
+}
- data->indirect_b |= (md5bit (data->digest,
- data->indirect_7[i + 8]) << i);
- }
+void
+gensalt_sunmd5_rn (unsigned long count,
+ const uint8_t *rbytes,
+ size_t nrbytes,
+ uint8_t *output,
+ size_t o_size)
+{
+ if (o_size < SUNMD5_MAX_SETTING_LEN + 1 || nrbytes < 6 + 2)
+ {
+ errno = ERANGE;
+ return;
+ }
+ if (count > SUNMD5_MAX_ROUNDS)
+ {
+ errno = EINVAL;
+ return;
+ }
- /* shall we utilise the top or bottom 7 bits? */
- data->indirect_a = (data->indirect_a >> data->shift_a) & 0x7f;
- data->indirect_b = (data->indirect_b >> data->shift_b) & 0x7f;
+ /* The default number of rounds, 4096, is much too low. The actual
+ number of rounds is somewhat randomized to make construction of
+ rainbow tables more difficult (effectively this means an extra 16
+ bits of entropy are smuggled into the salt via the round number). */
+ if (count < 32768)
+ count = 32768;
+ else if (count + 65536 > SUNMD5_MAX_ROUNDS)
+ count = SUNMD5_MAX_ROUNDS - 65536;
- /* extract two data->digest bits */
- data->bit_a = md5bit (data->digest, data->indirect_a);
- data->bit_b = md5bit (data->digest, data->indirect_b);
+ count += ((unsigned int)rbytes[0]) << 8;
+ count += ((unsigned int)rbytes[1]) << 0;
- /* xor a coin-toss; if true, mix-in the constant phrase */
+ assert (count != 0);
- if (data->bit_a ^ data->bit_b)
- md5_process_bytes ((const unsigned char *) constant_phrase,
- sizeof (constant_phrase),
- &(data->context));
+ size_t written = (size_t) snprintf ((char *)output, o_size,
+ "%s,rounds=%lu$", SUNMD5_PREFIX, count);
- /* digest a decimal sprintf of the current roundcount */
- snprintf (data->roundascii, ROUND_BUFFER_LEN, "%d", round);
- md5_process_bytes ((unsigned char *) data->roundascii,
- strlen (data->roundascii),
- &(data->context));
- /* compute/flush the digest, and loop */
- md5_finish_ctx (&(data->context), &(data->digest));
- }
+ write_itoa64_4(output + written + 0, rbytes[2], rbytes[3], rbytes[4]);
+ write_itoa64_4(output + written + 4, rbytes[5], rbytes[6], rbytes[7]);
- (void)snprintf ((char *)output, o_size, "%s$", puresalt);
-
- free (puresalt);
-
- p = (char *)output + strlen ((const char *)output);
-
- l = (uint32_t)((data->digest[ 0]<<16) | (data->digest[ 6]<<8) | data->digest[12]);
- to64 (p, l, 4);
- p += 4;
- l = (uint32_t)((data->digest[ 1]<<16) | (data->digest[ 7]<<8) | data->digest[13]);
- to64 (p, l, 4);
- p += 4;
- l = (uint32_t)((data->digest[ 2]<<16) | (data->digest[ 8]<<8) | data->digest[14]);
- to64 (p, l, 4);
- p += 4;
- l = (uint32_t)((data->digest[ 3]<<16) | (data->digest[ 9]<<8) | data->digest[15]);
- to64 (p, l, 4);
- p += 4;
- l = (uint32_t)((data->digest[ 4]<<16) | (data->digest[10]<<8) | data->digest[ 5]);
- to64 (p, l, 4);
- p += 4;
- l = (uint32_t)data->digest[11];
- to64 (p, l, 2);
- p += 2;
- *p = '\0';
+ output[written + 8] = '$';
+ output[written + 9] = '\0';
}
#endif
diff --git a/test-gensalt.c b/test-gensalt.c
index c08627e..f8d95c3 100644
--- a/test-gensalt.c
+++ b/test-gensalt.c
@@ -45,7 +45,13 @@ static const char *const nthash_expected_output[] =
};
#endif
#if INCLUDE_sunmd5
-#define sunmd5_expected_output 0 /* output is not deterministic */
+static const char *const sunmd5_expected_output[] =
+{
+ "$md5,rounds=55349$BPm.fm03$",
+ "$md5,rounds=72501$WKoucttX$",
+ "$md5,rounds=42259$3HtkHq/x$",
+ "$md5,rounds=73773$p.5e9AQf$",
+};
#endif
#if INCLUDE_sha1
#define pbkdf_expected_output 0 /* output is not deterministic */
From 4067bee9f5b24d5323af232ef25f3b6dc4950f5a Mon Sep 17 00:00:00 2001
From: Zack Weinberg <zackw@panix.com>
Date: Tue, 10 Jul 2018 20:32:11 -0400
Subject: [PATCH 24/38] Make crypt_gensalt for $sha1 deterministic.
All of the randomness is now drawn from the 'rbytes' argument, rather
than taking some of it from direct calls to get_random_bytes. This
simplifies the logic and enables us to test the output more
thoroughly.
Relatedly, the amount of randomness crypt_gensalt will supply to $sha1
and $3 when it calls get_random_bytes itself is no longer oversized.
---
crypt-pbkdf1-sha1.c | 90 ++++++++++++++++++++++++++---------------------------
hashes.lst | 9 +++---
test-gensalt.c | 13 +++++---
3 files changed, 59 insertions(+), 53 deletions(-)
diff --git a/crypt-pbkdf1-sha1.c b/crypt-pbkdf1-sha1.c
index 6bacc21..ac201f0 100644
--- a/crypt-pbkdf1-sha1.c
+++ b/crypt-pbkdf1-sha1.c
@@ -66,34 +66,6 @@ to64 (uint8_t *s, unsigned long v, int n)
}
}
-/*
- * This may be called from crypt_sha1 or gensalt.
- *
- * The value returned will be slightly less than <hint> which defaults
- * to 24680. The goals are that the number of iterations should take
- * non-zero amount of time on a fast cpu while not taking insanely
- * long on a slow cpu. The current default will take about 5 seconds
- * on a 100MHz sparc, and about 0.04 seconds on a 3GHz i386.
- * The number is varied to frustrate those attempting to generate a
- * dictionary of pre-computed hashes.
- */
-static unsigned long
-crypt_sha1_iterations (unsigned long hint)
-{
- unsigned long random;
-
- /*
- * We treat CRYPT_SHA1_ITERATIONS as a hint.
- * Make it harder for someone to pre-compute hashes for a
- * dictionary attack by not using the same iteration count for
- * every entry.
- */
- get_random_bytes (&random, sizeof (unsigned long));
- if (hint == 0)
- hint = CRYPT_SHA1_ITERATIONS;
- return hint - (random % (hint / 4));
-}
-
/*
* UNIX password using hmac_sha1
* This is PBKDF1 from RFC 2898, but using hmac_sha1.
@@ -107,7 +79,7 @@ crypt_sha1_iterations (unsigned long hint)
* have been applied to <digest>. The number
* should vary slightly for each password to make
* it harder to generate a dictionary of
- * pre-computed hashes. See crypt_sha1_iterations.
+ * pre-computed hashes. See gensalt_sha1_rn.
* <salt> up to 64 bytes of random data, 8 bytes is
* currently considered more than enough.
* <digest> the hashed password.
@@ -234,34 +206,62 @@ gensalt_sha1_rn (unsigned long count,
const uint8_t *rbytes, size_t nrbytes,
uint8_t *output, size_t o_size)
{
- /* The salt can be up to 64 bytes, but 32
- is considered enough for now. */
- const uint8_t saltlen = 16;
+ static_assert (sizeof (uint32_t) == 4,
+ "space calculations below assume 8-bit bytes");
- const size_t enclen = sizeof (unsigned long)*4/3;
+ /* Make sure we have enough random bytes to use for the salt.
+ The format supports using up to 48 random bytes, but 12 is
+ enough. We require another 4 bytes of randomness to perturb
+ 'count' with. */
+ if (nrbytes < 12 + 4)
+ {
+ errno = ERANGE;
+ return;
+ }
- if ((o_size < (size_t)(6 + CRYPT_SHA1_SALT_LENGTH + 2)) ||
- ((nrbytes*4/3) < saltlen))
+ /* Make sure we have enough output space, given the amount of
+ randomness available. $sha1$<10digits>$<(nrbytes-4)*4/3>$ */
+ if (o_size < (nrbytes - 4) * 4 / 3 + sizeof "$sha1$$$" + 10)
{
errno = ERANGE;
return;
}
- unsigned long c, encbuf;
+ /*
+ * We treat 'count' as a hint.
+ * Make it harder for someone to pre-compute hashes for a
+ * dictionary attack by not using the same iteration count for
+ * every entry.
+ */
+ uint32_t rounds, random;
+ memcpy (&random, rbytes, 4);
+ if (count == 0)
+ count = CRYPT_SHA1_ITERATIONS;
+ if (count > UINT32_MAX)
+ count = UINT32_MAX;
+ rounds = (uint32_t) (count - (random % (count / 4)));
+
+ uint32_t encbuf;
+ int n = snprintf((char *)output, o_size, "$sha1$%u$", (unsigned int)rounds);
+ assert (n >= 1 && (size_t)n + 2 < o_size);
- unsigned int n = (unsigned int) snprintf((char *)output, o_size, "$sha1$%u$",
- (unsigned int)crypt_sha1_iterations(count));
+ const uint8_t *r = rbytes + 4;
+ const uint8_t *rlim = rbytes + nrbytes;
+ uint8_t *o = output + n;
+ uint8_t *olim = output + n + CRYPT_SHA1_SALT_LENGTH;
+ if (olim + 2 > output + o_size)
+ olim = output + o_size - 2;
- for (c = 0; (c * sizeof (unsigned long)) + sizeof (unsigned long) <= nrbytes &&
- (c * enclen) + enclen <= CRYPT_SHA1_SALT_LENGTH; ++c)
+ for (; r + 3 < rlim && o + 4 < olim; r += 3, o += 4)
{
- memcpy (&encbuf, rbytes + (c * sizeof (unsigned long)),
- sizeof (unsigned long));
- to64 (output + n + (c * enclen), encbuf, (int)enclen);
+ encbuf = ((((uint32_t)r[0]) << 16) |
+ (((uint32_t)r[1]) << 8) |
+ (((uint32_t)r[2]) << 0));
+ to64 (o, encbuf, 4);
}
- output[n + (c * enclen)] = '$';
- output[n + (c * enclen) + 1] = '\0';
+ o[0] = '$';
+ o[1] = '\0';
}
#endif
diff --git a/hashes.lst b/hashes.lst
index 488768f..4ec79cc 100644
--- a/hashes.lst
+++ b/hashes.lst
@@ -5,8 +5,9 @@
# name used for the 'crypt_fn' and 'gensalt_fn' entry points to the
# relevant algorithm module; an optional suffix on the name of the
# 'gensalt_fn'; the prefix used to identify the algorithm in hash
-# strings; the number of bytes of random data required to generate a
-# salt; and a set of flags. Currently there are three flags: DEFAULT
+# strings; the number of bytes of random data that crypt_gensalt
+# should draw from the OS when its caller doesn't supply any;
+# and a set of flags. Currently there are three flags: DEFAULT
# means this is the hash to use when no prefix was supplied to
# crypt_gensalt, STRONG means the hash is still considered strong
# enough to use for newly hashed passwords, and GLIBC means the hash
@@ -33,8 +34,8 @@ sha512 : $6$ 15 STRONG,GLIBC
sha256 : $5$ 15 STRONG,GLIBC
md5 : $1$ 9 GLIBC
sunmd5 : $md5 8 :
-sha1 : $sha1 48 :
-nthash : $3$ 16 :
+sha1 : $sha1 20 :
+nthash : $3$ 7 :
des_xbsd : _ 3 :
des_big : : 2 :
des : : 2 GLIBC
diff --git a/test-gensalt.c b/test-gensalt.c
index f8d95c3..98923e5 100644
--- a/test-gensalt.c
+++ b/test-gensalt.c
@@ -54,7 +54,13 @@ static const char *const sunmd5_expected_output[] =
};
#endif
#if INCLUDE_sha1
-#define pbkdf_expected_output 0 /* output is not deterministic */
+static const char *const pbkdf_expected_output[] =
+{
+ "$sha1$248488$ggu.H673kaZ5$",
+ "$sha1$248421$SWqudaxXA5L0$",
+ "$sha1$257243$RAtkIrDxEovH$",
+ "$sha1$250464$1j.eVxRfNAPO$",
+};
#endif
#if INCLUDE_sha256
static const char *const sha256_expected_output[] =
@@ -131,7 +137,7 @@ static const struct testcase testcases[] =
{ "$md5", sunmd5_expected_output, 27, 0 }, // SUNMD5
#endif
#if INCLUDE_sha1
- { "$sha1", pbkdf_expected_output, 34, 74 }, // PBKDF with SHA1
+ { "$sha1", pbkdf_expected_output, 26, 34 }, // PBKDF with SHA1
#endif
#if INCLUDE_sha256
{ "$5$", sha256_expected_output, 19, 0 }, // SHA-2-256
@@ -203,8 +209,7 @@ main (void)
tcase->prefix, ent, salt);
status = 1;
}
- else if (entropy[ent] && tcase->expected_output &&
- strcmp (salt, tcase->expected_output[ent]))
+ else if (entropy[ent] && strcmp (salt, tcase->expected_output[ent]))
{
fprintf (stderr, "ERROR: %s/%u -> %s (expected %s)\n",
tcase->prefix, ent, salt, tcase->expected_output[ent]);
From 9bed27f2bd0495361e892a0740bcdf237f560b98 Mon Sep 17 00:00:00 2001
From: Zack Weinberg <zackw@panix.com>
Date: Tue, 10 Jul 2018 21:36:11 -0400
Subject: [PATCH 25/38] Don't use malloc in crypt-pbkdf1-sha1.c.
There's no need to copy the salt when we can just use %.*s in two
places.
Making this change revealed that -Wformat-truncation=2 is too
aggressive; we are actually taking appropriate precautions against
truncated strings in this case, but it warns anyway. Back down to
-Wformat-truncation=1, which warns only when the return value of
snprintf is ignored.
---
crypt-pbkdf1-sha1.c | 20 ++++++--------------
m4/zw_simple_warnings.m4 | 2 +-
2 files changed, 7 insertions(+), 15 deletions(-)
diff --git a/crypt-pbkdf1-sha1.c b/crypt-pbkdf1-sha1.c
index ac201f0..cbf390e 100644
--- a/crypt-pbkdf1-sha1.c
+++ b/crypt-pbkdf1-sha1.c
@@ -109,7 +109,6 @@ crypt_sha1_rn (const char *phrase, const char *setting,
unsigned long ul;
size_t sl;
size_t pl;
- char *salt;
int dl;
unsigned long iterations;
unsigned long i;
@@ -148,32 +147,27 @@ crypt_sha1_rn (const char *phrase, const char *setting,
return;
}
- /* Get the length of the actual salt */
sl = (size_t)(sp - setting);
-
- salt = malloc (sl + 1);
- strncpy (salt, setting, sl);
- salt[sl] = '\0';
-
pl = strlen (phrase);
/*
* Now get to work...
* Prime the pump with <salt><magic><iterations>
*/
- dl = snprintf ((char *)output, o_size, "%s%s%lu",
- salt, magic, iterations);
+ dl = snprintf ((char *)output, o_size, "%.*s%s%lu",
+ (int)sl, setting, magic, iterations);
/*
* Then hmac using <phrase> as key, and repeat...
*/
- hmac_sha1_process_data ((const unsigned char *)output, (size_t)dl, pwu, pl, hmac_buf);
+ hmac_sha1_process_data ((const unsigned char *)output, (size_t)dl,
+ pwu, pl, hmac_buf);
for (i = 1; i < iterations; ++i)
{
hmac_sha1_process_data (hmac_buf, SHA1_SIZE, pwu, pl, hmac_buf);
}
/* Now output... */
- pl = (size_t)snprintf ((char *)output, o_size, "%s%lu$%s$",
- magic, iterations, salt);
+ pl = (size_t)snprintf ((char *)output, o_size, "%s%lu$%.*s$",
+ magic, iterations, (int)sl, setting);
ep = output + pl;
/* Every 3 bytes of hash gives 24 bits which is 4 base64 chars */
@@ -195,8 +189,6 @@ crypt_sha1_rn (const char *phrase, const char *setting,
/* Don't leave anything around in vm they could use. */
XCRYPT_SECURE_MEMSET (scratch, s_size)
- XCRYPT_SECURE_MEMSET (salt, sl)
- free (salt);
}
/* Modified excerpt from:
diff --git a/m4/zw_simple_warnings.m4 b/m4/zw_simple_warnings.m4
index eeb57d5..75ca300 100644
--- a/m4/zw_simple_warnings.m4
+++ b/m4/zw_simple_warnings.m4
@@ -112,7 +112,7 @@ AC_ARG_ENABLE(
-Wformat=2 dnl
-Wformat-overflow=2 dnl
-Wformat-signedness dnl
- -Wformat-truncation=2 dnl
+ -Wformat-truncation=1 dnl
-Winline dnl
-Wlogical-op dnl
-Wmissing-declarations dnl
From c20f9f161c0aa362e0ed8bc8ee387badd8acbc38 Mon Sep 17 00:00:00 2001
From: Zack Weinberg <zackw@panix.com>
Date: Tue, 10 Jul 2018 21:44:02 -0400
Subject: [PATCH 26/38] Fix incorrect output-size computation in crypt_sha1_rn.
It was testing for enough space for the raw SHA1 digest, not the
digest after base64 expansion.
(This is not presently detectable by the test suite because the higher
layers always supply crypt_<alg>_rn functions with CRYPT_OUTPUT_SIZE
bytes of space, which is far more than any of them need.)
---
crypt-pbkdf1-sha1.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/crypt-pbkdf1-sha1.c b/crypt-pbkdf1-sha1.c
index cbf390e..c96b72d 100644
--- a/crypt-pbkdf1-sha1.c
+++ b/crypt-pbkdf1-sha1.c
@@ -51,7 +51,8 @@
# define CRYPT_SHA1_SALT_LENGTH 64
#endif
-#define SHA1_SIZE 20
+#define SHA1_SIZE 20 /* size of raw SHA1 digest, 160 bits */
+#define SHA1_OUTPUT_SIZE 28 /* size of base64-ed output string */
static const uint8_t itoa64[] =
"./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
@@ -97,7 +98,8 @@ crypt_sha1_rn (const char *phrase, const char *setting,
{
static const char *magic = "$sha1$";
- if ((o_size < (strlen (magic) + 2 + 10 + CRYPT_SHA1_SALT_LENGTH + SHA1_SIZE)) ||
+ if ((o_size < (strlen (magic) + 2 + 10 + CRYPT_SHA1_SALT_LENGTH +
+ SHA1_OUTPUT_SIZE)) ||
s_size < SHA1_SIZE)
{
errno = ERANGE;
From 8639108dea0b847282e1de2bae6c7aef8f778b99 Mon Sep 17 00:00:00 2001
From: Zack Weinberg <zackw@panix.com>
Date: Tue, 10 Jul 2018 21:49:14 -0400
Subject: [PATCH 27/38] Make XCRYPT_SECURE_MEMSET() syntactically a normal
expression.
All of the alternative definitions of XCRYPT_SECURE_MEMSET expanded to
a full statement including the terminating semicolon, and none of its
uses had a terminating semicolon, which looked like a typo. Correct
this: put semicolons on each use, and remove them from the
definitions. This is entirely cosmetic, but it's been bugging me.
(There is no risk of unexpected parser behavior after macro expansion:
after this change, XCRYPT_SECURE_MEMSET(...) looks like a function
call expression, and all of its possible expansions are, in fact,
function call expressions.)
---
alg-md4.c | 6 +++---
alg-md5.c | 4 ++--
alg-sha1.c | 4 ++--
alg-sha256.c | 4 ++--
alg-sha512.c | 4 ++--
crypt-des-obsolete.c | 2 +-
crypt-des.c | 4 ++--
crypt-nthash.c | 2 +-
crypt-pbkdf1-sha1.c | 2 +-
crypt-port.h | 8 ++++----
crypt.c | 2 +-
randombytes.c | 2 +-
12 files changed, 22 insertions(+), 22 deletions(-)
diff --git a/alg-md4.c b/alg-md4.c
index ce62490..c1c4075 100644
--- a/alg-md4.c
+++ b/alg-md4.c
@@ -163,7 +163,7 @@ md4_read_ctx (struct md4_ctx *ctx, void *resbuf)
cpu_to_le32 (buf + 4, ctx->b);
cpu_to_le32 (buf + 8, ctx->c);
cpu_to_le32 (buf + 12, ctx->d);
- XCRYPT_SECURE_MEMSET (ctx, sizeof(struct md4_ctx))
+ XCRYPT_SECURE_MEMSET (ctx, sizeof(struct md4_ctx));
return resbuf;
}
@@ -230,13 +230,13 @@ md4_finish_ctx (struct md4_ctx *ctx, void *resbuf)
if (free < 8)
{
- XCRYPT_SECURE_MEMSET (&ctx->buffer[used], free)
+ XCRYPT_SECURE_MEMSET (&ctx->buffer[used], free);
body(ctx, ctx->buffer, 64);
used = 0;
free = 64;
}
- XCRYPT_SECURE_MEMSET (&ctx->buffer[used], free - 8)
+ XCRYPT_SECURE_MEMSET (&ctx->buffer[used], free - 8);
ctx->lo <<= 3;
ctx->buffer[56] = (unsigned char)((ctx->lo) & 0xff);
diff --git a/alg-md5.c b/alg-md5.c
index df49fc6..9d9e4e3 100644
--- a/alg-md5.c
+++ b/alg-md5.c
@@ -52,7 +52,7 @@ md5_read_ctx (struct md5_ctx *ctx, void *resbuf)
cpu_to_le32 (buf + 4, ctx->B);
cpu_to_le32 (buf + 8, ctx->C);
cpu_to_le32 (buf + 12, ctx->D);
- XCRYPT_SECURE_MEMSET (ctx, sizeof(*ctx))
+ XCRYPT_SECURE_MEMSET (ctx, sizeof(*ctx));
return resbuf;
}
@@ -74,7 +74,7 @@ md5_finish_ctx (struct md5_ctx *ctx, void *resbuf)
/* The first byte of padding should be 0x80 and the rest should be
zero. (RFC 1321, 3.1: Step 1) */
ctx->buffer[bytes] = 0x80u;
- XCRYPT_SECURE_MEMSET (&ctx->buffer[bytes+1], pad-1)
+ XCRYPT_SECURE_MEMSET (&ctx->buffer[bytes+1], pad-1);
/* Put the 64-bit file length in little-endian *bits* at the end of
the buffer. */
diff --git a/alg-sha1.c b/alg-sha1.c
index 421ffbd..a00b06b 100644
--- a/alg-sha1.c
+++ b/alg-sha1.c
@@ -274,8 +274,8 @@ sha1_finish_ctx (struct sha1_ctx *ctx, void *resbuf)
/* Wipe variables */
i = 0;
- XCRYPT_SECURE_MEMSET (ctx, sizeof (struct sha1_ctx))
- XCRYPT_SECURE_MEMSET (finalcount, 8) /* SWR */
+ XCRYPT_SECURE_MEMSET (ctx, sizeof (struct sha1_ctx));
+ XCRYPT_SECURE_MEMSET (finalcount, 8); /* SWR */
return resbuf;
}
diff --git a/alg-sha256.c b/alg-sha256.c
index 713385d..db4a2fd 100644
--- a/alg-sha256.c
+++ b/alg-sha256.c
@@ -183,7 +183,7 @@ sha256_finish_ctx (struct sha256_ctx *ctx, void *resbuf)
/* The first byte of padding should be 0x80 and the rest should be
zero. (FIPS 180-2:5.1.1) */
ctx->buffer[bytes] = 0x80u;
- XCRYPT_SECURE_MEMSET (&ctx->buffer[bytes+1], pad-1)
+ XCRYPT_SECURE_MEMSET (&ctx->buffer[bytes+1], pad-1);
/* Put the 64-bit file length in big-endian *bits* at the end of the
buffer. */
@@ -196,7 +196,7 @@ sha256_finish_ctx (struct sha256_ctx *ctx, void *resbuf)
for (i = 0; i < 8; i++)
cpu_to_be32 (rp + i*4, ctx->H[i]);
- XCRYPT_SECURE_MEMSET (ctx, sizeof (struct sha256_ctx))
+ XCRYPT_SECURE_MEMSET (ctx, sizeof (struct sha256_ctx));
return resbuf;
}
diff --git a/alg-sha512.c b/alg-sha512.c
index 6a6aab2..60c1877 100644
--- a/alg-sha512.c
+++ b/alg-sha512.c
@@ -213,7 +213,7 @@ sha512_finish_ctx (struct sha512_ctx *ctx, void *resbuf)
/* The first byte of padding should be 0x80 and the rest should be
zero. (FIPS 180-2:5.1.2) */
ctx->buffer[bytes] = 0x80u;
- XCRYPT_SECURE_MEMSET (&ctx->buffer[bytes+1], pad-1)
+ XCRYPT_SECURE_MEMSET (&ctx->buffer[bytes+1], pad-1);
/* Put the 128-bit file length in big-endian *bits* at the end of
the buffer. */
@@ -229,7 +229,7 @@ sha512_finish_ctx (struct sha512_ctx *ctx, void *resbuf)
for (i = 0; i < 8; ++i)
cpu_to_be64 (rp + i*8, ctx->H[i]);
- XCRYPT_SECURE_MEMSET (ctx, sizeof (struct sha512_ctx))
+ XCRYPT_SECURE_MEMSET (ctx, sizeof (struct sha512_ctx));
return resbuf;
}
diff --git a/crypt-des-obsolete.c b/crypt-des-obsolete.c
index afe279b..52853e3 100644
--- a/crypt-des-obsolete.c
+++ b/crypt-des-obsolete.c
@@ -106,7 +106,7 @@ pack_bits (unsigned char bitv[8], const char bytev[64])
static void
do_setkey_r (const char *key, struct des_ctx *ctx)
{
- XCRYPT_SECURE_MEMSET (ctx, sizeof (struct des_ctx))
+ XCRYPT_SECURE_MEMSET (ctx, sizeof (struct des_ctx));
des_set_salt (ctx, 0);
unsigned char bkey[8];
diff --git a/crypt-des.c b/crypt-des.c
index b197dcd..733c4d3 100644
--- a/crypt-des.c
+++ b/crypt-des.c
@@ -107,7 +107,7 @@ des_gen_hash (struct des_ctx *ctx, uint32_t count, uint8_t *output,
uint8_t cbuf[8])
{
uint8_t plaintext[8];
- XCRYPT_SECURE_MEMSET (plaintext, 8)
+ XCRYPT_SECURE_MEMSET (plaintext, 8);
des_crypt_block (ctx, cbuf, plaintext, count, false);
/* Now encode the result. */
@@ -369,7 +369,7 @@ crypt_des_xbsd_rn (const char *phrase, const char *setting,
set as the DES key, and encrypted to produce the round output.
The salt is zero throughout this procedure. */
des_set_salt (ctx, 0);
- XCRYPT_SECURE_MEMSET (pkbuf, 8)
+ XCRYPT_SECURE_MEMSET (pkbuf, 8);
for (;;)
{
for (i = 0; i < 8; i++)
diff --git a/crypt-nthash.c b/crypt-nthash.c
index f9fee7b..890f57f 100644
--- a/crypt-nthash.c
+++ b/crypt-nthash.c
@@ -78,7 +78,7 @@ crypt_nthash_rn (const char *phrase,
return;
}
- XCRYPT_SECURE_MEMSET (unipw, sizeof unipw)
+ XCRYPT_SECURE_MEMSET (unipw, sizeof unipw);
/* convert to unicode (thanx Archie) */
unipwLen = 0;
for (s = phrase; unipwLen < sizeof(unipw) / 2 && *s; s++)
diff --git a/crypt-pbkdf1-sha1.c b/crypt-pbkdf1-sha1.c
index c96b72d..f15b55d 100644
--- a/crypt-pbkdf1-sha1.c
+++ b/crypt-pbkdf1-sha1.c
@@ -190,7 +190,7 @@ crypt_sha1_rn (const char *phrase, const char *setting,
*ep = '\0';
/* Don't leave anything around in vm they could use. */
- XCRYPT_SECURE_MEMSET (scratch, s_size)
+ XCRYPT_SECURE_MEMSET (scratch, s_size);
}
/* Modified excerpt from:
diff --git a/crypt-port.h b/crypt-port.h
index 6d94b09..80fa489 100644
--- a/crypt-port.h
+++ b/crypt-port.h
@@ -95,15 +95,15 @@ typedef union
#if defined HAVE_MEMSET_S
/* Will never be optimized out. */
#define XCRYPT_SECURE_MEMSET(s, len) \
- memset_s (s, len, 0x00, len);
+ memset_s (s, len, 0x00, len)
#elif defined HAVE_EXPLICIT_BZERO
/* explicit_bzero() should give us enough guarantees. */
#define XCRYPT_SECURE_MEMSET(s, len) \
- explicit_bzero(s, len);
+ explicit_bzero(s, len)
#elif defined HAVE_EXPLICIT_MEMSET
/* Same guarantee goes for explicit_memset(). */
#define XCRYPT_SECURE_MEMSET(s, len) \
- explicit_memset (s, 0x00, len);
+ explicit_memset (s, 0x00, len)
#else
/* The best hope we have in this case. */
static inline
@@ -114,7 +114,7 @@ void _xcrypt_secure_memset (void *s, size_t len)
*c++ = 0x00;
}
#define XCRYPT_SECURE_MEMSET(s, len) \
- _xcrypt_secure_memset (s, len);
+ _xcrypt_secure_memset (s, len)
#endif
/* Per-symbol version tagging. Currently we only know how to do this
diff --git a/crypt.c b/crypt.c
index 387b69a..405d9a3 100644
--- a/crypt.c
+++ b/crypt.c
@@ -259,7 +259,7 @@ do_crypt (const char *phrase, const char *setting, struct crypt_data *data)
#endif
}
- XCRYPT_SECURE_MEMSET (data->internal, sizeof data->internal)
+ XCRYPT_SECURE_MEMSET (data->internal, sizeof data->internal);
}
#if INCLUDE_crypt_rn
diff --git a/randombytes.c b/randombytes.c
index 5647250..5053525 100644
--- a/randombytes.c
+++ b/randombytes.c
@@ -68,7 +68,7 @@ get_random_bytes(void *buf, size_t buflen)
}
/* To eliminate the possibility of one of the primitives below failing
with EFAULT, force a crash now if the buffer is unwritable. */
- XCRYPT_SECURE_MEMSET (buf, buflen)
+ XCRYPT_SECURE_MEMSET (buf, buflen);
#ifdef HAVE_ARC4RANDOM_BUF
/* arc4random_buf, if it exists, can never fail. */
From 15d1e3bf3d259ea262f3d34e8c225a3abfabaa09 Mon Sep 17 00:00:00 2001
From: Zack Weinberg <zackw@panix.com>
Date: Wed, 11 Jul 2018 17:15:46 -0400
Subject: [PATCH 28/38] Add more tests based on gaps in line coverage.
We were not adequately testing invalid-argument error paths within
crypt_gensalt, and we were also not adequately testing a variety of
corner cases related to non-default round parameters
After this change, I believe that all of the non-covered lines fall
into three categories: genuinely impossible to hit from the public
API (usually these are double-checks for preconditions already
verified at a higher level); checks for memory allocation failure; and
fallback paths within get_random_bytes. The first two of these, IMHO,
are fine to leave as is. It would probably be worth writing a test
that exercises the get_random_bytes fallbacks but it'd involve getting
one's hands dirty with ELF. I may do it eventually if no one else does.
This change makes us pickier about non-default round parameters to $5$
and $6$ hashes; numbers outside the valid range are now rejected, as
are numbers with leading zeroes and an explicit request for the
default number of rounds. This is in keeping with the observation, in
the Passlib documentation, that allowing more than one valid crypt
output string for any given (rounds, salt, phrase) triple is asking
for trouble.
This partially reverts commit
a7f9df50cecec46bb8176382faa685ce35ca72be, which accidentally caused us
to fail to reject invalid DES setting strings. Because of this, a few
lines in crypt-des.c cease to be covered; they are in category
1 (double-checks of preconditions).
---
Makefile.am | 4 +-
crypt-pbkdf1-sha1.c | 2 +-
crypt-sha256.c | 26 ++++--
crypt-sha512.c | 26 ++++--
crypt-sunmd5.c | 4 +-
crypt.c | 13 ++-
test-badsalt.c | 40 +++++++--
test-badsetting.c | 236 ++++++++++++++++++++++++++++++++++++++++++++++++++++
test-crypt-sha256.c | 10 ---
test-crypt-sha512.c | 10 ---
test-gensalt.c | 82 ++++++++++++++----
11 files changed, 391 insertions(+), 62 deletions(-)
create mode 100644 test-badsetting.c
diff --git a/Makefile.am b/Makefile.am
index fec069e..51cba76 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -126,7 +126,8 @@ check_PROGRAMS = \
test-crypt-md5 test-crypt-nthash \
test-crypt-pbkdf1-sha1 test-crypt-sha256 test-crypt-sha512 \
test-crypt-sunmd5 \
- test-byteorder test-badsalt test-gensalt test-short-outbuf
+ test-byteorder test-badsalt test-badsetting test-gensalt \
+ test-short-outbuf
if ENABLE_OBSOLETE_API
libcrypt_la_SOURCES += crypt-des-obsolete.c
@@ -166,6 +167,7 @@ test_crypt_sha256_LDADD = libcrypt.la
test_crypt_sha512_LDADD = libcrypt.la
test_crypt_sunmd5_LDADD = libcrypt.la
test_badsalt_LDADD = libcrypt.la
+test_badsetting_LDADD = libcrypt.la
test_gensalt_LDADD = libcrypt.la
test_des_obsolete_LDADD = libcrypt.la
test_des_obsolete_r_LDADD = libcrypt.la
diff --git a/crypt-pbkdf1-sha1.c b/crypt-pbkdf1-sha1.c
index f15b55d..cf22f67 100644
--- a/crypt-pbkdf1-sha1.c
+++ b/crypt-pbkdf1-sha1.c
@@ -209,7 +209,7 @@ gensalt_sha1_rn (unsigned long count,
'count' with. */
if (nrbytes < 12 + 4)
{
- errno = ERANGE;
+ errno = EINVAL;
return;
}
diff --git a/crypt-sha256.c b/crypt-sha256.c
index b8640b8..22c6423 100644
--- a/crypt-sha256.c
+++ b/crypt-sha256.c
@@ -111,7 +111,6 @@ crypt_sha256_rn (const char *phrase, const char *setting,
size_t cnt;
/* Default number of rounds. */
size_t rounds = ROUNDS_DEFAULT;
- bool rounds_custom = false;
/* Find beginning of salt string. The prefix should normally always
be present. Just in case it is not. */
@@ -123,14 +122,27 @@ crypt_sha256_rn (const char *phrase, const char *setting,
== 0)
{
const char *num = salt + sizeof (sha256_rounds_prefix) - 1;
+ /* Do not allow an explicit setting of zero rounds, nor of the
+ default number of rounds, nor leading zeroes on the rounds. */
+ if (!(*num >= '1' && *num <= '9'))
+ {
+ errno = EINVAL;
+ return;
+ }
+
+ errno = 0;
char *endp;
- unsigned long int srounds = strtoul (num, &endp, 10);
- if (*endp == '$')
+ rounds = strtoul (num, &endp, 10);
+ if (endp == num || *endp != '$'
+ || rounds < ROUNDS_MIN
+ || rounds > ROUNDS_MAX
+ || rounds == ROUNDS_DEFAULT
+ || errno)
{
- salt = endp + 1;
- rounds = MAX (ROUNDS_MIN, MIN (srounds, ROUNDS_MAX));
- rounds_custom = true;
+ errno = EINVAL;
+ return;
}
+ salt = endp + 1;
}
salt_len = strspn (salt, b64t);
@@ -243,7 +255,7 @@ crypt_sha256_rn (const char *phrase, const char *setting,
memcpy (cp, sha256_salt_prefix, sizeof (sha256_salt_prefix) - 1);
cp += sizeof (sha256_salt_prefix) - 1;
- if (rounds_custom)
+ if (rounds != ROUNDS_DEFAULT)
{
int n = snprintf (cp,
SHA256_HASH_LENGTH - (sizeof (sha256_salt_prefix) - 1),
diff --git a/crypt-sha512.c b/crypt-sha512.c
index 1a651e0..7df4805 100644
--- a/crypt-sha512.c
+++ b/crypt-sha512.c
@@ -111,7 +111,6 @@ crypt_sha512_rn (const char *phrase, const char *setting,
size_t cnt;
/* Default number of rounds. */
size_t rounds = ROUNDS_DEFAULT;
- bool rounds_custom = false;
/* Find beginning of salt string. The prefix should normally always
be present. Just in case it is not. */
@@ -123,14 +122,27 @@ crypt_sha512_rn (const char *phrase, const char *setting,
== 0)
{
const char *num = salt + sizeof (sha512_rounds_prefix) - 1;
+ /* Do not allow an explicit setting of zero rounds, nor of the
+ default number of rounds, nor leading zeroes on the rounds. */
+ if (!(*num >= '1' && *num <= '9'))
+ {
+ errno = EINVAL;
+ return;
+ }
+
+ errno = 0;
char *endp;
- unsigned long int srounds = strtoul (num, &endp, 10);
- if (*endp == '$')
+ rounds = strtoul (num, &endp, 10);
+ if (endp == num || *endp != '$'
+ || rounds < ROUNDS_MIN
+ || rounds > ROUNDS_MAX
+ || rounds == ROUNDS_DEFAULT
+ || errno)
{
- salt = endp + 1;
- rounds = MAX (ROUNDS_MIN, MIN (srounds, ROUNDS_MAX));
- rounds_custom = true;
+ errno = EINVAL;
+ return;
}
+ salt = endp + 1;
}
salt_len = strspn (salt, b64t);
@@ -246,7 +258,7 @@ crypt_sha512_rn (const char *phrase, const char *setting,
memcpy (cp, sha512_salt_prefix, sizeof (sha512_salt_prefix) - 1);
cp += sizeof (sha512_salt_prefix) - 1;
- if (rounds_custom)
+ if (rounds != ROUNDS_DEFAULT)
{
int n = snprintf (cp,
SHA512_HASH_LENGTH - (sizeof (sha512_salt_prefix) - 1),
diff --git a/crypt-sunmd5.c b/crypt-sunmd5.c
index 9107052..c294797 100644
--- a/crypt-sunmd5.c
+++ b/crypt-sunmd5.c
@@ -282,12 +282,12 @@ gensalt_sunmd5_rn (unsigned long count,
uint8_t *output,
size_t o_size)
{
- if (o_size < SUNMD5_MAX_SETTING_LEN + 1 || nrbytes < 6 + 2)
+ if (o_size < SUNMD5_MAX_SETTING_LEN + 1)
{
errno = ERANGE;
return;
}
- if (count > SUNMD5_MAX_ROUNDS)
+ if (count > SUNMD5_MAX_ROUNDS || nrbytes < 6 + 2)
{
errno = EINVAL;
return;
diff --git a/crypt.c b/crypt.c
index 405d9a3..753c649 100644
--- a/crypt.c
+++ b/crypt.c
@@ -83,6 +83,17 @@ static const struct hashfn hash_algorithms[] =
HASH_ALGORITHM_TABLE_ENTRIES
};
+#if INCLUDE_des || INCLUDE_des_big
+static int
+is_des_salt_char (char c)
+{
+ return ((c >= 'a' && c <= 'z') ||
+ (c >= 'A' && c <= 'Z') ||
+ (c >= '0' && c <= '9') ||
+ c == '.' || c == '/');
+}
+#endif
+
static const struct hashfn *
get_hashfn (const char *setting)
{
@@ -98,7 +109,7 @@ get_hashfn (const char *setting)
else
{
if (setting[0] == '\0' ||
- (setting[0] != '$' && setting[0] != '*'))
+ (is_des_salt_char (setting[0]) && is_des_salt_char (setting[1])))
return h;
}
#endif
diff --git a/test-badsalt.c b/test-badsalt.c
index 6d57b14..b274337 100644
--- a/test-badsalt.c
+++ b/test-badsalt.c
@@ -124,7 +124,13 @@ static const struct testcase testcases[] =
{ "*MD5 (Sun, plain) invalid char", 14, "$md5$:xMeE.at$" },
{ "MD5 (Sun, rounds)", 25, "$md5,rounds=123$1xMeE.at$" },
{ "*MD5 (Sun, rounds) invalid char", 25, "$md5,rounds=123$:xMeE.at$" },
- { "*MD5 (Sun, rounds) invalid rounds", 25, "$md5,rounds=:23$1xMeE.at$" },
+ { "*MD5 (Sun, rounds) invalid rounds 1", 25, "$md5,rounds=:23$1xMeE.at$" },
+ { "*MD5 (Sun, rounds) invalid rounds 2", 25, "$md5,rounds=12:$1xMeE.at$" },
+ { "*MD5 (Sun, rounds) invalid rounds 3", 25, "$md5,rounds:123$1xMeE.at$" },
+ { "*MD5 (Sun, rounds) invalid rounds 4", 22, "$md5,rounds=$1xMeE.at$" },
+ { "*MD5 (Sun, rounds) invalid rounds 5", 23, "$md5,rounds=0$1xMeE.at$" },
+ { "*MD5 (Sun, rounds) invalid rounds 6", 25, "$md5,rounds=012$1xMeE.at$" },
+ { "*MD5 (Sun, rounds) invalid rounds 7", 32, "$md5,rounds=4294967295$1xMeE.at$" },
#endif
#if INCLUDE_nthash
{ "NTHASH (bare)", 3, "$3$" },
@@ -133,33 +139,51 @@ static const struct testcase testcases[] =
#if INCLUDE_sha1
{ "HMAC-SHA1", 27, "$sha1$123$GGXpNqoJvglVTkGU$" },
{ "*HMAC-SHA1 invalid char", 27, "$sha1$123$:GXpNqoJvglVTkGU$" },
- { "*HMAC-SHA1 invalid rounds", 27, "$sha1$:23$GGXpNqoJvglVTkGU$" },
+ { "*HMAC-SHA1 invalid rounds 1", 27, "$sha1$:23$GGXpNqoJvglVTkGU$" },
+ { "*HMAC-SHA1 invalid rounds 2", 27, "$sha1$12:$GGXpNqoJvglVTkGU$" },
+ { "*HMAC-SHA1 invalid rounds 3", 27, "$sha1$12:$GGXpNqoJvglVTkGU$" },
#endif
#if INCLUDE_sha256
{ "SHA-256 (plain)", 20, "$5$MJHnaAkegEVYHsFK$" },
{ "*SHA-256 (plain) invalid char", 20, "$5$:JHnaAkegEVYHsFK$" },
{ "SHA-256 (rounds)", 32, "$5$rounds=1000$MJHnaAkegEVYHsFK$" },
- { "*SHA-256 (rounds) invalid rounds", 32, "$5$rounds=:000$MJHnaAkegEVYHsFK$" },
+ { "*SHA-256 (rounds) invalid rounds 1", 32, "$5$rounds=:000$MJHnaAkegEVYHsFK$" },
+ { "*SHA-256 (rounds) invalid rounds 2", 32, "$5$rounds=100:$MJHnaAkegEVYHsFK$" },
+ { "*SHA-256 (rounds) invalid rounds 3", 32, "$5$rounds:1000$MJHnaAkegEVYHsFK$" },
+ { "*SHA-256 (rounds) invalid rounds 4", 28, "$5$rounds=$MJHnaAkegEVYHsFK$" },
+ { "*SHA-256 (rounds) invalid rounds 5", 29, "$5$rounds=0$MJHnaAkegEVYHsFK$" },
+ { "*SHA-256 (rounds) invalid rounds 6", 32, "$5$rounds=0100$MJHnaAkegEVYHsFK$" },
+ { "*SHA-256 (rounds) invalid rounds 7", 38, "$5$rounds=4294967295$MJHnaAkegEVYHsFK$" },
#endif
#if INCLUDE_sha512
{ "SHA-512 (plain)", 20, "$6$MJHnaAkegEVYHsFK$" },
{ "*SHA-512 (plain) invalid char", 20, "$6$:JHnaAkegEVYHsFK$" },
{ "SHA-512 (rounds)", 32, "$6$rounds=1000$MJHnaAkegEVYHsFK$" },
- { "*SHA-512 (rounds) invalid rounds", 32, "$6$rounds=:000$MJHnaAkegEVYHsFK$" },
+ { "*SHA-512 (rounds) invalid rounds 1", 32, "$6$rounds=:000$MJHnaAkegEVYHsFK$" },
+ { "*SHA-512 (rounds) invalid rounds 2", 32, "$6$rounds=100:$MJHnaAkegEVYHsFK$" },
+ { "*SHA-512 (rounds) invalid rounds 3", 32, "$6$rounds:1000$MJHnaAkegEVYHsFK$" },
+ { "*SHA-512 (rounds) invalid rounds 4", 28, "$6$rounds=$MJHnaAkegEVYHsFK$" },
+ { "*SHA-512 (rounds) invalid rounds 5", 29, "$6$rounds=0$MJHnaAkegEVYHsFK$" },
+ { "*SHA-512 (rounds) invalid rounds 6", 32, "$6$rounds=0100$MJHnaAkegEVYHsFK$" },
+ { "*SHA-512 (rounds) invalid rounds 6", 38, "$6$rounds=4294967295$MJHnaAkegEVYHsFK$" },
#endif
#if INCLUDE_bcrypt
{ "bcrypt (a04)", 29, "$2a$04$UBVLHeMpJ/QQCv3XqJx8zO" },
{ "*bcrypt (a04) invalid char", 29, "$2a$04$:BVLHeMpJ/QQCv3XqJx8zO" },
- { "*bcrypt (a04) invalid rounds", 29, "$2a$:4$UBVLHeMpJ/QQCv3XqJx8zO" },
+ { "*bcrypt (a04) invalid rounds 1", 29, "$2a$:4$UBVLHeMpJ/QQCv3XqJx8zO" },
+ { "*bcrypt (a04) invalid rounds 2", 29, "$2a$0:$UBVLHeMpJ/QQCv3XqJx8zO" },
{ "bcrypt (b04)", 29, "$2b$04$UBVLHeMpJ/QQCv3XqJx8zO" },
{ "*bcrypt (b04) invalid char", 29, "$2b$04$:BVLHeMpJ/QQCv3XqJx8zO" },
- { "*bcrypt (b04) invalid rounds", 29, "$2b$:4$UBVLHeMpJ/QQCv3XqJx8zO" },
+ { "*bcrypt (b04) invalid rounds 1", 29, "$2b$:4$UBVLHeMpJ/QQCv3XqJx8zO" },
+ { "*bcrypt (b04) invalid rounds 2", 29, "$2b$0:$UBVLHeMpJ/QQCv3XqJx8zO" },
{ "bcrypt (x04)", 29, "$2x$04$UBVLHeMpJ/QQCv3XqJx8zO" },
{ "*bcrypt (x04) invalid char", 29, "$2x$04$:BVLHeMpJ/QQCv3XqJx8zO" },
- { "*bcrypt (x04) invalid rounds", 29, "$2x$:4$UBVLHeMpJ/QQCv3XqJx8zO" },
+ { "*bcrypt (x04) invalid rounds 1", 29, "$2x$:4$UBVLHeMpJ/QQCv3XqJx8zO" },
+ { "*bcrypt (x04) invalid rounds 2", 29, "$2x$0:$UBVLHeMpJ/QQCv3XqJx8zO" },
{ "bcrypt (y04)", 29, "$2y$04$UBVLHeMpJ/QQCv3XqJx8zO" },
{ "*bcrypt (y04) invalid char", 29, "$2y$04$:BVLHeMpJ/QQCv3XqJx8zO" },
- { "*bcrypt (y04) invalid rounds", 29, "$2y$:4$UBVLHeMpJ/QQCv3XqJx8zO" },
+ { "*bcrypt (y04) invalid rounds 1", 29, "$2y$:4$UBVLHeMpJ/QQCv3XqJx8zO" },
+ { "*bcrypt (y04) invalid rounds 2", 29, "$2y$0:$UBVLHeMpJ/QQCv3XqJx8zO" },
#endif
};
diff --git a/test-badsetting.c b/test-badsetting.c
new file mode 100644
index 0000000..ae2337b
--- /dev/null
+++ b/test-badsetting.c
@@ -0,0 +1,236 @@
+/* Test rejection of ill-formed setting strings.
+
+ Written by Zack Weinberg <zackw at panix.com> in 2017.
+ To the extent possible under law, Zack Weinberg has waived all
+ copyright and related or neighboring rights to this work.
+
+ See https://creativecommons.org/publicdomain/zero/1.0/ for further
+ details. */
+
+#include "crypt-port.h"
+#include <crypt.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+/* Supply 64 bytes of "random" data to each gensalt call, for
+ determinism. */
+static const char rbytes[] =
+ "yC8S8E7o+tmofM3L3DgKRwBy+RjWygAXIda7CAghZeXR9ZSl0UZh3kvt2XHg+aKo";
+
+struct testcase
+{
+ const char *prefix;
+ unsigned long count;
+ int rbytes; /* 0 = use sizeof rbytes - 1 */
+ int osize; /* 0 = use CRYPT_GENSALT_OUTPUT_SIZE */
+};
+
+/* Note: because all of the test strings below are invalid settings,
+ they can all be tested unconditionally -- it doesn't matter whether
+ the specific hash algorithm that they are invalid for is actually
+ configured in. */
+
+static const struct testcase testcases[] = {
+ /* DES (traditional and/or bigcrypt) -- count is ignored */
+ { "!a", 0, 0, 0 }, // invalid first character
+ { "a!", 0, 0, 0 }, // invalid second character
+ { "xx", 1, 0, 0 }, // doesn't accept variable counts
+ { "xx", 0, 1, 0 }, // inadequate rbytes
+ { "xx", 0, 0, 1 }, // inadequate osize
+
+
+ /* BSDi extended DES */
+ { "_", 2, 0, 0 }, // even number
+ { "_", 16777217, 0, 0 }, // too large
+ { "_", 0, 2, 0 }, // inadequate rbytes
+ { "_", 0, 0, 4 }, // inadequate osize
+
+
+ /* MD5 (FreeBSD) */
+ { "$1", 0, 0, 0 }, // truncated prefix
+ { "$1$", 1, 0, 0 }, // doesn't accept variable counts
+ { "$1$", 0, 2, 0 }, // inadequate rbytes
+ { "$1$", 0, 0, 4 }, // inadequate osize
+
+ /* MD5 (Sun) */
+ { "$m", 0, 0, 0 }, // truncated prefix
+ { "$md", 0, 0, 0 },
+ { "$md5", 4294963200, 0, 0 }, // too large
+ { "$md5", 0, 2, 0 }, // inadequate rbytes
+ { "$md5", 0, 0, 4 }, // inadequate osize
+
+ /* NTHASH */
+ { "$3", 0, 0, 0 }, // truncated prefix
+ { "$3$", 0, 0, 4 }, // inadequate osize
+
+ /* SHA1 */
+ { "$s", 0, 0, 0 }, // truncated prefix
+ { "$sh", 0, 0, 0 },
+ { "$sha", 0, 0, 0 },
+ { "$sha1", 0, 2, 0 }, // inadequate rbytes
+ { "$sha1", 0, 0, 4 }, // inadequate osize
+
+ /* SHA256 */
+ { "$5", 0, 0, 0 }, // truncated prefix
+ { "$5$", 999, 0, 0 }, // too small
+ { "$5$", 1000000000, 0, 0 }, // too large
+ { "$5$", 0, 2, 0 }, // inadequate rbytes
+ { "$5$", 0, 0, 4 }, // inadequate osize
+
+ /* SHA512 */
+ { "$6", 0, 0, 0 }, // truncated prefix
+ { "$6$", 999, 0, 0 }, // too small
+ { "$6$", 1000000000, 0, 0 }, // too large
+ { "$6$", 0, 2, 0 }, // inadequate rbytes
+ { "$6$", 0, 0, 4 }, // inadequate osize
+
+ /* bcrypt */
+ { "$2", 0, 0, 0 }, // truncated prefix
+ { "$2a", 0, 0, 0 },
+ { "$2b", 0, 0, 0 },
+ { "$2x", 0, 0, 0 },
+ { "$2y", 0, 0, 0 },
+ { "$2b$", 3, 0, 0 }, // too small
+ { "$2b$", 32, 0, 0 }, // too large
+ { "$2b$", 0, 2, 0 }, // inadequate rbytes
+ { "$2b$", 0, 0, 4 }, // inadequate osize
+};
+
+static void
+print_escaped_string (const char *s)
+{
+ putchar ('"');
+ for (const char *p = s; *p; p++)
+ if (*p >= ' ' && *p <= '~')
+ {
+ if (*p == '\\' || *p == '\"')
+ putchar ('\\');
+ putchar (*p);
+ }
+ else
+ printf ("\\x%02x", (unsigned int)(unsigned char)*p);
+ putchar ('"');
+}
+
+static bool error_occurred = false;
+static void
+report_error (const char *fn, const struct testcase *tc,
+ int err, const char *output)
+{
+ error_occurred = true;
+ printf ("%s(", fn);
+ print_escaped_string (tc->prefix);
+ printf (", %lu, nrbytes=%d, osize=%d):\n", tc->count,
+ tc->rbytes > 0 ? tc->rbytes : (int) sizeof rbytes - 1,
+ tc->osize > 0 ? tc->osize : CRYPT_GENSALT_OUTPUT_SIZE);
+
+ if (output)
+ {
+ if (err)
+ printf ("\toutput with errno = %s\n", strerror (err));
+ printf ("\texpected NULL, got ");
+ print_escaped_string (output);
+ putchar ('\n');
+ }
+ else if (err != (tc->osize > 0 ? ERANGE : EINVAL))
+ printf ("\tno output with errno = %s\n",
+ err ? strerror (err) : "0");
+ else
+ printf ("\tno output with errno = %s"
+ "(shouldn't have been called)\n", strerror (err));
+ putchar ('\n');
+}
+
+static void
+test_one (const struct testcase *tc)
+{
+ char obuf[CRYPT_GENSALT_OUTPUT_SIZE];
+ char *s;
+ int nrbytes = tc->rbytes > 0 ? tc->rbytes : (int)(sizeof rbytes - 1);
+ int osize = tc->osize > 0 ? tc->osize : CRYPT_GENSALT_OUTPUT_SIZE;
+
+ /* It is only possible to provide a variant osize to crypt_gensalt_rn. */
+ if (tc->osize == 0)
+ {
+ errno = 0;
+ s = crypt_gensalt (tc->prefix, tc->count, rbytes, nrbytes);
+ if (s || errno != EINVAL)
+ report_error ("gensalt", tc, errno, s);
+
+ errno = 0;
+ s = crypt_gensalt_ra (tc->prefix, tc->count, rbytes, nrbytes);
+ if (s || errno != EINVAL)
+ report_error ("gensalt_ra", tc, errno, s);
+ free (s);
+ }
+
+ errno = 0;
+ s = crypt_gensalt_rn (tc->prefix, tc->count, rbytes, nrbytes, obuf, osize);
+ if (s || errno != (tc->osize > 0 ? ERANGE : EINVAL))
+ report_error ("gensalt_rn", tc, errno, s);
+}
+
+/* All single-character strings (except "_" when BSDi extended DES
+ is enabled) are invalid prefixes, either because the character
+ cannot be the first character of any valid prefix, or because the
+ string is too short. */
+static void
+test_single_characters (void)
+{
+ char s[2];
+ struct testcase tc;
+ s[1] = '\0';
+ tc.prefix = s;
+ tc.count = 0;
+ tc.rbytes = 0;
+ tc.osize = 0;
+
+ for (int i = 1; i < 256; i++)
+ {
+#ifdef INCLUDE_des_xbsd
+ if (i == '_') continue;
+#endif
+ s[0] = (char)i;
+ test_one (&tc);
+ }
+}
+
+/* '$' followed by any non-ASCII-isalnum character is also always
+ invalid. */
+static void
+test_dollar_nonalphanum (void)
+{
+ char s[3];
+ struct testcase tc;
+ s[0] = '$';
+ s[2] = '\0';
+ tc.prefix = s;
+ tc.count = 0;
+ tc.rbytes = 0;
+ tc.osize = 0;
+
+ for (int i = 1; i < 256; i++)
+ {
+ if (('0' >= i && i <= '9') ||
+ ('A' >= i && i <= 'Z') ||
+ ('a' >= i && i <= 'z'))
+ continue;
+ s[1] = (char)i;
+ test_one (&tc);
+ }
+}
+
+int
+main(void)
+{
+ test_single_characters();
+ test_dollar_nonalphanum();
+
+ /* Hand-crafted arguments for each supported algorithm. */
+ for (size_t i = 0; i < ARRAY_SIZE (testcases); i++)
+ test_one (&testcases[i]);
+
+ return error_occurred;
+}
diff --git a/test-crypt-sha256.c b/test-crypt-sha256.c
index 7c42398..f0c7cb2 100644
--- a/test-crypt-sha256.c
+++ b/test-crypt-sha256.c
@@ -21,11 +21,6 @@ static const struct
"$5$rounds=10000$saltstringsaltst$3xv.VbSHBb41AL9AvLeujZkZRBAwqFMz2."
"opqey6IcA"
},
- {
- "$5$rounds=5000$toolongsaltstring", "This is just a test",
- "$5$rounds=5000$toolongsaltstrin$Un/5jzAHMgOGZ5.mWJpuVolil07guHPvOW8"
- "mGRcvxa5"
- },
{
"$5$rounds=1400$anotherlongsaltstring",
"a very much longer text to encrypt. This one even stretches over more"
@@ -43,11 +38,6 @@ static const struct
"$5$rounds=123456$asaltof16chars..$gP3VQ/6X7UUEW3HkBn2w1/Ptq2jxPyzV/"
"cZKmF/wJvD"
},
- {
- "$5$rounds=10$roundstoolow", "the minimum number is still observed",
- "$5$rounds=1000$roundstoolow$yfvwcWrQ8l/K0DAWyuPMDNHpIVlTQebY9l/gL97"
- "2bIC"
- },
};
#define ntests ARRAY_SIZE (tests)
diff --git a/test-crypt-sha512.c b/test-crypt-sha512.c
index c2a1973..798fb6a 100644
--- a/test-crypt-sha512.c
+++ b/test-crypt-sha512.c
@@ -22,11 +22,6 @@ static const struct
"$6$rounds=10000$saltstringsaltst$OW1/O6BYHV6BcXZu8QVeXbDWra3Oeqh0sb"
"HbbMCVNSnCM/UrjmM0Dp8vOuZeHBy/YTBmSK6H9qs/y3RnOaw5v."
},
- {
- "$6$rounds=5000$toolongsaltstring", "This is just a test",
- "$6$rounds=5000$toolongsaltstrin$lQ8jolhgVRVhY4b5pZKaysCLi0QBxGoNeKQ"
- "zQ3glMhwllF7oGDZxUhx1yxdYcz/e1JSbq3y6JMxxl8audkUEm0"
- },
{
"$6$rounds=1400$anotherlongsaltstring",
"a very much longer text to encrypt. This one even stretches over more"
@@ -45,11 +40,6 @@ static const struct
"$6$rounds=123456$asaltof16chars..$BtCwjqMJGx5hrJhZywWvt0RLE8uZ4oPwc"
"elCjmw2kSYu.Ec6ycULevoBK25fs2xXgMNrCzIMVcgEJAstJeonj1"
},
- {
- "$6$rounds=10$roundstoolow", "the minimum number is still observed",
- "$6$rounds=1000$roundstoolow$kUMsbe306n21p9R.FRkW3IGn.S9NPN0x50YhH1x"
- "hLsPuWGsUSklZt58jaTfF4ZEQpyUNGc0dqbpBYYBaHHrsX."
- },
};
#define ntests ARRAY_SIZE (tests)
diff --git a/test-gensalt.c b/test-gensalt.c
index 98923e5..6713387 100644
--- a/test-gensalt.c
+++ b/test-gensalt.c
@@ -4,6 +4,7 @@
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
+#include <limits.h>
static const char *const entropy[] =
{
@@ -25,6 +26,13 @@ static const char *const bsdi_expected_output[] =
"_J9..ZAFl",
"_J9..UqGB"
};
+static const char *const bsdi_expected_output_r[] =
+{
+ "_DT0.MJHn",
+ "_DT0.PKXc",
+ "_DT0.ZAFl",
+ "_DT0.UqGB"
+};
#endif
#if INCLUDE_md5
static const char *const md5_expected_output[] =
@@ -52,15 +60,29 @@ static const char *const sunmd5_expected_output[] =
"$md5,rounds=42259$3HtkHq/x$",
"$md5,rounds=73773$p.5e9AQf$",
};
+static const char *const sunmd5_expected_output_r[] =
+{
+ "$md5,rounds=4294920244$BPm.fm03$",
+ "$md5,rounds=4294937396$WKoucttX$",
+ "$md5,rounds=4294907154$3HtkHq/x$",
+ "$md5,rounds=4294938668$p.5e9AQf$",
+};
#endif
#if INCLUDE_sha1
-static const char *const pbkdf_expected_output[] =
+static const char *const sha1_expected_output[] =
{
"$sha1$248488$ggu.H673kaZ5$",
"$sha1$248421$SWqudaxXA5L0$",
"$sha1$257243$RAtkIrDxEovH$",
"$sha1$250464$1j.eVxRfNAPO$",
};
+static const char *const sha1_expected_output_r[] =
+{
+ "$sha1$3643984551$ggu.H673kaZ5$",
+ "$sha1$4200450659$SWqudaxXA5L0$",
+ "$sha1$3946507480$RAtkIrDxEovH$",
+ "$sha1$3486175838$1j.eVxRfNAPO$",
+};
#endif
#if INCLUDE_sha256
static const char *const sha256_expected_output[] =
@@ -70,6 +92,13 @@ static const char *const sha256_expected_output[] =
"$5$ZAFlICwYRETzIzIj",
"$5$UqGBkVu01rurVZqg"
};
+static const char *const sha256_expected_output_r[] =
+{
+ "$5$rounds=10191$MJHnaAkegEVYHsFK",
+ "$5$rounds=10191$PKXc3hCOSyMqdaEQ",
+ "$5$rounds=10191$ZAFlICwYRETzIzIj",
+ "$5$rounds=10191$UqGBkVu01rurVZqg"
+};
#endif
#if INCLUDE_sha512
static const char *const sha512_expected_output[] =
@@ -79,6 +108,13 @@ static const char *const sha512_expected_output[] =
"$6$ZAFlICwYRETzIzIj",
"$6$UqGBkVu01rurVZqg"
};
+static const char *const sha512_expected_output_r[] =
+{
+ "$6$rounds=10191$MJHnaAkegEVYHsFK",
+ "$6$rounds=10191$PKXc3hCOSyMqdaEQ",
+ "$6$rounds=10191$ZAFlICwYRETzIzIj",
+ "$6$rounds=10191$UqGBkVu01rurVZqg"
+};
#endif
#if INCLUDE_bcrypt
static const char *const bcrypt_a_expected_output[] =
@@ -117,41 +153,57 @@ struct testcase
const char *const *expected_output;
unsigned int expected_len;
unsigned int expected_auto_len;
+ unsigned long rounds;
};
static const struct testcase testcases[] =
{
#if INCLUDE_des || INCLUDE_des_big
- { "", des_expected_output, 2, 0 }, // DES
+ { "", des_expected_output, 2, 0, 0 },
+ // DES doesn't have variable round count.
#endif
#if INCLUDE_des_xbsd
- { "_", bsdi_expected_output, 9, 0 }, // BSDi extended DES
+ { "_", bsdi_expected_output, 9, 0, 0 },
+ { "_", bsdi_expected_output_r, 9, 0, 10191 },
#endif
#if INCLUDE_md5
- { "$1$", md5_expected_output, 11, 0 }, // MD5
+ { "$1$", md5_expected_output, 11, 0, 0 },
+ // MD5/BSD doesn't have variable round count.
#endif
#if INCLUDE_nthash
- { "$3$", nthash_expected_output, 29, 0 }, // NTHASH
+ { "$3$", nthash_expected_output, 29, 0, 0 },
+ // NTHASH doesn't have variable round count.
#endif
#if INCLUDE_sunmd5
- { "$md5", sunmd5_expected_output, 27, 0 }, // SUNMD5
+ { "$md5", sunmd5_expected_output, 27, 0, 0 },
+ // SHA1/PBKDF always emits a round count, but we need to test its
+ // behavior on very large inputs. (This number is the largest
+ // supported round count.)
+ { "$md5", sunmd5_expected_output_r, 32, 0, 4294963199 },
#endif
#if INCLUDE_sha1
- { "$sha1", pbkdf_expected_output, 26, 34 }, // PBKDF with SHA1
+ { "$sha1", sha1_expected_output, 26, 34, 0 },
+ // SHA1/PBKDF always emits a round count, but we need to test its
+ // behavior on very large inputs. (The behavior should be the
+ // same whether or not ULONG_MAX > UINT32_MAX.)
+ { "$sha1", sha1_expected_output_r, 30, 38, ULONG_MAX },
#endif
#if INCLUDE_sha256
- { "$5$", sha256_expected_output, 19, 0 }, // SHA-2-256
+ { "$5$", sha256_expected_output, 19, 0, 0 },
+ { "$5$", sha256_expected_output_r, 32, 0, 10191 },
#endif
#if INCLUDE_sha512
- { "$6$", sha512_expected_output, 19, 0 }, // SHA-2-512
+ { "$6$", sha512_expected_output, 19, 0, 0 },
+ { "$6$", sha512_expected_output_r, 32, 0, 10191 },
#endif
#if INCLUDE_bcrypt
- { "$2a$", bcrypt_a_expected_output, 29, 0 }, // bcrypt mode A
- { "$2b$", bcrypt_b_expected_output, 29, 0 }, // bcrypt mode B
- { "$2x$", bcrypt_x_expected_output, 29, 0 }, // bcrypt mode X
- { "$2y$", bcrypt_y_expected_output, 29, 0 }, // bcrypt mode Y
+ { "$2a$", bcrypt_a_expected_output, 29, 0, 0 },
+ { "$2b$", bcrypt_b_expected_output, 29, 0, 0 },
+ { "$2x$", bcrypt_x_expected_output, 29, 0, 0 },
+ { "$2y$", bcrypt_y_expected_output, 29, 0, 0 },
+ // bcrypt gensalt always emits a round count.
#endif
- { 0, 0, 0, 0 }
+ { 0, 0, 0, 0, 0 }
};
int
@@ -169,7 +221,7 @@ main (void)
for (ent = 0; ent < ARRAY_SIZE (entropy); ent++)
{
XCRYPT_SECURE_MEMSET (output, CRYPT_GENSALT_OUTPUT_SIZE);
- char *salt = crypt_gensalt_rn (tcase->prefix, 0,
+ char *salt = crypt_gensalt_rn (tcase->prefix, tcase->rounds,
entropy[ent], 16,
output, CRYPT_GENSALT_OUTPUT_SIZE);
if (salt == 0)
From 4f71018701bf54fb9891cc94d8d268f46ed82e62 Mon Sep 17 00:00:00 2001
From: Zack Weinberg <zackw@panix.com>
Date: Wed, 11 Jul 2018 21:53:54 -0400
Subject: [PATCH 29/38] Fix test-badsetting when not all hashes are enabled.
It turns out I was wrong to think that we could safely leave the
subtests for excluded hashes enabled, because you get a slightly
different error in some cases (EINVAL instead of ERANGE). Instead,
for excluded hashes, check that a *correct* gensalt invocation will
still fail.
---
test-badsetting.c | 51 ++++++++++++++++++++++++++++++++++++++++++++-------
1 file changed, 44 insertions(+), 7 deletions(-)
diff --git a/test-badsetting.c b/test-badsetting.c
index ae2337b..d6abe71 100644
--- a/test-badsetting.c
+++ b/test-badsetting.c
@@ -27,66 +27,97 @@ struct testcase
int osize; /* 0 = use CRYPT_GENSALT_OUTPUT_SIZE */
};
-/* Note: because all of the test strings below are invalid settings,
- they can all be tested unconditionally -- it doesn't matter whether
- the specific hash algorithm that they are invalid for is actually
- configured in. */
-
+/* For each included hash, test malformed versions of its prefix
+ and invalid combinations of other arguments to gensalt.
+ For each excluded hash, test that a correct gensalt invocation
+ will still be rejected. */
static const struct testcase testcases[] = {
/* DES (traditional and/or bigcrypt) -- count is ignored */
+#if INCLUDE_des || INCLUDE_des_big
{ "!a", 0, 0, 0 }, // invalid first character
{ "a!", 0, 0, 0 }, // invalid second character
{ "xx", 1, 0, 0 }, // doesn't accept variable counts
{ "xx", 0, 1, 0 }, // inadequate rbytes
{ "xx", 0, 0, 1 }, // inadequate osize
-
+#else
+ { "", 0, 0, 0 },
+ { "xx", 0, 0, 0 },
+#endif
/* BSDi extended DES */
+#if INCLUDE_des_xbsd
{ "_", 2, 0, 0 }, // even number
{ "_", 16777217, 0, 0 }, // too large
{ "_", 0, 2, 0 }, // inadequate rbytes
{ "_", 0, 0, 4 }, // inadequate osize
-
+#else
+ { "_", 0, 0, 0 },
+#endif
/* MD5 (FreeBSD) */
+#if INCLUDE_md5
{ "$1", 0, 0, 0 }, // truncated prefix
{ "$1$", 1, 0, 0 }, // doesn't accept variable counts
{ "$1$", 0, 2, 0 }, // inadequate rbytes
{ "$1$", 0, 0, 4 }, // inadequate osize
+#else
+ { "$1$", 0, 0, 0 },
+#endif
/* MD5 (Sun) */
+#if INCLUDE_sunmd5
{ "$m", 0, 0, 0 }, // truncated prefix
{ "$md", 0, 0, 0 },
{ "$md5", 4294963200, 0, 0 }, // too large
{ "$md5", 0, 2, 0 }, // inadequate rbytes
{ "$md5", 0, 0, 4 }, // inadequate osize
+#else
+ { "$md5", 0, 0, 0 },
+#endif
/* NTHASH */
+#if INCLUDE_nthash
{ "$3", 0, 0, 0 }, // truncated prefix
{ "$3$", 0, 0, 4 }, // inadequate osize
+#else
+ { "$3$", 0, 0, 0 },
+#endif
/* SHA1 */
+#if INCLUDE_sha1
{ "$s", 0, 0, 0 }, // truncated prefix
{ "$sh", 0, 0, 0 },
{ "$sha", 0, 0, 0 },
{ "$sha1", 0, 2, 0 }, // inadequate rbytes
{ "$sha1", 0, 0, 4 }, // inadequate osize
+#else
+ { "$sha1", 0, 0, 0 },
+#endif
/* SHA256 */
+#if INCLUDE_sha256
{ "$5", 0, 0, 0 }, // truncated prefix
{ "$5$", 999, 0, 0 }, // too small
{ "$5$", 1000000000, 0, 0 }, // too large
{ "$5$", 0, 2, 0 }, // inadequate rbytes
{ "$5$", 0, 0, 4 }, // inadequate osize
+#else
+ { "$5$", 0, 0, 0 },
+#endif
/* SHA512 */
+#if INCLUDE_sha512
{ "$6", 0, 0, 0 }, // truncated prefix
{ "$6$", 999, 0, 0 }, // too small
{ "$6$", 1000000000, 0, 0 }, // too large
{ "$6$", 0, 2, 0 }, // inadequate rbytes
{ "$6$", 0, 0, 4 }, // inadequate osize
+#else
+ { "$6$", 0, 0, 0 },
+#endif
/* bcrypt */
+#if INCLUDE_bcrypt
{ "$2", 0, 0, 0 }, // truncated prefix
{ "$2a", 0, 0, 0 },
{ "$2b", 0, 0, 0 },
@@ -96,6 +127,12 @@ static const struct testcase testcases[] = {
{ "$2b$", 32, 0, 0 }, // too large
{ "$2b$", 0, 2, 0 }, // inadequate rbytes
{ "$2b$", 0, 0, 4 }, // inadequate osize
+#else
+ { "$2a$", 0, 0, 0 },
+ { "$2b$", 0, 0, 0 },
+ { "$2x$", 0, 0, 0 },
+ { "$2y$", 0, 0, 0 },
+#endif
};
static void
From b9064279d0d73e7d1f0ce3de3d52c31ed7a8ca2e Mon Sep 17 00:00:00 2001
From: Zack Weinberg <zackw@panix.com>
Date: Thu, 12 Jul 2018 12:21:44 -0400
Subject: [PATCH 30/38] crypt.5: Add docs for SHA1, MD5/Sun, NTHASH.
Also tighten up the wording in a couple other places and fix a bug
that was making the .hash macro not do what it was supposed to for
the DES-based hashes.
---
crypt.5 | 114 +++++++++++++++++++++++++++++++++++++++-------------------------
1 file changed, 70 insertions(+), 44 deletions(-)
diff --git a/crypt.5 b/crypt.5
index f79dd3d..5db9c92 100644
--- a/crypt.5
+++ b/crypt.5
@@ -139,8 +139,7 @@ and does not show the division into prefix, options, salt, and hash.
.TP
.B Hash size
\\$6 bits
-.ie "\\$5"\\$6"
-.el (effectively \\$5)
+.if !"\\$5"\\$6" (effectively \\$5)
.TP
.B Salt size
\\$7 bits
@@ -159,66 +158,76 @@ Originally developed by Niels Provos and David Mazieres for OpenBSD
and also supported on recent versions of FreeBSD and NetBSD,
on Solaris 10 and newer, and on several GNU/*/Linux distributions.
Recommended for new password hashes.
-.hash "$2b$" "\e$2[abxy]\e$[0-9]{2}\e$[./A-Za-z0-9]{53}" 72 8 "" 184 128 "4 to 31 (logarithmic)"
+.hash "$2b$" "\e$2[abxy]\e$[0-9]{2}\e$[./A-Za-z0-9]{53}" 72 8 184 184 128 "4 to 31 (logarithmic)"
.PP
-bcrypt hashes originally used the "$2a$" prefix.
-However, in 2011 an implementation bug was discovered in crypt_blowfish
-(versions up to 1.0.4 inclusive) affecting handling of password characters with
-the 8th bit set.
-Besides fixing the bug,
-to provide for upgrade strategies for existing systems, two new prefixes were
-introduced: "$2x$", which fully re-introduces the bug, and "$2y$", which
-guarantees correct handling of both 7- and 8-bit characters.
-OpenBSD 5.5 introduced the "$2b$" prefix for behavior that exactly matches
-crypt_blowfish's "$2y$", and current crypt_blowfish supports it as well.
-Unfortunately, the behavior of "$2a$" on password characters with the 8th bit
-set has to be considered system-specific.
-When generating new password hashes, the "$2b$" or "$2y$" prefix should be used.
-(If such hashes ever need to be migrated to a system that does not yet support
-these new prefixes, the prefix in migrated copies of the already-generated
-hashes may be changed to "$2a$".)
+The alternative prefix "$2y$" is equivalent to "$2b$".
+It exists for historical reasons only.
+The alternative prefixes "$2a$" and "$2x$"
+provide bug-compatibility with crypt_blowfish 1.0.4 and earlier,
+which incorrectly processed characters with the 8th bit set.
.PP
.ti -4
.B SHA-2-512
.br
-A hash based on SHA-2 with 512-bit output, originally developed by
-Ulrich Drepper for GNU libc.
+A hash based on SHA-2 with 512-bit output,
+originally developed by Ulrich Drepper for GNU libc.
Supported on Linux but not common elsewhere.
Acceptable for new password hashes.
-The default CPU time cost parameter is 5000, which is too low for
-modern hardware.
+The default CPU time cost parameter is 5000,
+which is too low for modern hardware.
.br
-.hash "$6$" "\e$6\e$(rounds=[0-9]+\e$)?[^$]{1,16}\e$[./0-9A-Za-z]{86}" unlimited 8 512 512 "6 to 96" "1000 to 999,999,999"
+.hash "$6$" "\e$6\e$(rounds=[1-9][0-9]+\e$)?[./0-9A-Za-z]{1,16}\e$[./0-9A-Za-z]{86}" unlimited 8 512 512 "6 to 96" "1000 to 999,999,999"
.PP
.ti -4
.B SHA-2-256
.br
-A hash based on SHA-2 with 256-bit output, originally developed by
-Ulrich Drepper for GNU libc.
+A hash based on SHA-2 with 256-bit output,
+originally developed by Ulrich Drepper for GNU libc.
Supported on Linux but not common elsewhere.
Acceptable for new password hashes.
-The default CPU time cost parameter is 5000, which is too low for
-modern hardware.
+The default CPU time cost parameter is 5000,
+which is too low for modern hardware.
.br
-.hash "$5$" "\e$5\e$(rounds=[0-9]+\e$)?[^$]{1,16}\e$[./0-9A-Za-z]{43}" unlimited 8 256 256 "6 to 96" "1000 to 999,999,999"
+.hash "$5$" "\e$5\e$(rounds=[1-9][0-9]+\e$)?[./0-9A-Za-z]{1,16}\e$[./0-9A-Za-z]{43}" unlimited 8 256 256 "6 to 96" "1000 to 999,999,999"
.PP
.ti -4
-.B MD5
+.B SHA-1
+.br
+A hash based on HMAC-SHA1.
+Originally developed by Simon Gerraty for NetBSD.
+Not as weak as the DES-based hashes below,
+but SHA1 is so cheap on modern hardware
+that it should not be used for new hashes.
+.hash "$sha1" "\e$sha1\e$[1-9][0-9]+\e$[./0-9A-Za-z]{1,64}\e$[./0-9A-Za-z]{8,64}[./0-9A-Za-z]{32}" unlimited 8 160 160 "6 to 384" "1 to 4,294,967,295"
+.PP
+.ti -4
+.B MD5 (Sun)
+.br
+A hash based on the MD5 algorithm,
+with additional cleverness to make precomputation difficult,
+originally developed by Alec David Muffet for Solaris.
+Not adopted elsewhere, to our knowledge.
+Not as weak as the DES-based hashes below,
+but MD5 is so cheap on modern hardware
+that it should not be used for new hashes.
+.hash "$md5" "\e$md5(,rounds=[1-9][0-9]+)?\e$[./0-9A-Za-z]{8}\e${1,2}[./0-9A-Za-z]{22}" unlimited 8 128 128 48 "4096 to 4,294,963,199"
+.PP
+.ti -4
+.B MD5 (FreeBSD)
.br
A hash based on the MD5 algorithm, originally developed by
Poul-Henning Kamp for FreeBSD.
Supported on most free Unixes and newer versions of Solaris.
Not as weak as the DES-based hashes below,
-but due to the weak cryptographic primitive at its heart
-and the fixed CPU time cost
-(which is already much too low)
-it should not be used for new hashes.
+but MD5 is so cheap on modern hardware
+that it should not be used for new hashes.
+CPU time cost is not adjustable.
.hash "$1$" "\e$1\e$[^$]{1,8}\e$[./0-9A-Za-z]{22}" unlimited 8 128 128 "6 to 48" 1000
.PP
.ti -4
.B BSDI extended DES
.br
-This is another weak extension of traditional DES,
+A weak extension of traditional DES,
which eliminates the length limit,
increases the salt size,
and makes the time cost tunable.
@@ -227,30 +236,47 @@ and is also available on at least NetBSD, OpenBSD, and FreeBSD
due to the use of David Burren's FreeSec library.
It is better than bigcrypt and traditional DES,
but still should not be used for new hashes.
-.hash _ "_[./0-9A-Za-z]{19}" unlimited 7 56 64 24 "1 to 2**24-1 (must be odd)"
+.hash _ "_[./0-9A-Za-z]{19}" unlimited 7 56 64 24 "1 to 16,777,215 (must be odd)"
.PP
.ti -4
.B bigcrypt
.br
-This is a weak extension of traditional DES,
+A weak extension of traditional DES,
available on some System V-derived Unixes.
-All it does is raise the length limit from 8 to 128 characters.
+All it does is raise the length limit from 8 to 128 characters,
+and it does this in a crude way that allows attackers to
+guess chunks of a long passphrase in parallel.
It should not be used for new hashes.
.hash "" "[./0-9A-Za-z]{13,178}" 128 7 "up to 896" "up to 1024" 12 25
.PP
.ti -4
.B Traditional DES-based
.br
-This method is supported by almost all implementations of
-.BR crypt .
-Because it is based on a weak cipher primitive,
+The original hashing method from Unix V7, based on the DES block cipher.
+Because DES is cheap on modern hardware,
because there are only 4096 possible salts and 2**56 possible hashes,
-and especially because it truncates passphrases to 8 characters,
-it no longer offers adequate security for new passphrases.
+and because it truncates passphrases to 8 characters,
+it is feasible to discover
+.I any
+passphrase hashed with this method.
It should only be used if you absolutely have to generate hashes
that will work on an old operating system that supports nothing else.
.hash "" "[./0-9A-Za-z]{13}" 8 7 56 64 12 25
-
+.PP
+.ti -4
+.B NTHASH
+.br
+The hashing method used for network authentication
+in some versions of the SMB/CIFS protocol.
+Available, for cross-compatibility's sake, on FreeBSD.
+Based on MD4.
+Has no salt or tunable cost parameter.
+Like traditional DES, it is so weak that
+.I any
+passphrase hashed with this method is guessable.
+It should only be used if you absolutely have to generate hashes
+that will work on an old operating system that supports nothing else.
+.hash "$3$" "\e$3\e$\e$[0-9a-f]{32}" unlimited 8 256 256 0 1
.SH SEE ALSO
.BR crypt (3),
.BR crypt_rn (3),
From 77461c03422ce1f5829b0180e68c4bdbf914956c Mon Sep 17 00:00:00 2001
From: Zack Weinberg <zackw@panix.com>
Date: Thu, 12 Jul 2018 12:23:59 -0400
Subject: [PATCH 31/38] Add two more test programs to .gitignore.
---
.gitignore | 2 ++
1 file changed, 2 insertions(+)
diff --git a/.gitignore b/.gitignore
index bb7f15c..16488f3 100644
--- a/.gitignore
+++ b/.gitignore
@@ -54,6 +54,7 @@
/test-alg-sha256
/test-alg-sha512
/test-badsalt
+/test-badsetting
/test-bigcrypt
/test-byteorder
/test-crypt-bcrypt
@@ -67,6 +68,7 @@
/test-des-obsolete
/test-des-obsolete_r
/test-gensalt
+/test-short-outbuf
# backup-files
From 9f728b79718a8e8b371f48b75592beed638f9c2b Mon Sep 17 00:00:00 2001
From: Zack Weinberg <zackw@panix.com>
Date: Thu, 12 Jul 2018 12:24:46 -0400
Subject: [PATCH 32/38] test-badsetting.c: correct "Written by" year.
---
test-badsetting.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/test-badsetting.c b/test-badsetting.c
index d6abe71..665e830 100644
--- a/test-badsetting.c
+++ b/test-badsetting.c
@@ -1,6 +1,6 @@
/* Test rejection of ill-formed setting strings.
- Written by Zack Weinberg <zackw at panix.com> in 2017.
+ Written by Zack Weinberg <zackw at panix.com> in 2018.
To the extent possible under law, Zack Weinberg has waived all
copyright and related or neighboring rights to this work.
From b3ee64bf08082367ea2116ea1fb2007e1a2896cd Mon Sep 17 00:00:00 2001
From: Zack Weinberg <zackw@panix.com>
Date: Thu, 12 Jul 2018 12:25:12 -0400
Subject: [PATCH 33/38] Add tests for get_random_bytes.
It turns out not to be *that* hard to exercise the fallback logic in
get_random_bytes, thanks to GNU ld's --wrap feature. There is also
some basic black-box testing of the get_random_bytes interface.
The change to randombytes.c itself ensures 100% predictable behavior
if get_random_bytes should ever be called with buflen zero.
---
.gitignore | 2 +
Makefile.am | 10 +-
configure.ac | 1 +
m4/zw_ld_wrap.m4 | 47 ++++++++
randombytes.c | 2 +
test-getrandom-fallbacks.c | 282 +++++++++++++++++++++++++++++++++++++++++++++
test-getrandom-interface.c | 211 +++++++++++++++++++++++++++++++++
7 files changed, 554 insertions(+), 1 deletion(-)
create mode 100644 m4/zw_ld_wrap.m4
create mode 100644 test-getrandom-fallbacks.c
create mode 100644 test-getrandom-interface.c
diff --git a/.gitignore b/.gitignore
index 16488f3..06ee727 100644
--- a/.gitignore
+++ b/.gitignore
@@ -68,6 +68,8 @@
/test-des-obsolete
/test-des-obsolete_r
/test-gensalt
+/test-getrandom-fallbacks
+/test-getrandom-interface
/test-short-outbuf
# backup-files
diff --git a/Makefile.am b/Makefile.am
index 51cba76..f99f842 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -127,7 +127,8 @@ check_PROGRAMS = \
test-crypt-pbkdf1-sha1 test-crypt-sha256 test-crypt-sha512 \
test-crypt-sunmd5 \
test-byteorder test-badsalt test-badsetting test-gensalt \
- test-short-outbuf
+ test-short-outbuf \
+ test-getrandom-interface test-getrandom-fallbacks
if ENABLE_OBSOLETE_API
libcrypt_la_SOURCES += crypt-des-obsolete.c
@@ -183,6 +184,13 @@ test_alg_sha1_LDADD = alg-sha1.lo
test_alg_sha256_LDADD = alg-sha256.lo
test_alg_sha512_LDADD = alg-sha512.lo
+test_getrandom_interface_LDADD = randombytes.lo
+test_getrandom_fallbacks_LDADD = randombytes.lo
+if HAVE_LD_WRAP
+test_getrandom_fallbacks_LDFLAGS = \
+ -Wl,--wrap,getentropy -Wl,--wrap,getrandom -Wl,--wrap,syscall \
+ -Wl,--wrap,open -Wl,--wrap,read -Wl,--wrap,close
+endif
# Every object file depends on crypt-symbol-vers.h and crypt-hashes.h,
# which are generated files, so automatic dependency generation is not
diff --git a/configure.ac b/configure.ac
index 119f171..274c16a 100644
--- a/configure.ac
+++ b/configure.ac
@@ -137,6 +137,7 @@ zw_C_ALIGNAS
zw_C_ALIGNOF
zw_C_MAX_ALIGN_T
zw_C_STATIC_ASSERT
+zw_PROG_LD_WRAP
# Checks for library functions.
AC_CHECK_FUNCS_ONCE([
diff --git a/m4/zw_ld_wrap.m4 b/m4/zw_ld_wrap.m4
new file mode 100644
index 0000000..87b22e7
--- /dev/null
+++ b/m4/zw_ld_wrap.m4
@@ -0,0 +1,47 @@
+dnl Written by Zack Weinberg <zackw at panix.com> in 2018.
+dnl To the extent possible under law, Zack Weinberg has waived all
+dnl copyright and related or neighboring rights to this work.
+dnl
+dnl See https://creativecommons.org/publicdomain/zero/1.0/ for further
+dnl details.
+dnl
+dnl Find out whether ld --wrap is supported.
+AC_DEFUN([zw_PROG_LD_WRAP],
+ [AC_REQUIRE([AC_PROG_CC])
+ AC_CACHE_CHECK([for ld --wrap], [zw_cv_prog_ld_wrap],
+ [save_LDFLAGS="$LDFLAGS"
+ save_LIBS="$LIBS"
+ LDFLAGS=""
+ LIBS=""
+ AC_COMPILE_IFELSE(
+ [AC_LANG_SOURCE([[
+ extern void bar(void);
+ void foo(void) { bar(); }
+ ]])],
+ [mv conftest.$OBJEXT conftest2.$OBJEXT
+ LDFLAGS="-Wl,--wrap,bar"
+ LIBS="conftest2.$OBJEXT"
+ AC_LINK_IFELSE(
+ [AC_LANG_PROGRAM([[
+ extern void foo(void);
+ void __wrap_bar(void) {}
+ ]], [[
+ foo();
+ ]])],
+ [zw_cv_prog_ld_wrap=yes],
+ [zw_cv_prog_ld_wrap=no])
+ rm -f conftest2.$OBJEXT
+ ],
+ [zw_cv_prog_ld_wrap=no])
+ LDFLAGS="$save_LDFLAGS"
+ LIBS="$save_LIBS"])
+ if test x$zw_cv_prog_ld_wrap = xyes; then
+ have_ld_wrap=yes
+ AC_DEFINE([HAVE_LD_WRAP], 1,
+ [Define to 1 if -Wl,--wrap,SYMBOL can be used to intercept
+ calls to SYMBOL at link time.])
+ else
+ have_ld_wrap=no
+ fi
+ AM_CONDITIONAL([HAVE_LD_WRAP], [test $have_ld_wrap = yes])
+])
diff --git a/randombytes.c b/randombytes.c
index 5053525..8d95dcc 100644
--- a/randombytes.c
+++ b/randombytes.c
@@ -61,6 +61,8 @@
bool
get_random_bytes(void *buf, size_t buflen)
{
+ if (buflen == 0)
+ return true;
if (buflen > 256)
{
errno = EIO;
diff --git a/test-getrandom-fallbacks.c b/test-getrandom-fallbacks.c
new file mode 100644
index 0000000..8cbab5f
--- /dev/null
+++ b/test-getrandom-fallbacks.c
@@ -0,0 +1,282 @@
+/* Test the fallback logic in get_random_bytes.
+
+ Written by Zack Weinberg <zackw at panix.com> in 2018.
+ To the extent possible under law, Zack Weinberg has waived all
+ copyright and related or neighboring rights to this work.
+
+ See https://creativecommons.org/publicdomain/zero/1.0/ for further
+ details. */
+
+#include "crypt-port.h"
+#include "crypt-private.h"
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <limits.h>
+
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+#if defined HAVE_SYS_SYSCALL_H
+#include <sys/syscall.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+/* If arc4random_buf is available, all of the fallback logic is compiled
+ out and this test is unnecessary. If ld --wrap is not available this
+ test will not work. */
+#if defined HAVE_ARC4RANDOM_BUF || !defined HAVE_LD_WRAP
+
+int
+main (void)
+{
+ return 77;
+}
+
+#else
+
+/* All of the mock system primitives below fill in their buffer with
+ repeats of these bytes, so we can tell where the data came from. */
+#define MOCK_getentropy 'e'
+#define MOCK_getrandom 'r'
+#define MOCK_sys_getentropy 'E'
+#define MOCK_sys_getrandom 'R'
+#define MOCK_urandom 'u'
+
+#ifdef HAVE_GETENTROPY
+static bool getentropy_should_fail = false;
+extern int __wrap_getentropy (void *, size_t);
+int
+__wrap_getentropy (void *buf, size_t buflen)
+{
+ if (getentropy_should_fail)
+ {
+ errno = ENOSYS;
+ return -1;
+ }
+ else
+ {
+ memset (buf, MOCK_getentropy, buflen);
+ return 0;
+ }
+}
+#endif
+
+#ifdef HAVE_GETRANDOM
+static bool getrandom_should_fail = false;
+extern ssize_t __wrap_getrandom (void *, size_t, unsigned int);
+ssize_t
+__wrap_getrandom (void *buf, size_t buflen, unsigned int ARG_UNUSED(flags))
+{
+ if (getrandom_should_fail)
+ {
+ errno = ENOSYS;
+ return -1;
+ }
+ else
+ {
+ buflen = MIN (buflen, SSIZE_MAX);
+ memset (buf, MOCK_getrandom, buflen);
+ return (ssize_t)buflen;
+ }
+}
+#endif
+
+#ifdef HAVE_SYSCALL
+#ifdef SYS_getentropy
+static bool sys_getentropy_should_fail = false;
+#endif
+#ifdef SYS_getrandom
+static bool sys_getrandom_should_fail = false;
+#endif
+static bool other_syscalls = false;
+extern long __wrap_syscall (long, ...);
+long
+__wrap_syscall(long number, ...)
+{
+#ifdef SYS_getentropy
+ if (number == SYS_getentropy)
+ {
+ if (sys_getentropy_should_fail)
+ {
+ errno = ENOSYS;
+ return -1;
+ }
+ else
+ {
+ va_list ap;
+ va_start (ap, number);
+ void *buf = va_arg (ap, void *);
+ size_t buflen = va_arg (ap, size_t);
+ va_end (ap);
+ memset (buf, MOCK_sys_getentropy, buflen);
+ return 0;
+ }
+ }
+#endif
+#ifdef SYS_getrandom
+ if (number == SYS_getrandom)
+ {
+ if (sys_getrandom_should_fail)
+ {
+ errno = ENOSYS;
+ return -1;
+ }
+ else
+ {
+ va_list ap;
+ va_start (ap, number);
+ void *buf = va_arg (ap, void *);
+ size_t buflen = va_arg (ap, size_t);
+ buflen = MIN (buflen, SSIZE_MAX);
+ memset (buf, MOCK_sys_getrandom, buflen);
+ return (ssize_t)buflen;
+ }
+ }
+#endif
+ /* There is no vsyscall. We just have to hope nobody in this test
+ program wants to use syscall() for anything else. */
+ other_syscalls = true;
+ fprintf (stderr, "ERROR: unexpected syscall(%ld)\n", number);
+ errno = ENOSYS;
+ return -1;
+}
+#endif /* HAVE_SYSCALL */
+
+/* It is not possible to hit both of the code paths that can set the
+ "/dev/urandom doesn't work" flag in a single test program, because
+ there's no way to _clear_ that flag again. This test chooses to
+ exercise the read-failure path, not the open-failure path. */
+#if defined HAVE_SYS_STAT_H && defined HAVE_FCNTL_H && defined HAVE_UNISTD_H
+static bool urandom_should_fail = false;
+static int urandom_fd = -1;
+extern int __wrap_open (const char *, int, mode_t);
+extern int __real_open (const char *, int, mode_t);
+int
+__wrap_open (const char *path, int flags, mode_t mode)
+{
+ int ret = __real_open (path, flags, mode);
+ if (ret == -1)
+ return ret;
+ if (!strcmp (path, "/dev/urandom"))
+ urandom_fd = ret;
+ return ret;
+}
+
+extern int __wrap_close (int);
+extern int __real_close (int);
+int
+__wrap_close (int fd)
+{
+ if (fd == urandom_fd)
+ urandom_fd = -1;
+ return __real_close (fd);
+}
+
+extern ssize_t __wrap_read (int, void *, size_t);
+extern ssize_t __real_read (int, void *, size_t);
+ssize_t
+__wrap_read (int fd, void *buf, size_t count)
+{
+ if (fd == urandom_fd)
+ {
+ if (urandom_should_fail)
+ {
+ errno = ENOSYS;
+ return -1;
+ }
+ else
+ {
+ count = MIN (count, SSIZE_MAX);
+ memset (buf, MOCK_urandom, count);
+ return (ssize_t)count;
+ }
+ }
+ else
+ return __real_read (fd, buf, count);
+}
+
+#endif
+
+struct subtest
+{
+ const char *what;
+ bool *make_fail;
+ char expected;
+};
+const struct subtest subtests[] = {
+ { "initial", 0, 'x' },
+
+#ifdef HAVE_GETENTROPY
+ { "getentropy", &getentropy_should_fail, MOCK_getentropy },
+#endif
+#ifdef HAVE_GETRANDOM
+ { "getrandom", &getrandom_should_fail, MOCK_getrandom },
+#endif
+
+#ifdef HAVE_SYSCALL
+#ifdef SYS_getentropy
+ { "sys_getentropy", &sys_getentropy_should_fail, MOCK_sys_getentropy },
+#endif
+#ifdef SYS_getrandom
+ { "sys_getrandom", &sys_getrandom_should_fail, MOCK_sys_getrandom },
+#endif
+#endif
+
+#if defined HAVE_SYS_STAT_H && defined HAVE_FCNTL_H && defined HAVE_UNISTD_H
+ { "/dev/urandom", &urandom_should_fail, MOCK_urandom },
+#endif
+
+ { "final", 0, 0 }
+};
+
+int
+main (void)
+{
+ char buf[257];
+ char expected[2] = { 0, 0 };
+ memset (buf, 'x', sizeof buf - 1);
+ buf[256] = '\0';
+ bool failed = false;
+ const struct subtest *s;
+
+ for (s = subtests; s->expected;)
+ {
+ expected[0] = s->expected;
+ if (strspn (buf, expected) != 256)
+ {
+ printf ("FAIL: %s: buffer not filled with '%c'\n",
+ s->what, s->expected);
+ failed = true;
+ }
+ else
+ printf ("ok: %s (output)\n", s->what);
+
+ if (s->make_fail)
+ *(s->make_fail) = true;
+ s++;
+
+ bool r = get_random_bytes (buf, sizeof buf - 1);
+ if ((s->expected && !r) || (!s->expected && r))
+ {
+ printf ("FAIL: %s: get_random_bytes: %s\n",
+ s->what, strerror (errno));
+ failed = true;
+ }
+ else
+ printf ("ok: %s (return)\n", s->what);
+ }
+#if HAVE_SYSCALL
+ failed |= other_syscalls;
+#endif
+ return failed;
+}
+
+#endif
diff --git a/test-getrandom-interface.c b/test-getrandom-interface.c
new file mode 100644
index 0000000..16df6d0
--- /dev/null
+++ b/test-getrandom-interface.c
@@ -0,0 +1,211 @@
+/* Test the exposed interface of get_random_bytes.
+
+ Written by Zack Weinberg <zackw at panix.com> in 2018.
+ To the extent possible under law, Zack Weinberg has waived all
+ copyright and related or neighboring rights to this work.
+
+ See https://creativecommons.org/publicdomain/zero/1.0/ for further
+ details. */
+
+#include "crypt-port.h"
+#include "crypt-private.h"
+
+#include <errno.h>
+#include <setjmp.h>
+#include <stdio.h>
+#include <string.h>
+#include <signal.h>
+#include <sys/mman.h>
+#include <unistd.h>
+
+static bool error_occurred;
+
+/* Note: both of the following test functions expect PAGE to point to
+ PAGESIZE bytes of read-write memory followed by another PAGESIZE
+ bytes of unwritable memory. Both functions also assume that
+ PAGESIZE is greater than or equal to 256. */
+
+static void
+test_basic (char *page, size_t pagesize)
+{
+ printf ("Testing basic functionality...\n");
+
+ // A request for zero bytes should succeed, and should not touch the
+ // output buffer.
+ if (!get_random_bytes (page + pagesize, 0))
+ {
+ printf ("ERROR: get_random_bytes(0) = %s\n", strerror (errno));
+ error_occurred = 1;
+ }
+ else
+ printf ("ok: get_random_bytes(0)\n");
+
+ // A request for 257 bytes should fail, and should not touch the
+ // output buffer.
+ if (get_random_bytes (page + pagesize, 257))
+ {
+ printf ("ERROR: get_random_bytes(257) succeeded\n");
+ error_occurred = 1;
+ }
+ else if (errno != EIO)
+ {
+ printf ("ERROR: get_random_bytes(257) = %s (expected: %s)\n",
+ strerror (errno), strerror (EIO));
+ error_occurred = 1;
+ }
+ else
+ printf ("ok: get_random_bytes(257)\n");
+
+ // A request for five bytes should succeed, and should not write
+ // past the end of the buffer. (We use an odd, prime number here to
+ // catch implementations that might write e.g. four or eight bytes
+ // at once.)
+ if (!get_random_bytes (page + pagesize - 5, 5))
+ {
+ printf ("ERROR: get_random_bytes(5) = %s\n", strerror (errno));
+ error_occurred = 1;
+ }
+ else
+ printf ("ok: get_random_bytes(5)\n");
+
+ // It's extremely difficult to say whether any output of a random
+ // number generator is or is not "good", but the odds that 251 bytes
+ // of RNG output are all zero is one in 2**2008, and the odds that
+ // the first 251 bytes of RNG output are equal to the second 251
+ // bytes of RNG output is also one in 2**2008. (Again, we use an
+ // odd, prime number to trip up implementations that do wide writes.)
+
+ char prev[251];
+ memset (prev, 0, 251);
+
+ if (!get_random_bytes (page + pagesize - 251, 251))
+ {
+ printf ("ERROR: get_random_bytes(251)/1 = %s\n", strerror (errno));
+ error_occurred = 1;
+ return;
+ }
+
+ if (!memcmp (prev, page + pagesize - 251, 251))
+ {
+ printf ("ERROR: get_random_bytes(251)/1 produced all zeroes\n");
+ error_occurred = 1;
+ return;
+ }
+
+ memcpy (prev, page + pagesize - 251, 251);
+
+ if (!get_random_bytes (page + pagesize - 251, 251))
+ {
+ printf ("ERROR: get_random_bytes(251)/2 = %s\n", strerror (errno));
+ error_occurred = 1;
+ return;
+ }
+
+ if (!memcmp (prev, page + pagesize - 251, 251))
+ {
+ printf ("ERROR: get_random_bytes(251)/2 produced same output "
+ "as /1\n");
+ error_occurred = 1;
+ return;
+ }
+
+ printf ("ok: get_random_bytes(251) smoke test of output\n");
+}
+
+static void
+test_fault (char *page, size_t pagesize)
+{
+ printf ("Testing partially inaccessible output buffer...\n");
+ bool rv = get_random_bytes (page + pagesize - 64, 128);
+ /* shouldn't ever get here */
+ error_occurred = 1;
+ if (rv)
+ printf ("ERROR: success (should have faulted)\n");
+ else
+ printf ("ERROR: failed with %s (should have faulted)\n",
+ strerror (errno));
+}
+
+/* In one of the tests above, a segmentation fault is the expected result. */
+static jmp_buf env;
+static void
+segv_handler (int sig)
+{
+ siglongjmp (env, sig);
+}
+
+static void
+expect_no_fault (char *page, size_t pagesize,
+ void (*testfn) (char *, size_t))
+{
+ int rv = sigsetjmp (env, 1);
+ if (!rv)
+ testfn (page, pagesize);
+ else
+ {
+ printf ("ERROR: Unexpected %s\n", strsignal (rv));
+ error_occurred = 1;
+ }
+}
+
+static void
+expect_a_fault (char *page, size_t pagesize,
+ void (*testfn) (char *, size_t))
+{
+ int rv = sigsetjmp (env, 1);
+ if (!rv)
+ {
+ testfn (page, pagesize);
+ printf ("ERROR: No signal occurred\n");
+ error_occurred = 1;
+ }
+ else
+ {
+ printf ("ok: %s (as expected)\n", strsignal (rv));
+ }
+}
+
+int
+main (void)
+{
+ /* Set up a two-page region whose first page is read-write and
+ whose second page is inaccessible. */
+ size_t pagesize = (size_t) sysconf (_SC_PAGESIZE);
+ if (pagesize < 256)
+ {
+ printf ("ERROR: pagesize of %zu is too small\n", pagesize);
+ return 1;
+ }
+
+ char *page = mmap (0, pagesize * 2, PROT_READ|PROT_WRITE,
+ MAP_PRIVATE|MAP_ANON, -1, 0);
+ if (page == MAP_FAILED)
+ {
+ perror ("mmap");
+ return 1;
+ }
+ memset (page, 'x', pagesize * 2);
+ if (mprotect (page + pagesize, pagesize, PROT_NONE))
+ {
+ perror ("mprotect");
+ return 1;
+ }
+
+ struct sigaction sa, os, ob;
+ sigfillset (&sa.sa_mask);
+ sa.sa_flags = SA_RESTART;
+ sa.sa_handler = segv_handler;
+ if (sigaction (SIGBUS, &sa, &ob) || sigaction (SIGSEGV, &sa, &os))
+ {
+ perror ("sigaction");
+ return 1;
+ }
+
+ expect_no_fault (page, pagesize, test_basic);
+ expect_a_fault (page, pagesize, test_fault);
+
+ sigaction (SIGBUS, &ob, 0);
+ sigaction (SIGSEGV, &os, 0);
+
+ return error_occurred;
+}
From 59680ceac13f85a1506fca87255ea47304a8e493 Mon Sep 17 00:00:00 2001
From: "Dmitry V. Levin" <ldv@altlinux.org>
Date: Tue, 26 Jun 2018 22:45:01 +0000
Subject: [PATCH 34/38] crypt.h: introduce CRYPT_GENSALT_IMPLEMENTS_* feature
test macros
Define CRYPT_GENSALT_IMPLEMENTS_DEFAULT_PREFIX and
CRYPT_GENSALT_IMPLEMENTS_AUTO_ENTROPY feature test macros.
These macros could be checked by portable users of crypt_gensalt*
functions to find out whether null pointers could be specified
as PREFIX and RBYTES arguments.
---
crypt-base.h | 6 ++++++
crypt_gensalt.3 | 21 +++++++++++++++++++++
2 files changed, 27 insertions(+)
diff --git a/crypt-base.h b/crypt-base.h
index 565f943..dd27b8e 100644
--- a/crypt-base.h
+++ b/crypt-base.h
@@ -185,6 +185,12 @@ extern char *crypt_gensalt_ra (const char *__prefix, unsigned long __count,
const char *__rbytes, int __nrbytes)
__THROW;
+/* These macros could be checked by portable users of crypt_gensalt*
+ functions to find out whether null pointers could be specified
+ as PREFIX and RBYTES arguments. */
+#define CRYPT_GENSALT_IMPLEMENTS_DEFAULT_PREFIX 1
+#define CRYPT_GENSALT_IMPLEMENTS_AUTO_ENTROPY 1
+
/*TRAILER*/
#endif /* crypt.h */
diff --git a/crypt_gensalt.3 b/crypt_gensalt.3
index 8759011..ebfff28 100644
--- a/crypt_gensalt.3
+++ b/crypt_gensalt.3
@@ -172,6 +172,19 @@ failed to allocate memory for the compiled
string.
.ad b
.hy 1
+.SH FEATURE TEST MACROS
+The following macros are defined by
+.BR crypt.h :
+.TP
+.B CRYPT_GENSALT_IMPLEMENTS_DEFAULT_PREFIX
+A null pointer can be specified as
+.I prefix
+argument.
+.TP
+.B CRYPT_GENSALT_IMPLEMENTS_AUTO_ENTROPY
+A null pointer can be specified as
+.I rbytes
+argument.
.SH PORTABILITY NOTES
The functions
.BR crypt_gensalt ", " crypt_gensalt_rn ", and " crypt_gensalt_ra
@@ -181,6 +194,14 @@ A function with the name
.B crypt_gensalt
also exists on Solaris 10 and newer, but its prototype and semantics differ.
.PP
+The default prefix and auto entropy features are available since libxcrypt
+version 4.0.0. Portable software can use feature test macros to find out
+whether null pointers could be specified as
+.I prefix
+and
+.I rbytes
+arguments.
+.PP
The set of supported hashing methods varies considerably from system
to system.
.SH ATTRIBUTES
From d077e0bf39c7b4e3443c35ac8abd6eae4489aecd Mon Sep 17 00:00:00 2001
From: "Dmitry V. Levin" <ldv@altlinux.org>
Date: Mon, 9 Jul 2018 17:35:38 +0000
Subject: [PATCH 35/38] Install libcrypt.pc symlink along with libxcrypt.pc
As the library name differs from the project name, avoid potential
confusion libcrypt.pc vs libxcrypt.pc by installing libcrypt.pc symlink
to libxcrypt.pc file.
---
Makefile.am | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/Makefile.am b/Makefile.am
index f99f842..945f283 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -36,6 +36,15 @@ libcrypt_la_SOURCES = \
randombytes.c
pkgconfig_DATA = libxcrypt.pc
+# Install libcrypt.pc symlink to libxcrypt.pc file.
+.PHONY: install-data-hook-pkgconfig uninstall-hook-pkgconfig
+install-data-hook: install-data-hook-pkgconfig
+uninstall-hook: uninstall-hook-pkgconfig
+install-data-hook-pkgconfig:
+ cd $(DESTDIR)$(pkgconfigdir) && \
+ $(LN_S) libxcrypt.pc libcrypt.pc
+uninstall-hook-pkgconfig:
+ -rm -f $(DESTDIR)$(pkgconfigdir)/libcrypt.pc
# Build libcrypt.so.2 if obsolete APIs are excluded, libcrypt.so.1 otherwise.
if ENABLE_OBSOLETE_API
From 4f22827c619c2196898b32de44bd45ca627de545 Mon Sep 17 00:00:00 2001
From: "Dmitry V. Levin" <ldv@altlinux.org>
Date: Fri, 22 Jun 2018 00:07:54 +0000
Subject: [PATCH 36/38] Extend --enable-obsolete-api configure option
Make vendor specific parts of compatibility ABI that are enabled by
--enable-obsolete-api option configurable. This allows vendors to
enable only those parts of compatibility ABI that are relevant to them.
---
Makefile.am | 10 ++++++++--
configure.ac | 37 ++++++++++++++++++++++++++++---------
gen-map.awk | 29 +++++++++++++++++++++--------
gen-vers.awk | 26 +++++++++++++++++++-------
libcrypt.map.in | 10 +++++-----
5 files changed, 81 insertions(+), 31 deletions(-)
diff --git a/Makefile.am b/Makefile.am
index 945f283..be8b585 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -68,13 +68,17 @@ CLEANFILES = libcrypt.map libcrypt.map.T \
libcrypt.map: libcrypt.map.in gen-map.awk Makefile
$(AM_V_GEN)LC_ALL=C $(AWK) \
- -v SYMVER_MIN=$(SYMVER_MIN) -v SYMVER_FLOOR=$(SYMVER_FLOOR) \
+ -v SYMVER_MIN=$(SYMVER_MIN) \
+ -v SYMVER_FLOOR=$(SYMVER_FLOOR) \
+ -v COMPAT_ABI=$(COMPAT_ABI) \
-f $(srcdir)/gen-map.awk $(srcdir)/libcrypt.map.in > libcrypt.map.T
$(AM_V_at)mv -f libcrypt.map.T libcrypt.map
crypt-symbol-vers.h: libcrypt.map.in gen-vers.awk Makefile
$(AM_V_GEN)LC_ALL=C $(AWK) \
- -v SYMVER_MIN=$(SYMVER_MIN) -v SYMVER_FLOOR=$(SYMVER_FLOOR) \
+ -v SYMVER_MIN=$(SYMVER_MIN) \
+ -v SYMVER_FLOOR=$(SYMVER_FLOOR) \
+ -v COMPAT_ABI=$(COMPAT_ABI) \
-f $(srcdir)/gen-vers.awk \
$(srcdir)/libcrypt.map.in > crypt-symbol-vers.h.T
$(AM_V_at)mv -f crypt-symbol-vers.h.T crypt-symbol-vers.h
@@ -91,6 +95,7 @@ crypt-hashes.h: hashes.lst gen-hashes.awk Makefile
$(srcdir)/hashes.lst > crypt-hashes.h.T
$(AM_V_at)mv -f crypt-hashes.h.T crypt-hashes.h
+if ENABLE_COMPAT_SUSE
# When we are being binary compatible, also install symbolic links to
# mimic SUSE's libowcrypt; any program that uses -lowcrypt in its
# build, or already has a NEEDED entry for libowcrypt.so.1, will be
@@ -127,6 +132,7 @@ uninstall-hook-libshared:
$(DESTDIR)$(libdir)/libowcrypt.so.1
endif
endif
+endif
check_PROGRAMS = \
test-alg-des test-alg-hmac-sha1 test-alg-md4 test-alg-md5 \
diff --git a/configure.ac b/configure.ac
index 274c16a..3b13d9d 100644
--- a/configure.ac
+++ b/configure.ac
@@ -187,20 +187,38 @@ fi
AC_ARG_ENABLE([obsolete-api],
AS_HELP_STRING(
- [--disable-obsolete-api],
- [do not include compatibility definitions of obsolete APIs
- (fcrypt, encrypt, setkey) in the shared library.
- Breaks binary compatibility with glibc's libcrypt.
- Only affects existing binaries; new programs cannot be
- linked against these functions in any case.]
+ [--enable-obsolete-api[=ARG]],
+ [When set to "yes", include all compatibility interfaces.
+ When set to "alt", include interfaces for compatibility with ALT.
+ When set to "glibc", include interfaces for compatibility with glibc.
+ When set to "owl", include interfaces for compatibility with Owl.
+ When set to "suse", include interfaces for compatibility with SUSE.
+ When set to "no", do not include compatibility definitions of obsolete
+ APIs (fcrypt, encrypt, setkey) in the shared library, which breaks
+ binary compatibility with glibc's libcrypt. Only affects existing
+ binaries; new programs cannot be linked against these compatibility
+ functions in any case. [default=yes]]
),
[case "${enableval}" in
- yes) enable_obsolete_api=1 ;;
- no) enable_obsolete_api=0 ;;
+ alt|glibc|owl)
+ enable_obsolete_api=1
+ enable_compat_suse=0
+ COMPAT_ABI=${enableval} ;;
+ yes|suse)
+ enable_obsolete_api=1
+ enable_compat_suse=1
+ COMPAT_ABI=${enableval} ;;
+ no)
+ enable_obsolete_api=0
+ enable_compat_suse=0
+ COMPAT_ABI=${enableval} ;;
*) AC_MSG_ERROR([bad value ${enableval} for --enable-obsolete-api]) ;;
esac],
- [enable_obsolete_api=1]
+ [enable_obsolete_api=1
+ enable_compat_suse=1
+ COMPAT_ABI=yes]
)
+AC_SUBST(COMPAT_ABI)
AC_ARG_ENABLE([hashes],
AS_HELP_STRING(
@@ -298,6 +316,7 @@ AC_DEFINE_UNQUOTED([ENABLE_OBSOLETE_API], [$enable_obsolete_api],
[Define as 1 if the obsolete APIs (fcrypt, encrypt, setkey)
should be included, 0 otherwise.])
AM_CONDITIONAL([ENABLE_OBSOLETE_API], [test $enable_obsolete_api = 1])
+AM_CONDITIONAL([ENABLE_COMPAT_SUSE], [test $enable_compat_suse = 1])
# The Makefile needs to know which versions of the library we are building.
AM_CONDITIONAL([ENABLE_STATIC], [test $enable_static = yes])
diff --git a/gen-map.awk b/gen-map.awk
index f8289e2..025af05 100644
--- a/gen-map.awk
+++ b/gen-map.awk
@@ -8,10 +8,11 @@
# details.
# The .map.in file is the first input file, and we expect the Makefile
-# to have set the variables SYMVER_MIN and SYMVER_FLOOR. All symbol
-# versions lower than SYMVER_MIN are discarded from the output.
-# All symbol versions lower than SYMVER_FLOOR are replaced with
-# SYMVER_FLOOR. SYMVER_FLOOR must be greater than or equal to SYMVER_MIN.
+# to have set the variables SYMVER_MIN, SYMVER_FLOOR, and COMPAT_ABI.
+# All compat symbol versions that do not match COMPAT_ABI are ignored.
+# All symbol versions lower than SYMVER_MIN are discarded from the output.
+# All symbol versions lower than SYMVER_FLOOR are replaced with SYMVER_FLOOR.
+# SYMVER_FLOOR must be greater than or equal to SYMVER_MIN.
#
# The ordering of symbol versions is entirely controlled by the %chain
# directive, which must therefore list both all of the versions
@@ -42,11 +43,23 @@ $1 == "%chain" {
{
for (i = 2; i <= NF; i++) {
- if ($i != "-") {
- if ($i in SYMBOLS) {
- SYMBOLS[$i] = SYMBOLS[$i] SUBSEP $1
+ sym=$i
+ if (sym != "-") {
+ n=split(sym, a, ":")
+ if (n > 1) {
+ sym="-"
+ for (j = 2; j <= n; j++) {
+ if (COMPAT_ABI == "yes" || COMPAT_ABI == a[j]) {
+ sym=a[1]
+ }
+ }
+ }
+ }
+ if (sym != "-") {
+ if (sym in SYMBOLS) {
+ SYMBOLS[sym] = SYMBOLS[sym] SUBSEP $1
} else {
- SYMBOLS[$i] = $1
+ SYMBOLS[sym] = $1
}
}
}
diff --git a/gen-vers.awk b/gen-vers.awk
index 4870d05..a846a58 100644
--- a/gen-vers.awk
+++ b/gen-vers.awk
@@ -9,9 +9,9 @@
# details.
# The .map.in file is the first input file, and we expect the Makefile
-# to have set the variables SYMVER_MIN and SYMVER_FLOOR. See
-# libcrypt.map.in and gen-vers.awk for explanations of the format of
-# .map.in files. See crypt-port.h for an explanation of how to use
+# to have set the variables SYMVER_MIN, SYMVER_FLOOR, and COMPAT_ABI.
+# See libcrypt.map.in and gen-vers.awk for explanations of the format
+# of .map.in files. See crypt-port.h for an explanation of how to use
# the macros generated by this program.
#
# Note: if you change the format of .map.in files you probably need to
@@ -51,10 +51,22 @@ $1 == "%chain" {
}
}
for (i = 3; i <= NF; i++) {
- if ($i in SYMBOLS) {
- SYMBOLS[$i] = SYMBOLS[$i] SUBSEP $1
- } else {
- SYMBOLS[$i] = $1
+ sym=$i
+ n=split(sym, a, ":")
+ if (n > 1) {
+ sym=""
+ for (j = 2; j <= n; j++) {
+ if (COMPAT_ABI == "yes" || COMPAT_ABI == a[j]) {
+ sym=a[1]
+ }
+ }
+ }
+ if (sym != "") {
+ if (sym in SYMBOLS) {
+ SYMBOLS[sym] = SYMBOLS[sym] SUBSEP $1
+ } else {
+ SYMBOLS[sym] = $1
+ }
}
}
}
diff --git a/libcrypt.map.in b/libcrypt.map.in
index 18aac79..0989990 100644
--- a/libcrypt.map.in
+++ b/libcrypt.map.in
@@ -9,12 +9,12 @@ crypt_r XCRYPT_2.0 GLIBC_2.0
# Actively supported Openwall extensions; never actually added to
# upstream GNU libc, but present in at least Openwall, ALT, and SUSE
# Linux distributions with one or more of these symbol versions
-crypt_rn XCRYPT_2.0 GLIBC_2.0 GLIBC_2.2.1
-crypt_gensalt XCRYPT_2.0 GLIBC_2.0 GLIBC_2.2.1 OW_CRYPT_1.0
-crypt_gensalt_rn XCRYPT_2.0 GLIBC_2.0 GLIBC_2.2.1 OW_CRYPT_1.0
+crypt_rn XCRYPT_2.0 GLIBC_2.0:owl:suse GLIBC_2.2.1:alt
+crypt_gensalt XCRYPT_2.0 GLIBC_2.0:owl:suse GLIBC_2.2.1:alt OW_CRYPT_1.0:suse
+crypt_gensalt_rn XCRYPT_2.0 GLIBC_2.0:owl:suse GLIBC_2.2.1:alt OW_CRYPT_1.0:suse
-crypt_ra XCRYPT_2.0 GLIBC_2.0 GLIBC_2.2.2
-crypt_gensalt_ra XCRYPT_2.0 GLIBC_2.0 GLIBC_2.2.2 OW_CRYPT_1.0
+crypt_ra XCRYPT_2.0 GLIBC_2.0:owl:suse GLIBC_2.2.2:alt
+crypt_gensalt_ra XCRYPT_2.0 GLIBC_2.0:owl:suse GLIBC_2.2.2:alt OW_CRYPT_1.0:suse
# Deprecated interfaces, POSIX and otherwise; also present in GNU libc
# since 2.0
From 022c86e681d2497ac02d88ac265d3c7c2d8b4ac5 Mon Sep 17 00:00:00 2001
From: "Dmitry V. Levin" <ldv@altlinux.org>
Date: Tue, 10 Jul 2018 15:38:15 +0000
Subject: [PATCH 37/38] .travis.yml: add --enable-obsolete-api=glibc to the
test matrix
---
.travis.yml | 24 ++++++++++++++++++++++++
1 file changed, 24 insertions(+)
diff --git a/.travis.yml b/.travis.yml
index 31c50fa..db45ded 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -118,6 +118,30 @@ matrix:
env:
- CONF="--enable-obsolete-api --enable-hashes=glibc"
- FCVER="latest"
+ - compiler: gcc
+ os: linux
+ services: docker
+ env:
+ - CONF="--enable-obsolete-api=glibc --enable-hashes=strong,glibc"
+ - FCVER="rawhide"
+ - compiler: clang
+ os: linux
+ services: docker
+ env:
+ - CONF="--enable-obsolete-api=glibc --enable-hashes=strong,glibc"
+ - FCVER="rawhide"
+ - compiler: gcc
+ os: linux
+ services: docker
+ env:
+ - CONF="--enable-obsolete-api=glibc --enable-hashes=strong,glibc"
+ - FCVER="latest"
+ - compiler: clang
+ os: linux
+ services: docker
+ env:
+ - CONF="--enable-obsolete-api=glibc --enable-hashes=strong,glibc"
+ - FCVER="latest"
before_install:
- for i in `seq 0 99`; do docker pull fedora:$FCVER && i= && break || sleep 1; done; [ -z "$i" ]
From 430212bcae4b9f31ed12bc52706b313da723c5cb Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bj=C3=B6rn=20Esser?= <besser82@fedoraproject.org>
Date: Fri, 13 Jul 2018 12:21:32 +0200
Subject: [PATCH 38/38] test-short-outbuf.c: Fix to build on 32 bit arches
---
test-short-outbuf.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/test-short-outbuf.c b/test-short-outbuf.c
index 7ab9d11..d928daa 100644
--- a/test-short-outbuf.c
+++ b/test-short-outbuf.c
@@ -44,8 +44,8 @@ main (void)
ok = false;
}
- printf ("Test %lu.0: %s, expected: \"%-2s\", got: \"%-2s\"\n",
- i + 1, result, testcases[i].exp_rn, *outbuf);
+ printf ("Test %u.0: %s, expected: \"%-2s\", got: \"%-2s\"\n",
+ (unsigned int)(i + 1), result, testcases[i].exp_rn, *outbuf);
crypt_ra ("@@", "@@", (void **) outbuf, (int *) j);
@@ -59,8 +59,8 @@ main (void)
ok = false;
}
- printf ("Test %lu.1: %s, expected: \"%-2s\", got: \"%-2s\"\n",
- i + 1, result, testcases[i].exp_ra, *outbuf);
+ printf ("Test %u.1: %s, expected: \"%-2s\", got: \"%-2s\"\n",
+ (unsigned int)(i + 1), result, testcases[i].exp_ra, *outbuf);
free (j);
free (*outbuf);