Compare commits

..

245 Commits

Author SHA1 Message Date
Andreas Schneider
319129399d Bump version to 0.6.4. 2014-12-17 19:45:23 +01:00
Jon Simons
87ae95eb3c CVE-2014-8132: Fixup error path in ssh_packet_kexinit()
Before this change, dangling pointers can be unintentionally left in the
respective next_crypto kex methods slots.  Ensure to set all slots to
NULL in the error-out path.

Signed-off-by: Jon Simons <jon@jonsimons.org>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 2ced24ddd67a261dc364ad4d8958c068c1671ae7)
2014-12-17 19:45:23 +01:00
Andreas Schneider
055f102601 libcrypto: Fix Windows build with ssh_reseed().
gettimeofday() is not available on Windows and we need it only in case
of forking.

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit b7b535816d)
2014-12-17 19:40:57 +01:00
Andreas Schneider
2d6862ddb9 cmake: Fix the build on Windows.
(cherry picked from commit a738507ad2)
2014-12-17 19:31:32 +01:00
Andreas Schneider
22aa60d506 cmake: Fix config variable names.
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit d8e691b58a)
2014-12-17 10:40:31 +01:00
Andreas Schneider
4b02bbbd32 cmake: Fix libssh cmake-config files.
(cherry picked from commit 142b2e4ede)
2014-12-17 10:40:25 +01:00
William Orr
31ded2070e config: Also tokenize on equal sign.
The ssh config specifies it as a valid separator.

BUG: https://red.libssh.org/issues/166

Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 52968b1a11)
2014-12-17 10:35:17 +01:00
Davide \"FunkyAss\" Del Zompo
df3d53e561 doc: clarify tutorial error section
Signed-off-by: Davide "FunkyAss" Del Zompo <davide.delzompo@gmail.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit bb197de75d)
2014-12-05 11:09:34 +01:00
Hani Benhabiles
f28c3099da Set the correct error in ssh_options_set().
Signed-off-by: Hani Benhabiles <hani@linux.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 03095f1516)
2014-12-05 11:04:35 +01:00
Andreas Schneider
32a106c70d messages: Fix a possible double free.
Thanks to Ramana Gampa.

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2014-12-05 10:59:41 +01:00
Jon Simons
5d75090d9f pki_crypto.c: plug ecdsa_sig->[r,s] bignum leaks
Per ecdsa(3ssl), ECDSA_SIG_new does allocate its 'r' and 's' bignum fields.
Fix a bug where the initial 'r' and 's' bignums were being overwritten with
newly-allocated bignums, resulting in a memory leak.

BUG: https://red.libssh.org/issues/175

Signed-off-by: Jon Simons <jon@jonsimons.org>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>

(cherry picked from commit 4745d652b5)
2014-12-05 10:46:31 +01:00
Andreas Schneider
32a3cfe661 connect: Do not fail if the connect is in progress.
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit a48711ae7e)
2014-10-28 10:33:47 +01:00
Stef Walter
1c59844dfe gssapi: ssh_gssapi_set_creds() is a client side function
It should not be guarded by the WITH_SERVER #ifdef

Signed-off-by: Stef Walter <stefw@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit cd2dc3770a)
2014-10-12 15:47:13 +02:00
William Orr
f071954a76 Check return code of connect(2).
Signed-off-by: William Orr <will@worrbase.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 250f506487)
2014-10-12 15:47:12 +02:00
Artyom V. Poptsov
a033b93c61 pki_gcrypt: Initialize 'type_c' in 'pki_do_sign_sessionid'
Add missing initialization of 'type_c' field of a SSH signature in
'pki_do_sign_sessionid' procedure.

If libssh is compiled with GCrypt, 'dh_handshake_server' fails with
"Could not sign the session id" error.  The change fixes that.

Signed-off-by: Artyom V. Poptsov <poptsov.artyom@gmail.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit aaae6cd97d)
2014-10-02 08:30:30 +02:00
Jon Simons
b7856780a9 crypto: check malloc return in ssh_mac_ctx_init
Signed-off-by: Jon Simons <jon@jonsimons.org>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit af25c5e668)
2014-10-02 08:26:08 +02:00
Jon Simons
8b3425865a wrapper: fix z_stream leak
Ensure to free the z_stream structures as allocated from
the gzip.c initcompress, initdecompress functions.

Signed-off-by: Jon Simons <jon@jonsimons.org>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 092fe0b727)
2014-10-02 08:25:27 +02:00
Andreas Schneider
a30e234c03 string: Correctly burn the string buffer.
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Aris Adamantiadis <aris@0xbadc0de.be>
(cherry picked from commit 1ddb99c46f)
2014-09-15 20:46:06 +02:00
Jon Simons
bbf172a79c session: fix ssh_session->srv.ecdsa_key leak
Signed-off-by: Jon Simons <jon@jonsimons.org>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2014-05-28 10:24:01 +02:00
Andreas Schneider
f28748578d pki: Fix build without ECC support.
Signed-off-by: Andreas Schneider <asn@samba.org>
2014-05-09 08:56:10 +02:00
Andreas Schneider
36f7d1a614 pki: Add missing semi-colon. 2014-05-07 09:36:11 +02:00
Andreas Schneider
71241ca68c pki: Move ssh_pki_key_ecdsa_name() to the correct file. 2014-05-07 09:35:49 +02:00
Andreas Schneider
bfbf9283d0 cmake: Fix doxygen. 2014-05-07 09:35:34 +02:00
Andreas Schneider
d75573e665 cmake: Update doxygen module. 2014-05-07 09:35:34 +02:00
Jon Simons
8fe36e3d07 pki crypto: expose new ssh_pki_key_ecdsa_name API
Enable retrieving the "ecdsa-sha2-nistpNNN" name of ECDSA keys with a
new 'ssh_pki_key_ecdsa_name' API.  This gives more information than the
'ssh_key_type_to_char' API, which yields "ssh-ecdsa" for ECDSA keys.
The motivation is that this info is useful to have in a server context.

The torture_pki unit test is updated to include the new API, and a few
more passes are added to additionally test 384 and 521-bit keys.

Signed-off-by: Jon Simons <jon@jonsimons.org>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2014-05-07 09:35:06 +02:00
Alan Dunn
f2e9ce68e7 messages: Add missing ntohl on X11 request screen number
BUG: https://red.libssh.org/issues/160

Signed-off-by: Alan Dunn <amdunn@gmail.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2014-05-06 08:56:55 +02:00
Andreas Schneider
cfb4d27c47 pki: Correctly update the ECDSA keytype.
(cherry picked from commit 2884bbf5b1)
2014-05-06 08:54:11 +02:00
Andreas Schneider
d366e289f3 pki: Move ssh_pki_key_ecdsa_name() to the correct file.
(cherry picked from commit f48a99b97c)
2014-05-06 08:54:06 +02:00
Andreas Schneider
2fc8347504 pki: Make pki_key_ecdsa_nid_to_name() a shared function.
(cherry picked from commit 11cfb2903e)
2014-05-06 08:54:00 +02:00
Andreas Schneider
2691ed595e cmake: Install cmake config files to the correct directory.
(cherry picked from commit 291312c5e4)
2014-04-22 09:10:05 +02:00
Andreas Schneider
7b133cf9f5 doc: Improve docs for ssh_channel_get_exit_status().
BUG: https://red.libssh.org/issues/154
(cherry picked from commit adf23533e0)
2014-04-22 09:09:57 +02:00
Andreas Schneider
9b59f1a222 channels: Fix exit-signal request.
BUG: https://red.libssh.org/issues/153
(cherry picked from commit 927cd90dc1)
2014-04-22 09:09:56 +02:00
Andreas Schneider
8f21f879d3 session: Fix a memory leak with custom banner.
BUG: https://red.libssh.org/issues/152
(cherry picked from commit b5efbe75cd)
2014-04-22 09:09:39 +02:00
Andreas Schneider
67752dabfc cmake: Enable creation of the compile command database by default.
(cherry picked from commit 437a39c798)
2014-04-22 09:09:28 +02:00
Jon Simons
34ac4e4248 packet: elide two buffer_prepend calls into one
In packet_send2, rather than issue two separate buffer_prepend_data calls
(each of which may entail realloc + memmove + memcpy), elide the prepend
work into a single buffer_prepend_data: the header information is computed
locally, and a single 5 byte prepend operation is now done instead of
prepending 1, then 4 bytes.

Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit aa05248ca8)

Conflicts:
	src/packet.c
2014-03-27 11:25:15 +01:00
Andreas Schneider
1928fb6a85 doc: Fix ssh_userauth_none() function signature.
Thanks to David Tibbe!

BUG: https://red.libssh.org/issues/151
(cherry picked from commit 04543c9dbc)
2014-03-27 11:16:23 +01:00
Alan Dunn
5b1678f197 doc: Improve and consolidate ssh_bind_options_set docs
Signed-off-by: Alan Dunn <amdunn@gmail.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 47bd0b6d1f)
2014-03-27 11:15:39 +01:00
Petar Koretic
8aff91dfcb libssh: libhpp: overload read function to support timeout parameter
Signed-off-by: Petar Koretic <petar.koretic@sartura.hr>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 8e2590b535)
2014-03-27 11:15:39 +01:00
Petar Koretic
c0cc12d582 libssh: libhpp: avoid unnecessary call to ssh_channel_read
ssh_channel_read is a wrapper for ssh_channel_read_timeout with timeout
-1 (infinite) so we call that directly.

Signed-off-by: Petar Koretic <petar.koretic@sartura.hr>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit c51f42a566)
2014-03-27 11:15:39 +01:00
Petar Koretic
a162071f9a libssh: libhpp: fix multiple definitions for acceptForward function
Defining a non inlined class function in a header will cause multiple
definitions when header is included in more that one file since for each
file function will get defined.

Signed-off-by: Petar Koretic <petar.koretic@sartura.hr>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 00d4fbe753)

Conflicts:
	include/libssh/libsshpp.hpp
2014-03-27 11:15:19 +01:00
Jon Simons
2091dab273 channel: check for closed state in waitwindow loops
Signed-off-by: Jon Simons <jon@jonsimons.org>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit dee8e5688b)
2014-03-27 11:14:25 +01:00
Jon Simons
7f18ec4620 kex: enable more ECDSA hostkey algos
Signed-off-by: Jon Simons <jon@jonsimons.org>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 40d81bb7ca)
2014-03-27 11:14:25 +01:00
Jon Simons
8e698382db pki_crypto: guard against NULL pubkey->rsa in signature extraction
Signed-off-by: Jon Simons <jon@jonsimons.org>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 10bc5ac203)
2014-03-27 11:14:25 +01:00
Luka Perkov
ce10d40325 session: fix comment typo
Signed-off-by: Luka Perkov <luka.perkov@sartura.hr>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 8ba9402282)
2014-03-27 11:14:25 +01:00
Luka Perkov
3fed9a5aff messages: use predefined macro for clearing sensitive data
Signed-off-by: Luka Perkov <luka.perkov@sartura.hr>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit a2fe341da5)
2014-03-27 11:14:25 +01:00
Luka Perkov
da0c77fdb1 client: fix corner case when sockets are manually created
If the sockets are created manually and passed to libssh the internal session
state is set to SSH_SESSION_STATE_SOCKET_CONNECTED. Result of this fix can be
verified by running torture_connect test (torture_connect_socket) with -vvvv
flags.

Signed-off-by: Luka Perkov <luka.perkov@sartura.hr>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit dbb2de272b)
2014-03-27 11:14:25 +01:00
Luka Perkov
818c80baed tests: torture_connect: add test for user provided socket
Signed-off-by: Luka Perkov <luka.perkov@sartura.hr>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 9423a3a065)
2014-03-27 11:14:25 +01:00
Luka Perkov
bb55bb2daf tests: torture_connect: fix coding style
Signed-off-by: Luka Perkov <luka.perkov@sartura.hr>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 0c5d4954a7)
2014-03-27 11:14:25 +01:00
Petar Koretic
fdced9d544 pki_crypto: Replace deprecated RSA_generate_key() with RSA_generate_key_ex()
On Mar 16, 09:41, Aris Adamantiadis wrote:
> Hi Petar,
> I agree with the principle, but I don't think this code can work...
> RSA_generate_key takes an RSA* as parameter and in our code we probably
> have key->rsa==NULL. (if we don't then the old code had a memory leak).
>
> Does the test case work ?
>
> Aris
>

Yes, you are right. This works, tested with tests/unittests/torture_pki

Signed-off-by: Petar Koretic <petar.koretic@sartura.hr>
(cherry picked from commit 0b8d24f800)
2014-03-27 11:14:25 +01:00
Luka Perkov
96db44ff17 update gitignore file
The libssh library by default does not allow in-source build (with cmake
MacroEnsureOutOfSourceBuild macro). The INSTALL file (implicitly) suggests
creating a build directory. So lets add build to list of git ignore files to
avoid complaints from git.

Signed-off-by: Luka Perkov <luka.perkov@sartura.hr>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 48354f56ec)
2014-03-27 11:14:25 +01:00
Alan Dunn
70dbbfa320 doc: Add ECDSA keys to docs, make key docs consistent
Signed-off-by: Alan Dunn <amdunn@gmail.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit f6276fe739)
2014-03-27 11:13:15 +01:00
Alan Dunn
1118fc2adf options: Allow use of host ECDSA key
Signed-off-by: Alan Dunn <amdunn@gmail.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 2a1089d607)
2014-03-27 11:13:15 +01:00
Andreas Schneider
257449a0b6 tests: Check the the ecdsa_nid is the same.
(cherry picked from commit fbf73ede1e)
2014-03-27 11:13:15 +01:00
Alan Dunn
8752460df4 tests: Add test case for bug #147
Signed-off-by: Alan Dunn <amdunn@gmail.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 577840d7f7)
2014-03-27 11:13:15 +01:00
Alan Dunn
6f089a098b pki_crypto: Always copy ecdsa_nid into duplicated ECDSA keys
BUG: https://red.libssh.org/issues/147

Signed-off-by: Alan Dunn <amdunn@gmail.com>
2014-03-12 14:16:43 +01:00
Alan Dunn
8b3be050c9 pki: Use SHA-2 for session ID signing with ECDSA keys
Previously, SHA-1 was used always.

BUG: https://red.libssh.org/issues/148

Signed-off-by: Alan Dunn <amdunn@gmail.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2014-03-12 14:16:35 +01:00
Luka Perkov
ade33474be server: silence build warning
The commit fixes this build warning:

====
src/server.c:223:8: warning: ‘privkey’ may be used uninitialized in this function [-Wmaybe-uninitialized]
     rc = ssh_pki_export_privkey_to_pubkey(*privkey, &pubkey);
        ^
src/server.c:243:11: note: ‘privkey’ was declared here
   ssh_key privkey;
====

Signed-off-by: Luka Perkov <luka.perkov@sartura.hr>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2014-03-12 14:16:33 +01:00
Jon Simons
dbf7749696 packet: log disconnect code in host byte order
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2014-03-12 14:16:30 +01:00
Jon Simons
2db45dd547 bind: only set bindfd after successful listen
In 'ssh_bind_listen', move setting of 'sshbind->bindfd' to only happen after
the listen call: otherwise 'bindfd' can be set to a bogus descriptor for the
case that listen fails.

Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2014-03-12 14:16:28 +01:00
Andreas Schneider
87145387aa Prepare libssh-0.6.3.
We messed up some thing, so we release 0.6.3.
2014-03-04 13:20:52 +01:00
Aris Adamantiadis
d027460792 bump version to 0.6.2 2014-03-04 11:34:36 +01:00
Aris Adamantiadis
3fdd82f2a8 security: fix for vulnerability CVE-2014-0017
When accepting a new connection, a forking server based on libssh forks
and the child process handles the request. The RAND_bytes() function of
openssl doesn't reset its state after the fork, but simply adds the
current process id (getpid) to the PRNG state, which is not guaranteed
to be unique.
This can cause several children to end up with same PRNG state which is
a security issue.
2014-03-04 09:55:02 +01:00
Andreas Schneider
6cd94a63ff pki: Fix the build on OpenSolaris. 2014-02-12 09:40:09 +01:00
Andreas Schneider
e85b20ba82 pki: Fix memory leak with ecdsa signatures. 2014-02-11 10:31:51 +01:00
Andreas Schneider
78d5d64b38 Update ChangeLog. 2014-02-10 10:17:43 +01:00
Andreas Schneider
f73a44c223 cpack: Ignore obj directory. 2014-02-10 10:17:43 +01:00
Andreas Schneider
1cccfdf8a0 packet: Improve readablity of packet decrypt.
After discussion with Aris and it was not obvious enough to understand
the issue we decided to refactor it.

Reviewd-by: Aris Adamantiadis <aris@0xbadc0de.be>
2014-02-06 20:32:05 +01:00
Alan Dunn
abe4ed0e75 packet_crypt: Make packet_{en,de}crypt fail consistently on len == 0
Right now the behavior of packet_{en,de}crypt on len == 0 depends on
the behavior of malloc.  Instead, make these consistently fail based
on what I assume the desired behavior is due to the first error
message in each.

Signed-off-by: Alan Dunn <amdunn@gmail.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2014-02-06 19:40:29 +01:00
Alan Dunn
e7f831f0a3 packet: Do not decrypt zero length rest of buffer
If we receive a packet of length exactly blocksize, then
packet_decrypt gets called on a buffer of size 0.  The check at the
beginning of packet_decrypt indicates that the function should be
called on buffers of at least one blocksize, though the check allows
through zero length.  As is packet_decrypt can return -1 when len is 0
because malloc can return NULL in this case: according to the ISO C
standard, malloc is free to return NULL or a pointer that can be freed
when size == 0, and uclibc by default will return NULL here (in
"non-glibc-compatible" mode).  The net result is that when using
uclibc connections with libssh can anomalously fail.

Alternatively, packet_decrypt (and probably packet_encrypt for
consistency) could be made to always succeed on len == 0 without
depending on the behavior of malloc.

Thanks to Josh Berlin for bringing conneciton failures with uclibc to
my attention.

Signed-off-by: Alan Dunn <amdunn@gmail.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2014-02-06 19:40:09 +01:00
Raphael Kubo da Costa
4ea4e12df2 build: Use Threads_FOUND to decide whether to build ssh_threads.
Follow-up to 4e04ec8, which caused a regression on OS X.

Checking the value of CMAKE_THREAD_LIBS_INIT to decide whether any threading
library is present on a system turns out to be wrong -- in OS X, for
example, usage of pthreads does not depend on any additional linker or
compiler flags, so CMAKE_THREAD_LIBS_INIT is empty and our check in
src/CMakeLists.txt failed (it used to work before 4e04ec8 because
CMAKE_HAVE_THREADS_LIBRARY is set).

Instead, just look for Threads_FOUND, which FindThreads sets just like any
other Find module when it has found what it was looking for.

Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2014-02-06 11:13:23 +01:00
Jon Simons
fb49e194df session: skip timestamp init for non-blocking case
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2014-02-06 11:13:22 +01:00
Jon Simons
13f4e31ad1 session: add getters for session cipher names
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2014-02-06 11:13:20 +01:00
Aris Adamantiadis
da5fa4ef66 Revert f2c2687ca6
Fix bug #142
The mode does need to be an octal numeric string. Mode 0600 now gets sent on the wire as 0384, triggering a "scp: protocol error: bad mode" response, and an "scp status code 1d not valid" message from libssh.
2014-02-05 22:30:10 +01:00
Aris Adamantiadis
dca415a38e knownhosts: resolve leaks found by coverity 2014-02-05 08:08:31 +01:00
Aris Adamantiadis
56f86cd4a1 knownhosts: detect variations of ecdsa 2014-02-05 08:08:31 +01:00
Aris Adamantiadis
f265afacfb tests: lines lost during last cherry-pick merge 2014-02-04 16:20:20 +01:00
Aris Adamantiadis
99f8b2b803 Kex: fix coverity warning + edge case 2014-02-04 16:04:45 +01:00
Audrius Butkevicius
22edaf43ee server: use custom server banners
Value of session->serverbanner never gets used

Signed-off-by: Audrius Butkevicius <audrius.butkevicius@gmail.com>
2014-02-04 16:04:26 +01:00
Aris Adamantiadis
497bd31364 server: allow custom server banners (bug #83) 2014-02-04 16:04:26 +01:00
Aris Adamantiadis
8ed0c0b3c8 Knownhosts: implement hostkey with knownhosts heuristic 2014-02-04 16:01:37 +01:00
Aris Adamantiadis
ce39d2fa73 knownhosts: add test case for bug #138 2014-02-04 16:01:37 +01:00
Aris Adamantiadis
90d3768f0f known_hosts: add ssh_knownhosts_algorithms()
Goal of that function is to test the preferred key exchange methods
based on what's available in the known_hosts file

Conflicts:
	tests/client/torture_knownhosts.c
2014-02-04 16:01:02 +01:00
Aris Adamantiadis
6f66032209 build: remove OSX deprecated warnings for openssl 2014-02-04 15:55:37 +01:00
Raphael Kubo da Costa
c571cd8402 threads: Be less strict when deciding whether to build libssh_threads.
As mentioned in the previous commit, there are cases where
CMAKE_HAVE_THREADS_LIBRARY is not set and pthreads _is_ being used: one can
pass -DTHREADS_HAVE_PTHREAD_ARG=1 to CMake directly so that it just passes
-pthread to the compiler/linker and does not set CMAKE_HAVE_THREADS_LIBRARY.

Since we are only interested in knowing whether any threading library has
been found, we should use CMAKE_THREAD_LIBS_INIT instead (Threads_FOUND
would also work).

Note that, at the moment, there is only a pthreads backend available in
threads/, so if it is not found configuration will fail because CMake will
try to create a library from an empty set of source files.

Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2014-02-03 14:39:15 +01:00
Raphael Kubo da Costa
b049e12652 ConfigureChecks: Stop checking for CMAKE_HAVE_THREADS_LIBRARY.
libssh is primarily interested in whether pthreads is present and can be
used. Checking for CMAKE_HAVE_THREADS_LIBRARY is not the same thing, as
there are cases where pthread exists but CMAKE_HAVE_THREADS_LIBRARY is not
set (for example, FreeBSD passes -DTHREADS_HAVE_PTHREAD_ARG=1 to CMake by
default as a way to skip the checks for -lpthread, -lpthreads and others and
tell the build system that -pthread is the one expected to be used).

Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2014-02-03 14:39:14 +01:00
Jon Simons
785682ac28 socket: fix read of non-connected socket
Ensure to check whether the socket at hand is indeed still connected
throughout POLLIN processing in ssh_socket_pollcallback.

Before this change, the POLLIN block in ssh_socket_pollcallback is
predicated against the condition (s->state == SSH_SOCKET_CONNECTED).
Once entered, data from the socket is consumed through the data
callback in this loop:

  do {
    r = s->callbacks->data(buffer_get_rest(s->in_buffer),
                           buffer_get_rest_len(s->in_buffer),
                           s->callbacks->userdata);
    buffer_pass_bytes(s->in_buffer,r);
  } while (r > 0);

However, it is possible for the socket data callback to change the
state of the socket (closing it, for example).  Fix the loop to only
continue so long as the socket remains connected: this also entails
setting the ssh_socket state to SSH_SOCKET_CLOSED upon close.

The bug can be observed before the change by sending a bogus banner
to the server: 'echo -e "A\r\nB\r\n" | nc localhost 22'.  Each of
'A' and 'B' will be processed by 'callback_receive_banner', even
though the client socket is closed after rejection of 'A'.

Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2014-02-02 22:21:07 +01:00
Jon Simons
f29f10876a doc: correct ssh_channel_read_timeout units
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2014-02-02 22:21:07 +01:00
Audrius Butkevicius
45d28c7682 doc: Document expected return value of channel data callback
Signed-off-by: Audrius Butkevicius <audrius.butkevicius@gmail.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2014-02-02 22:21:07 +01:00
Audrius Butkevicius
2786565e77 src: Fix argument order in ssh_channel_pty_window_change_callback
So that it would match ssh_channel_pty_request_callback as well as the documentation

Signed-off-by: Audrius Butkevicius <audrius.butkevicius@gmail.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2014-02-02 22:21:07 +01:00
Joseph Southwell
96ad690c80 src: Define MAX_BUF_SIZE globally and use it.
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2014-02-02 22:21:07 +01:00
Joseph Southwell
0d82186503 client: Fix EOF session error reporting.
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2014-02-02 22:21:07 +01:00
Oleksandr Shneyder
5157d96958 Make function ssh_channel_accept() nonblocking if timeout is 0.
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2014-02-02 22:21:07 +01:00
Andreas Schneider
6a0787a366 pki_crypto: Fix memory leak with EC_KEY_set_public_key().
BUG: https://red.libssh.org/issues/146
2014-01-28 12:01:35 +01:00
Andreas Schneider
709e921942 doc: Document the unit for ssh_select() timeout.
BUG: https://red.libssh.org/issues/143
2014-01-23 11:29:58 +01:00
Rod Vagg
43a69b0a65 dh: Fix NULL check for p_group14.
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2014-01-23 11:22:22 +01:00
Jon Simons
18506f697c pki_crypto: fix DSA signature extraction
Fix the DSA portion of 'pki_signature_to_blob': before this change, it
is possible to sometimes observe DSA signature validation failure when
testing with OpenSSH clients.  The problem ended up being the following
snippet which did not account for the case when 'ssh_string_len(x)' may
be less than 20:

  r = make_bignum_string(sig->dsa_sig->r);
  ...
  memcpy(buffer,
         ((char *) ssh_string_data(r)) + ssh_string_len(r) - 20,
         20);

Above consider the case that ssh_string_len(r) is 19; in that case the
memcpy unintentionally starts in the wrong place.  The same situation
can happen for value 's' in this code.

To fix, adjust the offsets used for the input and output pointers, taking
into account that the lengths of 'r' and 's' can be less than 20.  With
the fix I am no longer able to reproduce the original failure mode.

BUG: https://red.libssh.org/issues/144

Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2014-01-23 11:17:45 +01:00
Alan Dunn
15bede0c0e doc: Fix description of error parameter for ssh_get_error*
ssh_get_error can actually work on anything with an ssh_common_struct
as its first member.  It is already used in examples in the
distribution with ssh_sessions and ssh_binds.

Signed-off-by: Alan Dunn <amdunn@gmail.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2014-01-22 09:46:00 +01:00
Jon Simons
92dde09a37 pki_crypto: pad RSA signature blobs
Pad RSA signature blobs to the expected RSA signature length
when processing via 'pki_signature_to_blob'.

Some clients, notably PuTTY, may send unpadded RSA signatures
during the public key exchange: before this change, one can
sometimes observe failure in signature validation when using
PuTTY's 'plink' client, along these lines:

   ssh_packet_process: ssh_packet_process: Dispatching handler for packet type 50
   ssh_packet_userauth_request: ssh_packet_userauth_request: Auth request for service ssh-connection, method publickey for user 'foo'
   ssh_pki_signature_verify_blob: ssh_pki_signature_verify_blob: Going to verify a ssh-rsa type signature
   pki_signature_verify: pki_signature_verify: RSA error: error:04091077:rsa routines:INT_RSA_VERIFY:wrong signature length
   ssh_packet_userauth_request: ssh_packet_userauth_request: Received an invalid  signature from peer

For cross-reference this issue once also existed between
PuTTY and OpenSSH:

  http://www.chiark.greenend.org.uk/~sgtatham/putty/wishlist/rsa-verify-failed.html

  http://www.openbsd.org/cgi-bin/cvsweb/src/usr.bin/ssh/ssh-rsa.c?rev=1.19;content-type=text%2Fx-cvsweb-markup

With the fix I am unable to reproduce the above failure mode when
testing with 'plink'.

Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2014-01-21 16:12:00 +01:00
Alan Dunn
809d76cbf2 Test change to ssh_bind_accept_fd
Signed-off-by: Alan Dunn <amdunn@gmail.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2014-01-21 16:08:12 +01:00
Alan Dunn
f78a74c160 Import keys during ssh_bind_accept_fd
Signed-off-by: Alan Dunn <amdunn@gmail.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2014-01-21 16:08:12 +01:00
Alan Dunn
b3b3045a81 Separate out key import functionality from ssh_bind_listen
Signed-off-by: Alan Dunn <amdunn@gmail.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2014-01-21 16:08:11 +01:00
Andreas Schneider
72fd3a73df doc: Fix channel documentation. 2014-01-17 11:09:07 +01:00
Jon Simons
cf19770ede bind: fix possible double-frees in ssh_bind_free
Make sure to explicitly set key pointers to NULL following the use
of 'ssh_key_free' throughout bind.c.

Before this change, a double free can happen via 'ssh_bind_free'
as in this example callpath:

  // create an ssh_bind
  ssh_bind b = ssh_bind_new();

  // provide a path to a wrong key-type
  ssh_bind_options_set(b, SSH_BIND_OPTIONS_DSAKEY, path_to_rsa_key);

  // initialize set key-type
  ssh_bind_listen(b);

    -> error path "The DSA host key has the wrong type: %d",

       ssh_key_free(sshbind->dsa)

         -> ssh_key_clean(key) // OK

         -> SAFE_FREE(key)     // OK, but, sshbind->dsa is *not* set to NULL

  // ssh_bind_listen failed, so clean up ssh_bind
  ssh_bind_free(b);

    -> ssh_key_free(sshbind->dsa)  // double-free here

To fix, set pointers to NULL that have been free'd with 'ssh_key_free'.

Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2014-01-16 09:27:55 +01:00
Andreas Schneider
7f42f5a3c9 cmake: Increase version numbers for 0.6.1. 2014-01-16 09:16:11 +01:00
Andreas Schneider
6223e05b23 doc: Use ssh_channel_accept_forward() in documentation. 2014-01-16 09:14:52 +01:00
Oleksandr Shneyder
634671db11 channel: Add ssh_channel_accept_forward().
This works same way as ssh_forward_accept() but can return a destination
port of the channel (useful if SSH connection forwarding several TCP/IP
ports).

Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2014-01-16 09:13:57 +01:00
Aris Adamantiadis
1f689261ec threads: support libgcrypt 1.6 hack
Not 100% satisfied of this patch, but the way libgcrypt handles
threading in 1.6 is not compatible with custom handlers. The
new code basicaly uses pthreads in every case. This will probably
not work on windows.
2014-01-08 22:06:38 +01:00
Andreas Schneider
4919771f0f ChangeLog: Set release date. 2014-01-08 11:17:12 +01:00
Andreas Schneider
8aad24c062 include: Remove warning cause VSC doesn't know about it. 2014-01-08 10:55:39 +01:00
Andreas Schneider
0e5510bb99 include: Fix building if we do not have asm volatile. 2014-01-08 10:52:57 +01:00
Andreas Schneider
de464cb74e src: Update my mail address. 2014-01-07 16:09:04 +01:00
Andreas Schneider
c41f32bcca cmake: Remove unused macro modules. 2014-01-07 16:09:02 +01:00
Aris Adamantiadis
61e701caaa update copyright information 2014-01-07 15:18:44 +01:00
Aris Adamantiadis
1c36642fed tests: avoid reading uninitialized bytes 2014-01-07 14:43:01 +01:00
Aris Adamantiadis
ad287371fb pki: fix gcrypt signature process 2014-01-07 14:21:15 +01:00
Andreas Schneider
ebfdfd9a14 examples: Make sure buffer is initialized. 2014-01-07 09:19:30 +01:00
Andreas Schneider
c9a1be5a85 example: Add missing include for forkpty(). 2014-01-07 09:04:06 +01:00
Aris Adamantiadis
fc0db4d982 test: fixed torture_auth_none condition 2014-01-06 22:10:23 +01:00
Aris Adamantiadis
8f1a350b6e test: test case for async auth_none
This test currently fails
2014-01-06 16:52:35 +01:00
Aris Adamantiadis
15ed51cf20 tests: auth_agent_nonblocking should run in nonblocking 2014-01-06 16:52:35 +01:00
Andreas Schneider
7b2e07ecbc session: Fix a possible memory leak. 2014-01-06 16:18:06 +01:00
Aris Adamantiadis
0404d45c29 poll: fix poll_handles ownerships 2014-01-06 16:18:06 +01:00
Aris Adamantiadis
f2215d14de socket: don't attempt reading a non-connected socket 2014-01-06 16:18:06 +01:00
Aris Adamantiadis
ebbf7988b9 tests: use LC_LIBSSH instead of LANG for env tests.
LANG is stripped and replaced on many distros and LC_* is accepted
by default on debian
2014-01-06 16:17:38 +01:00
Andreas Schneider
ec307d9862 examples: Fix building samplesshd-tty on FreeBSD. 2013-12-26 16:38:38 +01:00
Andreas Schneider
2068973ff3 poll: Correctly free ssh_event_fd_wrapper.
This is allocated by ssh_event_add_fd.
2013-12-22 22:26:51 +01:00
Andreas Schneider
6eea08a9ef config: Support expansion in the Host variable too.
BUG: https://red.libssh.org/issues/127
2013-12-21 14:37:55 +01:00
Andreas Schneider
3ba2e7ace7 tests: Fix non-blocking auth tests.
The ssh_userauth_none() call should already be non-blocking. However
this this function is broken in non-blocking mode. It should reveal the
existing bug.
2013-12-15 21:04:46 +01:00
Andreas Schneider
15c64b2981 tests: Use new auth API in the torture_session test. 2013-12-15 20:30:48 +01:00
Andreas Schneider
ce5d421753 tests: Use new auth API in the torture_auth test. 2013-12-15 20:26:59 +01:00
Andreas Schneider
fd77439a12 tests: Fix pki test with gcrypt. 2013-12-11 21:12:12 +01:00
Jon Simons
a633deb985 channel: fix setting of channel->flags
Fix the setting of 'channel->flags' to use '|='.  Before this
change, one bug symptom can be that channels are never fully
free'd via ssh_channel_free, resulting in memory leaks.

Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2013-12-11 21:03:45 +01:00
Jon Simons
50b9a182f5 client: use ssh_channel_do_free in ssh_disconnect
Ensure to use 'ssh_channel_do_free' in 'ssh_disconnect', when removing and
free'ing up a session's channels.  This matches the behavior in 'ssh_free',
and is necessary to fully free any channel which may not have been closed
completely (see usage of flags SSH_CHANNEL_FLAG_CLOSED_REMOTE,
SSH_CHANNEL_FLAG_FREED_LOCAL).

Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2013-12-11 21:03:43 +01:00
Andreas Schneider
bb88b637a9 bind: Correctly free all memory in ssh_bind_free().
Thanks to Jacob Baines.
2013-12-09 19:50:52 +01:00
Jon Simons
60d5824760 session: Add ssh_get_clientbanner(). 2013-12-07 16:24:53 +01:00
Andreas Schneider
397be918cd channels: Add a ssh_channel_read_timeout function. 2013-12-04 20:34:52 +01:00
Andreas Schneider
880fdb4b52 tests: Try to fix torture_forward. 2013-12-04 16:27:19 +01:00
Andreas Schneider
6a74677cef tests: Fix memory leaks. 2013-12-04 16:27:18 +01:00
Andreas Schneider
2c66eeaf75 pki: Fix a memory leak.
CID #1132819
2013-11-28 11:44:34 +01:00
Andreas Schneider
91edc0ee21 tests: Add torture_pki_write_privkey_ecdsa test. 2013-11-27 22:54:40 +01:00
Andreas Schneider
46bda45d95 tests: Add torture_pki_write_privkey_dsa test. 2013-11-27 22:54:40 +01:00
Andreas Schneider
9773c0852a tests: Add torture_pki_write_privkey_rsa test. 2013-11-27 22:54:40 +01:00
Andreas Schneider
f1c56e4309 pki: Add ssh_pki_import_privkey_file(). 2013-11-27 22:54:40 +01:00
Andreas Schneider
1fdc1025a8 pki_crypto: Add pki_private_key_to_pem(). 2013-11-27 22:54:40 +01:00
Andreas Schneider
a375b6c996 pki_gcrypt: Add pki_private_key_to_pem() stub. 2013-11-27 22:54:40 +01:00
Andreas Schneider
ecb01e05a2 curve25519: Fix memory leaks in ssh_server_curve25519_init().
CID #1125255
2013-11-27 22:53:53 +01:00
Andreas Schneider
b3911d0fa2 curve25519: Do not leak q_s_string.
CID #1125256
2013-11-27 22:53:53 +01:00
Andreas Schneider
1ee687ea6f curve25519: Fix a memory leak.
CID #1125257
2013-11-27 22:53:53 +01:00
Andreas Schneider
73e1f2691f examples: Fix else branch.
CID #1127816
2013-11-27 22:53:53 +01:00
Andreas Schneider
84e29f9c06 packet: Remove logically dead code.
CID #1128796
2013-11-27 22:53:53 +01:00
Andreas Schneider
23837b2080 tests: Try to fix valgrind warnings. 2013-11-27 22:53:53 +01:00
Andreas Schneider
4884f1d6fc tests: Fix a valgrind warning. 2013-11-27 22:53:53 +01:00
Andreas Schneider
ead1c4b168 ecdh: Check if we have ECC support. 2013-11-27 22:53:53 +01:00
Andreas Schneider
3e11cb8071 ecdh: Use bignum_bin2bn. 2013-11-27 22:53:48 +01:00
Nicolas Viennot
78e78642e7 server: Add a ssh_send_keepalive() function.
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2013-11-24 23:21:39 +01:00
Jon Simons
7ab0e3fe62 channel: fix infinite loop in channel_write_common
BUG: https://red.libssh.org/issues/130

Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2013-11-22 10:34:49 +01:00
Andreas Schneider
5da02d6de2 Update ChangeLog. 2013-11-19 10:29:59 +01:00
Rod Vagg
94db978218 flush channel after EOF and CLOSE 2013-11-18 17:23:52 +01:00
Aris Adamantiadis
78ea8608b0 logging: fix server-side logging 2013-11-18 15:28:59 +01:00
Aris Adamantiadis
7d9940d6eb gssapi: fix logging 2013-11-18 15:10:56 +01:00
Aris Adamantiadis
9f4fa22250 sockets: null pointer check 2013-11-18 14:42:06 +01:00
Simo Sorce
330f6c73f6 gssapi: Fix support of delegated credentials
In a previous refactoring patch, the code underpinning the
ssh_gssapi_set_creds() API was inadvertently removed. This patch
fixes the problem.

Also clarify what variable holds which credentials and insure that
credentials created within the library are propelry freed.

Signed-off-by: Simo Sorce <simo@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2013-11-17 11:43:52 +01:00
Simo Sorce
4a3934da48 gssapi: Add support for GSSAPIDelegateCredentials config option.
Signed-off-by: Simo Sorce <simo@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2013-11-17 11:43:52 +01:00
Simo Sorce
68b996bdbf options: Add SSH_OPTIONS_GSSAPI_DELEGATE_CREDENTIALS option.
Signed-off-by: Simo Sorce <simo@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2013-11-17 11:43:50 +01:00
Andreas Schneider
d364374422 gssapi: Add error checks and cleanup the code in ssh_gssapi_auth_mic(). 2013-11-15 16:29:49 +01:00
Simo Sorce
00af5bd582 gssapi: Use GSSAPIClientIdentity to acquire creds
Signed-off-by: Simo Sorce <simo@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2013-11-15 16:29:49 +01:00
Andreas Schneider
1ab5abf0e6 gssapi: Add support for GSSAPIClientIdentity config option. 2013-11-15 16:29:49 +01:00
Andreas Schneider
f5d1d813fb options: Add SSH_OPTIONS_GSSAPI_CLIENT_IDENTITY option. 2013-11-15 16:29:49 +01:00
Andreas Schneider
92928a7d8d gssapi: Add support for GSSAPIServerIdentity config option. 2013-11-15 16:29:49 +01:00
Andreas Schneider
651c173e72 gssapi: Add suppport to set GSSAPI server identity. 2013-11-15 16:29:49 +01:00
Simo Sorce
f76cd8b6d5 Fix gssapi credential handling.
- Properly acquire and inquitre credentials to get the list of available
credentials.
- Avoid enforcing a specific username it breaks some use cases (k5login).
- Remove confusing references to delegated credentials as there is no code
that actually uses delegated credentials in the initialization case.

Signed-off-by: Siom Sorce <simo@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2013-11-15 16:29:49 +01:00
Andreas Schneider
2bbeebd505 socket: Fix connect if we pass in a fd.
BUG: https://red.libssh.org/issues/106

Thanks to Saju Panikulam.
2013-11-15 08:54:18 +01:00
Andreas Schneider
fef32b4c14 packet: Remove dead code. 2013-11-14 11:44:12 +01:00
Andreas Schneider
2eaff2b363 packet: Set the packet to the processed data position.
Else we could end up with packet - current_macsize if to_be_read is 0.
2013-11-14 11:44:11 +01:00
Andreas Schneider
2b3e69fd5f dh: Fix wrong assignment.
Ups, sorry.
2013-11-14 08:09:42 +01:00
Andreas Schneider
cd992a90fb poll: Fix realloc in ssh_poll_ctx_resize(). 2013-11-13 16:29:41 +01:00
Andreas Schneider
6ea111fd8a dh: Avoid possible memory leaks with realloc. 2013-11-13 16:29:41 +01:00
Andreas Schneider
cda641176d packet: Refactor ssh_packet_socket_callback().
Make error checking more readable and add additional NULL checks.
2013-11-13 16:29:41 +01:00
Andreas Schneider
5581645500 server: Fix malloc call. 2013-11-13 16:29:41 +01:00
Colin Walters
3e64ef3bf5 session: Always request POLLIN
The assumption is that if libssh functions are being invoked, we want
to read data.

Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2013-11-09 12:29:26 +01:00
Colin Walters
7372cd837a Add ssh_get_poll_flags()
For integration with an external mainloop, we need to know how to
replicate libssh's internal poll() calls.  We originally through
ssh_get_status() was that API, but it's not really - those flags only
get updated from the *result* of a poll(), where what we really need
is to know how libssh would *start* a poll().

Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2013-11-09 12:29:25 +01:00
Colin Walters
1ecf7003f6 client: If we have a pre-connected FD, set state to SOCKET_CONNECTED
Otherwise applications providing their own fd end up tripping an
assertion, since the session is just in _CONNECTING.

Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2013-11-09 12:29:24 +01:00
Andreas Schneider
70c54d9445 example: Use ssh_get_publickey_hash(). 2013-11-06 17:11:26 +01:00
Andreas Schneider
e52ff2c8ff dh: Move ssh_get_hexa() and ssh_print_hexa() down.
This way they are in the documentation block for the session and we get
documentation for them.
2013-11-06 17:11:25 +01:00
Andreas Schneider
9bf9d52e21 dh: Add new ssh_get_publickey_hash() function. 2013-11-06 17:11:24 +01:00
Andreas Schneider
965000129e doc: Fix doxygen warnings. 2013-11-04 21:55:58 +01:00
Aris Adamantiadis
0940c6f1b0 Fix cast warnings on 64bits 2013-11-04 10:51:17 +01:00
Aris Adamantiadis
2e6dbe8d3d remove warnings on OSX (workaround) 2013-11-04 10:51:09 +01:00
Aris Adamantiadis
8bf6907c1d curve25519: include reference implementation 2013-11-03 14:58:47 +01:00
Aris Adamantiadis
6e9e13cc24 examples: fix forktty() warning on OSX 2013-11-03 14:09:28 +01:00
Aris Adamantiadis
5bc32bfd88 Fix examples compilation on OSX (libargp) 2013-11-03 13:51:03 +01:00
Aris Adamantiadis
7c8a793b0a socket: Fix check for pending data.
BUG: https://red.libssh.org/issues/119

Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2013-11-03 12:48:12 +01:00
Nicolas Viennot
e9b0a8210d server: Fix ssh_execute_server_callbacks() client execution
When the public key auth handler is executed and returns SSH_OK,
ssh_execute_server_callbacks() still runs some client callbacks,
which may set rc to SSH_AGAIN, which triggers a default reply on
auth, denying auth.

Signed-off-by: Nicolas Viennot <nicolas@viennot.biz>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2013-11-03 10:53:44 +01:00
Nicolas Viennot
fb63887c16 server kex: enable delayed compression
The code is careful to reenable compression when rekeying.

Signed-off-by: Nicolas Viennot <nicolas@viennot.biz>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2013-11-03 10:53:42 +01:00
Andreas Schneider
b113b78dfc session: Make sure we correctly burn the buffer. 2013-11-03 10:53:41 +01:00
Andreas Schneider
646112b4e4 wrapper: Make sure we really burn the buffer. 2013-11-03 10:53:40 +01:00
Andreas Schneider
ba4346f089 priv: Fix brackets of burn macros. 2013-11-03 10:53:38 +01:00
Jon Simons
401865d725 server: fix pubkey reply for key probes
Per RFC 4252, it is required to send back only one of either
SSH_MSG_USERAUTH_PK_OK or SSH_MSG_USERAUTH_FAILURE for public
key probes.

Update the handling of 'auth_pubkey_function' to send back PK_OK
instead of SSH_MSG_USERAUTH_SUCCESS for the case that the state
of the message at hand is SSH_PUBLICKEY_STATE_NONE.

With this change, it is now possible to process an initial key probe
and then subsequent signature validation using the server callbacks.

Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2013-11-02 21:03:20 +01:00
William Orr
d312af1ed5 ssh_options_get can now return ProxyCommand
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2013-11-02 21:03:19 +01:00
Jon Simons
3cfd8a126b connect: fix memory leak in ssh_select
Balance 'ssh_event_add_fd' with 'ssh_event_remove_fd' in 'ssh_select'.

BUG: https://red.libssh.org/issues/128

Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2013-10-31 12:48:56 +01:00
Andreas Schneider
24ebbb8b39 tests: Add a test for ssh_channel(). 2013-10-31 12:48:55 +01:00
Jon Simons
447ee309b0 poll: fix leak in ssh_poll_ctx_free
Fix a memory leak in 'ssh_poll_ctx_free': issue 'ssh_poll_free'
to remove the poll handle from its context and free it.

BUG: https://red.libssh.org/issues/128

Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2013-10-31 11:55:27 +01:00
Alan Dunn
6c213c913b SSH_AUTH_OK -> SSH_AUTH_SUCCESS in comments
A few callback descriptions refer to a non-existent value SSH_AUTH_OK,
which should be SSH_AUTH_SUCCESS.  This commit fixes these.

Signed-off-by: Alan Dunn <amdunn@gmail.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2013-10-31 08:19:35 +01:00
Andreas Schneider
f8f6eb0ce6 cmake: Check for isblank(). 2013-10-30 17:33:32 +01:00
Jon Simons
54f89af6d3 bind: fix leak in ssh_bind_accept error path
Use 'ssh_socket_free' to cleanup if 'ssh_bind_accept_fd'
fails, to be sure to free the ssh_socket in/out buffers.
2013-10-24 10:37:59 +02:00
Andreas Schneider
0e4a1b1f66 tests: Add a sftp_read blocking test. 2013-10-23 15:54:40 +02:00
Colin Walters
5eeadf533f auth: docs: Fix typo optoins -> options
I'm just getting my feet wet with this codebase.

Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2013-10-23 09:55:39 +02:00
Andreas Schneider
a4e2e01d3e doc: Improve sftp_read_sync() example. 2013-10-23 09:55:38 +02:00
Andreas Schneider
3911046f7e include: Fix build on platforms without ECC. 2013-10-21 07:16:26 +02:00
Andreas Schneider
2727af0fe6 tests: Add a test for ssh_channel_request_env(). 2013-10-20 17:06:23 +02:00
Andreas Schneider
c42da23348 tests: We can't test the accept right now. 2013-10-20 17:06:22 +02:00
Andreas Schneider
e0adcea90d tests: Fix torture_forward. 2013-10-20 17:06:21 +02:00
Andreas Schneider
a62399fcd5 channel: Reinit the buffer and reset the state on error.
BUG: https://red.libssh.org/issues/126
2013-10-20 12:47:17 +02:00
Andreas Schneider
0ee68ac2a1 channel: Fix ssh_global_request_termination().
BUG: https://red.libssh.org/issues/126
2013-10-20 12:47:16 +02:00
Andreas Schneider
796d285eaf tests: Add torture forward test. 2013-10-20 12:47:16 +02:00
Andreas Schneider
b5f71f35a3 pki: Don't leak a buffer. 2013-10-19 10:42:18 +02:00
Andreas Schneider
b98ea81903 wrapper: Fix compilation with gcrypt. 2013-10-19 10:39:44 +02:00
Andreas Schneider
beeca3c650 pki_crpypto: Fix ecdsa signature to blob.
BUG: https://red.libssh.org/issues/118
2013-10-18 23:50:09 +02:00
Andreas Schneider
9f5abdb526 pki: Add support for ECDSA private key signing. 2013-10-18 23:50:08 +02:00
Andreas Schneider
02f80eb288 pki: Add the type as a char pointer. 2013-10-18 23:50:08 +02:00
Andreas Schneider
5b7f07b484 wrapper: Add more evp functions. 2013-10-18 23:50:06 +02:00
Andreas Schneider
ec5278e34d client: Fix the build. 2013-10-18 21:19:33 +02:00
Oliver Stöneberg
e554f0dc0d scp: Fixed result of ssh_scp_string_mode() to get SCP working.
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2013-10-18 14:59:01 +02:00
Oliver Stöneberg
e8e1916d2e client: Added a missing NULL pointer check.
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2013-10-18 14:58:59 +02:00
Andreas Schneider
58893352b0 doc: Make sure we have the defines to build all docs. 2013-10-14 15:40:18 +02:00
Aris Adamantiadis
cdcc92e344 Compile libssh with nacl if possible
Conflicts:
	DefineOptions.cmake
2013-10-06 17:43:53 +02:00
Andreas Schneider
29b3a94032 channel: Fix packets termination timeout in global_request().
BUG: https://red.libssh.org/issues/126
2013-10-01 14:51:55 +02:00
Andreas Schneider
8f2b26a837 session: Try the ecdsa default key first. 2013-10-01 14:48:20 +02:00
Andreas Schneider
42c07f379d channels: Correctly handle timeouts in channel functions. 2013-10-01 14:47:58 +02:00
Andreas Schneider
f79c4fd7a3 channel: Use the correct timeout option in channel_open().
BUG: https://red.libssh.org/issues/124
2013-10-01 14:47:58 +02:00
Andreas Schneider
7b2aee90f0 callbacks: Improve the documentation of ssh_threads_set_callbacks().
BUG: https://red.libssh.org/issues/123
2013-10-01 14:47:58 +02:00
Andreas Schneider
aaacd18031 callbacks: Improve the documentation of ssh_threads_get_noop().
BUG: https://red.libssh.org/issues/123
2013-10-01 14:47:58 +02:00
Andreas Schneider
9f60352497 session: Document return value of ssh_get_serverbanner().
BUG: https://red.libssh.org/issues/122
2013-10-01 14:47:58 +02:00
Andreas Schneider
70c796e8b8 session: Remove obsolete status variables.
BUG: https://red.libssh.org/issues/121
2013-10-01 14:47:57 +02:00
Andreas Schneider
5b7a696cf2 client: Add example code for ssh_get_openssh_version().
BUG: https://red.libssh.org/issues/120
2013-10-01 14:47:57 +02:00
Andreas Schneider
c59568c3c1 channels: Correctly decrement timeout value in ssh_channel_accept().
BUG: https://red.libssh.org/issues/116
2013-10-01 14:47:57 +02:00
Andreas Schneider
6f10422685 channel: Document SSH_AGAIN in ssh_channel_read().
BUG: https://red.libssh.org/issues/115
2013-10-01 14:47:57 +02:00
Andreas Schneider
44f851d287 cmake: Allow to build without examples.
BUG: https://red.libssh.org/issues/114
2013-10-01 14:47:57 +02:00
Andreas Schneider
3d158fffa0 doc: Improve the PKI documentation a bit. 2013-10-01 14:47:57 +02:00
Andreas Schneider
c8be0201c6 doc: Update documentation of ssh_set_blocking().
This should work correctly in libssh 0.6.0. If not then you hit a bug.
2013-10-01 14:47:57 +02:00
Tristan CACQUERAY
a8969c4be6 callbacks: add support for auth_none_function 2013-09-27 16:06:09 +02:00
Aris Adamantiadis
8ec8d35e1a doc: Documentation of curve25519-sha256@libssh.org 2013-09-27 16:06:09 +02:00
Aris Adamantiadis
666db37e21 kex: implement curve25519-sha256@libssh.org 2013-09-27 16:06:09 +02:00
Andreas Schneider
391bd88355 scp: Document more scp functionts. 2013-08-12 11:25:15 +02:00
Andreas Schneider
5f90b77a1b cmake: Update libssh version. 2013-08-07 17:33:03 +02:00
178 changed files with 5388 additions and 16102 deletions

View File

@@ -4,8 +4,6 @@
-DWITH_SFTP=1
-DWITH_SSH1=1
-DWITH_PCAP=1
-DHAVE_ECDH=1
-DHAVE_ECC=1
-Iinclude/libssh
-Iinclude
-Ibuild

4
.gitignore vendored
View File

@@ -3,7 +3,7 @@
.*
*.swp
*~$
build
cscope.*
tags
/build
/obj*
build

View File

@@ -1,14 +1,14 @@
project(libssh C)
# Required cmake version
cmake_minimum_required(VERSION 2.8.5)
cmake_minimum_required(VERSION 2.6.0)
# global needed variables
set(APPLICATION_NAME ${PROJECT_NAME})
set(APPLICATION_VERSION_MAJOR "0")
set(APPLICATION_VERSION_MINOR "7")
set(APPLICATION_VERSION_PATCH "7")
set(APPLICATION_VERSION_MINOR "6")
set(APPLICATION_VERSION_PATCH "4")
set(APPLICATION_VERSION "${APPLICATION_VERSION_MAJOR}.${APPLICATION_VERSION_MINOR}.${APPLICATION_VERSION_PATCH}")
@@ -19,12 +19,12 @@ set(APPLICATION_VERSION "${APPLICATION_VERSION_MAJOR}.${APPLICATION_VERSION_MINO
# Increment AGE. Set REVISION to 0
# If the source code was changed, but there were no interface changes:
# Increment REVISION.
set(LIBRARY_VERSION "4.4.4")
set(LIBRARY_VERSION "4.5.0")
set(LIBRARY_SOVERSION "4")
# where to look first for cmake modules, before ${CMAKE_ROOT}/Modules/ is checked
set(CMAKE_MODULE_PATH
${CMAKE_CURRENT_SOURCE_DIR}/cmake/Modules
${CMAKE_SOURCE_DIR}/cmake/Modules
)
# add definitions
@@ -84,8 +84,8 @@ add_subdirectory(include)
add_subdirectory(src)
# pkg-config file
if (UNIX)
configure_file(libssh.pc.cmake ${CMAKE_CURRENT_BINARY_DIR}/libssh.pc)
configure_file(libssh_threads.pc.cmake ${CMAKE_CURRENT_BINARY_DIR}/libssh_threads.pc)
install(
FILES
${CMAKE_CURRENT_BINARY_DIR}/libssh.pc
@@ -96,20 +96,6 @@ install(
pkgconfig
)
if (LIBSSH_THREADS)
configure_file(libssh_threads.pc.cmake ${CMAKE_CURRENT_BINARY_DIR}/libssh_threads.pc)
install(
FILES
${CMAKE_CURRENT_BINARY_DIR}/libssh.pc
${CMAKE_CURRENT_BINARY_DIR}/libssh_threads.pc
DESTINATION
${LIB_INSTALL_DIR}/pkgconfig
COMPONENT
pkgconfig
)
endif (LIBSSH_THREADS)
endif (UNIX)
# cmake config files
set(LIBSSH_LIBRARY_NAME ${CMAKE_SHARED_LIBRARY_PREFIX}ssh${CMAKE_SHARED_LIBRARY_SUFFIX})
set(LIBSSH_THREADS_LIBRARY_NAME ${CMAKE_SHARED_LIBRARY_PREFIX}ssh${CMAKE_SHARED_LIBRARY_SUFFIX})

View File

@@ -4,10 +4,10 @@
### general settings
set(CPACK_PACKAGE_NAME ${APPLICATION_NAME})
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "The SSH library")
set(CPACK_PACKAGE_DESCRIPTION_FILE "${CMAKE_CURRENT_SOURCE_DIR}/README")
set(CPACK_PACKAGE_DESCRIPTION_FILE "${CMAKE_SOURCE_DIR}/README")
set(CPACK_PACKAGE_VENDOR "The SSH Library Development Team")
set(CPACK_PACKAGE_INSTALL_DIRECTORY ${CPACK_PACKAGE_NAME})
set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/COPYING")
set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_SOURCE_DIR}/COPYING")
### versions
@@ -18,8 +18,8 @@ set(CPACK_PACKAGE_VERSION "${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSIO
### source generator
set(CPACK_SOURCE_GENERATOR "TXZ")
set(CPACK_SOURCE_IGNORE_FILES "~$;[.]swp$;/[.]git/;.gitignore;/build*;/obj*;tags;cscope.*")
set(CPACK_SOURCE_GENERATOR "TGZ")
set(CPACK_SOURCE_IGNORE_FILES "~$;[.]swp$;/[.]svn/;/[.]git/;.gitignore;/build/;/obj/;tags;cscope.*")
set(CPACK_SOURCE_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME}-${CPACK_PACKAGE_VERSION}")
if (WIN32)

View File

@@ -3,7 +3,7 @@ set(UPDATE_TYPE "true")
set(CTEST_PROJECT_NAME "libssh")
set(CTEST_NIGHTLY_START_TIME "01:00:00 UTC")
set(CTEST_DROP_METHOD "https")
set(CTEST_DROP_METHOD "http")
set(CTEST_DROP_SITE "test.libssh.org")
set(CTEST_DROP_LOCATION "/submit.php?project=libssh")
set(CTEST_DROP_SITE_CDASH TRUE)

View File

@@ -1,74 +1,6 @@
ChangeLog
==========
version 0.7.7 (released 2018-10-29)
* Fixed issues with MSVC
* Fixed keyboard-interactive auth in server mode
(regression from CVE-2018-10933)
* Fixed gssapi auth in server mode (regression from CVE-2018-10933)
* Fixed a memory leak with OpenSSL
version 0.7.6 (released 2018-10-16)
* Fixed CVE-2018-10933
* Added support for OpenSSL 1.1
* Added SHA256 support for ssh_get_publickey_hash()
* Fixed config parsing
* Fixed random memory corruption when importing pubkeys
version 0.7.5 (released 2017-04-13)
* Fixed a memory allocation issue with buffers
* Fixed PKI on Windows
* Fixed some SSHv1 functions
* Fixed config hostname expansion
version 0.7.4 (released 2017-02-03)
* Added id_ed25519 to the default identity list
* Fixed sftp EOF packet handling
* Fixed ssh_send_banner() to confirm with RFC 4253
* Fixed some memory leaks
version 0.7.3 (released 2016-01-23)
* Fixed CVE-2016-0739
* Fixed ssh-agent on big endian
* Fixed some documentation issues
version 0.7.2 (released 2015-09-15)
* Fixed OpenSSL detection on Windows
* Fixed return status for ssh_userauth_agent()
* Fixed KEX to prefer hmac-sha2-256
* Fixed sftp packet handling
* Fixed return values of ssh_key_is_(public|private)
* Fixed bug in global success reply
version 0.7.1 (released 2015-06-30)
* Fixed SSH_AUTH_PARTIAL auth with auto public key
* Fixed memory leak in session options
* Fixed allocation of ed25519 public keys
* Fixed channel exit-status and exit-signal
* Reintroduce ssh_forward_listen()
version 0.7.0 (released 2015-05-11)
* Added support for ed25519 keys
* Added SHA2 algorithms for HMAC
* Added improved and more secure buffer handling code
* Added callback for auth_none_function
* Added support for ECDSA private key signing
* Added more tests
* Fixed a lot of bugs
* Improved API documentation
version 0.6.5 (released 2015-04-29)
* Fixed CVE-2015-3146
* Fixed port handling in config file
* Fixed the build with libgcrypt
* Fixed SFTP endian issues (rlo #179)
* Fixed uninitilized sig variable (rlo #167)
* Fixed polling issues which could result in a hang
* Fixed handling of EINTR in ssh_poll() (rlo #186)
* Fixed C99 issues with __func__
* Fixed some memory leaks
* Improved macro detection on Windows
version 0.6.4 (released 2014-12-19)
* Fixed CVE-2014-8132.
* Added SHA-2 for session ID signing with ECDSA keys.

59
CodingStyle Normal file
View File

@@ -0,0 +1,59 @@
Coding Style Conventions
========================
Coding style guidelines are about reducing the number of unnecessary
reformatting patches and making things easier for developers to work together.
You don't have to like them or even agree with them, but once put in place we
all have to abide by them (or vote to change them). However, coding style
should never outweigh coding itself and so the guidelines described here are
hopefully easy enough to follow as they are very common and supported by tools
and editors.
The basic style for C code is the Linux kernel coding style [1] with one
excecption, we use 4 spaces instead of tabs. This closely matches what most
libssh developers use already anyways, with a few exceptions as mentioned
below.
To shorthen this here are the highlights:
* Maximum line width is 80 characters
The reason is not about people with low-res screens but rather sticking
to 80 columns prevents you from easily nesting more than one level of
if statements or other code blocks.
* Use 4 spaces to indent
* No trailing whitespaces
* Follow the K&R guidelines. We won't go through all of them here. Do you
have a copy of "The C Programming Language" anyways right?
Editors
========
VIM
----
set ts=4 sw=4 et cindent
For Vim, the following settings in $HOME/.vimrc will also deal with
displaying trailing whitespace:
if has("syntax") && (&t_Co > 2 || has("gui_running"))
syntax on
function! ActivateInvisibleCharIndicator()
syntax match TrailingSpace "[ \t]\+$" display containedin=ALL
highlight TrailingSpace ctermbg=Red
endf
autocmd BufNewFile,BufRead * call ActivateInvisibleCharIndicator()
endif
" Show tabs, trailing whitespace, and continued lines visually
set list listchars=tab:»·,trail:·,extends:…
" highlight overly long lines same as TODOs.
set textwidth=80
autocmd BufNewFile,BufRead *.c,*.h exec 'match Todo /\%>' . &textwidth . 'v.\+/'
[1] https://www.kernel.org/doc/Documentation/CodingStyle

View File

@@ -1,5 +1,4 @@
include(CheckIncludeFile)
include(CheckIncludeFiles)
include(CheckSymbolExists)
include(CheckFunctionExists)
include(CheckLibraryExists)
@@ -49,15 +48,10 @@ endif(CMAKE_COMPILER_IS_GNUCC AND NOT MINGW AND NOT OS2)
# HEADER FILES
check_include_file(argp.h HAVE_ARGP_H)
check_include_file(pty.h HAVE_PTY_H)
check_include_file(utmp.h HAVE_UTMP_H)
check_include_file(termios.h HAVE_TERMIOS_H)
check_include_file(unistd.h HAVE_UNISTD_H)
check_include_file(util.h HAVE_UTIL_H)
check_include_file(libutil.h HAVE_LIBUTIL_H)
check_include_file(sys/time.h HAVE_SYS_TIME_H)
check_include_file(sys/param.h HAVE_SYS_PARAM_H)
check_include_file(arpa/inet.h HAVE_ARPA_INET_H)
check_include_file(byteswap.h HAVE_BYTESWAP_H)
if (WIN32)
check_include_files("winsock2.h;ws2tcpip.h;wspiapi.h" HAVE_WSPIAPI_H)
@@ -67,35 +61,23 @@ if (WIN32)
check_include_files("winsock2.h;ws2tcpip.h" HAVE_WS2TCPIP_H)
endif (WIN32)
if (OPENSSL_FOUND)
set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR})
check_include_file(openssl/des.h HAVE_OPENSSL_DES_H)
if (NOT HAVE_OPENSSL_DES_H)
message(FATAL_ERROR "Could not detect openssl/des.h")
endif()
set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIRS})
check_include_file(openssl/aes.h HAVE_OPENSSL_AES_H)
set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR})
check_include_file(openssl/aes.h HAVE_OPENSSL_AES_H)
if (NOT HAVE_OPENSSL_AES_H)
message(FATAL_ERROR "Could not detect openssl/aes.h")
endif()
set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIRS})
check_include_file(openssl/blowfish.h HAVE_OPENSSL_BLOWFISH_H)
set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR})
check_include_file(openssl/blowfish.h HAVE_OPENSSL_BLOWFISH_H)
set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIRS})
check_include_file(openssl/des.h HAVE_OPENSSL_DES_H)
set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR})
check_include_file(openssl/ecdh.h HAVE_OPENSSL_ECDH_H)
set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIRS})
check_include_file(openssl/ecdh.h HAVE_OPENSSL_ECDH_H)
set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR})
check_include_file(openssl/ec.h HAVE_OPENSSL_EC_H)
set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIRS})
check_include_file(openssl/ec.h HAVE_OPENSSL_EC_H)
set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR})
check_include_file(openssl/ecdsa.h HAVE_OPENSSL_ECDSA_H)
set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR})
set(CMAKE_REQUIRED_LIBRARIES ${OPENSSL_CRYPTO_LIBRARY})
check_function_exists(CRYPTO_ctr128_encrypt HAVE_OPENSSL_CRYPTO_CTR128_ENCRYPT)
endif()
set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIRS})
check_include_file(openssl/ecdsa.h HAVE_OPENSSL_ECDSA_H)
if (CMAKE_HAVE_PTHREAD_H)
set(HAVE_PTHREAD_H 1)
@@ -115,48 +97,34 @@ endif (NOT WITH_GCRYPT)
check_function_exists(isblank HAVE_ISBLANK)
check_function_exists(strncpy HAVE_STRNCPY)
check_function_exists(strndup HAVE_STRNDUP)
check_function_exists(strtoull HAVE_STRTOULL)
if (NOT WIN32)
check_function_exists(vsnprintf HAVE_VSNPRINTF)
check_function_exists(snprintf HAVE_SNPRINTF)
endif (NOT WIN32)
check_function_exists(vsnprintf HAVE_VSNPRINTF)
check_function_exists(snprintf HAVE_SNPRINTF)
check_function_exists(poll HAVE_POLL)
check_function_exists(select HAVE_SELECT)
check_function_exists(getaddrinfo HAVE_GETADDRINFO)
check_function_exists(ntohll HAVE_NTOHLL)
check_function_exists(htonll HAVE_HTONLL)
if (WIN32)
check_symbol_exists(vsnprintf "stdio.h" HAVE_VSNPRINTF)
check_symbol_exists(snprintf "stdio.h" HAVE_SNPRINTF)
check_symbol_exists(_vsnprintf_s "stdio.h" HAVE__VSNPRINTF_S)
check_symbol_exists(_vsnprintf "stdio.h" HAVE__VSNPRINTF)
check_symbol_exists(_snprintf "stdio.h" HAVE__SNPRINTF)
check_symbol_exists(_snprintf_s "stdio.h" HAVE__SNPRINTF_S)
if (HAVE_WSPIAPI_H OR HAVE_WS2TCPIP_H)
check_symbol_exists(ntohll winsock2.h HAVE_NTOHLL)
check_symbol_exists(htonll winsock2.h HAVE_HTONLL)
set(CMAKE_REQUIRED_LIBRARIES ws2_32)
check_symbol_exists(select "winsock2.h;ws2tcpip.h" HAVE_SELECT)
check_symbol_exists(poll "winsock2.h;ws2tcpip.h" HAVE_SELECT)
# The getaddrinfo function is defined to the WspiapiGetAddrInfo inline function
check_symbol_exists(getaddrinfo "winsock2.h;ws2tcpip.h" HAVE_GETADDRINFO)
set(CMAKE_REQUIRED_LIBRARIES)
endif (HAVE_WSPIAPI_H OR HAVE_WS2TCPIP_H)
check_function_exists(_strtoui64 HAVE__STRTOUI64)
check_function_exists(_vsnprintf_s HAVE__VSNPRINTF_S)
check_function_exists(_vsnprintf HAVE__VSNPRINTF)
check_function_exists(_snprintf HAVE__SNPRINTF)
check_function_exists(_snprintf_s HAVE__SNPRINTF_S)
if (HAVE_WSPIAPI_H OR HAVE_WS2TCPIP_H)
set(HAVE_GETADDRINFO TRUE)
set(HAVE_GETHOSTBYNAME TRUE)
if (MSVC)
set(HAVE_NTOHLL TRUE)
set(HAVE_HTONLL TRUE)
endif (MSVC)
endif (HAVE_WSPIAPI_H OR HAVE_WS2TCPIP_H)
set(HAVE_SELECT TRUE)
else (WIN32)
check_function_exists(poll HAVE_POLL)
check_function_exists(select HAVE_SELECT)
check_function_exists(getaddrinfo HAVE_GETADDRINFO)
check_symbol_exists(ntohll arpa/inet.h HAVE_NTOHLL)
check_symbol_exists(htonll arpa/inet.h HAVE_HTONLL)
endif (WIN32)
if (UNIX)
if (NOT LINUX)
# libsocket (Solaris)
@@ -183,6 +151,7 @@ if (UNIX)
check_library_exists(util forkpty "" HAVE_LIBUTIL)
check_function_exists(cfmakeraw HAVE_CFMAKERAW)
check_function_exists(strtoull HAVE_STRTOULL)
check_function_exists(__strtoull HAVE___STRTOULL)
endif (UNIX)
@@ -232,33 +201,6 @@ int main(void)
return 0;
}" HAVE_GCC_VOLATILE_MEMORY_PROTECTION)
check_c_source_compiles("
#include <stdio.h>
#define __VA_NARG__(...) (__VA_NARG_(_0, ## __VA_ARGS__, __RSEQ_N()) - 1)
#define __VA_NARG_(...) __VA_ARG_N(__VA_ARGS__)
#define __VA_ARG_N( _1, _2, _3, _4, _5, _6, _7, _8, _9,_10,N,...) N
#define __RSEQ_N() 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0
#define myprintf(format, ...) printf((format), __VA_NARG__(__VA_ARGS__), __VA_ARGS__)
int main(void) {
myprintf(\"%d %d %d %d\",1,2,3);
return 0;
}" HAVE_GCC_NARG_MACRO)
check_c_source_compiles("
#include <stdio.h>
int main(void) {
printf(\"%s\", __func__);
return 0;
}" HAVE_COMPILER__FUNC__)
check_c_source_compiles("
#include <stdio.h>
int main(void) {
printf(\"%s\", __FUNCTION__);
return 0;
}" HAVE_COMPILER__FUNCTION__)
if (WITH_DEBUG_CRYPTO)
set(DEBUG_CRYPTO 1)
endif (WITH_DEBUG_CRYPTO)

125
README
View File

@@ -33,11 +33,130 @@ If you ask yourself how to compile libssh, please read INSTALL before anything.
http://www.libssh.org
4* Contributing
4* API Changes !
-_-_-_-_-_-_-_-_-_
Please read the file 'SubmittingPatches' next to this README file. It explains
our copyright policy and how you should send patches for upstream inclusion.
Changes between 0.4 and 0.5
---------------------------
We use the ssh_ prefix as namespace for every function now. There is a legacy.h
which could be used to get the old function names.
Changes between 0.3 and 0.4
---------------------------
We changed libssh to be typesafe now:
SSH_SESSION *session -> ssh_session session
SFTP_SESSION *sftp -> sftp_session sftp
CHANNEL *channel -> ssh_channel channel
STRING *string -> ssh_string string
...
The options structure has been removed and there is a new function. This
function can set all available options now. You can find the enum in the
header file and it is documented. Example:
ssh_options_set(session, SSH_OPTIONS_HOST, "localhost");
5* Copyright policy
-_-_-_-_-_-_-_-_-_-_
libssh is a project with distributed copyright ownership, which means we prefer
the copyright on parts of libssh to be held by individuals rather than
corporations if possible. There are historical legal reasons for this, but one
of the best ways to explain it is that its much easier to work with
individuals who have ownership than corporate legal departments if we ever need
to make reasonable compromises with people using and working with libssh.
We track the ownership of every part of libssh via git, our source code control
system, so we know the provenance of every piece of code that is committed to
libssh.
So if possible, if youre doing libssh changes on behalf of a company who
normally owns all the work you do please get them to assign personal copyright
ownership of your changes to you as an individual, that makes things very easy
for us to work with and avoids bringing corporate legal departments into the
picture.
If you cant do this we can still accept patches from you owned by your
employer under a standard employment contract with corporate copyright
ownership. It just requires a simple set-up process first.
We use a process very similar to the way things are done in the Linux Kernel
community, so it should be very easy to get a sign off from your corporate
legal department. The only changes weve made are to accommodate the license we
use, which is LGPLv2 (or later) whereas the Linux kernel uses GPLv2.
The process is called signing.
How to sign your work
----------------------
Once you have permission to contribute to libssh from your employer, simply
email a copy of the following text from your corporate email address to:
contributing@libssh.org
--------------------------------------------------------------------------
libssh Developer's Certificate of Origin. Version 1.0
By making a contribution to this project, I certify that:
(a) The contribution was created in whole or in part by me and I
have the right to submit it under the appropriate
version of the GNU General Public License; or
(b) The contribution is based upon previous work that, to the best of
my knowledge, is covered under an appropriate open source license
and I have the right under that license to submit that work with
modifications, whether created in whole or in part by me, under
the GNU General Public License, in the appropriate version; or
(c) The contribution was provided directly to me by some other
person who certified (a) or (b) and I have not modified it.
(d) I understand and agree that this project and the contribution are
public and that a record of the contribution (including all
metadata and personal information I submit with it, including my
sign-off) is maintained indefinitely and may be redistributed
consistent with the libssh Team's policies and the requirements of
the GNU GPL where they are relevant.
(e) I am granting this work to this project 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 the option of the project) any later version.
http://www.gnu.org/licenses/lgpl-2.1.html
--------------------------------------------------------------------------
We will maintain a copy of that email as a record that you have the rights to
contribute code to libssh under the required licenses whilst working for the
company where the email came from.
Then when sending in a patch via the normal mechanisms described above, add a
line that states:
Signed-off-by: Random J Developer <random@developer.example.org>
using your real name and the email address you sent the original email you used
to send the libssh Developers Certificate of Origin to us (sorry, no
pseudonyms or anonymous contributions.)
Thats it! Such code can then quite happily contain changes that have copyright
messages such as:
(c) Example Corporation.
and can be merged into the libssh codebase in the same way as patches from any
other individual. You dont need to send in a copy of the libssh Developers
Certificate of Origin for each patch, or inside each patch. Just the sign-off
message is all that is required once weve received the initial email.
Have fun and happy libssh hacking!

View File

@@ -1,354 +0,0 @@
Coding conventions in the libssh tree
======================================
===========
Quick Start
===========
Coding style guidelines are about reducing the number of unnecessary
reformatting patches and making things easier for developers to work together.
You don't have to like them or even agree with them, but once put in place we
all have to abide by them (or vote to change them). However, coding style
should never outweigh coding itself and so the guidelines described here are
hopefully easy enough to follow as they are very common and supported by tools
and editors.
The basic style for C code, is the Linux kernel coding style (See
Documentation/CodingStyle in the kernel source tree). This closely matches what
libssh developers use already anyways, with a few exceptions as mentioned
below.
But to save you the trouble of reading the Linux kernel style guide, here
are the highlights.
* Maximum Line Width is 80 Characters
The reason is not about people with low-res screens but rather sticking
to 80 columns prevents you from easily nesting more than one level of
if statements or other code blocks.
* Use 4 Spaces to Indent
* No Trailing Whitespace
Clean up your files before committing.
* Follow the K&R guidelines. We won't go through all of them here. Do you
have a copy of "The C Programming Language" anyways right?
=============
Editor Hints
=============
Emacs
------
Add the follow to your $HOME/.emacs file:
(add-hook 'c-mode-hook
(lambda ()
(c-set-style "linux")
(c-toggle-auto-state)))
Vim
----
For the basic vi editor included with all variants of \*nix, add the
following to $HOME/.vimrc:
set ts=4 sw=4 et cindent
You can use the Vim gitmodline plugin to store this in the git config:
http://git.cryptomilk.org/projects/vim-gitmodeline.git/
For Vim, the following settings in $HOME/.vimrc will also deal with
displaying trailing whitespace:
if has("syntax") && (&t_Co > 2 || has("gui_running"))
syntax on
function! ActivateInvisibleCharIndicator()
syntax match TrailingSpace "[ \t]\+$" display containedin=ALL
highlight TrailingSpace ctermbg=Red
endf
autocmd BufNewFile,BufRead * call ActivateInvisibleCharIndicator()
endif
" Show tabs, trailing whitespace, and continued lines visually
set list listchars=tab:»·,trail:·,extends:…
" highlight overly long lines same as TODOs.
set textwidth=80
autocmd BufNewFile,BufRead *.c,*.h exec 'match Todo /\%>' . &textwidth . 'v.\+/'
==========================
FAQ & Statement Reference
==========================
Comments
---------
Comments should always use the standard C syntax. C++ style comments are not
currently allowed.
The lines before a comment should be empty. If the comment directly belongs to
the following code, there should be no empty line after the comment, except if
the comment contains a summary of multiple following code blocks.
This is good:
...
int i;
/*
* This is a multi line comment,
* which explains the logical steps we have to do:
*
* 1. We need to set i=5, because...
* 2. We need to call complex_fn1
*/
/* This is a one line comment about i = 5. */
i = 5;
/*
* This is a multi line comment,
* explaining the call to complex_fn1()
*/
ret = complex_fn1();
if (ret != 0) {
...
/**
* @brief This is a doxygen comment.
*
* This is a more detailed explanation of
* this simple function.
*
* @param[in] param1 The parameter value of the function.
*
* @param[out] result1 The result value of the function.
*
* @return 0 on success and -1 on error.
*/
int example(int param1, int *result1);
This is bad:
...
int i;
/*
* This is a multi line comment,
* which explains the logical steps we have to do:
*
* 1. We need to set i=5, because...
* 2. We need to call complex_fn1
*/
/* This is a one line comment about i = 5. */
i = 5;
/*
* This is a multi line comment,
* explaining the call to complex_fn1()
*/
ret = complex_fn1();
if (ret != 0) {
...
/*This is a one line comment.*/
/* This is a multi line comment,
with some more words...*/
/*
* This is a multi line comment,
* with some more words...*/
Indention & Whitespace & 80 columns
------------------------------------
To avoid confusion, indentations have to be 4 spaces. Do not use tabs!. When
wrapping parameters for function calls, align the parameter list with the first
parameter on the previous line. For example,
var1 = foo(arg1,
arg2,
arg3);
The previous example is intended to illustrate alignment of function
parameters across lines and not as encourage for gratuitous line
splitting. Never split a line before columns 70 - 79 unless you
have a really good reason. Be smart about formatting.
If, switch, & Code blocks
--------------------------
Always follow an 'if' keyword with a space but don't include additional
spaces following or preceding the parentheses in the conditional.
This is good:
if (x == 1)
This is bad:
if ( x == 1 )
or
if (x==1)
Yes we have a lot of code that uses the second and third form and we are trying
to clean it up without being overly intrusive.
Note that this is a rule about parentheses following keywords and not
functions. Don't insert a space between the name and left parentheses when
invoking functions.
Braces for code blocks used by for, if, switch, while, do..while, etc. should
begin on the same line as the statement keyword and end on a line of their own.
You should always include braces, even if the block only contains one
statement. NOTE: Functions are different and the beginning left brace should
be located in the first column on the next line.
If the beginning statement has to be broken across lines due to length, the
beginning brace should be on a line of its own.
The exception to the ending rule is when the closing brace is followed by
another language keyword such as else or the closing while in a do..while loop.
Good examples:
if (x == 1) {
printf("good\n");
}
for (x = 1; x < 10; x++) {
print("%d\n", x);
}
for (really_really_really_really_long_var_name = 0;
really_really_really_really_long_var_name < 10;
really_really_really_really_long_var_name++)
{
print("%d\n", really_really_really_really_long_var_name);
}
do {
printf("also good\n");
} while (1);
Bad examples:
while (1)
{
print("I'm in a loop!\n"); }
for (x=1;
x<10;
x++)
{
print("no good\n");
}
if (i < 10)
print("I should be in braces.\n");
Goto
-----
While many people have been academically taught that "goto"s are fundamentally
evil, they can greatly enhance readability and reduce memory leaks when used as
the single exit point from a function. But in no libssh world what so ever is a
goto outside of a function or block of code a good idea.
Good Examples:
int function foo(int y)
{
int *z = NULL;
int rc = 0;
if (y < 10) {
z = malloc(sizeof(int)*y);
if (z == NULL) {
rc = 1;
goto done;
}
}
print("Allocated %d elements.\n", y);
done:
if (z != NULL) {
free(z);
}
return rc;
}
Typedefs
---------
libssh tries to avoid "typedef struct { .. } x_t;" so we do always try to use
"struct x { .. };". We know there are still such typedefs in the code, but for
new code, please don't do that anymore.
Make use of helper variables
-----------------------------
Please try to avoid passing function calls as function parameters in new code.
This makes the code much easier to read and it's also easier to use the "step"
command within gdb.
Good Example:
char *name;
name = get_some_name();
if (name == NULL) {
...
}
rc = some_function_my_name(name);
...
Bad Example:
rc = some_function_my_name(get_some_name());
...
Please try to avoid passing function return values to if- or while-conditions.
The reason for this is better handling of code under a debugger.
Good example:
x = malloc(sizeof(short) * 10);
if (x == NULL) {
fprintf(stderr, "Unable to alloc memory!\n");
}
Bad example:
if ((x = malloc(sizeof(short)*10)) == NULL ) {
fprintf(stderr, "Unable to alloc memory!\n");
}
There are exceptions to this rule. One example is walking a data structure in
an iterator style:
while ((opt = poptGetNextOpt(pc)) != -1) {
... do something with opt ...
}
But in general, please try to avoid this pattern.
Control-Flow changing macros
-----------------------------
Macros like STATUS_NOT_OK_RETURN that change control flow (return/goto/etc)
from within the macro are considered bad, because they look like function calls
that never change control flow. Please do not introduce them.

View File

@@ -10,17 +10,10 @@ enable_testing()
include(CTest)
if(CMAKE_COMPILER_IS_GNUCC AND NOT MINGW)
# Profiling
set(CMAKE_C_FLAGS_PROFILING "-g -O0 -Wall -W -Wshadow -Wunused-variable -Wunused-parameter -Wunused-function -Wunused -Wno-system-headers -Wwrite-strings -fprofile-arcs -ftest-coverage" CACHE STRING "Profiling Compiler Flags")
set(CMAKE_SHARED_LINKER_FLAGS_PROFILING " -fprofile-arcs -ftest-coverage" CACHE STRING "Profiling Linker Flags")
set(CMAKE_MODULE_LINKER_FLAGS_PROFILING " -fprofile-arcs -ftest-coverage" CACHE STRING "Profiling Linker Flags")
set(CMAKE_EXEC_LINKER_FLAGS_PROFILING " -fprofile-arcs -ftest-coverage" CACHE STRING "Profiling Linker Flags")
# Address Sanitizer
set(CMAKE_C_FLAGS_ADDRESSSANITIZER "-g -O1 -fsanitize=address -fno-omit-frame-pointer" CACHE STRING "Address sanitizer compiler flags")
set(CMAKE_SHARED_LINKER_FLAGS_ADDRESSSANITIZER "-fsanitize=address" CACHE STRING "Address sanitizer shared linker flags")
set(CMAKE_MODULE_LINKER_FLAGS_ADDRESSSANITIZER "-fsanitize=address" CACHE STRING "Address sanitizer module linker flags")
set(CMAKE_EXEC_LINKER_FLAGS_ADDRESSSANITIZER "-fsanitize=address" CACHE STRING "Address sanitizer executable linker flags")
endif(CMAKE_COMPILER_IS_GNUCC AND NOT MINGW)
function (ADD_CMOCKA_TEST _testName _testSource)

View File

@@ -35,8 +35,6 @@ find_path(GCRYPT_INCLUDE_DIR
gcrypt.h
HINTS
${_GCRYPT_ROOT_HINTS_AND_PATHS}
PATH_SUFFIXES
include
)
find_library(GCRYPT_LIBRARY
@@ -46,8 +44,6 @@ find_library(GCRYPT_LIBRARY
libgcrypt-11
HINTS
${_GCRYPT_ROOT_HINTS_AND_PATHS}
PATH_SUFFIXES
lib
)
set(GCRYPT_LIBRARIES ${GCRYPT_LIBRARY})

View File

@@ -0,0 +1,208 @@
# - Try to find OpenSSL
# Once done this will define
#
# OPENSSL_ROOT_DIR - Set this variable to the root installation of OpenSSL
#
# Read-Only variables:
# OPENSSL_FOUND - system has OpenSSL
# OPENSSL_INCLUDE_DIRS - the OpenSSL include directory
# OPENSSL_LIBRARIES - Link these to use OpenSSL
# OPENSSL_DEFINITIONS - Compiler switches required for using OpenSSL
#
#=============================================================================
# Copyright (c) 2006-2009 Kitware, Inc.
# Copyright (c) 2006 Alexander Neundorf <neundorf@kde.org>
# Copyright (c) 2009-2010 Mathieu Malaterre <mathieu.malaterre@gmail.com>
# Copyright (c) 2011 Andreas Schneider <asn@cryptomilk.org>
#
# Distributed under the OSI-approved BSD License (the "License");
# see accompanying file Copyright.txt for details.
#
# This software is distributed WITHOUT ANY WARRANTY; without even the
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the License for more information.
#=============================================================================
#
if (OPENSSL_LIBRARIES AND OPENSSL_INCLUDE_DIRS)
# in cache already
set(OPENSSL_FOUND TRUE)
else (OPENSSL_LIBRARIES AND OPENSSL_INCLUDE_DIRS)
if (UNIX)
find_package(PkgConfig)
if (PKG_CONFIG_FOUND)
pkg_check_modules(_OPENSSL openssl)
endif (PKG_CONFIG_FOUND)
endif (UNIX)
# http://www.slproweb.com/products/Win32OpenSSL.html
set(_OPENSSL_ROOT_HINTS
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\OpenSSL (32-bit)_is1;Inno Setup: App Path]"
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\OpenSSL (64-bit)_is1;Inno Setup: App Path]"
)
set(_OPENSSL_ROOT_PATHS
"C:/OpenSSL/"
"C:/OpenSSL-Win32/"
"C:/OpenSSL-Win64/"
"$ENV{PROGRAMFILES}/OpenSSL"
"$ENV{PROGRAMFILES}/OpenSSL-Win32"
"$ENV{PROGRAMFILES}/OpenSSL-Win64"
)
find_path(OPENSSL_ROOT_DIR
NAMES
include/openssl/ssl.h
HINTS
${_OPENSSL_ROOT_HINTS}
PATHS
${_OPENSSL_ROOT_PATHS}
)
mark_as_advanced(OPENSSL_ROOT_DIR)
find_path(OPENSSL_INCLUDE_DIR
NAMES
openssl/ssl.h
PATHS
/usr/local/include
/opt/local/include
/sw/include
/usr/lib/sfw/include
${OPENSSL_ROOT_DIR}/include
)
set(OPENSSL_INCLUDE_DIRS ${OPENSSL_INCLUDE_DIR})
mark_as_advanced(OPENSSL_INCLUDE_DIRS)
if (WIN32 AND NOT CYGWIN)
# MINGW should go here too
if (MSVC)
# /MD and /MDd are the standard values - if someone wants to use
# others, the libnames have to change here too
# use also ssl and ssleay32 in debug as fallback for openssl < 0.9.8b
# TODO: handle /MT and static lib
# In Visual C++ naming convention each of these four kinds of Windows libraries has it's standard suffix:
# * MD for dynamic-release
# * MDd for dynamic-debug
# * MT for static-release
# * MTd for static-debug
# Implementation details:
# We are using the libraries located in the VC subdir instead of the parent directory eventhough :
# libeay32MD.lib is identical to ../libeay32.lib, and
# ssleay32MD.lib is identical to ../ssleay32.lib
find_library(LIB_EAY_DEBUG
NAMES
libeay32MDd
libeay32
PATHS
${OPENSSL_ROOT_DIR}/lib/VC
)
find_library(LIB_EAY_RELEASE
NAMES
libeay32MD
libeay32
PATHS
${OPENSSL_ROOT_DIR}/lib/VC
)
find_library(SSL_EAY_DEBUG
NAMES
ssleay32MDd
ssleay32
ssl
PATHS ${OPENSSL_ROOT_DIR}/lib/VC
)
find_library(SSL_EAY_RELEASE
NAMES
ssleay32MD
ssleay32
ssl
PATHS
${OPENSSL_ROOT_DIR}/lib/VC
)
if (CMAKE_CONFIGURATION_TYPES OR CMAKE_BUILD_TYPE)
set(OPENSSL_LIBRARIES
optimized ${SSL_EAY_RELEASE} debug ${SSL_EAY_DEBUG}
optimized ${LIB_EAY_RELEASE} debug ${LIB_EAY_DEBUG}
)
else (CMAKE_CONFIGURATION_TYPES OR CMAKE_BUILD_TYPE)
set( OPENSSL_LIBRARIES ${SSL_EAY_RELEASE} ${LIB_EAY_RELEASE} )
endif (CMAKE_CONFIGURATION_TYPES OR CMAKE_BUILD_TYPE)
mark_as_advanced(SSL_EAY_DEBUG SSL_EAY_RELEASE)
mark_as_advanced(LIB_EAY_DEBUG LIB_EAY_RELEASE)
elseif (MINGW)
# same player, for MingW
find_library(LIB_EAY
NAMES
libeay32
PATHS
${OPENSSL_ROOT_DIR}/lib/MinGW
)
find_library(SSL_EAY
NAMES
ssleay32
PATHS
${OPENSSL_ROOT_DIR}/lib/MinGW
)
mark_as_advanced(SSL_EAY LIB_EAY)
set(OPENSSL_LIBRARIES ${SSL_EAY} ${LIB_EAY})
else(MSVC)
# Not sure what to pick for -say- intel, let's use the toplevel ones and hope someone report issues:
find_library(LIB_EAY
NAMES
libeay32
PATHS
${OPENSSL_ROOT_DIR}/lib
)
find_library(SSL_EAY
NAMES
ssleay32
PATHS
${OPENSSL_ROOT_DIR}/lib
)
mark_as_advanced(SSL_EAY LIB_EAY)
set(OPENSSL_LIBRARIES ${SSL_EAY} ${LIB_EAY})
endif(MSVC)
else (WIN32 AND NOT CYGWIN)
find_library(OPENSSL_SSL_LIBRARIES
NAMES
ssl
ssleay32
ssleay32MD
PATHS
${_OPENSSL_LIBDIR}
/opt/local/lib
/sw/lib
/usr/sfw/lib/64
/usr/sfw/lib
)
find_library(OPENSSL_CRYPTO_LIBRARIES
NAMES
crypto
PATHS
${_OPENSSL_LIBDIR}
/opt/local/lib
/sw/lib
/usr/sfw/lib/64
/usr/sfw/lib
)
mark_as_advanced(OPENSSL_CRYPTO_LIBRARIES OPENSSL_SSL_LIBRARIES)
set(OPENSSL_LIBRARIES ${OPENSSL_SSL_LIBRARIES} ${OPENSSL_CRYPTO_LIBRARIES})
endif (WIN32 AND NOT CYGWIN)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(OpenSSL DEFAULT_MSG OPENSSL_LIBRARIES OPENSSL_INCLUDE_DIRS)
endif (OPENSSL_LIBRARIES AND OPENSSL_INCLUDE_DIRS)

View File

@@ -0,0 +1,120 @@
# - Try to find ZLIB
# Once done this will define
#
# ZLIB_ROOT_DIR - Set this variable to the root installation of ZLIB
#
# Read-Only variables:
# ZLIB_FOUND - system has ZLIB
# ZLIB_INCLUDE_DIRS - the ZLIB include directory
# ZLIB_LIBRARIES - Link these to use ZLIB
#
# ZLIB_VERSION_STRING - The version of zlib found (x.y.z)
# ZLIB_VERSION_MAJOR - The major version of zlib
# ZLIB_VERSION_MINOR - The minor version of zlib
# ZLIB_VERSION_PATCH - The patch version of zlib
# ZLIB_VERSION_TWEAK - The tweak version of zlib
#
# The following variable are provided for backward compatibility
#
# ZLIB_MAJOR_VERSION - The major version of zlib
# ZLIB_MINOR_VERSION - The minor version of zlib
# ZLIB_PATCH_VERSION - The patch version of zlib
#
#=============================================================================
# Copyright (c) 2001-2009 Kitware, Inc.
# Copyright (c) 2011 Andreas Schneider <asn@cryptomilk.org>
#
# Distributed under the OSI-approved BSD License (the "License");
# see accompanying file Copyright.txt for details.
#
# This software is distributed WITHOUT ANY WARRANTY; without even the
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the License for more information.
#=============================================================================
#
if (ZLIB_LIBRARIES AND ZLIB_INCLUDE_DIRS)
# in cache already
set(ZLIB_FOUND TRUE)
else (ZLIB_LIBRARIES AND ZLIB_INCLUDE_DIRS)
set(_ZLIB_ROOT_HINTS
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\GnuWin32\\Zlib;InstallPath]/include"
)
set(_ZLIB_ROOT_PATHS
"$ENV{PROGRAMFILES}/zlib"
)
find_path(ZLIB_ROOT_DIR
NAMES
include/zlib.h
HINTS
${_ZLIB_ROOT_HINTS}
PATHS
${_ZLIB_ROOT_PATHS}
)
mark_as_advanced(ZLIB_ROOT_DIR)
# check for header file
find_path(ZLIB_INCLUDE_DIR
NAMES
zlib.h
PATHS
/usr/local/include
/opt/local/include
/sw/include
/usr/lib/sfw/include
${ZLIB_ROOT_DIR}/include
)
mark_as_advanced(ZLIB_INCLUDE_DIR)
# check version number
if (ZLIB_INCLUDE_DIR AND EXISTS "${ZLIB_INCLUDE_DIR}/zlib.h")
file(STRINGS "${ZLIB_INCLUDE_DIR}/zlib.h" ZLIB_H REGEX "^#define ZLIB_VERSION \"[^\"]*\"$")
string(REGEX REPLACE "^.*ZLIB_VERSION \"([0-9]+).*$" "\\1" ZLIB_VERSION_MAJOR "${ZLIB_H}")
string(REGEX REPLACE "^.*ZLIB_VERSION \"[0-9]+\\.([0-9]+).*$" "\\1" ZLIB_VERSION_MINOR "${ZLIB_H}")
string(REGEX REPLACE "^.*ZLIB_VERSION \"[0-9]+\\.[0-9]+\\.([0-9]+).*$" "\\1" ZLIB_VERSION_PATCH "${ZLIB_H}")
set(ZLIB_VERSION_STRING "${ZLIB_VERSION_MAJOR}.${ZLIB_VERSION_MINOR}.${ZLIB_VERSION_PATCH}")
# only append a TWEAK version if it exists:
set(ZLIB_VERSION_TWEAK "")
if ("${ZLIB_H}" MATCHES "^.*ZLIB_VERSION \"[0-9]+\\.[0-9]+\\.[0-9]+\\.([0-9]+).*$")
set(ZLIB_VERSION_TWEAK "${CMAKE_MATCH_1}")
set(ZLIB_VERSION_STRING "${ZLIB_VERSION_STRING}.${ZLIB_VERSION_TWEAK}")
endif ("${ZLIB_H}" MATCHES "^.*ZLIB_VERSION \"[0-9]+\\.[0-9]+\\.[0-9]+\\.([0-9]+).*$")
set(ZLIB_MAJOR_VERSION "${ZLIB_VERSION_MAJOR}")
set(ZLIB_MINOR_VERSION "${ZLIB_VERSION_MINOR}")
set(ZLIB_PATCH_VERSION "${ZLIB_VERSION_PATCH}")
endif (ZLIB_INCLUDE_DIR AND EXISTS "${ZLIB_INCLUDE_DIR}/zlib.h")
find_library(ZLIB_LIBRARY
NAMES
z
zdll
zlib
zlib1
zlibd
PATHS
/usr/local/lib
/opt/local/lib
/sw/lib
/usr/sfw/lib/64
/usr/sfw/lib
${ZLIB_ROOT_DIR}/lib
)
mark_as_advanced(ZLIB_LIBRARY)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(ZLIB DEFAULT_MSG ZLIB_INCLUDE_DIR ZLIB_LIBRARY)
#find_package_handle_standard_args(ZLIB REQUIRED_VARS ZLIB_INCLUDE_DIR ZLIB_LIBRARY
# VERSION_VAR ZLIB_VERSION_STRING)
if (ZLIB_FOUND)
set(ZLIB_INCLUDE_DIRS ${ZLIB_INCLUDE_DIR})
set(ZLIB_LIBRARIES ${ZLIB_LIBRARY})
endif (ZLIB_FOUND)
endif (ZLIB_LIBRARIES AND ZLIB_INCLUDE_DIRS)

View File

@@ -17,21 +17,12 @@
/* Define to 1 if you have the <argp.h> header file. */
#cmakedefine HAVE_ARGP_H 1
/* Define to 1 if you have the <aprpa/inet.h> header file. */
#cmakedefine HAVE_ARPA_INET_H 1
/* Define to 1 if you have the <pty.h> header file. */
#cmakedefine HAVE_PTY_H 1
/* Define to 1 if you have the <utmp.h> header file. */
#cmakedefine HAVE_UTMP_H 1
/* Define to 1 if you have the <util.h> header file. */
#cmakedefine HAVE_UTIL_H 1
/* Define to 1 if you have the <libutil.h> header file. */
#cmakedefine HAVE_LIBUTIL_H 1
/* Define to 1 if you have the <sys/time.h> header file. */
#cmakedefine HAVE_SYS_TIME_H 1
@@ -76,9 +67,6 @@
/*************************** FUNCTIONS ***************************/
/* Define to 1 if you have the `CRYPTO_ctr128_encrypt' function. */
#cmakedefine HAVE_OPENSSL_CRYPTO_CTR128_ENCRYPT 1
/* Define to 1 if you have the `snprintf' function. */
#cmakedefine HAVE_SNPRINTF 1
@@ -103,9 +91,6 @@
/* Define to 1 if you have the `strncpy' function. */
#cmakedefine HAVE_STRNCPY 1
/* Define to 1 if you have the `strndup' function. */
#cmakedefine HAVE_STRNDUP 1
/* Define to 1 if you have the `cfmakeraw' function. */
#cmakedefine HAVE_CFMAKERAW 1
@@ -153,10 +138,6 @@
#cmakedefine HAVE_MSC_THREAD_LOCAL_STORAGE 1
#cmakedefine HAVE_GCC_VOLATILE_MEMORY_PROTECTION 1
#cmakedefine HAVE_GCC_NARG_MACRO 1
#cmakedefine HAVE_COMPILER__FUNC__ 1
#cmakedefine HAVE_COMPILER__FUNCTION__ 1
/* Define to 1 if you want to enable GSSAPI */
#cmakedefine WITH_GSSAPI 1

View File

@@ -721,7 +721,7 @@ EXCLUDE_SYMLINKS = NO
EXCLUDE_PATTERNS = */.git/* \
*/.svn/* \
*/cmake/* \
*/obj/*
*/build/*
# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
# (namespaces, classes, functions, etc.) that should be excluded from the

View File

@@ -56,7 +56,7 @@ If an error has been encountered, it returns a negative value:
@code
char buffer[256];
int nbytes;
unsigned int nbytes;
nbytes = ssh_channel_read(channel, buffer, sizeof(buffer), 0);
while (nbytes > 0)

View File

@@ -1,6 +1,6 @@
curve25519-sha256@libssh.org.txt Aris Adamantiadis <aris@badcode.be>
21/9/2013
1. Introduction
This document describes the key exchange methode curve25519-sha256@libssh.org
@@ -22,14 +22,14 @@ claims to be able to eavesdrop. Having a secure replacement would make passive
attacks much harder if such a backdoor exists.
However an alternative exists in the form of Curve25519. This algorithm has been
proposed in 2006 by DJB [Curve25519]. Its main strengths are its speed, its
proposed in 2006 by DJB [Curve25519]. Its main stengths are its speed, its
constant-time run time (and resistance against side-channel attacks), and its
lack of nebulous hard-coded constants.
The reference version being used in this document is the one described in
[Curve25519] as implemented in the library NaCl [NaCl].
This document does not attempt to provide alternatives to the ecdsa-sha1-*
authentication keys.
This document does not attempts to provide alternatives to the ecdsa-sha1-*
authentication keys.
2. Key exchange
@@ -99,7 +99,7 @@ It should be noted that, in opposition to NIST curves, no special validation
should be done to ensure the received public keys are valid curves point. The
Curve25519 algorithm ensure that every possible public key maps to a valid
ECC Point.
4.3 Shared secret generation
The shared secret, k, is defined in SSH specifications to be a big integer.
@@ -107,7 +107,7 @@ This number is calculated using the following procedure:
X is the 32 bytes point obtained by the scalar multiplication of the other
side's public key and the local private key scalar.
The whole 32 bytes of the number X are then converted into a big integer k.
This conversion follows the network byte order. This step differs from
RFC5656.
@@ -115,5 +115,5 @@ This number is calculated using the following procedure:
[RFC5656] http://tools.ietf.org/html/rfc5656
[SCHNEIER] https://www.schneier.com/blog/archives/2013/09/the_nsa_is_brea.html#c1675929
[DJB] http://cr.yp.to/talks/2013.05.31/slides-dan+tanja-20130531-4x3.pdf
[Curve25519] "Curve25519: new Diffie-Hellman speed records."
http://cr.yp.to/ecdh/curve25519-20060209.pdf
[Curve25519] "Curve25519: new Diffie-Hellman speed records."
http://cr.yp.to/ecdh/curve25519-20060209.pdf

View File

@@ -144,10 +144,10 @@ or whatever use you have for it.
@subsection libssh_reverse Doing reverse port forwarding with libssh
To do reverse port forwarding, call ssh_channel_listen_forward(),
To do reverse port forwarding, call ssh_forward_listen(),
then ssh_channel_accept_forward().
When you call ssh_channel_listen_forward(), you can let the remote server
When you call ssh_forward_listen(), you can let the remote server
chose the non-priviledged port it should listen to. Otherwise, you can chose
your own priviledged or non-priviledged port. Beware that you should have
administrative priviledges on the remote server to open a priviledged port
@@ -164,7 +164,7 @@ int web_server(ssh_session session)
ssh_channel channel;
char buffer[256];
int nbytes, nwritten;
int port = 0;
int port;
char *helloworld = ""
"HTTP/1.1 200 OK\n"
"Content-Type: text/html\n"
@@ -179,7 +179,7 @@ int web_server(ssh_session session)
" </body>\n"
"</html>\n";
rc = ssh_channel_listen_forward(session, NULL, 8080, NULL);
rc = ssh_forward_listen(session, NULL, 8080, NULL);
if (rc != SSH_OK)
{
fprintf(stderr, "Error opening remote port: %s\n",

View File

@@ -367,7 +367,7 @@ int show_remote_processes(ssh_session session)
ssh_channel channel;
int rc;
char buffer[256];
int nbytes;
unsigned int nbytes;
channel = ssh_channel_new(session);
if (channel == NULL)
@@ -391,7 +391,7 @@ int show_remote_processes(ssh_session session)
nbytes = ssh_channel_read(channel, buffer, sizeof(buffer), 0);
while (nbytes > 0)
{
if (write(1, buffer, nbytes) != (unsigned int) nbytes)
if (write(1, buffer, nbytes) != nbytes)
{
ssh_channel_close(channel);
ssh_channel_free(channel);

View File

@@ -19,7 +19,7 @@ the interesting functions as you go.
The libssh library provides:
- <strong>Key Exchange Methods</strong>: <i>curve25519-sha256@libssh.org, ecdh-sha2-nistp256</i>, diffie-hellman-group1-sha1, diffie-hellman-group14-sha1
- <strong>Key Exchange Methods</strong>: <i>ecdh-sha2-nistp256</i>, diffie-hellman-group1-sha1, diffie-hellman-group14-sha1
- <strong>Hostkey Types</strong>: <i>ecdsa-sha2-nistp256</i>, ssh-dss, ssh-rsa
- <strong>Ciphers</strong>: <i>aes256-ctr, aes192-ctr, aes128-ctr</i>, aes256-cbc (rijndael-cbc@lysator.liu.se), aes192-cbc, aes128-cbc, 3des-cbc, des-cbc-ssh1, blowfish-cbc, none
- <strong>Compression Schemes</strong>: zlib, <i>zlib@openssh.com</i>, none
@@ -184,8 +184,6 @@ It was later modified and expanded by the following RFCs.
Authentication and Key Exchange for the Secure Shell (SSH) Protocol
- <a href="http://tools.ietf.org/html/rfc4716" target="_blank">RFC 4716</a>,
The Secure Shell (SSH) Public Key File Format
- <a href="http://tools.ietf.org/html/rfc5647" target="_blank">RFC 5647</a>,
AES Galois Counter Mode for the Secure Shell Transport Layer Protocol
- <a href="http://tools.ietf.org/html/rfc5656" target="_blank">RFC 5656</a>,
Elliptic Curve Algorithm Integration in the Secure Shell Transport Layer
@@ -205,12 +203,6 @@ do the same in libssh.
@subsection main-rfc-extensions Secure Shell Extensions
The libssh project has an extension to support Curve25519 which is also supported by
the OpenSSH project.
- <a href="http://git.libssh.org/projects/libssh.git/tree/doc/curve25519-sha256@libssh.org.txt" target="_blank">curve25519-sha256@libssh.org</a>,
Curve25519-SHA256 for ECDH KEX
The OpenSSH project has defined some extensions to the protocol. We support some of
them like the statvfs calls in SFTP or the ssh-agent.

View File

@@ -253,7 +253,7 @@ int sftp_read_sync(ssh_session session, sftp_session sftp)
return SSH_ERROR;
}
nwritten = write(fd, buffer, nbytes);
nwritten = write(fd, buf, nbytes);
if (nwritten != nbytes) {
fprintf(stderr, "Error writing: %s\n",
strerror(errno));
@@ -282,7 +282,7 @@ sftp_async_read() waits for the data to come. To open a file in nonblocking mode
call sftp_file_set_nonblocking() right after you opened it. Default is blocking mode.
The example below reads a very big file in asynchronous, nonblocking, mode. Each
time the data is not ready yet, a counter is incremented.
time the data are not ready yet, a counter is incrementer.
@code
// Good chunk size

View File

@@ -25,6 +25,13 @@ if (UNIX AND NOT WIN32)
add_executable(sshnetcat sshnetcat.c ${examples_SRCS})
target_link_libraries(sshnetcat ${LIBSSH_SHARED_LIBRARY})
if (WITH_SERVER)
if (HAVE_LIBUTIL)
add_executable(samplesshd-tty samplesshd-tty.c)
target_link_libraries(samplesshd-tty ${LIBSSH_SHARED_LIBRARY} ${ARGP_LIBRARIES} util)
endif (HAVE_LIBUTIL)
endif (WITH_SERVER)
if (WITH_SFTP)
add_executable(samplesftp samplesftp.c ${examples_SRCS})
target_link_libraries(samplesftp ${LIBSSH_SHARED_LIBRARY})
@@ -34,10 +41,8 @@ if (UNIX AND NOT WIN32)
target_link_libraries(samplessh ${LIBSSH_SHARED_LIBRARY})
if (WITH_SERVER)
if (HAVE_LIBUTIL)
add_executable(ssh_server_fork ssh_server_fork.c)
target_link_libraries(ssh_server_fork ${LIBSSH_SHARED_LIBRARY} ${ARGP_LIBRARIES} util)
endif (HAVE_LIBUTIL)
add_executable(samplesshd samplesshd.c)
target_link_libraries(samplesshd ${LIBSSH_SHARED_LIBRARY} ${ARGP_LIBRARIES})
if (WITH_GSSAPI AND GSSAPI_FOUND)
add_executable(samplesshd-cb samplesshd-cb.c)

View File

@@ -116,7 +116,7 @@ int authenticate_console(ssh_session session){
return rc;
}
method = ssh_userauth_list(session, NULL);
method = ssh_auth_list(session);
while (rc != SSH_AUTH_SUCCESS) {
if (method & SSH_AUTH_METHOD_GSSAPI_MIC){
rc = ssh_userauth_gssapi(session);
@@ -129,10 +129,10 @@ int authenticate_console(ssh_session session){
}
// Try to authenticate with public key first
if (method & SSH_AUTH_METHOD_PUBLICKEY) {
rc = ssh_userauth_publickey_auto(session, NULL, NULL);
rc = ssh_userauth_autopubkey(session, NULL);
if (rc == SSH_AUTH_ERROR) {
error(session);
return rc;
error(session);
return rc;
} else if (rc == SSH_AUTH_SUCCESS) {
break;
}

View File

@@ -229,7 +229,6 @@ static int do_copy(struct location *src, struct location *dest, int recursive){
fprintf(stderr,"error: %s\n",ssh_get_error(dest->session));
ssh_string_free_char(filename);
ssh_scp_free(dest->scp);
dest->scp = NULL;
return -1;
}
} else {

View File

@@ -298,22 +298,13 @@ static void select_loop(ssh_session session,ssh_channel channel){
int ret;
while(channel){
do{
int fd;
FD_ZERO(&fds);
if(!eof)
FD_SET(0,&fds);
timeout.tv_sec=30;
timeout.tv_usec=0;
fd = ssh_get_fd(session);
if (fd < 0) {
fprintf(stderr, "Error getting fd\n");
return;
}
FD_SET(fd, &fds);
maxfd = fd + 1;
FD_SET(ssh_get_fd(session),&fds);
maxfd=ssh_get_fd(session)+1;
channels[0]=channel; // set the first channel we want to read from
channels[1]=NULL;
ret=ssh_select(channels,outchannels,maxfd,&fds,&timeout);

View File

@@ -23,7 +23,6 @@ clients must be made or how a client should react.
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <stdbool.h>
#define SSHD_USER "libssh"
#define SSHD_PASSWORD "libssh"
@@ -37,7 +36,6 @@ clients must be made or how a client should react.
#endif
static int port = 22;
static bool authenticated = false;
#ifdef WITH_PCAP
static const char *pcap_file = "debug.server.pcap";
@@ -63,20 +61,11 @@ static void cleanup_pcap(void) {
#endif
static int auth_password(const char *user, const char *password)
{
int cmp;
cmp = strcmp(user, SSHD_USER);
if (cmp != 0) {
static int auth_password(const char *user, const char *password){
if(strcmp(user, SSHD_USER))
return 0;
}
cmp = strcmp(password, SSHD_PASSWORD);
if (cmp != 0) {
if(strcmp(password, SSHD_PASSWORD))
return 0;
}
authenticated = true;
return 1; // authenticated
}
#ifdef HAVE_ARGP_H
@@ -211,7 +200,6 @@ static int kbdint_check_response(ssh_session session) {
return 0;
}
authenticated = true;
return 1;
}
@@ -340,7 +328,7 @@ int main(int argc, char **argv){
/* proceed to authentication */
auth = authenticate(session);
if (!auth || !authenticated) {
if(!auth){
printf("Authentication error: %s\n", ssh_get_error(session));
ssh_disconnect(session);
return 1;

469
examples/samplesshd-tty.c Normal file
View File

@@ -0,0 +1,469 @@
/* This is a sample implementation of a libssh based SSH server */
/*
Copyright 2003-2011 Aris Adamantiadis
This file is part of the SSH Library
You are free to copy this file, modify it in any way, consider it being public
domain. This does not apply to the rest of the library though, but it is
allowed to cut-and-paste working code from this file to any license of
program.
The goal is to show the API in action. It's not a reference on how terminal
clients must be made or how a client should react.
*/
#include "config.h"
#include <libssh/libssh.h>
#include <libssh/server.h>
#include <libssh/callbacks.h>
#ifdef HAVE_ARGP_H
#include <argp.h>
#endif
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <poll.h>
#ifdef HAVE_PTY_H
#include <pty.h>
#endif
#ifdef HAVE_UTIL_H
#include <util.h>
#endif
#ifdef HAVE_TERMIOS_H
#include <termios.h>
#endif
#define SSHD_USER "libssh"
#define SSHD_PASSWORD "libssh"
#ifndef KEYS_FOLDER
#ifdef _WIN32
#define KEYS_FOLDER
#else
#define KEYS_FOLDER "/etc/ssh/"
#endif
#endif
static int port = 22;
#ifdef WITH_PCAP
const char *pcap_file="debug.server.pcap";
ssh_pcap_file pcap;
static void set_pcap(ssh_session session){
if(!pcap_file)
return;
pcap=ssh_pcap_file_new();
if(ssh_pcap_file_open(pcap,pcap_file) == SSH_ERROR){
printf("Error opening pcap file\n");
ssh_pcap_file_free(pcap);
pcap=NULL;
return;
}
ssh_set_pcap_file(session,pcap);
}
static void cleanup_pcap(){
ssh_pcap_file_free(pcap);
pcap=NULL;
}
#endif
static int auth_password(const char *user, const char *password){
if(strcmp(user, SSHD_USER))
return 0;
if(strcmp(password, SSHD_PASSWORD))
return 0;
return 1; // authenticated
}
#ifdef HAVE_ARGP_H
const char *argp_program_version = "libssh server example "
SSH_STRINGIFY(LIBSSH_VERSION);
const char *argp_program_bug_address = "<libssh@libssh.org>";
/* Program documentation. */
static char doc[] = "libssh -- a Secure Shell protocol implementation";
/* A description of the arguments we accept. */
static char args_doc[] = "BINDADDR";
/* The options we understand. */
static struct argp_option options[] = {
{
.name = "port",
.key = 'p',
.arg = "PORT",
.flags = 0,
.doc = "Set the port to bind.",
.group = 0
},
{
.name = "hostkey",
.key = 'k',
.arg = "FILE",
.flags = 0,
.doc = "Set the host key.",
.group = 0
},
{
.name = "dsakey",
.key = 'd',
.arg = "FILE",
.flags = 0,
.doc = "Set the dsa key.",
.group = 0
},
{
.name = "rsakey",
.key = 'r',
.arg = "FILE",
.flags = 0,
.doc = "Set the rsa key.",
.group = 0
},
{
.name = "verbose",
.key = 'v',
.arg = NULL,
.flags = 0,
.doc = "Get verbose output.",
.group = 0
},
{NULL, 0, 0, 0, NULL, 0}
};
/* Parse a single option. */
static error_t parse_opt (int key, char *arg, struct argp_state *state) {
/* Get the input argument from argp_parse, which we
* know is a pointer to our arguments structure.
*/
ssh_bind sshbind = state->input;
switch (key) {
case 'p':
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_BINDPORT_STR, arg);
port = atoi(arg);
break;
case 'd':
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_DSAKEY, arg);
break;
case 'k':
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_HOSTKEY, arg);
break;
case 'r':
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_RSAKEY, arg);
break;
case 'v':
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_LOG_VERBOSITY_STR, "3");
break;
case ARGP_KEY_ARG:
if (state->arg_num >= 1) {
/* Too many arguments. */
argp_usage (state);
}
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_BINDADDR, arg);
break;
case ARGP_KEY_END:
if (state->arg_num < 1) {
/* Not enough arguments. */
argp_usage (state);
}
break;
default:
return ARGP_ERR_UNKNOWN;
}
return 0;
}
/* Our argp parser. */
static struct argp argp = {options, parse_opt, args_doc, doc, NULL, NULL, NULL};
#endif /* HAVE_ARGP_H */
static int authenticate(ssh_session session) {
ssh_message message;
do {
message=ssh_message_get(session);
if(!message)
break;
switch(ssh_message_type(message)){
case SSH_REQUEST_AUTH:
switch(ssh_message_subtype(message)){
case SSH_AUTH_METHOD_PASSWORD:
printf("User %s wants to auth with pass %s\n",
ssh_message_auth_user(message),
ssh_message_auth_password(message));
if(auth_password(ssh_message_auth_user(message),
ssh_message_auth_password(message))){
ssh_message_auth_reply_success(message,0);
ssh_message_free(message);
return 1;
}
ssh_message_auth_set_methods(message,
SSH_AUTH_METHOD_PASSWORD |
SSH_AUTH_METHOD_INTERACTIVE);
// not authenticated, send default message
ssh_message_reply_default(message);
break;
case SSH_AUTH_METHOD_NONE:
default:
printf("User %s wants to auth with unknown auth %d\n",
ssh_message_auth_user(message),
ssh_message_subtype(message));
ssh_message_auth_set_methods(message,
SSH_AUTH_METHOD_PASSWORD |
SSH_AUTH_METHOD_INTERACTIVE);
ssh_message_reply_default(message);
break;
}
break;
default:
ssh_message_auth_set_methods(message,
SSH_AUTH_METHOD_PASSWORD |
SSH_AUTH_METHOD_INTERACTIVE);
ssh_message_reply_default(message);
}
ssh_message_free(message);
} while (1);
return 0;
}
static int copy_fd_to_chan(socket_t fd, int revents, void *userdata) {
ssh_channel chan = (ssh_channel)userdata;
char buf[2048];
int sz = 0;
if(!chan) {
close(fd);
return -1;
}
if(revents & POLLIN) {
sz = read(fd, buf, 2048);
if(sz > 0) {
ssh_channel_write(chan, buf, sz);
}
}
if(revents & POLLHUP) {
ssh_channel_close(chan);
sz = -1;
}
return sz;
}
static int copy_chan_to_fd(ssh_session session,
ssh_channel channel,
void *data,
uint32_t len,
int is_stderr,
void *userdata) {
int fd = *(int*)userdata;
int sz;
(void)session;
(void)channel;
(void)is_stderr;
sz = write(fd, data, len);
return sz;
}
static void chan_close(ssh_session session, ssh_channel channel, void *userdata) {
int fd = *(int*)userdata;
(void)session;
(void)channel;
close(fd);
}
struct ssh_channel_callbacks_struct cb = {
.channel_data_function = copy_chan_to_fd,
.channel_eof_function = chan_close,
.channel_close_function = chan_close,
.userdata = NULL
};
static int main_loop(ssh_channel chan) {
ssh_session session = ssh_channel_get_session(chan);
socket_t fd;
struct termios *term = NULL;
struct winsize *win = NULL;
pid_t childpid;
ssh_event event;
short events;
int rc;
childpid = forkpty(&fd, NULL, term, win);
if(childpid == 0) {
execl("/bin/bash", "/bin/bash", (char *)NULL);
abort();
}
cb.userdata = &fd;
ssh_callbacks_init(&cb);
ssh_set_channel_callbacks(chan, &cb);
events = POLLIN | POLLPRI | POLLERR | POLLHUP | POLLNVAL;
event = ssh_event_new();
if(event == NULL) {
printf("Couldn't get a event\n");
return -1;
}
if(ssh_event_add_fd(event, fd, events, copy_fd_to_chan, chan) != SSH_OK) {
printf("Couldn't add an fd to the event\n");
ssh_event_free(event);
return -1;
}
if(ssh_event_add_session(event, session) != SSH_OK) {
printf("Couldn't add the session to the event\n");
ssh_event_remove_fd(event, fd);
ssh_event_free(event);
return -1;
}
do {
rc = ssh_event_dopoll(event, 1000);
if (rc == SSH_ERROR){
fprintf(stderr, "Error : %s\n", ssh_get_error(session));
ssh_event_free(event);
ssh_disconnect(session);
return -1;
}
} while(!ssh_channel_is_closed(chan));
ssh_event_remove_fd(event, fd);
ssh_event_remove_session(event, session);
ssh_event_free(event);
return 0;
}
int main(int argc, char **argv){
ssh_session session;
ssh_bind sshbind;
ssh_message message;
ssh_channel chan=0;
int auth=0;
int shell=0;
int r;
sshbind=ssh_bind_new();
session=ssh_new();
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_DSAKEY,
KEYS_FOLDER "ssh_host_dsa_key");
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_RSAKEY,
KEYS_FOLDER "ssh_host_rsa_key");
#ifdef HAVE_ARGP_H
/*
* Parse our arguments; every option seen by parse_opt will
* be reflected in arguments.
*/
argp_parse (&argp, argc, argv, 0, 0, sshbind);
#else
(void) argc;
(void) argv;
#endif
#ifdef WITH_PCAP
set_pcap(session);
#endif
if(ssh_bind_listen(sshbind)<0){
printf("Error listening to socket: %s\n", ssh_get_error(sshbind));
return 1;
}
printf("Started sample libssh sshd on port %d\n", port);
printf("You can login as the user %s with the password %s\n", SSHD_USER,
SSHD_PASSWORD);
r = ssh_bind_accept(sshbind, session);
if(r==SSH_ERROR){
printf("Error accepting a connection: %s\n", ssh_get_error(sshbind));
return 1;
}
if (ssh_handle_key_exchange(session)) {
printf("ssh_handle_key_exchange: %s\n", ssh_get_error(session));
return 1;
}
/* proceed to authentication */
auth = authenticate(session);
if(!auth){
printf("Authentication error: %s\n", ssh_get_error(session));
ssh_disconnect(session);
return 1;
}
/* wait for a channel session */
do {
message = ssh_message_get(session);
if(message){
if(ssh_message_type(message) == SSH_REQUEST_CHANNEL_OPEN &&
ssh_message_subtype(message) == SSH_CHANNEL_SESSION) {
chan = ssh_message_channel_request_open_reply_accept(message);
ssh_message_free(message);
break;
} else {
ssh_message_reply_default(message);
ssh_message_free(message);
}
} else {
break;
}
} while(!chan);
if(!chan) {
printf("Error: cleint did not ask for a channel session (%s)\n",
ssh_get_error(session));
ssh_finalize();
return 1;
}
/* wait for a shell */
do {
message = ssh_message_get(session);
if(message != NULL) {
if(ssh_message_type(message) == SSH_REQUEST_CHANNEL) {
if(ssh_message_subtype(message) == SSH_CHANNEL_REQUEST_SHELL) {
shell = 1;
ssh_message_channel_request_reply_success(message);
ssh_message_free(message);
break;
} else if(ssh_message_subtype(message) == SSH_CHANNEL_REQUEST_PTY) {
ssh_message_channel_request_reply_success(message);
ssh_message_free(message);
continue;
}
}
ssh_message_reply_default(message);
ssh_message_free(message);
} else {
break;
}
} while(!shell);
if(!shell) {
printf("Error: No shell requested (%s)\n", ssh_get_error(session));
return 1;
}
printf("it works !\n");
main_loop(chan);
ssh_disconnect(session);
ssh_bind_free(sshbind);
#ifdef WITH_PCAP
cleanup_pcap();
#endif
ssh_finalize();
return 0;
}

314
examples/samplesshd.c Normal file
View File

@@ -0,0 +1,314 @@
/* This is a sample implementation of a libssh based SSH server */
/*
Copyright 2003-2009 Aris Adamantiadis
This file is part of the SSH Library
You are free to copy this file, modify it in any way, consider it being public
domain. This does not apply to the rest of the library though, but it is
allowed to cut-and-paste working code from this file to any license of
program.
The goal is to show the API in action. It's not a reference on how terminal
clients must be made or how a client should react.
*/
#include "config.h"
#include <libssh/libssh.h>
#include <libssh/server.h>
#ifdef HAVE_ARGP_H
#include <argp.h>
#endif
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#ifndef KEYS_FOLDER
#ifdef _WIN32
#define KEYS_FOLDER
#else
#define KEYS_FOLDER "/etc/ssh/"
#endif
#endif
#ifdef WITH_PCAP
static const char *pcap_file="debug.server.pcap";
static ssh_pcap_file pcap;
static void set_pcap(ssh_session session) {
if(!pcap_file)
return;
pcap=ssh_pcap_file_new();
if(ssh_pcap_file_open(pcap,pcap_file) == SSH_ERROR){
printf("Error opening pcap file\n");
ssh_pcap_file_free(pcap);
pcap=NULL;
return;
}
ssh_set_pcap_file(session,pcap);
}
static void cleanup_pcap(void) {
ssh_pcap_file_free(pcap);
pcap=NULL;
}
#endif
static int auth_password(const char *user, const char *password){
if(strcmp(user,"aris"))
return 0;
if(strcmp(password,"lala"))
return 0;
return 1; // authenticated
}
#ifdef HAVE_ARGP_H
const char *argp_program_version = "libssh server example "
SSH_STRINGIFY(LIBSSH_VERSION);
const char *argp_program_bug_address = "<libssh@libssh.org>";
/* Program documentation. */
static char doc[] = "libssh -- a Secure Shell protocol implementation";
/* A description of the arguments we accept. */
static char args_doc[] = "BINDADDR";
/* The options we understand. */
static struct argp_option options[] = {
{
.name = "port",
.key = 'p',
.arg = "PORT",
.flags = 0,
.doc = "Set the port to bind.",
.group = 0
},
{
.name = "hostkey",
.key = 'k',
.arg = "FILE",
.flags = 0,
.doc = "Set the host key.",
.group = 0
},
{
.name = "dsakey",
.key = 'd',
.arg = "FILE",
.flags = 0,
.doc = "Set the dsa key.",
.group = 0
},
{
.name = "rsakey",
.key = 'r',
.arg = "FILE",
.flags = 0,
.doc = "Set the rsa key.",
.group = 0
},
{
.name = "verbose",
.key = 'v',
.arg = NULL,
.flags = 0,
.doc = "Get verbose output.",
.group = 0
},
{NULL, 0, NULL, 0, NULL, 0}
};
/* Parse a single option. */
static error_t parse_opt (int key, char *arg, struct argp_state *state) {
/* Get the input argument from argp_parse, which we
* know is a pointer to our arguments structure.
*/
ssh_bind sshbind = state->input;
switch (key) {
case 'p':
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_BINDPORT_STR, arg);
break;
case 'd':
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_DSAKEY, arg);
break;
case 'k':
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_HOSTKEY, arg);
break;
case 'r':
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_RSAKEY, arg);
break;
case 'v':
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_LOG_VERBOSITY_STR, "3");
break;
case ARGP_KEY_ARG:
if (state->arg_num >= 1) {
/* Too many arguments. */
argp_usage (state);
}
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_BINDADDR, arg);
break;
case ARGP_KEY_END:
if (state->arg_num < 1) {
/* Not enough arguments. */
argp_usage (state);
}
break;
default:
return ARGP_ERR_UNKNOWN;
}
return 0;
}
/* Our argp parser. */
static struct argp argp = {options, parse_opt, args_doc, doc, NULL, NULL, NULL};
#endif /* HAVE_ARGP_H */
int main(int argc, char **argv){
ssh_session session;
ssh_bind sshbind;
ssh_message message;
ssh_channel chan=0;
char buf[2048];
int auth=0;
int sftp=0;
int i;
int r;
sshbind=ssh_bind_new();
session=ssh_new();
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_DSAKEY, KEYS_FOLDER "ssh_host_dsa_key");
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_RSAKEY, KEYS_FOLDER "ssh_host_rsa_key");
#ifdef HAVE_ARGP_H
/*
* Parse our arguments; every option seen by parse_opt will
* be reflected in arguments.
*/
argp_parse (&argp, argc, argv, 0, 0, sshbind);
#else
(void) argc;
(void) argv;
#endif
#ifdef WITH_PCAP
set_pcap(session);
#endif
if(ssh_bind_listen(sshbind)<0){
printf("Error listening to socket: %s\n",ssh_get_error(sshbind));
return 1;
}
r=ssh_bind_accept(sshbind,session);
if(r==SSH_ERROR){
printf("error accepting a connection : %s\n",ssh_get_error(sshbind));
return 1;
}
if (ssh_handle_key_exchange(session)) {
printf("ssh_handle_key_exchange: %s\n", ssh_get_error(session));
return 1;
}
do {
message=ssh_message_get(session);
if(!message)
break;
switch(ssh_message_type(message)){
case SSH_REQUEST_AUTH:
switch(ssh_message_subtype(message)){
case SSH_AUTH_METHOD_PASSWORD:
printf("User %s wants to auth with pass %s\n",
ssh_message_auth_user(message),
ssh_message_auth_password(message));
if(auth_password(ssh_message_auth_user(message),
ssh_message_auth_password(message))){
auth=1;
ssh_message_auth_reply_success(message,0);
break;
}
// not authenticated, send default message
case SSH_AUTH_METHOD_NONE:
default:
ssh_message_auth_set_methods(message,SSH_AUTH_METHOD_PASSWORD);
ssh_message_reply_default(message);
break;
}
break;
default:
ssh_message_reply_default(message);
}
ssh_message_free(message);
} while (!auth);
if(!auth){
printf("auth error: %s\n",ssh_get_error(session));
ssh_disconnect(session);
return 1;
}
do {
message=ssh_message_get(session);
if(message){
switch(ssh_message_type(message)){
case SSH_REQUEST_CHANNEL_OPEN:
if(ssh_message_subtype(message)==SSH_CHANNEL_SESSION){
chan=ssh_message_channel_request_open_reply_accept(message);
break;
}
default:
ssh_message_reply_default(message);
}
ssh_message_free(message);
}
} while(message && !chan);
if(!chan){
printf("error : %s\n",ssh_get_error(session));
ssh_finalize();
return 1;
}
do {
message=ssh_message_get(session);
if(message && ssh_message_type(message)==SSH_REQUEST_CHANNEL &&
(ssh_message_subtype(message)==SSH_CHANNEL_REQUEST_SHELL ||
ssh_message_subtype(message)==SSH_CHANNEL_REQUEST_PTY)) {
// if(!strcmp(ssh_message_channel_request_subsystem(message),"sftp")){
sftp=1;
ssh_message_channel_request_reply_success(message);
break;
// }
}
if(!sftp){
ssh_message_reply_default(message);
}
ssh_message_free(message);
} while (message && !sftp);
if(!sftp){
printf("error : %s\n",ssh_get_error(session));
return 1;
}
printf("it works !\n");
do{
i=ssh_channel_read(chan,buf, 2048, 0);
if(i>0) {
ssh_channel_write(chan, buf, i);
if (write(1,buf,i) < 0) {
printf("error writing to buffer\n");
return 1;
}
if (buf[0] == '\x0d') {
if (write(1, "\n", 1) < 0) {
printf("error writing to buffer\n");
return 1;
}
ssh_channel_write(chan, "\n", 1);
}
}
} while (i>0);
ssh_disconnect(session);
ssh_bind_free(sshbind);
#ifdef WITH_PCAP
cleanup_pcap();
#endif
ssh_finalize();
return 0;
}

View File

@@ -1,697 +0,0 @@
/* This is a sample implementation of a libssh based SSH server */
/*
Copyright 2014 Audrius Butkevicius
This file is part of the SSH Library
You are free to copy this file, modify it in any way, consider it being public
domain. This does not apply to the rest of the library though, but it is
allowed to cut-and-paste working code from this file to any license of
program.
The goal is to show the API in action.
*/
#include "config.h"
#include <libssh/callbacks.h>
#include <libssh/poll.h>
#include <libssh/server.h>
#ifdef HAVE_ARGP_H
#include <argp.h>
#endif
#include <fcntl.h>
#ifdef HAVE_LIBUTIL_H
#include <libutil.h>
#endif
#ifdef HAVE_PTY_H
#include <pty.h>
#endif
#include <signal.h>
#include <stdlib.h>
#ifdef HAVE_UTMP_H
#include <utmp.h>
#endif
#ifdef HAVE_UTIL_H
#include <util.h>
#endif
#include <sys/ioctl.h>
#include <sys/wait.h>
#include <stdio.h>
#ifndef KEYS_FOLDER
#ifdef _WIN32
#define KEYS_FOLDER
#else
#define KEYS_FOLDER "/etc/ssh/"
#endif
#endif
#define USER "myuser"
#define PASS "mypassword"
#define BUF_SIZE 1048576
#define SESSION_END (SSH_CLOSED | SSH_CLOSED_ERROR)
#define SFTP_SERVER_PATH "/usr/lib/sftp-server"
static void set_default_keys(ssh_bind sshbind,
int rsa_already_set,
int dsa_already_set,
int ecdsa_already_set) {
if (!rsa_already_set) {
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_RSAKEY,
KEYS_FOLDER "ssh_host_rsa_key");
}
if (!dsa_already_set) {
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_DSAKEY,
KEYS_FOLDER "ssh_host_dsa_key");
}
if (!ecdsa_already_set) {
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_ECDSAKEY,
KEYS_FOLDER "ssh_host_ecdsa_key");
}
}
#ifdef HAVE_ARGP_H
const char *argp_program_version = "libssh server example "
SSH_STRINGIFY(LIBSSH_VERSION);
const char *argp_program_bug_address = "<libssh@libssh.org>";
/* Program documentation. */
static char doc[] = "libssh -- a Secure Shell protocol implementation";
/* A description of the arguments we accept. */
static char args_doc[] = "BINDADDR";
/* The options we understand. */
static struct argp_option options[] = {
{
.name = "port",
.key = 'p',
.arg = "PORT",
.flags = 0,
.doc = "Set the port to bind.",
.group = 0
},
{
.name = "hostkey",
.key = 'k',
.arg = "FILE",
.flags = 0,
.doc = "Set a host key. Can be used multiple times. "
"Implies no default keys.",
.group = 0
},
{
.name = "dsakey",
.key = 'd',
.arg = "FILE",
.flags = 0,
.doc = "Set the dsa key.",
.group = 0
},
{
.name = "rsakey",
.key = 'r',
.arg = "FILE",
.flags = 0,
.doc = "Set the rsa key.",
.group = 0
},
{
.name = "ecdsakey",
.key = 'e',
.arg = "FILE",
.flags = 0,
.doc = "Set the ecdsa key.",
.group = 0
},
{
.name = "no-default-keys",
.key = 'n',
.arg = NULL,
.flags = 0,
.doc = "Do not set default key locations.",
.group = 0
},
{
.name = "verbose",
.key = 'v',
.arg = NULL,
.flags = 0,
.doc = "Get verbose output.",
.group = 0
},
{NULL, 0, NULL, 0, NULL, 0}
};
/* Parse a single option. */
static error_t parse_opt (int key, char *arg, struct argp_state *state) {
/* Get the input argument from argp_parse, which we
* know is a pointer to our arguments structure. */
ssh_bind sshbind = state->input;
static int no_default_keys = 0;
static int rsa_already_set = 0, dsa_already_set = 0, ecdsa_already_set = 0;
switch (key) {
case 'n':
no_default_keys = 1;
break;
case 'p':
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_BINDPORT_STR, arg);
break;
case 'd':
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_DSAKEY, arg);
dsa_already_set = 1;
break;
case 'k':
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_HOSTKEY, arg);
/* We can't track the types of keys being added with this
option, so let's ensure we keep the keys we're adding
by just not setting the default keys */
no_default_keys = 1;
break;
case 'r':
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_RSAKEY, arg);
rsa_already_set = 1;
break;
case 'e':
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_ECDSAKEY, arg);
ecdsa_already_set = 1;
break;
case 'v':
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_LOG_VERBOSITY_STR,
"3");
break;
case ARGP_KEY_ARG:
if (state->arg_num >= 1) {
/* Too many arguments. */
argp_usage (state);
}
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_BINDADDR, arg);
break;
case ARGP_KEY_END:
if (state->arg_num < 1) {
/* Not enough arguments. */
argp_usage (state);
}
if (!no_default_keys) {
set_default_keys(sshbind,
rsa_already_set,
dsa_already_set,
ecdsa_already_set);
}
break;
default:
return ARGP_ERR_UNKNOWN;
}
return 0;
}
/* Our argp parser. */
static struct argp argp = {options, parse_opt, args_doc, doc, NULL, NULL, NULL};
#endif /* HAVE_ARGP_H */
/* A userdata struct for channel. */
struct channel_data_struct {
/* pid of the child process the channel will spawn. */
pid_t pid;
/* For PTY allocation */
socket_t pty_master;
socket_t pty_slave;
/* For communication with the child process. */
socket_t child_stdin;
socket_t child_stdout;
/* Only used for subsystem and exec requests. */
socket_t child_stderr;
/* Event which is used to poll the above descriptors. */
ssh_event event;
/* Terminal size struct. */
struct winsize *winsize;
};
/* A userdata struct for session. */
struct session_data_struct {
/* Pointer to the channel the session will allocate. */
ssh_channel channel;
int auth_attempts;
int authenticated;
};
static int data_function(ssh_session session, ssh_channel channel, void *data,
uint32_t len, int is_stderr, void *userdata) {
struct channel_data_struct *cdata = (struct channel_data_struct *) userdata;
(void) session;
(void) channel;
(void) is_stderr;
if (len == 0 || cdata->pid < 1 || kill(cdata->pid, 0) < 0) {
return 0;
}
return write(cdata->child_stdin, (char *) data, len);
}
static int pty_request(ssh_session session, ssh_channel channel,
const char *term, int cols, int rows, int py, int px,
void *userdata) {
struct channel_data_struct *cdata = (struct channel_data_struct *)userdata;
(void) session;
(void) channel;
(void) term;
cdata->winsize->ws_row = rows;
cdata->winsize->ws_col = cols;
cdata->winsize->ws_xpixel = px;
cdata->winsize->ws_ypixel = py;
if (openpty(&cdata->pty_master, &cdata->pty_slave, NULL, NULL,
cdata->winsize) != 0) {
fprintf(stderr, "Failed to open pty\n");
return SSH_ERROR;
}
return SSH_OK;
}
static int pty_resize(ssh_session session, ssh_channel channel, int cols,
int rows, int py, int px, void *userdata) {
struct channel_data_struct *cdata = (struct channel_data_struct *)userdata;
(void) session;
(void) channel;
cdata->winsize->ws_row = rows;
cdata->winsize->ws_col = cols;
cdata->winsize->ws_xpixel = px;
cdata->winsize->ws_ypixel = py;
if (cdata->pty_master != -1) {
return ioctl(cdata->pty_master, TIOCSWINSZ, cdata->winsize);
}
return SSH_ERROR;
}
static int exec_pty(const char *mode, const char *command,
struct channel_data_struct *cdata) {
switch(cdata->pid = fork()) {
case -1:
close(cdata->pty_master);
close(cdata->pty_slave);
fprintf(stderr, "Failed to fork\n");
return SSH_ERROR;
case 0:
close(cdata->pty_master);
if (login_tty(cdata->pty_slave) != 0) {
exit(1);
}
execl("/bin/sh", "sh", mode, command, NULL);
exit(0);
default:
close(cdata->pty_slave);
/* pty fd is bi-directional */
cdata->child_stdout = cdata->child_stdin = cdata->pty_master;
}
return SSH_OK;
}
static int exec_nopty(const char *command, struct channel_data_struct *cdata) {
int in[2], out[2], err[2];
/* Do the plumbing to be able to talk with the child process. */
if (pipe(in) != 0) {
goto stdin_failed;
}
if (pipe(out) != 0) {
goto stdout_failed;
}
if (pipe(err) != 0) {
goto stderr_failed;
}
switch(cdata->pid = fork()) {
case -1:
goto fork_failed;
case 0:
/* Finish the plumbing in the child process. */
close(in[1]);
close(out[0]);
close(err[0]);
dup2(in[0], STDIN_FILENO);
dup2(out[1], STDOUT_FILENO);
dup2(err[1], STDERR_FILENO);
close(in[0]);
close(out[1]);
close(err[1]);
/* exec the requested command. */
execl("/bin/sh", "sh", "-c", command, NULL);
exit(0);
}
close(in[0]);
close(out[1]);
close(err[1]);
cdata->child_stdin = in[1];
cdata->child_stdout = out[0];
cdata->child_stderr = err[0];
return SSH_OK;
fork_failed:
close(err[0]);
close(err[1]);
stderr_failed:
close(out[0]);
close(out[1]);
stdout_failed:
close(in[0]);
close(in[1]);
stdin_failed:
return SSH_ERROR;
}
static int exec_request(ssh_session session, ssh_channel channel,
const char *command, void *userdata) {
struct channel_data_struct *cdata = (struct channel_data_struct *) userdata;
(void) session;
(void) channel;
if(cdata->pid > 0) {
return SSH_ERROR;
}
if (cdata->pty_master != -1 && cdata->pty_slave != -1) {
return exec_pty("-c", command, cdata);
}
return exec_nopty(command, cdata);
}
static int shell_request(ssh_session session, ssh_channel channel,
void *userdata) {
struct channel_data_struct *cdata = (struct channel_data_struct *) userdata;
(void) session;
(void) channel;
if(cdata->pid > 0) {
return SSH_ERROR;
}
if (cdata->pty_master != -1 && cdata->pty_slave != -1) {
return exec_pty("-l", NULL, cdata);
}
/* Client requested a shell without a pty, let's pretend we allow that */
return SSH_OK;
}
static int subsystem_request(ssh_session session, ssh_channel channel,
const char *subsystem, void *userdata) {
/* subsystem requests behave simillarly to exec requests. */
if (strcmp(subsystem, "sftp") == 0) {
return exec_request(session, channel, SFTP_SERVER_PATH, userdata);
}
return SSH_ERROR;
}
static int auth_password(ssh_session session, const char *user,
const char *pass, void *userdata) {
struct session_data_struct *sdata = (struct session_data_struct *) userdata;
(void) session;
if (strcmp(user, USER) == 0 && strcmp(pass, PASS) == 0) {
sdata->authenticated = 1;
return SSH_AUTH_SUCCESS;
}
sdata->auth_attempts++;
return SSH_AUTH_DENIED;
}
static ssh_channel channel_open(ssh_session session, void *userdata) {
struct session_data_struct *sdata = (struct session_data_struct *) userdata;
sdata->channel = ssh_channel_new(session);
return sdata->channel;
}
static int process_stdout(socket_t fd, int revents, void *userdata) {
char buf[BUF_SIZE];
int n = -1;
ssh_channel channel = (ssh_channel) userdata;
if (channel != NULL && (revents & POLLIN) != 0) {
n = read(fd, buf, BUF_SIZE);
if (n > 0) {
ssh_channel_write(channel, buf, n);
}
}
return n;
}
static int process_stderr(socket_t fd, int revents, void *userdata) {
char buf[BUF_SIZE];
int n = -1;
ssh_channel channel = (ssh_channel) userdata;
if (channel != NULL && (revents & POLLIN) != 0) {
n = read(fd, buf, BUF_SIZE);
if (n > 0) {
ssh_channel_write_stderr(channel, buf, n);
}
}
return n;
}
static void handle_session(ssh_event event, ssh_session session) {
int n, rc;
/* Structure for storing the pty size. */
struct winsize wsize = {
.ws_row = 0,
.ws_col = 0,
.ws_xpixel = 0,
.ws_ypixel = 0
};
/* Our struct holding information about the channel. */
struct channel_data_struct cdata = {
.pid = 0,
.pty_master = -1,
.pty_slave = -1,
.child_stdin = -1,
.child_stdout = -1,
.child_stderr = -1,
.event = NULL,
.winsize = &wsize
};
/* Our struct holding information about the session. */
struct session_data_struct sdata = {
.channel = NULL,
.auth_attempts = 0,
.authenticated = 0
};
struct ssh_channel_callbacks_struct channel_cb = {
.userdata = &cdata,
.channel_pty_request_function = pty_request,
.channel_pty_window_change_function = pty_resize,
.channel_shell_request_function = shell_request,
.channel_exec_request_function = exec_request,
.channel_data_function = data_function,
.channel_subsystem_request_function = subsystem_request
};
struct ssh_server_callbacks_struct server_cb = {
.userdata = &sdata,
.auth_password_function = auth_password,
.channel_open_request_session_function = channel_open,
};
ssh_callbacks_init(&server_cb);
ssh_callbacks_init(&channel_cb);
ssh_set_server_callbacks(session, &server_cb);
if (ssh_handle_key_exchange(session) != SSH_OK) {
fprintf(stderr, "%s\n", ssh_get_error(session));
return;
}
ssh_set_auth_methods(session, SSH_AUTH_METHOD_PASSWORD);
ssh_event_add_session(event, session);
n = 0;
while (sdata.authenticated == 0 || sdata.channel == NULL) {
/* If the user has used up all attempts, or if he hasn't been able to
* authenticate in 10 seconds (n * 100ms), disconnect. */
if (sdata.auth_attempts >= 3 || n >= 100) {
return;
}
if (ssh_event_dopoll(event, 100) == SSH_ERROR) {
fprintf(stderr, "%s\n", ssh_get_error(session));
return;
}
n++;
}
ssh_set_channel_callbacks(sdata.channel, &channel_cb);
do {
/* Poll the main event which takes care of the session, the channel and
* even our child process's stdout/stderr (once it's started). */
if (ssh_event_dopoll(event, -1) == SSH_ERROR) {
ssh_channel_close(sdata.channel);
}
/* If child process's stdout/stderr has been registered with the event,
* or the child process hasn't started yet, continue. */
if (cdata.event != NULL || cdata.pid == 0) {
continue;
}
/* Executed only once, once the child process starts. */
cdata.event = event;
/* If stdout valid, add stdout to be monitored by the poll event. */
if (cdata.child_stdout != -1) {
if (ssh_event_add_fd(event, cdata.child_stdout, POLLIN, process_stdout,
sdata.channel) != SSH_OK) {
fprintf(stderr, "Failed to register stdout to poll context\n");
ssh_channel_close(sdata.channel);
}
}
/* If stderr valid, add stderr to be monitored by the poll event. */
if (cdata.child_stderr != -1){
if (ssh_event_add_fd(event, cdata.child_stderr, POLLIN, process_stderr,
sdata.channel) != SSH_OK) {
fprintf(stderr, "Failed to register stderr to poll context\n");
ssh_channel_close(sdata.channel);
}
}
} while(ssh_channel_is_open(sdata.channel) &&
(cdata.pid == 0 || waitpid(cdata.pid, &rc, WNOHANG) == 0));
close(cdata.pty_master);
close(cdata.child_stdin);
close(cdata.child_stdout);
close(cdata.child_stderr);
/* Remove the descriptors from the polling context, since they are now
* closed, they will always trigger during the poll calls. */
ssh_event_remove_fd(event, cdata.child_stdout);
ssh_event_remove_fd(event, cdata.child_stderr);
/* If the child process exited. */
if (kill(cdata.pid, 0) < 0 && WIFEXITED(rc)) {
rc = WEXITSTATUS(rc);
ssh_channel_request_send_exit_status(sdata.channel, rc);
/* If client terminated the channel or the process did not exit nicely,
* but only if something has been forked. */
} else if (cdata.pid > 0) {
kill(cdata.pid, SIGKILL);
}
ssh_channel_send_eof(sdata.channel);
ssh_channel_close(sdata.channel);
/* Wait up to 5 seconds for the client to terminate the session. */
for (n = 0; n < 50 && (ssh_get_status(session) & SESSION_END) == 0; n++) {
ssh_event_dopoll(event, 100);
}
}
/* SIGCHLD handler for cleaning up dead children. */
static void sigchld_handler(int signo) {
(void) signo;
while (waitpid(-1, NULL, WNOHANG) > 0);
}
int main(int argc, char **argv) {
ssh_bind sshbind;
ssh_session session;
ssh_event event;
struct sigaction sa;
/* Set up SIGCHLD handler. */
sa.sa_handler = sigchld_handler;
sigemptyset(&sa.sa_mask);
sa.sa_flags = SA_RESTART | SA_NOCLDSTOP;
if (sigaction(SIGCHLD, &sa, NULL) != 0) {
fprintf(stderr, "Failed to register SIGCHLD handler\n");
return 1;
}
ssh_init();
sshbind = ssh_bind_new();
#ifdef HAVE_ARGP_H
argp_parse(&argp, argc, argv, 0, 0, sshbind);
#else
(void) argc;
(void) argv;
set_default_keys(sshbind, 0, 0, 0);
#endif /* HAVE_ARGP_H */
if(ssh_bind_listen(sshbind) < 0) {
fprintf(stderr, "%s\n", ssh_get_error(sshbind));
return 1;
}
while (1) {
session = ssh_new();
if (session == NULL) {
fprintf(stderr, "Failed to allocate session\n");
continue;
}
/* Blocks until there is a new incoming connection. */
if(ssh_bind_accept(sshbind, session) != SSH_ERROR) {
switch(fork()) {
case 0:
/* Remove the SIGCHLD handler inherited from parent. */
sa.sa_handler = SIG_DFL;
sigaction(SIGCHLD, &sa, NULL);
/* Remove socket binding, which allows us to restart the
* parent process, without terminating existing sessions. */
ssh_bind_free(sshbind);
event = ssh_event_new();
if (event != NULL) {
/* Blocks until the SSH session ends by either
* child process exiting, or client disconnecting. */
handle_session(event, session);
ssh_event_free(event);
} else {
fprintf(stderr, "Could not create polling context\n");
}
ssh_disconnect(session);
ssh_free(session);
exit(0);
case -1:
fprintf(stderr, "Failed to fork\n");
}
} else {
fprintf(stderr, "%s\n", ssh_get_error(sshbind));
}
/* Since the session has been passed to a child fork, do some cleaning
* up at the parent process. */
ssh_disconnect(session);
ssh_free(session);
}
ssh_bind_free(sshbind);
ssh_finalize();
return 0;
}

View File

@@ -87,23 +87,13 @@ static void select_loop(ssh_session session,ssh_channel channel){
int ret;
while(channel){
do{
int fd;
FD_ZERO(&fds);
if(!eof)
FD_SET(0,&fds);
timeout.tv_sec=30;
timeout.tv_usec=0;
fd = ssh_get_fd(session);
if (fd == -1) {
fprintf(stderr, "Error getting the session file descriptor: %s\n",
ssh_get_error(session));
return;
}
FD_SET(fd, &fds);
maxfd = fd + 1;
FD_SET(ssh_get_fd(session),&fds);
maxfd=ssh_get_fd(session)+1;
channels[0]=channel; // set the first channel we want to read from
channels[1]=NULL;
ret=ssh_select(channels,outchannels,maxfd,&fds,&timeout);
@@ -112,27 +102,27 @@ static void select_loop(ssh_session session,ssh_channel channel){
if(FD_ISSET(0,&fds)){
lus=read(0,buffer,sizeof(buffer));
if(lus)
ssh_channel_write(channel,buffer,lus);
channel_write(channel,buffer,lus);
else {
eof=1;
ssh_channel_send_eof(channel);
channel_send_eof(channel);
}
}
if(channel && ssh_channel_is_closed(channel)){
ssh_channel_free(channel);
if(channel && channel_is_closed(channel)){
channel_free(channel);
channel=NULL;
channels[0]=NULL;
}
if(outchannels[0]){
while(channel && ssh_channel_is_open(channel) && ssh_channel_poll(channel,0)){
lus = ssh_channel_read(channel,buffer,sizeof(buffer),0);
while(channel && channel_is_open(channel) && channel_poll(channel,0)){
lus=channel_read(channel,buffer,sizeof(buffer),0);
if(lus==-1){
fprintf(stderr, "Error reading channel: %s\n",
ssh_get_error(session));
return;
}
if(lus==0){
ssh_channel_free(channel);
channel_free(channel);
channel=channels[0]=NULL;
} else {
ret = write(1, buffer, lus);
@@ -143,15 +133,15 @@ static void select_loop(ssh_session session,ssh_channel channel){
}
}
}
while(channel && ssh_channel_is_open(channel) && ssh_channel_poll(channel,1)){ /* stderr */
lus = ssh_channel_read(channel, buffer, sizeof(buffer), 1);
while(channel && channel_is_open(channel) && channel_poll(channel,1)){ /* stderr */
lus=channel_read(channel,buffer,sizeof(buffer),1);
if(lus==-1){
fprintf(stderr, "Error reading channel: %s\n",
ssh_get_error(session));
return;
}
if(lus==0){
ssh_channel_free(channel);
channel_free(channel);
channel=channels[0]=NULL;
} else {
ret = write(2, buffer, lus);
@@ -163,8 +153,8 @@ static void select_loop(ssh_session session,ssh_channel channel){
}
}
}
if(channel && ssh_channel_is_closed(channel)){
ssh_channel_free(channel);
if(channel && channel_is_closed(channel)){
channel_free(channel);
channel=NULL;
}
} while (ret==EINTR || ret==SSH_EINTR);
@@ -175,8 +165,8 @@ static void select_loop(ssh_session session,ssh_channel channel){
static void forwarding(ssh_session session){
ssh_channel channel;
int r;
channel = ssh_channel_new(session);
r = ssh_channel_open_forward(channel, desthost, atoi(port), "localhost", 22);
channel=channel_new(session);
r=channel_open_forward(channel,desthost,atoi(port),"localhost",22);
if(r<0) {
printf("error forwarding port : %s\n",ssh_get_error(session));
return;

View File

@@ -1,3 +1,3 @@
project(libssh-headers-x C)
project(headers C)
add_subdirectory(libssh)

View File

@@ -5,7 +5,6 @@ set(libssh_HDRS
libssh.h
ssh2.h
legacy.h
libsshpp.hpp
)
if (WITH_SFTP)

View File

@@ -90,14 +90,6 @@ enum ssh_auth_state_e {
SSH_AUTH_STATE_GSSAPI_TOKEN,
/** We have sent the MIC and expecting to be authenticated */
SSH_AUTH_STATE_GSSAPI_MIC_SENT,
/** We have offered a pubkey to check if it is supported */
SSH_AUTH_STATE_PUBKEY_OFFER_SENT,
/** We have sent pubkey and signature expecting to be authenticated */
SSH_AUTH_STATE_PUBKEY_AUTH_SENT,
/** We have sent a password expecting to be authenticated */
SSH_AUTH_STATE_PASSWORD_AUTH_SENT,
/** We have sent a request without auth information (method 'none') */
SSH_AUTH_STATE_AUTH_NONE_SENT,
};
/** @internal

View File

@@ -1,33 +0,0 @@
/*
* This file is part of the SSH Library
*
* Copyright (c) 2014 by Aris Adamantiadis <aris@badcode.be>
*
* 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, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef BIGNUM_H_
#define BIGNUM_H_
#include "libssh/libcrypto.h"
#include "libssh/libgcrypt.h"
bignum make_string_bn(ssh_string string);
void make_string_bn_inplace(ssh_string string, bignum bnout);
ssh_string make_bignum_string(bignum num);
void ssh_print_bignum(const char *which,bignum num);
#endif /* BIGNUM_H_ */

View File

@@ -36,11 +36,9 @@ struct ssh_bind_struct {
char *ecdsakey;
char *dsakey;
char *rsakey;
char *ed25519key;
ssh_key ecdsa;
ssh_key dsa;
ssh_key rsa;
ssh_key ed25519;
char *bindaddr;
socket_t bindfd;
unsigned int bindport;

View File

@@ -1,87 +0,0 @@
/* $OpenBSD: blf.h,v 1.7 2007/03/14 17:59:41 grunk Exp $ */
/*
* Blowfish - a fast block cipher designed by Bruce Schneier
*
* Copyright 1997 Niels Provos <provos@physnet.uni-hamburg.de>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Niels Provos.
* 4. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _BLF_H_
#define _BLF_H_
//#include "includes.h"
#if !defined(HAVE_BCRYPT_PBKDF) && !defined(HAVE_BLH_H)
/* Schneier specifies a maximum key length of 56 bytes.
* This ensures that every key bit affects every cipher
* bit. However, the subkeys can hold up to 72 bytes.
* Warning: For normal blowfish encryption only 56 bytes
* of the key affect all cipherbits.
*/
#define BLF_N 16 /* Number of Subkeys */
#define BLF_MAXKEYLEN ((BLF_N-2)*4) /* 448 bits */
#define BLF_MAXUTILIZED ((BLF_N+2)*4) /* 576 bits */
/* Blowfish context */
typedef struct BlowfishContext {
uint32_t S[4][256]; /* S-Boxes */
uint32_t P[BLF_N + 2]; /* Subkeys */
} blf_ctx;
/* Raw access to customized Blowfish
* blf_key is just:
* Blowfish_initstate( state )
* Blowfish_expand0state( state, key, keylen )
*/
void Blowfish_encipher(blf_ctx *, uint32_t *, uint32_t *);
void Blowfish_decipher(blf_ctx *, uint32_t *, uint32_t *);
void Blowfish_initstate(blf_ctx *);
void Blowfish_expand0state(blf_ctx *, const uint8_t *, uint16_t);
void Blowfish_expandstate
(blf_ctx *, const uint8_t *, uint16_t, const uint8_t *, uint16_t);
/* Standard Blowfish */
void blf_key(blf_ctx *, const uint8_t *, uint16_t);
void blf_enc(blf_ctx *, uint32_t *, uint16_t);
void blf_dec(blf_ctx *, uint32_t *, uint16_t);
void blf_ecb_encrypt(blf_ctx *, uint8_t *, uint32_t);
void blf_ecb_decrypt(blf_ctx *, uint8_t *, uint32_t);
void blf_cbc_encrypt(blf_ctx *, uint8_t *, uint8_t *, uint32_t);
void blf_cbc_decrypt(blf_ctx *, uint8_t *, uint8_t *, uint32_t);
/* Converts uint8_t to uint32_t */
uint32_t Blowfish_stream2word(const uint8_t *, uint16_t , uint16_t *);
#endif /* !defined(HAVE_BCRYPT_PBKDF) && !defined(HAVE_BLH_H) */
#endif /* _BLF_H */

View File

@@ -21,8 +21,6 @@
#ifndef BUFFER_H_
#define BUFFER_H_
#include <stdarg.h>
#include "libssh/libssh.h"
/*
* Describes a buffer state
@@ -36,49 +34,21 @@ struct ssh_buffer_struct {
uint32_t used;
uint32_t allocated;
uint32_t pos;
int secure;
};
#define SSH_BUFFER_PACK_END ((uint32_t) 0x4f65feb3)
LIBSSH_API void ssh_buffer_free(ssh_buffer buffer);
LIBSSH_API void *ssh_buffer_get_begin(ssh_buffer buffer);
LIBSSH_API uint32_t ssh_buffer_get_len(ssh_buffer buffer);
LIBSSH_API ssh_buffer ssh_buffer_new(void);
void ssh_buffer_set_secure(ssh_buffer buffer);
int buffer_add_ssh_string(ssh_buffer buffer, ssh_string string);
int buffer_add_u8(ssh_buffer buffer, uint8_t data);
int buffer_add_u16(ssh_buffer buffer, uint16_t data);
int buffer_add_u32(ssh_buffer buffer, uint32_t data);
int buffer_add_u64(ssh_buffer buffer, uint64_t data);
int ssh_buffer_add_data(ssh_buffer buffer, const void *data, uint32_t len);
int ssh_buffer_validate_length(struct ssh_buffer_struct *buffer, size_t len);
int ssh_buffer_pack_va(struct ssh_buffer_struct *buffer,
const char *format,
int argc,
va_list ap);
int _ssh_buffer_pack(struct ssh_buffer_struct *buffer,
const char *format,
int argc,
...);
#define ssh_buffer_pack(buffer, format, ...) \
_ssh_buffer_pack((buffer), (format), __VA_NARG__(__VA_ARGS__), __VA_ARGS__, SSH_BUFFER_PACK_END)
int ssh_buffer_unpack_va(struct ssh_buffer_struct *buffer,
const char *format, int argc,
va_list ap);
int _ssh_buffer_unpack(struct ssh_buffer_struct *buffer,
const char *format,
int argc,
...);
#define ssh_buffer_unpack(buffer, format, ...) \
_ssh_buffer_unpack((buffer), (format), __VA_NARG__(__VA_ARGS__), __VA_ARGS__, SSH_BUFFER_PACK_END)
int buffer_add_data(ssh_buffer buffer, const void *data, uint32_t len);
int buffer_prepend_data(ssh_buffer buffer, const void *data, uint32_t len);
int buffer_add_buffer(ssh_buffer buffer, ssh_buffer source);
int ssh_buffer_reinit(ssh_buffer buffer);
int buffer_reinit(ssh_buffer buffer);
/* buffer_get_rest returns a pointer to the current position into the buffer */
void *buffer_get_rest(ssh_buffer buffer);

View File

@@ -75,8 +75,6 @@ struct ssh_channel_struct {
int exit_status;
enum ssh_channel_request_state_e request_state;
ssh_channel_callbacks callbacks;
/* counters */
ssh_counter counter;
};
SSH_PACKET_CALLBACK(ssh_packet_channel_open_conf);
@@ -98,6 +96,8 @@ int channel_default_bufferize(ssh_channel channel, void *data, int len,
int ssh_channel_flush(ssh_channel channel);
uint32_t ssh_channel_new_id(ssh_session session);
ssh_channel ssh_channel_from_local(ssh_session session, uint32_t id);
int channel_write_common(ssh_channel channel, const void *data,
uint32_t len, int is_stderr);
void ssh_channel_do_free(ssh_channel channel);
#ifdef WITH_SSH1
SSH_PACKET_CALLBACK(ssh_packet_data1);

View File

@@ -46,8 +46,6 @@
#include "libssh/kex.h"
#include "libssh/curve25519.h"
#define DIGEST_MAX_LEN 64
enum ssh_key_exchange_e {
/* diffie-hellman-group1-sha1 */
SSH_KEX_DH_GROUP1_SHA1=1,
@@ -81,10 +79,8 @@ struct ssh_crypto_struct {
unsigned char *encryptkey;
unsigned char *encryptMAC;
unsigned char *decryptMAC;
unsigned char hmacbuf[DIGEST_MAX_LEN];
unsigned char hmacbuf[EVP_MAX_MD_SIZE];
struct ssh_cipher_struct *in_cipher, *out_cipher; /* the cipher structures/objects */
enum ssh_hmac_e in_hmac, out_hmac; /* the MAC algorithms used */
ssh_string server_pubkey;
const char *server_pubkey_type;
int do_compress_out; /* idem */
@@ -115,9 +111,9 @@ struct ssh_cipher_struct {
/* sets the new key for immediate use */
int (*set_encrypt_key)(struct ssh_cipher_struct *cipher, void *key, void *IV);
int (*set_decrypt_key)(struct ssh_cipher_struct *cipher, void *key, void *IV);
void (*encrypt)(struct ssh_cipher_struct *cipher, void *in, void *out,
void (*cbc_encrypt)(struct ssh_cipher_struct *cipher, void *in, void *out,
unsigned long len);
void (*decrypt)(struct ssh_cipher_struct *cipher, void *in, void *out,
void (*cbc_decrypt)(struct ssh_cipher_struct *cipher, void *in, void *out,
unsigned long len);
};

View File

@@ -25,6 +25,7 @@
#include "libssh/crypto.h"
void ssh_print_bignum(const char *which,bignum num);
int dh_generate_e(ssh_session session);
int dh_generate_f(ssh_session session);
int dh_generate_x(ssh_session session);
@@ -47,5 +48,8 @@ int make_sessionid(ssh_session session);
int hashbufin_add_cookie(ssh_session session, unsigned char *cookie);
int hashbufout_add_cookie(ssh_session session);
int generate_session_keys(ssh_session session);
bignum make_string_bn(ssh_string string);
void make_string_bn_inplace(ssh_string string, bignum bnout);
ssh_string make_bignum_string(bignum num);
#endif /* DH_H_ */

View File

@@ -1,79 +0,0 @@
/*
* This file is part of the SSH Library
*
* Copyright (c) 2014 by Aris Adamantiadis
*
* 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, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef ED25519_H_
#define ED25519_H_
#include "libssh/priv.h"
/**
* @defgroup ed25519 ed25519 API
* @internal
* @brief API for DJB's ed25519
*
* @{ */
#define ED25519_PK_LEN 32
#define ED25519_SK_LEN 64
#define ED25519_SIG_LEN 64
typedef uint8_t ed25519_pubkey[ED25519_PK_LEN];
typedef uint8_t ed25519_privkey[ED25519_SK_LEN];
typedef uint8_t ed25519_signature[ED25519_SIG_LEN];
/** @internal
* @brief generate an ed25519 key pair
* @param[out] pk generated public key
* @param[out] sk generated secret key
* @return 0 on success, -1 on error.
* */
int crypto_sign_ed25519_keypair(ed25519_pubkey pk, ed25519_privkey sk);
/** @internal
* @brief sign a message with ed25519
* @param[out] sm location to store the signed message.
* Its length should be mlen + 64.
* @param[out] smlen pointer to the size of the signed message
* @param[in] m message to be signed
* @param[in] mlen length of the message to be signed
* @param[in] sk secret key to sign the message with
* @return 0 on success.
*/
int crypto_sign_ed25519(
unsigned char *sm,unsigned long long *smlen,
const unsigned char *m,unsigned long long mlen,
const ed25519_privkey sk);
/** @internal
* @brief "open" and verify the signature of a signed message
* @param[out] m location to store the verified message.
* Its length should be equal to smlen.
* @param[out] mlen pointer to the size of the verified message
* @param[in] sm signed message to verify
* @param[in] smlen length of the signed message to verify
* @param[in] pk public key used to sign the message
* @returns 0 on success (supposedly).
*/
int crypto_sign_ed25519_open(
unsigned char *m,unsigned long long *mlen,
const unsigned char *sm,unsigned long long smlen,
const ed25519_pubkey pk);
/** @} */
#endif /* ED25519_H_ */

View File

@@ -1,68 +0,0 @@
/* $OpenBSD: fe25519.h,v 1.3 2013/12/09 11:03:45 markus Exp $ */
/*
* Public Domain, Authors: Daniel J. Bernstein, Niels Duif, Tanja Lange,
* Peter Schwabe, Bo-Yin Yang.
* Copied from supercop-20130419/crypto_sign/ed25519/ref/fe25519.h
*/
#ifndef FE25519_H
#define FE25519_H
#include "libssh/priv.h"
#define fe25519 crypto_sign_ed25519_ref_fe25519
#define fe25519_freeze crypto_sign_ed25519_ref_fe25519_freeze
#define fe25519_unpack crypto_sign_ed25519_ref_fe25519_unpack
#define fe25519_pack crypto_sign_ed25519_ref_fe25519_pack
#define fe25519_iszero crypto_sign_ed25519_ref_fe25519_iszero
#define fe25519_iseq_vartime crypto_sign_ed25519_ref_fe25519_iseq_vartime
#define fe25519_cmov crypto_sign_ed25519_ref_fe25519_cmov
#define fe25519_setone crypto_sign_ed25519_ref_fe25519_setone
#define fe25519_setzero crypto_sign_ed25519_ref_fe25519_setzero
#define fe25519_neg crypto_sign_ed25519_ref_fe25519_neg
#define fe25519_getparity crypto_sign_ed25519_ref_fe25519_getparity
#define fe25519_add crypto_sign_ed25519_ref_fe25519_add
#define fe25519_sub crypto_sign_ed25519_ref_fe25519_sub
#define fe25519_mul crypto_sign_ed25519_ref_fe25519_mul
#define fe25519_square crypto_sign_ed25519_ref_fe25519_square
#define fe25519_invert crypto_sign_ed25519_ref_fe25519_invert
#define fe25519_pow2523 crypto_sign_ed25519_ref_fe25519_pow2523
typedef struct {
uint32_t v[32];
} fe25519;
void fe25519_freeze(fe25519 *r);
void fe25519_unpack(fe25519 *r, const unsigned char x[32]);
void fe25519_pack(unsigned char r[32], const fe25519 *x);
int fe25519_iszero(const fe25519 *x);
int fe25519_iseq_vartime(const fe25519 *x, const fe25519 *y);
void fe25519_cmov(fe25519 *r, const fe25519 *x, unsigned char b);
void fe25519_setone(fe25519 *r);
void fe25519_setzero(fe25519 *r);
void fe25519_neg(fe25519 *r, const fe25519 *x);
unsigned char fe25519_getparity(const fe25519 *x);
void fe25519_add(fe25519 *r, const fe25519 *x, const fe25519 *y);
void fe25519_sub(fe25519 *r, const fe25519 *x, const fe25519 *y);
void fe25519_mul(fe25519 *r, const fe25519 *x, const fe25519 *y);
void fe25519_square(fe25519 *r, const fe25519 *x);
void fe25519_invert(fe25519 *r, const fe25519 *x);
void fe25519_pow2523(fe25519 *r, const fe25519 *x);
#endif

View File

@@ -1,43 +0,0 @@
/* $OpenBSD: ge25519.h,v 1.3 2013/12/09 11:03:45 markus Exp $ */
/*
* Public Domain, Authors: Daniel J. Bernstein, Niels Duif, Tanja Lange,
* Peter Schwabe, Bo-Yin Yang.
* Copied from supercop-20130419/crypto_sign/ed25519/ref/ge25519.h
*/
#ifndef GE25519_H
#define GE25519_H
#include "fe25519.h"
#include "sc25519.h"
#define ge25519 crypto_sign_ed25519_ref_ge25519
#define ge25519_base crypto_sign_ed25519_ref_ge25519_base
#define ge25519_unpackneg_vartime crypto_sign_ed25519_ref_unpackneg_vartime
#define ge25519_pack crypto_sign_ed25519_ref_pack
#define ge25519_isneutral_vartime crypto_sign_ed25519_ref_isneutral_vartime
#define ge25519_double_scalarmult_vartime crypto_sign_ed25519_ref_double_scalarmult_vartime
#define ge25519_scalarmult_base crypto_sign_ed25519_ref_scalarmult_base
typedef struct
{
fe25519 x;
fe25519 y;
fe25519 z;
fe25519 t;
} ge25519;
const ge25519 ge25519_base;
int ge25519_unpackneg_vartime(ge25519 *r, const unsigned char p[32]);
void ge25519_pack(unsigned char r[32], const ge25519 *p);
int ge25519_isneutral_vartime(const ge25519 *p);
void ge25519_double_scalarmult_vartime(ge25519 *r, const ge25519 *p1, const sc25519 *s1, const ge25519 *p2, const sc25519 *s2);
void ge25519_scalarmult_base(ge25519 *r, const sc25519 *s);
#endif

View File

@@ -42,51 +42,51 @@ LIBSSH_API int ssh_userauth_autopubkey(ssh_session session, const char *passphra
LIBSSH_API int ssh_userauth_privatekey_file(ssh_session session, const char *username,
const char *filename, const char *passphrase);
SSH_DEPRECATED LIBSSH_API void buffer_free(ssh_buffer buffer);
SSH_DEPRECATED LIBSSH_API void *buffer_get(ssh_buffer buffer);
SSH_DEPRECATED LIBSSH_API uint32_t buffer_get_len(ssh_buffer buffer);
SSH_DEPRECATED LIBSSH_API ssh_buffer buffer_new(void);
LIBSSH_API void buffer_free(ssh_buffer buffer);
LIBSSH_API void *buffer_get(ssh_buffer buffer);
LIBSSH_API uint32_t buffer_get_len(ssh_buffer buffer);
LIBSSH_API ssh_buffer buffer_new(void);
SSH_DEPRECATED LIBSSH_API ssh_channel channel_accept_x11(ssh_channel channel, int timeout_ms);
SSH_DEPRECATED LIBSSH_API int channel_change_pty_size(ssh_channel channel,int cols,int rows);
SSH_DEPRECATED LIBSSH_API ssh_channel channel_forward_accept(ssh_session session, int timeout_ms);
SSH_DEPRECATED LIBSSH_API int channel_close(ssh_channel channel);
SSH_DEPRECATED LIBSSH_API int channel_forward_cancel(ssh_session session, const char *address, int port);
SSH_DEPRECATED LIBSSH_API int channel_forward_listen(ssh_session session, const char *address, int port, int *bound_port);
SSH_DEPRECATED LIBSSH_API void channel_free(ssh_channel channel);
SSH_DEPRECATED LIBSSH_API int channel_get_exit_status(ssh_channel channel);
SSH_DEPRECATED LIBSSH_API ssh_session channel_get_session(ssh_channel channel);
SSH_DEPRECATED LIBSSH_API int channel_is_closed(ssh_channel channel);
SSH_DEPRECATED LIBSSH_API int channel_is_eof(ssh_channel channel);
SSH_DEPRECATED LIBSSH_API int channel_is_open(ssh_channel channel);
SSH_DEPRECATED LIBSSH_API ssh_channel channel_new(ssh_session session);
SSH_DEPRECATED LIBSSH_API int channel_open_forward(ssh_channel channel, const char *remotehost,
LIBSSH_API ssh_channel channel_accept_x11(ssh_channel channel, int timeout_ms);
LIBSSH_API int channel_change_pty_size(ssh_channel channel,int cols,int rows);
LIBSSH_API ssh_channel channel_forward_accept(ssh_session session, int timeout_ms);
LIBSSH_API int channel_close(ssh_channel channel);
LIBSSH_API int channel_forward_cancel(ssh_session session, const char *address, int port);
LIBSSH_API int channel_forward_listen(ssh_session session, const char *address, int port, int *bound_port);
LIBSSH_API void channel_free(ssh_channel channel);
LIBSSH_API int channel_get_exit_status(ssh_channel channel);
LIBSSH_API ssh_session channel_get_session(ssh_channel channel);
LIBSSH_API int channel_is_closed(ssh_channel channel);
LIBSSH_API int channel_is_eof(ssh_channel channel);
LIBSSH_API int channel_is_open(ssh_channel channel);
LIBSSH_API ssh_channel channel_new(ssh_session session);
LIBSSH_API int channel_open_forward(ssh_channel channel, const char *remotehost,
int remoteport, const char *sourcehost, int localport);
SSH_DEPRECATED LIBSSH_API int channel_open_session(ssh_channel channel);
SSH_DEPRECATED LIBSSH_API int channel_poll(ssh_channel channel, int is_stderr);
SSH_DEPRECATED LIBSSH_API int channel_read(ssh_channel channel, void *dest, uint32_t count, int is_stderr);
LIBSSH_API int channel_open_session(ssh_channel channel);
LIBSSH_API int channel_poll(ssh_channel channel, int is_stderr);
LIBSSH_API int channel_read(ssh_channel channel, void *dest, uint32_t count, int is_stderr);
SSH_DEPRECATED LIBSSH_API int channel_read_buffer(ssh_channel channel, ssh_buffer buffer, uint32_t count,
LIBSSH_API int channel_read_buffer(ssh_channel channel, ssh_buffer buffer, uint32_t count,
int is_stderr);
SSH_DEPRECATED LIBSSH_API int channel_read_nonblocking(ssh_channel channel, void *dest, uint32_t count,
LIBSSH_API int channel_read_nonblocking(ssh_channel channel, void *dest, uint32_t count,
int is_stderr);
SSH_DEPRECATED LIBSSH_API int channel_request_env(ssh_channel channel, const char *name, const char *value);
SSH_DEPRECATED LIBSSH_API int channel_request_exec(ssh_channel channel, const char *cmd);
SSH_DEPRECATED LIBSSH_API int channel_request_pty(ssh_channel channel);
SSH_DEPRECATED LIBSSH_API int channel_request_pty_size(ssh_channel channel, const char *term,
LIBSSH_API int channel_request_env(ssh_channel channel, const char *name, const char *value);
LIBSSH_API int channel_request_exec(ssh_channel channel, const char *cmd);
LIBSSH_API int channel_request_pty(ssh_channel channel);
LIBSSH_API int channel_request_pty_size(ssh_channel channel, const char *term,
int cols, int rows);
SSH_DEPRECATED LIBSSH_API int channel_request_shell(ssh_channel channel);
SSH_DEPRECATED LIBSSH_API int channel_request_send_signal(ssh_channel channel, const char *signum);
SSH_DEPRECATED LIBSSH_API int channel_request_sftp(ssh_channel channel);
SSH_DEPRECATED LIBSSH_API int channel_request_subsystem(ssh_channel channel, const char *subsystem);
SSH_DEPRECATED LIBSSH_API int channel_request_x11(ssh_channel channel, int single_connection, const char *protocol,
LIBSSH_API int channel_request_shell(ssh_channel channel);
LIBSSH_API int channel_request_send_signal(ssh_channel channel, const char *signum);
LIBSSH_API int channel_request_sftp(ssh_channel channel);
LIBSSH_API int channel_request_subsystem(ssh_channel channel, const char *subsystem);
LIBSSH_API int channel_request_x11(ssh_channel channel, int single_connection, const char *protocol,
const char *cookie, int screen_number);
SSH_DEPRECATED LIBSSH_API int channel_send_eof(ssh_channel channel);
SSH_DEPRECATED LIBSSH_API int channel_select(ssh_channel *readchans, ssh_channel *writechans, ssh_channel *exceptchans, struct
LIBSSH_API int channel_send_eof(ssh_channel channel);
LIBSSH_API int channel_select(ssh_channel *readchans, ssh_channel *writechans, ssh_channel *exceptchans, struct
timeval * timeout);
SSH_DEPRECATED LIBSSH_API void channel_set_blocking(ssh_channel channel, int blocking);
SSH_DEPRECATED LIBSSH_API int channel_write(ssh_channel channel, const void *data, uint32_t len);
LIBSSH_API void channel_set_blocking(ssh_channel channel, int blocking);
LIBSSH_API int channel_write(ssh_channel channel, const void *data, uint32_t len);
LIBSSH_API void privatekey_free(ssh_private_key prv);
LIBSSH_API ssh_private_key privatekey_from_file(ssh_session session, const char *filename,
@@ -107,14 +107,14 @@ LIBSSH_API ssh_string ssh_get_pubkey(ssh_session session);
LIBSSH_API ssh_message ssh_message_retrieve(ssh_session session, uint32_t packettype);
LIBSSH_API ssh_public_key ssh_message_auth_publickey(ssh_message msg);
SSH_DEPRECATED LIBSSH_API void string_burn(ssh_string str);
SSH_DEPRECATED LIBSSH_API ssh_string string_copy(ssh_string str);
SSH_DEPRECATED LIBSSH_API void *string_data(ssh_string str);
SSH_DEPRECATED LIBSSH_API int string_fill(ssh_string str, const void *data, size_t len);
SSH_DEPRECATED LIBSSH_API void string_free(ssh_string str);
SSH_DEPRECATED LIBSSH_API ssh_string string_from_char(const char *what);
SSH_DEPRECATED LIBSSH_API size_t string_len(ssh_string str);
SSH_DEPRECATED LIBSSH_API ssh_string string_new(size_t size);
SSH_DEPRECATED LIBSSH_API char *string_to_char(ssh_string str);
LIBSSH_API void string_burn(ssh_string str);
LIBSSH_API ssh_string string_copy(ssh_string str);
LIBSSH_API void *string_data(ssh_string str);
LIBSSH_API int string_fill(ssh_string str, const void *data, size_t len);
LIBSSH_API void string_free(ssh_string str);
LIBSSH_API ssh_string string_from_char(const char *what);
LIBSSH_API size_t string_len(ssh_string str);
LIBSSH_API ssh_string string_new(size_t size);
LIBSSH_API char *string_to_char(ssh_string str);
#endif /* LEGACY_H_ */

View File

@@ -36,8 +36,6 @@
typedef SHA_CTX* SHACTX;
typedef SHA256_CTX* SHA256CTX;
typedef SHA512_CTX* SHA384CTX;
typedef SHA512_CTX* SHA512CTX;
typedef MD5_CTX* MD5CTX;
typedef HMAC_CTX* HMACCTX;
#ifdef HAVE_ECC
@@ -47,9 +45,6 @@ typedef void *EVPCTX;
#endif
#define SHA_DIGEST_LEN SHA_DIGEST_LENGTH
#define SHA256_DIGEST_LEN SHA256_DIGEST_LENGTH
#define SHA384_DIGEST_LEN SHA384_DIGEST_LENGTH
#define SHA512_DIGEST_LEN SHA512_DIGEST_LENGTH
#ifdef MD5_DIGEST_LEN
#undef MD5_DIGEST_LEN
#endif
@@ -89,14 +84,6 @@ SHA256CTX sha256_init(void);
void sha256_update(SHA256CTX c, const void *data, unsigned long len);
void sha256_final(unsigned char *md, SHA256CTX c);
SHA384CTX sha384_init(void);
void sha384_update(SHA384CTX c, const void *data, unsigned long len);
void sha384_final(unsigned char *md, SHA384CTX c);
SHA512CTX sha512_init(void);
void sha512_update(SHA512CTX c, const void *data, unsigned long len);
void sha512_final(unsigned char *md, SHA512CTX c);
struct ssh_cipher_struct *ssh_get_ciphertab(void);
#endif /* HAVE_LIBCRYPTO */

View File

@@ -27,9 +27,6 @@
#include <gcrypt.h>
typedef gcry_md_hd_t SHACTX;
typedef gcry_md_hd_t SHA256CTX;
typedef gcry_md_hd_t SHA384CTX;
typedef gcry_md_hd_t SHA512CTX;
typedef gcry_md_hd_t MD5CTX;
typedef gcry_md_hd_t HMACCTX;
typedef void *EVPCTX;
@@ -37,14 +34,11 @@ typedef void *EVPCTX;
#define SHA_DIGEST_LEN SHA_DIGEST_LENGTH
#define MD5_DIGEST_LEN 16
#define SHA256_DIGEST_LENGTH 32
#define SHA256_DIGEST_LEN SHA256_DIGEST_LENGTH
#define SHA384_DIGEST_LENGTH 48
#define SHA384_DIGEST_LEN SHA384_DIGEST_LENGTH
#define SHA512_DIGEST_LENGTH 64
#define SHA512_DIGEST_LEN SHA512_DIGEST_LENGTH
#ifndef EVP_MAX_MD_SIZE
#define EVP_MAX_MD_SIZE 64
#define EVP_MAX_MD_SIZE 36
#endif
#define EVP_DIGEST_LEN EVP_MAX_MD_SIZE

View File

@@ -58,7 +58,6 @@
#else /* _MSC_VER */
#include <unistd.h>
#include <inttypes.h>
#include <sys/types.h>
#endif /* _MSC_VER */
#ifdef _WIN32
@@ -78,8 +77,8 @@
/* libssh version */
#define LIBSSH_VERSION_MAJOR 0
#define LIBSSH_VERSION_MINOR 7
#define LIBSSH_VERSION_MICRO 7
#define LIBSSH_VERSION_MINOR 6
#define LIBSSH_VERSION_MICRO 4
#define LIBSSH_VERSION_INT SSH_VERSION_INT(LIBSSH_VERSION_MAJOR, \
LIBSSH_VERSION_MINOR, \
@@ -105,13 +104,6 @@
extern "C" {
#endif
struct ssh_counter_struct {
uint64_t in_bytes;
uint64_t out_bytes;
uint64_t in_packets;
uint64_t out_packets;
};
typedef struct ssh_counter_struct *ssh_counter;
typedef struct ssh_agent_struct* ssh_agent;
typedef struct ssh_buffer_struct* ssh_buffer;
@@ -253,8 +245,7 @@ enum ssh_keytypes_e{
SSH_KEYTYPE_DSS=1,
SSH_KEYTYPE_RSA,
SSH_KEYTYPE_RSA1,
SSH_KEYTYPE_ECDSA,
SSH_KEYTYPE_ED25519
SSH_KEYTYPE_ECDSA
};
enum ssh_keycmp_e {
@@ -344,8 +335,6 @@ enum ssh_options_e {
SSH_OPTIONS_GSSAPI_SERVER_IDENTITY,
SSH_OPTIONS_GSSAPI_CLIENT_IDENTITY,
SSH_OPTIONS_GSSAPI_DELEGATE_CREDENTIALS,
SSH_OPTIONS_HMAC_C_S,
SSH_OPTIONS_HMAC_S_C,
};
enum {
@@ -406,8 +395,6 @@ LIBSSH_API int ssh_channel_send_eof(ssh_channel channel);
LIBSSH_API int ssh_channel_select(ssh_channel *readchans, ssh_channel *writechans, ssh_channel *exceptchans, struct
timeval * timeout);
LIBSSH_API void ssh_channel_set_blocking(ssh_channel channel, int blocking);
LIBSSH_API void ssh_channel_set_counter(ssh_channel channel,
ssh_counter counter);
LIBSSH_API int ssh_channel_write(ssh_channel channel, const void *data, uint32_t len);
LIBSSH_API uint32_t ssh_channel_window_size(ssh_channel channel);
@@ -418,19 +405,10 @@ LIBSSH_API const char *ssh_copyright(void);
LIBSSH_API void ssh_disconnect(ssh_session session);
LIBSSH_API char *ssh_dirname (const char *path);
LIBSSH_API int ssh_finalize(void);
/* REVERSE PORT FORWARDING */
LIBSSH_API ssh_channel ssh_channel_accept_forward(ssh_session session,
int timeout_ms,
int *destination_port);
LIBSSH_API int ssh_channel_cancel_forward(ssh_session session,
const char *address,
int port);
LIBSSH_API int ssh_channel_listen_forward(ssh_session session,
const char *address,
int port,
int *bound_port);
LIBSSH_API ssh_channel ssh_forward_accept(ssh_session session, int timeout_ms);
LIBSSH_API ssh_channel ssh_channel_accept_forward(ssh_session session, int timeout_ms, int *destination_port);
LIBSSH_API int ssh_forward_cancel(ssh_session session, const char *address, int port);
LIBSSH_API int ssh_forward_listen(ssh_session session, const char *address, int port, int *bound_port);
LIBSSH_API void ssh_free(ssh_session session);
LIBSSH_API const char *ssh_get_disconnect_message(ssh_session session);
LIBSSH_API const char *ssh_get_error(void *error);
@@ -444,20 +422,14 @@ LIBSSH_API int ssh_get_publickey(ssh_session session, ssh_key *key);
enum ssh_publickey_hash_type {
SSH_PUBLICKEY_HASH_SHA1,
SSH_PUBLICKEY_HASH_MD5,
SSH_PUBLICKEY_HASH_SHA256
SSH_PUBLICKEY_HASH_MD5
};
LIBSSH_API int ssh_get_publickey_hash(const ssh_key key,
enum ssh_publickey_hash_type type,
unsigned char **hash,
size_t *hlen);
/* DEPRECATED FUNCTIONS */
SSH_DEPRECATED LIBSSH_API int ssh_get_pubkey_hash(ssh_session session, unsigned char **hash);
SSH_DEPRECATED LIBSSH_API ssh_channel ssh_forward_accept(ssh_session session, int timeout_ms);
SSH_DEPRECATED LIBSSH_API int ssh_forward_cancel(ssh_session session, const char *address, int port);
SSH_DEPRECATED LIBSSH_API int ssh_forward_listen(ssh_session session, const char *address, int port, int *bound_port);
LIBSSH_API int ssh_get_random(void *where,int len,int strong);
LIBSSH_API int ssh_get_version(ssh_session session);
@@ -564,10 +536,6 @@ LIBSSH_API int ssh_pki_export_pubkey_file(const ssh_key key,
LIBSSH_API const char *ssh_pki_key_ecdsa_name(const ssh_key key);
LIBSSH_API char *ssh_get_fingerprint_hash(enum ssh_publickey_hash_type type,
unsigned char *hash,
size_t len);
LIBSSH_API void ssh_print_hash(enum ssh_publickey_hash_type type, unsigned char *hash, size_t len);
LIBSSH_API void ssh_print_hexa(const char *descr, const unsigned char *what, size_t len);
LIBSSH_API int ssh_send_ignore (ssh_session session, const char *data);
LIBSSH_API int ssh_send_debug (ssh_session session, const char *message, int always_display);
@@ -594,10 +562,7 @@ LIBSSH_API int ssh_select(ssh_channel *channels, ssh_channel *outchannels, socke
fd_set *readfds, struct timeval *timeout);
LIBSSH_API int ssh_service_request(ssh_session session, const char *service);
LIBSSH_API int ssh_set_agent_channel(ssh_session session, ssh_channel channel);
LIBSSH_API int ssh_set_agent_socket(ssh_session session, socket_t fd);
LIBSSH_API void ssh_set_blocking(ssh_session session, int blocking);
LIBSSH_API void ssh_set_counters(ssh_session session, ssh_counter scounter,
ssh_counter rcounter);
LIBSSH_API void ssh_set_fd_except(ssh_session session);
LIBSSH_API void ssh_set_fd_toread(ssh_session session);
LIBSSH_API void ssh_set_fd_towrite(ssh_session session);
@@ -665,11 +630,8 @@ LIBSSH_API int ssh_event_remove_session(ssh_event event, ssh_session session);
LIBSSH_API void ssh_event_free(ssh_event event);
LIBSSH_API const char* ssh_get_clientbanner(ssh_session session);
LIBSSH_API const char* ssh_get_serverbanner(ssh_session session);
LIBSSH_API const char* ssh_get_kex_algo(ssh_session session);
LIBSSH_API const char* ssh_get_cipher_in(ssh_session session);
LIBSSH_API const char* ssh_get_cipher_out(ssh_session session);
LIBSSH_API const char* ssh_get_hmac_in(ssh_session session);
LIBSSH_API const char* ssh_get_hmac_out(ssh_session session);
#ifndef LIBSSH_LEGACY_0_4
#include "libssh/legacy.h"

View File

@@ -56,7 +56,6 @@
#include <stdlib.h>
#include <stdarg.h>
#include <stdio.h>
#include <string>
namespace ssh {
@@ -366,14 +365,14 @@ public:
/* implemented outside the class due Channel references */
void_throwable cancelForward(const char *address, int port){
int err=ssh_channel_cancel_forward(c_session, address, port);
int err=ssh_forward_cancel(c_session, address, port);
ssh_throw(err);
return_throwable;
}
void_throwable listenForward(const char *address, int port,
int &boundport){
int err=ssh_channel_listen_forward(c_session, address, port, &boundport);
int err=ssh_forward_listen(c_session, address, port, &boundport);
ssh_throw(err);
return_throwable;
}
@@ -600,9 +599,10 @@ private:
};
inline Channel *Session::acceptForward(int timeout_ms){
ssh_channel forward =
ssh_channel_accept_forward(c_session, timeout_ms, NULL);
/* This code cannot be put inline due to references to Channel */
Channel *Session::acceptForward(int timeout_ms){
ssh_channel forward = ssh_forward_accept(c_session,
timeout_ms);
ssh_throw_null(c_session,forward);
Channel *newchan = new Channel(*this,forward);
return newchan;

View File

@@ -76,8 +76,8 @@ struct ssh_channel_request {
/* X11 */
uint8_t x11_single_connection;
char *x11_auth_protocol;
char *x11_auth_cookie;
const char *x11_auth_protocol;
const char *x11_auth_cookie;
uint32_t x11_screen_number;
};

View File

@@ -33,6 +33,15 @@ int ssh_analyze_banner(ssh_session session, int server, int *ssh1, int *ssh2);
int ssh_is_ipaddr_v4(const char *str);
int ssh_is_ipaddr(const char *str);
#ifndef HAVE_NTOHLL
/* macro for byte ordering */
uint64_t ntohll(uint64_t);
#endif
#ifndef HAVE_HTONLL
#define htonll(x) ntohll((x))
#endif
/* list processing */
struct ssh_list {

View File

@@ -21,8 +21,6 @@
#ifndef PACKET_H_
#define PACKET_H_
#include "libssh/wrapper.h"
struct ssh_socket_struct;
/* this structure should go someday */
@@ -43,12 +41,6 @@ enum ssh_packet_state_e {
PACKET_STATE_PROCESSING
};
enum ssh_packet_filter_result_e {
SSH_PACKET_UNKNOWN,
SSH_PACKET_ALLOWED,
SSH_PACKET_DENIED
};
int packet_send(ssh_session session);
#ifdef WITH_SSH1
@@ -90,6 +82,6 @@ unsigned char *packet_encrypt(ssh_session session,
void *packet,
unsigned int len);
int packet_hmac_verify(ssh_session session,ssh_buffer buffer,
unsigned char *mac, enum ssh_hmac_e type);
unsigned char *mac);
#endif /* PACKET_H_ */

View File

@@ -21,7 +21,6 @@
#ifndef PKI_H_
#define PKI_H_
#include "libssh/priv.h"
#ifdef HAVE_OPENSSL_EC_H
#include <openssl/ec.h>
#endif
@@ -30,7 +29,6 @@
#endif
#include "libssh/crypto.h"
#include "libssh/ed25519.h"
#define MAX_PUBKEY_SIZE 0x100000 /* 1M */
#define MAX_PRIVKEY_SIZE 0x400000 /* 4M */
@@ -57,8 +55,6 @@ struct ssh_key_struct {
void *ecdsa;
#endif /* HAVE_OPENSSL_EC_H */
#endif
ed25519_pubkey *ed25519_pubkey;
ed25519_privkey *ed25519_privkey;
void *cert;
};
@@ -78,7 +74,6 @@ struct ssh_signature_struct {
void *ecdsa_sig;
# endif
#endif
ed25519_signature *ed25519_sig;
};
typedef struct ssh_signature_struct *ssh_signature;

View File

@@ -21,30 +21,15 @@
#ifndef PKI_PRIV_H_
#define PKI_PRIV_H_
#include "libssh/pki.h"
/* defined in bcrypt_pbkdf.c */
int bcrypt_pbkdf(const char *pass,
size_t passlen,
const uint8_t *salt,
size_t saltlen,
uint8_t *key,
size_t keylen,
unsigned int rounds);
#define RSA_HEADER_BEGIN "-----BEGIN RSA PRIVATE KEY-----"
#define RSA_HEADER_END "-----END RSA PRIVATE KEY-----"
#define DSA_HEADER_BEGIN "-----BEGIN DSA PRIVATE KEY-----"
#define DSA_HEADER_END "-----END DSA PRIVATE KEY-----"
#define ECDSA_HEADER_BEGIN "-----BEGIN EC PRIVATE KEY-----"
#define ECDSA_HEADER_END "-----END EC PRIVATE KEY-----"
#define OPENSSH_HEADER_BEGIN "-----BEGIN OPENSSH PRIVATE KEY-----"
#define OPENSSH_HEADER_END "-----END OPENSSH PRIVATE KEY-----"
/* Magic defined in OpenSSH/PROTOCOL.key */
#define OPENSSH_AUTH_MAGIC "openssh-key-v1"
#define ssh_pki_log(...) \
_ssh_log(SSH_LOG_FUNCTIONS, __func__, __VA_ARGS__)
_ssh_pki_log(__FUNCTION__, __VA_ARGS__)
void _ssh_pki_log(const char *function,
const char *format, ...) PRINTF_ATTRIBUTE(2, 3);
@@ -56,8 +41,6 @@ ssh_key pki_key_dup(const ssh_key key, int demote);
int pki_key_generate_rsa(ssh_key key, int parameter);
int pki_key_generate_dss(ssh_key key, int parameter);
int pki_key_generate_ecdsa(ssh_key key, int parameter);
int pki_key_generate_ed25519(ssh_key key);
int pki_key_compare(const ssh_key k1,
const ssh_key k2,
enum ssh_keycmp_e what);
@@ -108,22 +91,4 @@ ssh_signature pki_do_sign(const ssh_key privkey,
ssh_signature pki_do_sign_sessionid(const ssh_key key,
const unsigned char *hash,
size_t hlen);
int pki_ed25519_sign(const ssh_key privkey, ssh_signature sig,
const unsigned char *hash, size_t hlen);
int pki_ed25519_verify(const ssh_key pubkey, ssh_signature sig,
const unsigned char *hash, size_t hlen);
int pki_ed25519_key_cmp(const ssh_key k1,
const ssh_key k2,
enum ssh_keycmp_e what);
int pki_ed25519_key_dup(ssh_key new, const ssh_key key);
int pki_ed25519_public_key_to_blob(ssh_buffer buffer, ssh_key key);
ssh_string pki_ed25519_sig_to_blob(ssh_signature sig);
int pki_ed25519_sig_from_blob(ssh_signature sig, ssh_string sig_blob);
/* PKI Container OpenSSH */
ssh_key ssh_pki_openssh_privkey_import(const char *text_key,
const char *passphrase, ssh_auth_callback auth_fn, void *auth_data);
ssh_string ssh_pki_openssh_privkey_export(const ssh_key privkey,
const char *passphrase, ssh_auth_callback auth_fn, void *auth_data);
#endif /* PKI_PRIV_H_ */

View File

@@ -31,8 +31,6 @@
#include "config.h"
#include <stddef.h>
#if !defined(HAVE_STRTOULL)
# if defined(HAVE___STRTOULL)
# define strtoull __strtoull
@@ -45,20 +43,6 @@
# endif
#endif /* !defined(HAVE_STRTOULL) */
#if !defined(HAVE_STRNDUP)
char *strndup(const char *s, size_t n);
#endif /* ! HAVE_STRNDUP */
#ifdef HAVE_BYTESWAP_H
#include <byteswap.h>
#endif
#ifndef bswap_32
#define bswap_32(x) \
((((x) & 0xff000000) >> 24) | (((x) & 0x00ff0000) >> 8) | \
(((x) & 0x0000ff00) << 8) | (((x) & 0x000000ff) << 24))
#endif
#ifdef _WIN32
/* Imitate define of inttypes.h */
@@ -76,16 +60,11 @@ char *strndup(const char *s, size_t n);
# ifdef _MSC_VER
# include <stdio.h>
# include <stdarg.h> /* va_copy define check */
/* On Microsoft compilers define inline to __inline on all others use inline */
# undef inline
# define inline __inline
# ifndef va_copy
# define va_copy(dest, src) (dest = src)
# endif
# define strcasecmp _stricmp
# define strncasecmp _strnicmp
# if ! defined(HAVE_ISBLANK)
@@ -130,15 +109,11 @@ char *strndup(const char *s, size_t n);
struct timeval;
int gettimeofday(struct timeval *__p, void *__t);
#define _XCLOSESOCKET closesocket
#else /* _WIN32 */
#include <unistd.h>
#define PRIdS "zd"
#define _XCLOSESOCKET close
#endif /* _WIN32 */
#include "libssh/libssh.h"
@@ -152,10 +127,10 @@ int gettimeofday(struct timeval *__p, void *__t);
#define ERROR_BUFFERLEN 1024
#endif
#ifndef CLIENTBANNER1
#define CLIENTBANNER1 "SSH-1.5-libssh_" SSH_STRINGIFY(LIBSSH_VERSION)
#define CLIENTBANNER1 "SSH-1.5-libssh-" SSH_STRINGIFY(LIBSSH_VERSION)
#endif
#ifndef CLIENTBANNER2
#define CLIENTBANNER2 "SSH-2.0-libssh_" SSH_STRINGIFY(LIBSSH_VERSION)
#define CLIENTBANNER2 "SSH-2.0-libssh-" SSH_STRINGIFY(LIBSSH_VERSION)
#endif
#ifndef KBDINT_MAX_PROMPT
#define KBDINT_MAX_PROMPT 256 /* more than openssh's :) */
@@ -164,12 +139,10 @@ int gettimeofday(struct timeval *__p, void *__t);
#define MAX_BUF_SIZE 4096
#endif
#ifndef HAVE_COMPILER__FUNC__
# ifdef HAVE_COMPILER__FUNCTION__
# define __func__ __FUNCTION__
# else
# error "Your system must provide a __func__ macro"
# endif
#ifndef __FUNCTION__
#if defined(__SUNPRO_C)
#define __FUNCTION__ __func__
#endif
#endif
#if defined(HAVE_GCC_THREAD_LOCAL_STORAGE)
@@ -206,7 +179,7 @@ void ssh_log_function(int verbosity,
const char *function,
const char *buffer);
#define SSH_LOG(priority, ...) \
_ssh_log(priority, __func__, __VA_ARGS__)
_ssh_log(priority, __FUNCTION__, __VA_ARGS__)
/* LEGACY */
void ssh_log_common(struct ssh_common_struct *common,
@@ -224,18 +197,18 @@ struct error_struct {
};
#define ssh_set_error(error, code, ...) \
_ssh_set_error(error, code, __func__, __VA_ARGS__)
_ssh_set_error(error, code, __FUNCTION__, __VA_ARGS__)
void _ssh_set_error(void *error,
int code,
const char *function,
const char *descr, ...) PRINTF_ATTRIBUTE(4, 5);
#define ssh_set_error_oom(error) \
_ssh_set_error_oom(error, __func__)
_ssh_set_error_oom(error, __FUNCTION__)
void _ssh_set_error_oom(void *error, const char *function);
#define ssh_set_error_invalid(error) \
_ssh_set_error_invalid(error, __func__)
_ssh_set_error_invalid(error, __FUNCTION__)
void _ssh_set_error_invalid(void *error, const char *function);
@@ -265,9 +238,8 @@ int decompress_buffer(ssh_session session,ssh_buffer buf, size_t maxlen);
/* match.c */
int match_hostname(const char *host, const char *pattern, unsigned int len);
#ifndef MIN
#define MIN(a,b) ((a) < (b) ? (a) : (b))
#endif
/** Free memory space */
#define SAFE_FREE(x) do { if ((x) != NULL) {free(x); x=NULL;} } while(0)
@@ -328,64 +300,5 @@ int match_hostname(const char *host, const char *pattern, unsigned int len);
*/
#define discard_const_p(type, ptr) ((type *)discard_const(ptr))
/**
* Get the argument cound of variadic arguments
*/
#ifdef HAVE_GCC_NARG_MACRO
/*
* Since MSVC 2010 there is a bug in passing __VA_ARGS__ to subsequent
* macros as a single token, which results in:
* warning C4003: not enough actual parameters for macro '_VA_ARG_N'
* and incorrect behavior. This fixes issue.
*/
#define VA_APPLY_VARIADIC_MACRO(macro, tuple) macro tuple
#define __VA_NARG__(...) \
(__VA_NARG_(_0, ## __VA_ARGS__, __RSEQ_N()) - 1)
#define __VA_NARG_(...) \
VA_APPLY_VARIADIC_MACRO(__VA_ARG_N, (__VA_ARGS__))
#define __VA_ARG_N( \
_1, _2, _3, _4, _5, _6, _7, _8, _9,_10, \
_11,_12,_13,_14,_15,_16,_17,_18,_19,_20, \
_21,_22,_23,_24,_25,_26,_27,_28,_29,_30, \
_31,_32,_33,_34,_35,_36,_37,_38,_39,_40, \
_41,_42,_43,_44,_45,_46,_47,_48,_49,_50, \
_51,_52,_53,_54,_55,_56,_57,_58,_59,_60, \
_61,_62,_63,N,...) N
#define __RSEQ_N() \
63, 62, 61, 60, \
59, 58, 57, 56, 55, 54, 53, 52, 51, 50, \
49, 48, 47, 46, 45, 44, 43, 42, 41, 40, \
39, 38, 37, 36, 35, 34, 33, 32, 31, 30, \
29, 28, 27, 26, 25, 24, 23, 22, 21, 20, \
19, 18, 17, 16, 15, 14, 13, 12, 11, 10, \
9, 8, 7, 6, 5, 4, 3, 2, 1, 0
#else
/* clang does not support the above construction */
#define __VA_NARG__(...) (-1)
#endif
#define CLOSE_SOCKET(s) do { if ((s) != SSH_INVALID_SOCKET) { _XCLOSESOCKET(s); (s) = SSH_INVALID_SOCKET;} } while(0)
#ifndef HAVE_HTONLL
# ifdef WORDS_BIGENDIAN
# define htonll(x) (x)
# else
# define htonll(x) \
(((uint64_t)htonl((x) & 0xFFFFFFFF) << 32) | htonl((x) >> 32))
# endif
#endif
#ifndef HAVE_NTOHLL
# ifdef WORDS_BIGENDIAN
# define ntohll(x) (x)
# else
# define ntohll(x) \
(((uint64_t)ntohl((x) & 0xFFFFFFFF) << 32) | ntohl((x) >> 32))
# endif
#endif
void ssh_agent_state_free(void *data);
#endif /* _LIBSSH_PRIV_H */
/* vim: set ts=4 sw=4 et cindent: */

View File

@@ -1,74 +0,0 @@
/* $OpenBSD: sc25519.h,v 1.3 2013/12/09 11:03:45 markus Exp $ */
/*
* Public Domain, Authors: Daniel J. Bernstein, Niels Duif, Tanja Lange,
* Peter Schwabe, Bo-Yin Yang.
* Copied from supercop-20130419/crypto_sign/ed25519/ref/sc25519.h
*/
#ifndef SC25519_H
#define SC25519_H
#define sc25519 crypto_sign_ed25519_ref_sc25519
#define shortsc25519 crypto_sign_ed25519_ref_shortsc25519
#define sc25519_from32bytes crypto_sign_ed25519_ref_sc25519_from32bytes
#define shortsc25519_from16bytes crypto_sign_ed25519_ref_shortsc25519_from16bytes
#define sc25519_from64bytes crypto_sign_ed25519_ref_sc25519_from64bytes
#define sc25519_from_shortsc crypto_sign_ed25519_ref_sc25519_from_shortsc
#define sc25519_to32bytes crypto_sign_ed25519_ref_sc25519_to32bytes
#define sc25519_iszero_vartime crypto_sign_ed25519_ref_sc25519_iszero_vartime
#define sc25519_isshort_vartime crypto_sign_ed25519_ref_sc25519_isshort_vartime
#define sc25519_lt_vartime crypto_sign_ed25519_ref_sc25519_lt_vartime
#define sc25519_add crypto_sign_ed25519_ref_sc25519_add
#define sc25519_sub_nored crypto_sign_ed25519_ref_sc25519_sub_nored
#define sc25519_mul crypto_sign_ed25519_ref_sc25519_mul
#define sc25519_mul_shortsc crypto_sign_ed25519_ref_sc25519_mul_shortsc
#define sc25519_window3 crypto_sign_ed25519_ref_sc25519_window3
#define sc25519_window5 crypto_sign_ed25519_ref_sc25519_window5
#define sc25519_2interleave2 crypto_sign_ed25519_ref_sc25519_2interleave2
typedef struct {
uint32_t v[32];
} sc25519;
typedef struct {
uint32_t v[16];
} shortsc25519;
void sc25519_from32bytes(sc25519 *r, const unsigned char x[32]);
void shortsc25519_from16bytes(shortsc25519 *r, const unsigned char x[16]);
void sc25519_from64bytes(sc25519 *r, const unsigned char x[64]);
void sc25519_from_shortsc(sc25519 *r, const shortsc25519 *x);
void sc25519_to32bytes(unsigned char r[32], const sc25519 *x);
int sc25519_iszero_vartime(const sc25519 *x);
int sc25519_isshort_vartime(const sc25519 *x);
int sc25519_lt_vartime(const sc25519 *x, const sc25519 *y);
void sc25519_add(sc25519 *r, const sc25519 *x, const sc25519 *y);
void sc25519_sub_nored(sc25519 *r, const sc25519 *x, const sc25519 *y);
void sc25519_mul(sc25519 *r, const sc25519 *x, const sc25519 *y);
void sc25519_mul_shortsc(sc25519 *r, const sc25519 *x, const shortsc25519 *y);
/* Convert s into a representation of the form \sum_{i=0}^{84}r[i]2^3
* with r[i] in {-4,...,3}
*/
void sc25519_window3(signed char r[85], const sc25519 *s);
/* Convert s into a representation of the form \sum_{i=0}^{50}r[i]2^5
* with r[i] in {-16,...,15}
*/
void sc25519_window5(signed char r[51], const sc25519 *s);
void sc25519_2interleave2(unsigned char r[127], const sc25519 *s1, const sc25519 *s2);
#endif

View File

@@ -127,15 +127,6 @@ struct ssh_session_struct {
struct ssh_agent_state_struct *agent_state;
struct ssh_auth_auto_state_struct *auth_auto_state;
/*
* RFC 4253, 7.1: if the first_kex_packet_follows flag was set in
* the received SSH_MSG_KEXINIT, but the guess was wrong, this
* field will be set such that the following guessed packet will
* be ignored. Once that packet has been received and ignored,
* this field is cleared.
*/
int first_kex_follows_guess_wrong;
ssh_buffer in_hashbuf;
ssh_buffer out_hashbuf;
struct ssh_crypto_struct *current_crypto;
@@ -156,7 +147,7 @@ struct ssh_session_struct {
ssh_key rsa_key;
ssh_key dsa_key;
ssh_key ecdsa_key;
ssh_key ed25519_key;
/* The type of host key wanted by client */
enum ssh_keytypes_e hostkey;
} srv;
@@ -197,9 +188,6 @@ struct ssh_session_struct {
char *gss_client_identity;
int gss_delegate_creds;
} opts;
/* counters */
ssh_counter socket_counter;
ssh_counter raw_counter;
};
/** @internal

View File

@@ -143,10 +143,10 @@ struct sftp_request_queue_struct {
/* SSH_FXP_MESSAGE described into .7 page 26 */
struct sftp_status_message_struct {
uint32_t id;
uint32_t status;
ssh_string error_unused; /* not used anymore */
ssh_string lang_unused; /* not used anymore */
uint32_t id;
uint32_t status;
ssh_string error;
ssh_string lang;
char *errormsg;
char *langmsg;
};

View File

@@ -22,7 +22,6 @@
#define WRAPPER_H_
#include "config.h"
#include "libssh/libssh.h"
#include "libssh/libcrypto.h"
#include "libssh/libgcrypt.h"
@@ -35,9 +34,6 @@ enum ssh_mac_e {
enum ssh_hmac_e {
SSH_HMAC_SHA1 = 1,
SSH_HMAC_SHA256,
SSH_HMAC_SHA384,
SSH_HMAC_SHA512,
SSH_HMAC_MD5
};
@@ -46,36 +42,16 @@ enum ssh_des_e {
SSH_DES
};
struct ssh_hmac_struct {
const char* name;
enum ssh_hmac_e hmac_type;
};
typedef struct ssh_mac_ctx_struct *ssh_mac_ctx;
MD5CTX md5_init(void);
void md5_update(MD5CTX c, const void *data, unsigned long len);
void md5_final(unsigned char *md,MD5CTX c);
SHACTX sha1_init(void);
void sha1_update(SHACTX c, const void *data, unsigned long len);
void sha1_final(unsigned char *md,SHACTX c);
void sha1(unsigned char *digest,int len,unsigned char *hash);
SHA256CTX sha256_init(void);
void sha256_update(SHA256CTX c, const void *data, unsigned long len);
void sha256_final(unsigned char *md,SHA256CTX c);
void sha256(unsigned char *digest, int len, unsigned char *hash);
SHA384CTX sha384_init(void);
void sha384_update(SHA384CTX c, const void *data, unsigned long len);
void sha384_final(unsigned char *md,SHA384CTX c);
void sha384(unsigned char *digest, int len, unsigned char *hash);
SHA512CTX sha512_init(void);
void sha512_update(SHA512CTX c, const void *data, unsigned long len);
void sha512_final(unsigned char *md,SHA512CTX c);
void sha512(unsigned char *digest, int len, unsigned char *hash);
void evp(int nid, unsigned char *digest, int len, unsigned char *hash, unsigned int *hlen);
EVPCTX evp_init(int nid);
void evp_update(EVPCTX ctx, const void *data, unsigned long len);
@@ -88,7 +64,6 @@ void ssh_mac_final(unsigned char *md, ssh_mac_ctx ctx);
HMACCTX hmac_init(const void *key,int len, enum ssh_hmac_e type);
void hmac_update(HMACCTX c, const void *data, unsigned long len);
void hmac_final(HMACCTX ctx,unsigned char *hashmacbuf,unsigned int *len);
size_t hmac_digest_len(enum ssh_hmac_e type);
int crypt_set_algorithms(ssh_session session, enum ssh_des_e des_type);
int crypt_set_algorithms_server(ssh_session session);
@@ -97,8 +72,4 @@ void crypto_free(struct ssh_crypto_struct *crypto);
void ssh_reseed(void);
void ssh_cipher_clear(struct ssh_cipher_struct *cipher);
struct ssh_hmac_struct *ssh_get_hmactab(void);
const char *ssh_hmac_type_to_string(enum ssh_hmac_e hmac_type);
#endif /* WRAPPER_H_ */

View File

@@ -1,12 +1,13 @@
project(libssh-library C)
set(LIBSSH_PUBLIC_INCLUDE_DIRS
${libssh_SOURCE_DIR}/include
${CMAKE_SOURCE_DIR}/include
CACHE INTERNAL "libssh public include directories"
)
set(LIBSSH_PRIVATE_INCLUDE_DIRS
${libssh_BINARY_DIR}
${CMAKE_BINARY_DIR}
${OPENSSL_INCLUDE_DIRS}
)
set(LIBSSH_LINK_LIBRARIES
@@ -27,17 +28,17 @@ if (HAVE_LIBSOCKET)
)
endif (HAVE_LIBSOCKET)
if (OPENSSL_CRYPTO_LIBRARY)
if (OPENSSL_LIBRARIES)
set(LIBSSH_PRIVATE_INCLUDE_DIRS
${LIBSSH_PRIVATE_INCLUDE_DIRS}
${OPENSSL_INCLUDE_DIR}
${OPENSSL_INCLUDE_DIRS}
)
set(LIBSSH_LINK_LIBRARIES
${LIBSSH_LINK_LIBRARIES}
${OPENSSL_CRYPTO_LIBRARY}
${OPENSSL_LIBRARIES}
)
endif (OPENSSL_CRYPTO_LIBRARY)
endif (OPENSSL_LIBRARIES)
if (GCRYPT_LIBRARY)
set(LIBSSH_PRIVATE_INCLUDE_DIRS
@@ -54,7 +55,7 @@ endif (GCRYPT_LIBRARY)
if (WITH_ZLIB)
set(LIBSSH_PRIVATE_INCLUDE_DIRS
${LIBSSH_PRIVATE_INCLUDE_DIRS}
${ZLIB_INCLUDE_DIR}
${ZLIB_INCLUDE_DIRS}
)
set(LIBSSH_LINK_LIBRARIES
@@ -108,7 +109,6 @@ set(libssh_SRCS
agent.c
auth.c
base64.c
bignum.c
buffer.c
callbacks.c
channels.c
@@ -124,6 +124,7 @@ set(libssh_SRCS
kex.c
known_hosts.c
legacy.c
libcrypto.c
log.c
match.c
messages.c
@@ -134,8 +135,6 @@ set(libssh_SRCS
packet_crypt.c
pcap.c
pki.c
pki_container_openssh.c
pki_ed25519.c
poll.c
session.c
scp.c
@@ -143,12 +142,6 @@ set(libssh_SRCS
string.c
threads.c
wrapper.c
external/bcrypt_pbkdf.c
external/blowfish.c
external/ed25519.c
external/fe25519.c
external/ge25519.c
external/sc25519.c
)
if (WITH_GCRYPT)
@@ -162,11 +155,7 @@ else (WITH_GCRYPT)
set(libssh_SRCS
${libssh_SRCS}
pki_crypto.c
libcrypto.c
)
if(OPENSSL_VERSION VERSION_LESS "1.1.0")
set(libssh_SRCS ${libssh_SRCS} libcrypto-compat.c)
endif()
endif (WITH_GCRYPT)
if (WITH_SFTP)
@@ -219,7 +208,7 @@ endif (WITH_GSSAPI AND GSSAPI_FOUND)
if (NOT WITH_NACL)
set(libssh_SRCS
${libssh_SRCS}
external/curve25519_ref.c
curve25519_ref.c
)
endif (NOT WITH_NACL)
@@ -249,10 +238,6 @@ if (WITH_VISIBILITY_HIDDEN)
set_target_properties(${LIBSSH_SHARED_LIBRARY} PROPERTIES COMPILE_FLAGS "-fvisibility=hidden")
endif (WITH_VISIBILITY_HIDDEN)
if (MINGW)
set_target_properties(${LIBSSH_SHARED_LIBRARY} PROPERTIES LINK_FLAGS "-Wl,--enable-stdcall-fixup")
endif ()
install(
TARGETS
@@ -303,7 +288,6 @@ if (WITH_STATIC_LIB)
)
endif (WITH_STATIC_LIB)
message(STATUS "Threads_FOUND=${Threads_FOUND}")
if (Threads_FOUND)
add_subdirectory(threads)
endif (Threads_FOUND)

View File

@@ -185,32 +185,15 @@ int ssh_set_agent_channel(ssh_session session, ssh_channel channel){
return SSH_OK;
}
/** @brief sets the SSH agent socket.
* The SSH agent will be used to authenticate this client using
* the given socket to communicate with the ssh-agent. The caller
* is responsible for connecting to the socket prior to calling
* this function.
* @returns SSH_OK in case of success
* SSH_ERROR in case of an error
*/
int ssh_set_agent_socket(ssh_session session, socket_t fd){
if (!session)
return SSH_ERROR;
if (!session->agent){
ssh_set_error(session, SSH_REQUEST_DENIED, "Session has no active agent");
return SSH_ERROR;
}
ssh_socket_set_fd(session->agent->sock, fd);
return SSH_OK;
}
void agent_close(struct ssh_agent_struct *agent) {
if (agent == NULL) {
return;
}
ssh_socket_close(agent->sock);
if (getenv("SSH_AUTH_SOCK")) {
ssh_socket_close(agent->sock);
}
}
void agent_free(ssh_agent agent) {
@@ -317,7 +300,7 @@ static int agent_talk(struct ssh_session_struct *session,
"Error reading response from authentication socket.");
return -1;
}
if (ssh_buffer_add_data(reply, payload, n) < 0) {
if (buffer_add_data(reply, payload, n) < 0) {
SSH_LOG(SSH_LOG_WARN, "Not enough space");
return -1;
}
@@ -382,9 +365,6 @@ int ssh_agent_get_ident_count(struct ssh_session_struct *session) {
ssh_buffer_free(reply);
return -1;
}
#ifdef WORDS_BIGENDIAN
type = bswap_32(type);
#endif
SSH_LOG(SSH_LOG_WARN,
"Answer type: %d, expected answer: %d",
@@ -395,7 +375,7 @@ int ssh_agent_get_ident_count(struct ssh_session_struct *session) {
return 0;
} else if (type != c2) {
ssh_set_error(session, SSH_FATAL,
"Bad authentication reply message type: %u", type);
"Bad authentication reply message type: %d", type);
ssh_buffer_free(reply);
return -1;
}
@@ -413,7 +393,7 @@ int ssh_agent_get_ident_count(struct ssh_session_struct *session) {
}
if (session->agent->ident) {
ssh_buffer_reinit(session->agent->ident);
buffer_reinit(session->agent->ident);
}
session->agent->ident = reply;
@@ -510,8 +490,8 @@ ssh_string ssh_agent_sign_data(ssh_session session,
ssh_buffer reply;
ssh_string key_blob;
ssh_string sig_blob;
unsigned int type = 0;
unsigned int flags = 0;
int type = SSH2_AGENT_FAILURE;
int flags = 0;
uint32_t dlen;
int rc;
@@ -546,7 +526,7 @@ ssh_string ssh_agent_sign_data(ssh_session session,
ssh_buffer_free(request);
return NULL;
}
if (ssh_buffer_add_data(request, buffer_get_rest(data), dlen) < 0) {
if (buffer_add_data(request, buffer_get_rest(data), dlen) < 0) {
ssh_buffer_free(request);
return NULL;
}
@@ -575,19 +555,13 @@ ssh_string ssh_agent_sign_data(ssh_session session,
ssh_buffer_free(reply);
return NULL;
}
#ifdef WORDS_BIGENDIAN
type = bswap_32(type);
#endif
if (agent_failed(type)) {
SSH_LOG(SSH_LOG_WARN, "Agent reports failure in signing the key");
ssh_buffer_free(reply);
return NULL;
} else if (type != SSH2_AGENT_SIGN_RESPONSE) {
ssh_set_error(session,
SSH_FATAL,
"Bad authentication response: %u",
type);
ssh_set_error(session, SSH_FATAL, "Bad authentication response: %d", type);
ssh_buffer_free(reply);
return NULL;
}

661
src/auth.c Executable file → Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -23,7 +23,6 @@
#include "config.h"
#include <errno.h>
#include <string.h>
#include <stdlib.h>
@@ -118,7 +117,6 @@ static int send_username(ssh_session session, const char *username) {
if (packet_send(session) == SSH_ERROR) {
return SSH_AUTH_ERROR;
}
return SSH_AUTH_AGAIN;
pending:
rc = wait_auth1_status(session);
switch (rc){
@@ -163,14 +161,12 @@ int ssh_userauth1_password(ssh_session session, const char *username,
ssh_string pwd = NULL;
int rc;
if (session->pending_call_state == SSH_PENDING_CALL_AUTH_PASSWORD) {
goto pending;
}
rc = send_username(session, username);
if (rc != SSH_AUTH_DENIED) {
return rc;
}
if (session->pending_call_state == SSH_PENDING_CALL_AUTH_PASSWORD)
goto pending;
/* we trick a bit here. A known flaw in SSH1 protocol is that it's
* easy to guess password sizes.
* not that sure ...
@@ -223,11 +219,8 @@ int ssh_userauth1_password(ssh_session session, const char *username,
}
pending:
rc = wait_auth1_status(session);
if (rc == SSH_AUTH_ERROR && errno == EAGAIN) {
/* Nothing to do */
} else if (rc != SSH_AUTH_AGAIN) {
session->pending_call_state = SSH_PENDING_CALL_NONE;
}
if (rc != SSH_AUTH_AGAIN)
session->pending_call_state = SSH_PENDING_CALL_NONE;
return rc;
}

View File

@@ -82,18 +82,13 @@ ssh_buffer base64_to_bin(const char *source) {
SAFE_FREE(base64);
return NULL;
}
/*
* The base64 buffer often contains sensitive data. Make sure we don't leak
* sensitive data
*/
ssh_buffer_set_secure(buffer);
len = strlen(ptr);
while (len > 4) {
if (_base64_to_bin(block, ptr, 3) < 0) {
goto error;
}
if (ssh_buffer_add_data(buffer, block, 3) < 0) {
if (buffer_add_data(buffer, block, 3) < 0) {
goto error;
}
len -= 4;
@@ -117,7 +112,7 @@ ssh_buffer base64_to_bin(const char *source) {
if (_base64_to_bin(block, ptr, 3) < 0) {
goto error;
}
if (ssh_buffer_add_data(buffer, block, 3) < 0) {
if (buffer_add_data(buffer, block, 3) < 0) {
goto error;
}
SAFE_FREE(base64);
@@ -136,7 +131,7 @@ ssh_buffer base64_to_bin(const char *source) {
if (_base64_to_bin(block, ptr, 1) < 0) {
goto error;
}
if (ssh_buffer_add_data(buffer, block, 1) < 0) {
if (buffer_add_data(buffer, block, 1) < 0) {
goto error;
}
SAFE_FREE(base64);
@@ -154,7 +149,7 @@ ssh_buffer base64_to_bin(const char *source) {
if (_base64_to_bin(block, ptr, 2) < 0) {
goto error;
}
if (ssh_buffer_add_data(buffer,block,2) < 0) {
if (buffer_add_data(buffer,block,2) < 0) {
goto error;
}
SAFE_FREE(base64);

View File

@@ -1,111 +0,0 @@
/*
* This file is part of the SSH Library
*
* Copyright (c) 2014 by Aris Adamantiadis <aris@badcode.be>
*
* The SSH 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 SSH 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 SSH Library; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
* MA 02111-1307, USA.
*/
#include <stdio.h>
#include "libssh/priv.h"
#include "libssh/bignum.h"
#include "libssh/string.h"
ssh_string make_bignum_string(bignum num) {
ssh_string ptr = NULL;
int pad = 0;
unsigned int len = bignum_num_bytes(num);
unsigned int bits = bignum_num_bits(num);
if (len == 0) {
return NULL;
}
/* If the first bit is set we have a negative number */
if (!(bits % 8) && bignum_is_bit_set(num, bits - 1)) {
pad++;
}
#ifdef DEBUG_CRYPTO
fprintf(stderr, "%d bits, %d bytes, %d padding\n", bits, len, pad);
#endif /* DEBUG_CRYPTO */
ptr = ssh_string_new(len + pad);
if (ptr == NULL) {
return NULL;
}
/* We have a negative number so we need a leading zero */
if (pad) {
ptr->data[0] = 0;
}
#ifdef HAVE_LIBGCRYPT
bignum_bn2bin(num, len, ptr->data + pad);
#elif HAVE_LIBCRYPTO
bignum_bn2bin(num, ptr->data + pad);
#endif
return ptr;
}
bignum make_string_bn(ssh_string string){
bignum bn = NULL;
unsigned int len = ssh_string_len(string);
#ifdef DEBUG_CRYPTO
fprintf(stderr, "Importing a %d bits, %d bytes object ...\n",
len * 8, len);
#endif /* DEBUG_CRYPTO */
#ifdef HAVE_LIBGCRYPT
bignum_bin2bn(string->data, len, &bn);
#elif defined HAVE_LIBCRYPTO
bn = bignum_bin2bn(string->data, len, NULL);
#endif
return bn;
}
void make_string_bn_inplace(ssh_string string, bignum bnout) {
unsigned int len = ssh_string_len(string);
#ifdef HAVE_LIBGCRYPT
/* XXX: FIXME as needed for LIBGCRYPT ECDSA codepaths. */
(void) len;
(void) bnout;
#elif defined HAVE_LIBCRYPTO
bignum_bin2bn(string->data, len, bnout);
#endif
}
/* prints the bignum on stderr */
void ssh_print_bignum(const char *which, bignum num) {
#ifdef HAVE_LIBGCRYPT
unsigned char *hex = NULL;
bignum_bn2hex(num, &hex);
#elif defined HAVE_LIBCRYPTO
char *hex = NULL;
hex = bignum_bn2hex(num);
#endif
fprintf(stderr, "%s value: ", which);
fprintf(stderr, "%s\n", (hex == NULL) ? "(null)" : (char *) hex);
#ifdef HAVE_LIBGCRYPT
SAFE_FREE(hex);
#elif defined HAVE_LIBCRYPTO
OPENSSL_free(hex);
#endif
}

View File

@@ -109,7 +109,7 @@ static socket_t bind_socket(ssh_bind sshbind, const char *hostname,
"Setting socket options failed: %s",
strerror(errno));
freeaddrinfo (ai);
CLOSE_SOCKET(s);
close(s);
return -1;
}
@@ -121,7 +121,7 @@ static socket_t bind_socket(ssh_bind sshbind, const char *hostname,
port,
strerror(errno));
freeaddrinfo (ai);
CLOSE_SOCKET(s);
close(s);
return -1;
}
@@ -259,7 +259,7 @@ int ssh_bind_listen(ssh_bind sshbind) {
ssh_set_error(sshbind, SSH_FATAL,
"Listening to socket %d: %s",
fd, strerror(errno));
CLOSE_SOCKET(fd);
close(fd);
ssh_key_free(sshbind->dsa);
sshbind->dsa = NULL;
ssh_key_free(sshbind->rsa);
@@ -350,7 +350,11 @@ void ssh_bind_free(ssh_bind sshbind){
}
if (sshbind->bindfd >= 0) {
CLOSE_SOCKET(sshbind->bindfd);
#ifdef _WIN32
closesocket(sshbind->bindfd);
#else
close(sshbind->bindfd);
#endif
}
sshbind->bindfd = SSH_INVALID_SOCKET;
@@ -361,7 +365,6 @@ void ssh_bind_free(ssh_bind sshbind){
SAFE_FREE(sshbind->dsakey);
SAFE_FREE(sshbind->rsakey);
SAFE_FREE(sshbind->ecdsakey);
SAFE_FREE(sshbind->ed25519key);
ssh_key_free(sshbind->dsa);
sshbind->dsa = NULL;
@@ -369,8 +372,6 @@ void ssh_bind_free(ssh_bind sshbind){
sshbind->rsa = NULL;
ssh_key_free(sshbind->ecdsa);
sshbind->ecdsa = NULL;
ssh_key_free(sshbind->ed25519);
sshbind->ed25519 = NULL;
for (i = 0; i < 10; i++) {
if (sshbind->wanted_methods[i]) {
@@ -393,7 +394,7 @@ int ssh_bind_accept_fd(ssh_bind sshbind, ssh_session session, socket_t fd){
session->version = 2;
/* copy options */
for (i = 0; i < 10; i++) {
for (i = 0; i < 10; ++i) {
if (sshbind->wanted_methods[i]) {
session->opts.wanted_methods[i] = strdup(sshbind->wanted_methods[i]);
if (session->opts.wanted_methods[i] == NULL) {
@@ -458,14 +459,6 @@ int ssh_bind_accept_fd(ssh_bind sshbind, ssh_session session, socket_t fd){
return SSH_ERROR;
}
}
if (sshbind->ed25519 != NULL) {
session->srv.ed25519_key = ssh_key_dup(sshbind->ed25519);
if (session->srv.ed25519_key == NULL){
ssh_set_error_oom(sshbind);
return SSH_ERROR;
}
}
/* force PRNG to change state in case we fork after ssh_bind_accept */
ssh_reseed();
return SSH_OK;
@@ -495,7 +488,11 @@ int ssh_bind_accept(ssh_bind sshbind, ssh_session session) {
rc = ssh_bind_accept_fd(sshbind, session, fd);
if(rc == SSH_ERROR){
CLOSE_SOCKET(fd);
#ifdef _WIN32
closesocket(fd);
#else
close(fd);
#endif
ssh_socket_free(session->socket);
}
return rc;

View File

@@ -24,7 +24,6 @@
#include <limits.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#ifndef _WIN32
#include <netinet/in.h>
@@ -33,8 +32,6 @@
#include "libssh/priv.h"
#include "libssh/buffer.h"
#include "libssh/misc.h"
#include "libssh/bignum.h"
/**
* @defgroup libssh_buffer The SSH buffer functions.
@@ -107,25 +104,13 @@ void ssh_buffer_free(struct ssh_buffer_struct *buffer) {
if (buffer->data) {
/* burn the data */
BURN_BUFFER(buffer->data, buffer->allocated);
memset(buffer->data, 0, buffer->allocated);
SAFE_FREE(buffer->data);
}
BURN_BUFFER(buffer, sizeof(struct ssh_buffer_struct));
memset(buffer, 'X', sizeof(*buffer));
SAFE_FREE(buffer);
}
/**
* @brief Sets the buffer as secure.
*
* A secure buffer will never leave cleartext data in the heap
* after being reallocated or freed.
*
* @param[in] buffer buffer to set secure.
*/
void ssh_buffer_set_secure(ssh_buffer buffer){
buffer->secure = 1;
}
static int realloc_buffer(struct ssh_buffer_struct *buffer, size_t needed) {
size_t smallest = 1;
char *new;
@@ -140,20 +125,9 @@ static int realloc_buffer(struct ssh_buffer_struct *buffer, size_t needed) {
smallest <<= 1;
}
needed = smallest;
if (buffer->secure){
new = malloc(needed);
if (new == NULL) {
return -1;
}
memcpy(new, buffer->data,buffer->used);
BURN_BUFFER(buffer->data, buffer->used);
SAFE_FREE(buffer->data);
} else {
new = realloc(buffer->data, needed);
if (new == NULL) {
buffer->data = NULL;
return -1;
}
new = realloc(buffer->data, needed);
if (new == NULL) {
return -1;
}
buffer->data = new;
buffer->allocated = needed;
@@ -166,20 +140,12 @@ static int realloc_buffer(struct ssh_buffer_struct *buffer, size_t needed) {
* @param buffer SSH buffer
*/
static void buffer_shift(ssh_buffer buffer){
uint32_t burn_pos = buffer->pos;
buffer_verify(buffer);
if(buffer->pos==0)
return;
memmove(buffer->data, buffer->data + buffer->pos, buffer->used - buffer->pos);
buffer->used -= buffer->pos;
buffer->pos=0;
if (buffer->secure){
void *ptr = buffer->data + buffer->used;
BURN_BUFFER(ptr, burn_pos);
}
buffer_verify(buffer);
}
@@ -192,10 +158,9 @@ static void buffer_shift(ssh_buffer buffer){
*
* @return 0 on success, < 0 on error.
*/
int ssh_buffer_reinit(struct ssh_buffer_struct *buffer)
{
int buffer_reinit(struct ssh_buffer_struct *buffer) {
buffer_verify(buffer);
BURN_BUFFER(buffer->data, buffer->used);
memset(buffer->data, 0, buffer->used);
buffer->used = 0;
buffer->pos = 0;
if(buffer->allocated > 127) {
@@ -220,14 +185,9 @@ int ssh_buffer_reinit(struct ssh_buffer_struct *buffer)
*
* @return 0 on success, < 0 on error.
*/
int ssh_buffer_add_data(struct ssh_buffer_struct *buffer, const void *data, uint32_t len)
{
int buffer_add_data(struct ssh_buffer_struct *buffer, const void *data, uint32_t len) {
buffer_verify(buffer);
if (data == NULL) {
return -1;
}
if (buffer->used + len < len) {
return -1;
}
@@ -261,12 +221,8 @@ int buffer_add_ssh_string(struct ssh_buffer_struct *buffer,
struct ssh_string_struct *string) {
uint32_t len = 0;
if (string == NULL) {
return -1;
}
len = ssh_string_len(string);
if (ssh_buffer_add_data(buffer, string, len + sizeof(uint32_t)) < 0) {
if (buffer_add_data(buffer, string, len + sizeof(uint32_t)) < 0) {
return -1;
}
@@ -284,16 +240,12 @@ int buffer_add_ssh_string(struct ssh_buffer_struct *buffer,
*
* @return 0 on success, -1 on error.
*/
int buffer_add_u32(struct ssh_buffer_struct *buffer,uint32_t data)
{
int rc;
int buffer_add_u32(struct ssh_buffer_struct *buffer,uint32_t data){
if (buffer_add_data(buffer, &data, sizeof(data)) < 0) {
return -1;
}
rc = ssh_buffer_add_data(buffer, &data, sizeof(data));
if (rc < 0) {
return -1;
}
return 0;
return 0;
}
/**
@@ -307,16 +259,12 @@ int buffer_add_u32(struct ssh_buffer_struct *buffer,uint32_t data)
*
* @return 0 on success, -1 on error.
*/
int buffer_add_u16(struct ssh_buffer_struct *buffer,uint16_t data)
{
int rc;
int buffer_add_u16(struct ssh_buffer_struct *buffer,uint16_t data){
if (buffer_add_data(buffer, &data, sizeof(data)) < 0) {
return -1;
}
rc = ssh_buffer_add_data(buffer, &data, sizeof(data));
if (rc < 0) {
return -1;
}
return 0;
return 0;
}
/**
@@ -330,16 +278,12 @@ int buffer_add_u16(struct ssh_buffer_struct *buffer,uint16_t data)
*
* @return 0 on success, -1 on error.
*/
int buffer_add_u64(struct ssh_buffer_struct *buffer, uint64_t data)
{
int rc;
int buffer_add_u64(struct ssh_buffer_struct *buffer, uint64_t data){
if (buffer_add_data(buffer, &data, sizeof(data)) < 0) {
return -1;
}
rc = ssh_buffer_add_data(buffer, &data, sizeof(data));
if (rc < 0) {
return -1;
}
return 0;
return 0;
}
/**
@@ -353,16 +297,12 @@ int buffer_add_u64(struct ssh_buffer_struct *buffer, uint64_t data)
*
* @return 0 on success, -1 on error.
*/
int buffer_add_u8(struct ssh_buffer_struct *buffer,uint8_t data)
{
int rc;
int buffer_add_u8(struct ssh_buffer_struct *buffer,uint8_t data){
if (buffer_add_data(buffer, &data, sizeof(uint8_t)) < 0) {
return -1;
}
rc = ssh_buffer_add_data(buffer, &data, sizeof(uint8_t));
if (rc < 0) {
return -1;
}
return 0;
return 0;
}
/**
@@ -420,18 +360,12 @@ int buffer_prepend_data(struct ssh_buffer_struct *buffer, const void *data,
* @return 0 on success, -1 on error.
*/
int buffer_add_buffer(struct ssh_buffer_struct *buffer,
struct ssh_buffer_struct *source)
{
int rc;
struct ssh_buffer_struct *source) {
if (buffer_add_data(buffer, buffer_get_rest(source), buffer_get_rest_len(source)) < 0) {
return -1;
}
rc = ssh_buffer_add_data(buffer,
buffer_get_rest(source),
buffer_get_rest_len(source));
if (rc < 0) {
return -1;
}
return 0;
return 0;
}
/**
@@ -563,15 +497,12 @@ uint32_t buffer_pass_bytes_end(struct ssh_buffer_struct *buffer, uint32_t len){
* @returns 0 if there is not enough data in buffer, len otherwise.
*/
uint32_t buffer_get_data(struct ssh_buffer_struct *buffer, void *data, uint32_t len){
int rc;
/*
* Check for a integer overflow first, then check if not enough data is in
* the buffer.
*/
rc = ssh_buffer_validate_length(buffer, len);
if (rc != SSH_OK) {
return 0;
if (buffer->pos + len < len || buffer->pos + len > buffer->used) {
return 0;
}
memcpy(data,buffer->data+buffer->pos,len);
buffer->pos+=len;
@@ -620,24 +551,6 @@ int buffer_get_u64(struct ssh_buffer_struct *buffer, uint64_t *data){
return buffer_get_data(buffer,data,sizeof(uint64_t));
}
/**
* @brief Valdiates that the given length can be obtained from the buffer.
*
* @param[in] buffer The buffer to read from.
*
* @param[in] len The length to be checked.
*
* @return SSH_OK if the length is valid, SSH_ERROR otherwise.
*/
int ssh_buffer_validate_length(struct ssh_buffer_struct *buffer, size_t len)
{
if (buffer->pos + len < len || buffer->pos + len > buffer->used) {
return SSH_ERROR;
}
return SSH_OK;
}
/**
* @internal
*
@@ -651,15 +564,13 @@ struct ssh_string_struct *buffer_get_ssh_string(struct ssh_buffer_struct *buffer
uint32_t stringlen;
uint32_t hostlen;
struct ssh_string_struct *str = NULL;
int rc;
if (buffer_get_u32(buffer, &stringlen) == 0) {
return NULL;
}
hostlen = ntohl(stringlen);
/* verify if there is enough space in buffer to get it */
rc = ssh_buffer_validate_length(buffer, hostlen);
if (rc != SSH_OK) {
if (buffer->pos + hostlen < hostlen || buffer->pos + hostlen > buffer->used) {
return NULL; /* it is indeed */
}
str = ssh_string_new(hostlen);
@@ -710,388 +621,6 @@ struct ssh_string_struct *buffer_get_mpint(struct ssh_buffer_struct *buffer) {
return str;
}
/** @internal
* @brief Add multiple values in a buffer on a single function call
* @param[in] buffer The buffer to add to
* @param[in] format A format string of arguments.
* @param[in] ap A va_list of arguments.
* @returns SSH_OK on success
* SSH_ERROR on error
* @see ssh_buffer_add_format() for format list values.
*/
int ssh_buffer_pack_va(struct ssh_buffer_struct *buffer,
const char *format,
int argc,
va_list ap)
{
int rc = SSH_ERROR;
const char *p;
union {
uint8_t byte;
uint16_t word;
uint32_t dword;
uint64_t qword;
ssh_string string;
void *data;
} o;
char *cstring;
bignum b;
size_t len;
int count;
for (p = format, count = 0; *p != '\0'; p++, count++) {
/* Invalid number of arguments passed */
if (argc != -1 && count > argc) {
return SSH_ERROR;
}
switch(*p) {
case 'b':
o.byte = (uint8_t)va_arg(ap, unsigned int);
rc = buffer_add_u8(buffer, o.byte);
break;
case 'w':
o.word = (uint16_t)va_arg(ap, unsigned int);
o.word = htons(o.word);
rc = buffer_add_u16(buffer, o.word);
break;
case 'd':
o.dword = va_arg(ap, uint32_t);
o.dword = htonl(o.dword);
rc = buffer_add_u32(buffer, o.dword);
break;
case 'q':
o.qword = va_arg(ap, uint64_t);
o.qword = htonll(o.qword);
rc = buffer_add_u64(buffer, o.qword);
break;
case 'S':
o.string = va_arg(ap, ssh_string);
rc = buffer_add_ssh_string(buffer, o.string);
o.string = NULL;
break;
case 's':
cstring = va_arg(ap, char *);
len = strlen(cstring);
rc = buffer_add_u32(buffer, htonl(len));
if (rc == SSH_OK){
rc = ssh_buffer_add_data(buffer, cstring, len);
}
cstring = NULL;
break;
case 'P':
len = va_arg(ap, size_t);
o.data = va_arg(ap, void *);
count++; /* increase argument count */
rc = ssh_buffer_add_data(buffer, o.data, len);
o.data = NULL;
break;
case 'B':
b = va_arg(ap, bignum);
o.string = make_bignum_string(b);
if(o.string == NULL){
rc = SSH_ERROR;
break;
}
rc = buffer_add_ssh_string(buffer, o.string);
SAFE_FREE(o.string);
break;
case 't':
cstring = va_arg(ap, char *);
len = strlen(cstring);
rc = ssh_buffer_add_data(buffer, cstring, len);
cstring = NULL;
break;
default:
SSH_LOG(SSH_LOG_WARN, "Invalid buffer format %c", *p);
rc = SSH_ERROR;
}
if (rc != SSH_OK){
break;
}
}
if (argc != -1 && argc != count) {
return SSH_ERROR;
}
if (rc != SSH_ERROR){
/* Check if our canary is intact, if not somthing really bad happened */
uint32_t canary = va_arg(ap, uint32_t);
if (canary != SSH_BUFFER_PACK_END) {
if (argc == -1){
return SSH_ERROR;
} else {
abort();
}
}
}
return rc;
}
/** @internal
* @brief Add multiple values in a buffer on a single function call
* @param[in] buffer The buffer to add to
* @param[in] format A format string of arguments. This string contains single
* letters describing the order and type of arguments:
* 'b': uint8_t (pushed in network byte order)
* 'w': uint16_t (pushed in network byte order)
* 'd': uint32_t (pushed in network byte order)
* 'q': uint64_t (pushed in network byte order)
* 'S': ssh_string
* 's': char * (C string, pushed as SSH string)
* 't': char * (C string, pushed as free text)
* 'P': size_t, void * (len of data, pointer to data)
* only pushes data.
* 'B': bignum (pushed as SSH string)
* @returns SSH_OK on success
* SSH_ERROR on error
* @warning when using 'P' with a constant size (e.g. 8), do not
* forget to cast to (size_t).
*/
int _ssh_buffer_pack(struct ssh_buffer_struct *buffer,
const char *format,
int argc,
...)
{
va_list ap;
int rc;
va_start(ap, argc);
rc = ssh_buffer_pack_va(buffer, format, argc, ap);
va_end(ap);
return rc;
}
/** @internal
* @brief Get multiple values from a buffer on a single function call
* @param[in] buffer The buffer to get from
* @param[in] format A format string of arguments.
* @param[in] ap A va_list of arguments.
* @returns SSH_OK on success
* SSH_ERROR on error
* @see ssh_buffer_get_format() for format list values.
*/
int ssh_buffer_unpack_va(struct ssh_buffer_struct *buffer,
const char *format,
int argc,
va_list ap)
{
int rc = SSH_ERROR;
const char *p, *last;
union {
uint8_t *byte;
uint16_t *word;
uint32_t *dword;
uint64_t *qword;
ssh_string *string;
char **cstring;
void **data;
} o;
size_t len, rlen, max_len;
uint32_t u32len;
va_list ap_copy;
int count;
max_len = ssh_buffer_get_len(buffer);
/* copy the argument list in case a rollback is needed */
va_copy(ap_copy, ap);
for (p = format, count = 0; *p != '\0'; p++, count++) {
/* Invalid number of arguments passed */
if (argc != -1 && count > argc) {
va_end(ap_copy);
return SSH_ERROR;
}
switch (*p) {
case 'b':
o.byte = va_arg(ap, uint8_t *);
rlen = buffer_get_u8(buffer, o.byte);
rc = rlen==1 ? SSH_OK : SSH_ERROR;
break;
case 'w':
o.word = va_arg(ap, uint16_t *);
rlen = buffer_get_data(buffer, o.word, sizeof(uint16_t));
*o.word = ntohs(*o.word);
rc = rlen==2 ? SSH_OK : SSH_ERROR;
break;
case 'd':
o.dword = va_arg(ap, uint32_t *);
rlen = buffer_get_u32(buffer, o.dword);
*o.dword = ntohl(*o.dword);
rc = rlen==4 ? SSH_OK : SSH_ERROR;
break;
case 'q':
o.qword = va_arg(ap, uint64_t*);
rlen = buffer_get_u64(buffer, o.qword);
*o.qword = ntohll(*o.qword);
rc = rlen==8 ? SSH_OK : SSH_ERROR;
break;
case 'S':
o.string = va_arg(ap, ssh_string *);
*o.string = buffer_get_ssh_string(buffer);
rc = *o.string != NULL ? SSH_OK : SSH_ERROR;
o.string = NULL;
break;
case 's':
o.cstring = va_arg(ap, char **);
*o.cstring = NULL;
rc = buffer_get_u32(buffer, &u32len);
if (rc != 4){
rc = SSH_ERROR;
break;
}
len = ntohl(u32len);
if (len > max_len - 1) {
rc = SSH_ERROR;
break;
}
rc = ssh_buffer_validate_length(buffer, len);
if (rc != SSH_OK) {
break;
}
*o.cstring = malloc(len + 1);
if (*o.cstring == NULL){
rc = SSH_ERROR;
break;
}
rlen = buffer_get_data(buffer, *o.cstring, len);
if (rlen != len){
SAFE_FREE(*o.cstring);
rc = SSH_ERROR;
break;
}
(*o.cstring)[len] = '\0';
o.cstring = NULL;
rc = SSH_OK;
break;
case 'P':
len = va_arg(ap, size_t);
if (len > max_len - 1) {
rc = SSH_ERROR;
break;
}
rc = ssh_buffer_validate_length(buffer, len);
if (rc != SSH_OK) {
break;
}
o.data = va_arg(ap, void **);
count++;
*o.data = malloc(len);
if(*o.data == NULL){
rc = SSH_ERROR;
break;
}
rlen = buffer_get_data(buffer, *o.data, len);
if (rlen != len){
SAFE_FREE(*o.data);
rc = SSH_ERROR;
break;
}
o.data = NULL;
rc = SSH_OK;
break;
default:
SSH_LOG(SSH_LOG_WARN, "Invalid buffer format %c", *p);
rc = SSH_ERROR;
}
if (rc != SSH_OK) {
break;
}
}
if (argc != -1 && argc != count) {
rc = SSH_ERROR;
}
if (rc != SSH_ERROR){
/* Check if our canary is intact, if not somthing really bad happened */
uint32_t canary = va_arg(ap, uint32_t);
if (canary != SSH_BUFFER_PACK_END){
if (argc == -1){
rc = SSH_ERROR;
} else {
abort();
}
}
}
if (rc != SSH_OK){
/* Reset the format string and erase everything that was allocated */
last = p;
for(p=format;p<last;++p){
switch(*p){
case 'b':
case 'w':
case 'd':
case 'q':
(void)va_arg(ap_copy, void *);
break;
case 'S':
o.string=va_arg(ap_copy, ssh_string *);
SAFE_FREE(*o.string);
break;
case 's':
o.cstring=va_arg(ap_copy, char **);
SAFE_FREE(*o.cstring);
break;
case 'P':
(void)va_arg(ap_copy, size_t);
o.data = va_arg(ap_copy, void **);
SAFE_FREE(*o.data);
break;
default:
(void)va_arg(ap_copy, void *);
break;
}
}
}
va_end(ap_copy);
return rc;
}
/** @internal
* @brief Get multiple values from a buffer on a single function call
* @param[in] buffer The buffer to get from
* @param[in] format A format string of arguments. This string contains single
* letters describing the order and type of arguments:
* 'b': uint8_t * (pulled in network byte order)
* 'w': uint16_t * (pulled in network byte order)
* 'd': uint32_t * (pulled in network byte order)
* 'q': uint64_t * (pulled in network byte order)
* 'S': ssh_string *
* 's': char ** (C string, pulled as SSH string)
* 'P': size_t, void ** (len of data, pointer to data)
* only pulls data.
* @returns SSH_OK on success
* SSH_ERROR on error
* @warning when using 'P' with a constant size (e.g. 8), do not
* forget to cast to (size_t).
*/
int _ssh_buffer_unpack(struct ssh_buffer_struct *buffer,
const char *format,
int argc,
...)
{
va_list ap;
int rc;
va_start(ap, argc);
rc = ssh_buffer_unpack_va(buffer, format, argc, ap);
va_end(ap);
return rc;
}
/** @} */
/* vim: set ts=4 sw=4 et cindent: */

File diff suppressed because it is too large Load Diff

View File

@@ -101,8 +101,7 @@ int channel_request_pty_size1(ssh_channel channel, const char *terminal, int col
}
session = channel->session;
if(channel->request_state != SSH_CHANNEL_REQ_STATE_NONE &&
channel->request_state != SSH_CHANNEL_REQ_STATE_ACCEPTED){
if(channel->request_state != SSH_CHANNEL_REQ_STATE_NONE){
ssh_set_error(session,SSH_REQUEST_DENIED,"Wrong request state");
return SSH_ERROR;
}
@@ -357,7 +356,7 @@ int channel_write1(ssh_channel channel, const void *data, int len) {
effectivelen = len > 32000 ? 32000 : len;
if (buffer_add_u32(session->out_buffer, htonl(effectivelen)) < 0 ||
ssh_buffer_add_data(session->out_buffer, ptr, effectivelen) < 0) {
buffer_add_data(session->out_buffer, ptr, effectivelen) < 0) {
return -1;
}
@@ -368,9 +367,6 @@ int channel_write1(ssh_channel channel, const void *data, int len) {
return -1;
}
ssh_handle_packets(session, SSH_TIMEOUT_NONBLOCKING);
if (channel->counter != NULL) {
channel->counter->out_bytes += effectivelen;
}
}
if (ssh_blocking_flush(session,SSH_TIMEOUT_USER) == SSH_ERROR)
return -1;

View File

@@ -90,74 +90,52 @@ static void socket_callback_connected(int code, int errno_code, void *user){
* @param user is a pointer to session
* @returns Number of bytes processed, or zero if the banner is not complete.
*/
static int callback_receive_banner(const void *data, size_t len, void *user)
{
char *buffer = (char *)data;
ssh_session session=(ssh_session) user;
char *str = NULL;
size_t i;
int ret=0;
static int callback_receive_banner(const void *data, size_t len, void *user) {
char *buffer = (char *)data;
ssh_session session=(ssh_session) user;
char *str = NULL;
size_t i;
int ret=0;
if (session->session_state != SSH_SESSION_STATE_SOCKET_CONNECTED) {
ssh_set_error(session,SSH_FATAL,
"Wrong state in callback_receive_banner : %d",
session->session_state);
if(session->session_state != SSH_SESSION_STATE_SOCKET_CONNECTED){
ssh_set_error(session,SSH_FATAL,"Wrong state in callback_receive_banner : %d",session->session_state);
return SSH_ERROR;
}
for (i = 0; i < len; ++i) {
return SSH_ERROR;
}
for(i=0;i<len;++i){
#ifdef WITH_PCAP
if (session->pcap_ctx && buffer[i] == '\n') {
ssh_pcap_context_write(session->pcap_ctx,
SSH_PCAP_DIR_IN,
buffer,i+1,
i+1);
}
if(session->pcap_ctx && buffer[i] == '\n'){
ssh_pcap_context_write(session->pcap_ctx,SSH_PCAP_DIR_IN,buffer,i+1,i+1);
}
#endif
if (buffer[i] == '\r') {
buffer[i] = '\0';
}
if (buffer[i] == '\n') {
int cmp;
buffer[i] = '\0';
/* The server MAY send other lines of data... */
cmp = strncmp(buffer, "SSH-", 4);
if (cmp == 0) {
str = strdup(buffer);
if (str == NULL) {
return SSH_ERROR;
}
/* number of bytes read */
ret = i + 1;
session->serverbanner = str;
session->session_state = SSH_SESSION_STATE_BANNER_RECEIVED;
SSH_LOG(SSH_LOG_PACKET, "Received banner: %s", str);
session->ssh_connection_callback(session);
return ret;
} else {
SSH_LOG(SSH_LOG_DEBUG,
"ssh_protocol_version_exchange: %s",
buffer);
ret = i + 1;
break;
}
}
/* According to RFC 4253 the max banner length is 255 */
if (i > 255) {
/* Too big banner */
session->session_state=SSH_SESSION_STATE_ERROR;
ssh_set_error(session,
SSH_FATAL,
"Receiving banner: too large banner");
return 0;
}
if(buffer[i]=='\r') {
buffer[i]='\0';
}
if (buffer[i]=='\n') {
buffer[i] = '\0';
str = strdup(buffer);
if (str == NULL) {
return SSH_ERROR;
}
/* number of bytes read */
ret = i + 1;
session->serverbanner = str;
session->session_state=SSH_SESSION_STATE_BANNER_RECEIVED;
SSH_LOG(SSH_LOG_PACKET,"Received banner: %s",str);
session->ssh_connection_callback(session);
return ret;
return ret;
}
if(i>127){
/* Too big banner */
session->session_state=SSH_SESSION_STATE_ERROR;
ssh_set_error(session,SSH_FATAL,"Receiving banner: too large banner");
return 0;
}
}
return ret;
}
/** @internal
@@ -169,75 +147,46 @@ static int callback_receive_banner(const void *data, size_t len, void *user)
*
* @return 0 on success, < 0 on error.
*/
int ssh_send_banner(ssh_session session, int server)
{
const char *banner = NULL;
const char *terminator = NULL;
/* The maximum banner length is 255 for SSH2 */
char buffer[256] = {0};
size_t len;
int rc = SSH_ERROR;
int ssh_send_banner(ssh_session session, int server) {
const char *banner = NULL;
char buffer[128] = {0};
int err=SSH_ERROR;
banner = session->version == 1 ? CLIENTBANNER1 : CLIENTBANNER2;
terminator = session->version == 1 ? "\n" : "\r\n";
banner = session->version == 1 ? CLIENTBANNER1 : CLIENTBANNER2;
if (server == 1) {
if (session->opts.custombanner == NULL){
len = strlen(banner);
session->serverbanner = strdup(banner);
if (session->serverbanner == NULL) {
goto end;
}
} else {
len = strlen(session->opts.custombanner);
session->serverbanner = malloc(len + 8 + 1);
if(session->serverbanner == NULL) {
goto end;
}
snprintf(session->serverbanner,
len + 8 + 1,
"SSH-2.0-%s",
session->opts.custombanner);
}
snprintf(buffer,
sizeof(buffer),
"%s%s",
session->serverbanner,
terminator);
if (server) {
if(session->opts.custombanner == NULL){
session->serverbanner = strdup(banner);
} else {
session->clientbanner = strdup(banner);
if (session->clientbanner == NULL) {
goto end;
}
/* SSH version 1 has a banner length of 128 only */
len = session->version == 1 ? 128 : 0;
snprintf(buffer,
sizeof(buffer) - len,
"%s%s",
session->clientbanner,
terminator);
session->serverbanner = malloc(strlen(session->opts.custombanner) + 9);
if(!session->serverbanner)
goto end;
strcpy(session->serverbanner, "SSH-2.0-");
strcat(session->serverbanner, session->opts.custombanner);
}
rc = ssh_socket_write(session->socket, buffer, strlen(buffer));
if (rc == SSH_ERROR) {
goto end;
if (session->serverbanner == NULL) {
goto end;
}
snprintf(buffer, 128, "%s\n", session->serverbanner);
} else {
session->clientbanner = strdup(banner);
if (session->clientbanner == NULL) {
goto end;
}
snprintf(buffer, 128, "%s\n", session->clientbanner);
}
if (ssh_socket_write(session->socket, buffer, strlen(buffer)) == SSH_ERROR) {
goto end;
}
#ifdef WITH_PCAP
if (session->pcap_ctx != NULL) {
ssh_pcap_context_write(session->pcap_ctx,
SSH_PCAP_DIR_OUT,
buffer,
strlen(buffer),
strlen(buffer));
}
if(session->pcap_ctx)
ssh_pcap_context_write(session->pcap_ctx,SSH_PCAP_DIR_OUT,buffer,strlen(buffer),strlen(buffer));
#endif
rc = SSH_OK;
err=SSH_OK;
end:
return rc;
return err;
}
/** @internal
@@ -320,19 +269,24 @@ static int ssh_service_request_termination(void *s){
* @bug actually only works with ssh-userauth
*/
int ssh_service_request(ssh_session session, const char *service) {
ssh_string service_s = NULL;
int rc=SSH_ERROR;
if(session->auth_service_state != SSH_AUTH_SERVICE_NONE)
goto pending;
rc = ssh_buffer_pack(session->out_buffer,
"bs",
SSH2_MSG_SERVICE_REQUEST,
service);
if (rc != SSH_OK){
ssh_set_error_oom(session);
if (buffer_add_u8(session->out_buffer, SSH2_MSG_SERVICE_REQUEST) < 0) {
return SSH_ERROR;
}
service_s = ssh_string_from_char(service);
if (service_s == NULL) {
return SSH_ERROR;
}
if (buffer_add_ssh_string(session->out_buffer,service_s) < 0) {
ssh_string_free(service_s);
return SSH_ERROR;
}
ssh_string_free(service_s);
session->auth_service_state=SSH_AUTH_SERVICE_SENT;
if (packet_send(session) == SSH_ERROR) {
ssh_set_error(session, SSH_FATAL,
@@ -386,13 +340,7 @@ static void ssh_client_connection_callback(ssh_session session){
switch(session->session_state){
case SSH_SESSION_STATE_NONE:
case SSH_SESSION_STATE_CONNECTING:
break;
case SSH_SESSION_STATE_SOCKET_CONNECTED:
/* If SSHv1 is disabled, we can send the banner immedietly */
if (session->opts.ssh1 == 0) {
ssh_set_fd_towrite(session);
ssh_send_banner(session, 0);
}
break;
case SSH_SESSION_STATE_BANNER_RECEIVED:
if (session->serverbanner == NULL) {
@@ -438,9 +386,7 @@ static void ssh_client_connection_callback(ssh_session session){
#endif
ssh_packet_set_default_callbacks(session);
session->session_state=SSH_SESSION_STATE_INITIAL_KEX;
if (session->opts.ssh1 == 1) {
ssh_send_banner(session, 0);
}
ssh_send_banner(session, 0);
set_status(session, 0.5f);
break;
case SSH_SESSION_STATE_INITIAL_KEX:
@@ -560,12 +506,7 @@ int ssh_connect(ssh_session session) {
ssh_set_error(session, SSH_FATAL, "Couldn't apply options");
return SSH_ERROR;
}
SSH_LOG(SSH_LOG_PROTOCOL,
"libssh %s, using threading %s",
ssh_copyright(),
ssh_threads_get_type());
SSH_LOG(SSH_LOG_RARE,"libssh %s, using threading %s", ssh_copyright(), ssh_threads_get_type());
session->ssh_connection_callback = ssh_client_connection_callback;
session->session_state=SSH_SESSION_STATE_CONNECTING;
ssh_socket_set_callbacks(session->socket,&session->socket_callbacks);
@@ -585,7 +526,7 @@ int ssh_connect(ssh_session session) {
} else {
ret=ssh_socket_connect(session->socket,
session->opts.host,
session->opts.port > 0 ? session->opts.port : 22,
session->opts.port,
session->opts.bindaddr);
}
if (ret == SSH_ERROR) {
@@ -604,7 +545,7 @@ pending:
if (timeout == 0) {
timeout = 10 * 1000;
}
SSH_LOG(SSH_LOG_PACKET,"Actual timeout : %d", timeout);
SSH_LOG(SSH_LOG_PACKET,"ssh_connect: Actual timeout : %d", timeout);
ret = ssh_handle_packets_termination(session, timeout, ssh_connect_termination, session);
if (session->session_state != SSH_SESSION_STATE_ERROR &&
(ret == SSH_ERROR || !ssh_connect_termination(session))) {
@@ -622,7 +563,7 @@ pending:
session->session_state = SSH_SESSION_STATE_ERROR;
}
}
SSH_LOG(SSH_LOG_PACKET,"current state : %d",session->session_state);
SSH_LOG(SSH_LOG_PACKET,"ssh_connect: Actual state : %d",session->session_state);
if(!ssh_is_blocking(session) && !ssh_connect_termination(session)){
return SSH_AGAIN;
}
@@ -684,23 +625,32 @@ int ssh_get_openssh_version(ssh_session session) {
* @param[in] session The SSH session to use.
*/
void ssh_disconnect(ssh_session session) {
ssh_string str = NULL;
struct ssh_iterator *it;
int rc;
if (session == NULL) {
return;
}
if (session->socket != NULL && ssh_socket_is_open(session->socket)) {
rc = ssh_buffer_pack(session->out_buffer,
"bds",
SSH2_MSG_DISCONNECT,
SSH2_DISCONNECT_BY_APPLICATION,
"Bye Bye");
if (rc != SSH_OK){
ssh_set_error_oom(session);
if (buffer_add_u8(session->out_buffer, SSH2_MSG_DISCONNECT) < 0) {
goto error;
}
if (buffer_add_u32(session->out_buffer,
htonl(SSH2_DISCONNECT_BY_APPLICATION)) < 0) {
goto error;
}
str = ssh_string_from_char("Bye Bye");
if (str == NULL) {
goto error;
}
if (buffer_add_ssh_string(session->out_buffer,str) < 0) {
ssh_string_free(str);
goto error;
}
ssh_string_free(str);
packet_send(session);
ssh_socket_close(session->socket);
@@ -721,18 +671,14 @@ error:
crypto_free(session->current_crypto);
session->current_crypto=NULL;
}
if (session->in_buffer) {
ssh_buffer_reinit(session->in_buffer);
}
if (session->out_buffer) {
ssh_buffer_reinit(session->out_buffer);
}
if (session->in_hashbuf) {
ssh_buffer_reinit(session->in_hashbuf);
}
if (session->out_hashbuf) {
ssh_buffer_reinit(session->out_hashbuf);
}
if(session->in_buffer)
buffer_reinit(session->in_buffer);
if(session->out_buffer)
buffer_reinit(session->out_buffer);
if(session->in_hashbuf)
buffer_reinit(session->in_hashbuf);
if(session->out_hashbuf)
buffer_reinit(session->out_hashbuf);
session->auth_methods = 0;
SAFE_FREE(session->serverbanner);
SAFE_FREE(session->clientbanner);

View File

@@ -50,8 +50,6 @@ enum ssh_config_opcode_e {
SOC_GSSAPISERVERIDENTITY,
SOC_GSSAPICLIENTIDENTITY,
SOC_GSSAPIDELEGATECREDENTIALS,
SOC_END /* Keep this one last in the list */
};
struct ssh_config_keyword_table_s {
@@ -187,7 +185,7 @@ static int ssh_config_get_yesno(char **str, int notfound) {
}
static int ssh_config_parse_line(ssh_session session, const char *line,
unsigned int count, int *parsing, int seen[]) {
unsigned int count, int *parsing) {
enum ssh_config_opcode_e opcode;
const char *p;
char *s, *x;
@@ -218,47 +216,36 @@ static int ssh_config_parse_line(ssh_session session, const char *line,
}
opcode = ssh_config_get_opcode(keyword);
if (*parsing == 1 && opcode != SOC_HOST) {
if (seen[opcode] != 0) {
return 0;
}
seen[opcode] = 1;
}
switch (opcode) {
case SOC_HOST: {
int ok = 0;
case SOC_HOST:
*parsing = 0;
lowerhost = (session->opts.host) ? ssh_lowercase(session->opts.host) : NULL;
for (p = ssh_config_get_str_tok(&s, NULL);
p != NULL && p[0] != '\0';
p = ssh_config_get_str_tok(&s, NULL)) {
if (ok >= 0) {
ok = match_hostname(lowerhost, p, strlen(p));
if (ok < 0) {
*parsing = 0;
} else if (ok > 0) {
*parsing = 1;
}
char *z = ssh_path_expand_escape(session, p);
int ok;
if (z == NULL) {
z = strdup(p);
}
ok = match_hostname(lowerhost, z, strlen(z));
if (ok) {
*parsing = 1;
}
free(z);
}
SAFE_FREE(lowerhost);
break;
}
case SOC_HOSTNAME:
p = ssh_config_get_str_tok(&s, NULL);
if (p && *parsing) {
char *z = ssh_path_expand_escape(session, p);
if (z == NULL) {
z = strdup(p);
}
ssh_options_set(session, SSH_OPTIONS_HOST, z);
free(z);
ssh_options_set(session, SSH_OPTIONS_HOST, p);
}
break;
case SOC_PORT:
if (session->opts.port == 0) {
if (session->opts.port == 22) {
p = ssh_config_get_str_tok(&s, NULL);
if (p && *parsing) {
ssh_options_set(session, SSH_OPTIONS_PORT_STR, p);
@@ -391,18 +378,17 @@ int ssh_config_parse_file(ssh_session session, const char *filename) {
unsigned int count = 0;
FILE *f;
int parsing;
int seen[SOC_END - SOC_UNSUPPORTED] = {0};
if ((f = fopen(filename, "r")) == NULL) {
return 0;
}
SSH_LOG(SSH_LOG_PACKET, "Reading configuration data from %s", filename);
SSH_LOG(SSH_LOG_RARE, "Reading configuration data from %s", filename);
parsing = 1;
while (fgets(line, sizeof(line), f)) {
count++;
if (ssh_config_parse_line(session, line, count, &parsing, seen) < 0) {
if (ssh_config_parse_line(session, line, count, &parsing) < 0) {
fclose(f);
return -1;
}

View File

@@ -64,10 +64,6 @@
#include <wspiapi.h>
#endif
#ifndef EINPROGRESS
#define EINPROGRESS WSAEINPROGRESS
#endif
#else /* _WIN32 */
#include <netdb.h>
@@ -289,7 +285,6 @@ socket_t ssh_connect_host(ssh_session session, const char *host,
socket_t ret = ssh_connect_ai_timeout(session, host, port, itr,
timeout, usec, s);
freeaddrinfo(ai);
return ret;
}
@@ -387,9 +382,8 @@ socket_t ssh_connect_host_nonblocking(ssh_session session, const char *host,
continue;
}
errno = 0;
rc = connect(s, itr->ai_addr, itr->ai_addrlen);
if (rc == -1 && (errno != 0) && (errno != EINPROGRESS)) {
if (rc == -1 && (errno != EINPROGRESS)) {
ssh_set_error(session, SSH_FATAL,
"Failed to connect: %s", strerror(errno));
ssh_connect_socket_close(s);

View File

@@ -37,14 +37,19 @@
#include "libssh/crypto.h"
#include "libssh/dh.h"
#include "libssh/pki.h"
#include "libssh/bignum.h"
/** @internal
* @brief Starts curve25519-sha256@libssh.org key exchange
*/
int ssh_client_curve25519_init(ssh_session session){
ssh_string client_pubkey;
int rc;
rc = buffer_add_u8(session->out_buffer, SSH2_MSG_KEX_ECDH_INIT);
if (rc < 0) {
return SSH_ERROR;
}
rc = ssh_get_random(session->next_crypto->curve25519_privkey, CURVE25519_PRIVKEY_SIZE, 1);
if (rc == 0){
ssh_set_error(session, SSH_FATAL, "PRNG error");
@@ -53,14 +58,15 @@ int ssh_client_curve25519_init(ssh_session session){
crypto_scalarmult_base(session->next_crypto->curve25519_client_pubkey,
session->next_crypto->curve25519_privkey);
rc = ssh_buffer_pack(session->out_buffer,
"bdP",
SSH2_MSG_KEX_ECDH_INIT,
CURVE25519_PUBKEY_SIZE,
(size_t)CURVE25519_PUBKEY_SIZE, session->next_crypto->curve25519_client_pubkey);
if (rc != SSH_OK) {
ssh_set_error_oom(session);
client_pubkey = ssh_string_new(CURVE25519_PUBKEY_SIZE);
if (client_pubkey == NULL) {
return SSH_ERROR;
}
ssh_string_fill(client_pubkey, session->next_crypto->curve25519_client_pubkey,
CURVE25519_PUBKEY_SIZE);
rc = buffer_add_ssh_string(session->out_buffer,client_pubkey);
ssh_string_free(client_pubkey);
if (rc < 0) {
return SSH_ERROR;
}
@@ -277,7 +283,7 @@ int ssh_server_curve25519_init(ssh_session session, ssh_buffer packet){
return rc;
error:
ssh_buffer_reinit(session->out_buffer);
buffer_reinit(session->out_buffer);
return SSH_ERROR;
}

View File

@@ -269,3 +269,4 @@ int crypto_scalarmult(unsigned char *q,
for (i = 0;i < 32;++i) q[i] = work[64 + i];
return 0;
}

769
src/dh.c
View File

@@ -60,7 +60,6 @@
#include "libssh/dh.h"
#include "libssh/ssh2.h"
#include "libssh/pki.h"
#include "libssh/bignum.h"
/* todo: remove it */
#include "libssh/string.h"
@@ -226,22 +225,30 @@ void ssh_crypto_finalize(void) {
}
}
/* prints the bignum on stderr */
void ssh_print_bignum(const char *which, bignum num) {
#ifdef HAVE_LIBGCRYPT
unsigned char *hex = NULL;
bignum_bn2hex(num, &hex);
#elif defined HAVE_LIBCRYPTO
char *hex = NULL;
hex = bignum_bn2hex(num);
#endif
fprintf(stderr, "%s value: ", which);
fprintf(stderr, "%s\n", (hex == NULL) ? "(null)" : (char *) hex);
SAFE_FREE(hex);
}
int dh_generate_x(ssh_session session) {
int keysize;
if (session->next_crypto->kex_type == SSH_KEX_DH_GROUP1_SHA1) {
keysize = 1023;
} else {
keysize = 2047;
}
session->next_crypto->x = bignum_new();
if (session->next_crypto->x == NULL) {
return -1;
}
#ifdef HAVE_LIBGCRYPT
bignum_rand(session->next_crypto->x, keysize);
bignum_rand(session->next_crypto->x, 128);
#elif defined HAVE_LIBCRYPTO
bignum_rand(session->next_crypto->x, keysize, -1, 0);
bignum_rand(session->next_crypto->x, 128, 0, -1);
#endif
/* not harder than this */
@@ -254,21 +261,15 @@ int dh_generate_x(ssh_session session) {
/* used by server */
int dh_generate_y(ssh_session session) {
int keysize;
if (session->next_crypto->kex_type == SSH_KEX_DH_GROUP1_SHA1) {
keysize = 1023;
} else {
keysize = 2047;
}
session->next_crypto->y = bignum_new();
session->next_crypto->y = bignum_new();
if (session->next_crypto->y == NULL) {
return -1;
}
#ifdef HAVE_LIBGCRYPT
bignum_rand(session->next_crypto->y, keysize);
bignum_rand(session->next_crypto->y, 128);
#elif defined HAVE_LIBCRYPTO
bignum_rand(session->next_crypto->y, keysize, -1, 0);
bignum_rand(session->next_crypto->y, 128, 0, -1);
#endif
/* not harder than this */
@@ -350,6 +351,71 @@ int dh_generate_f(ssh_session session) {
return 0;
}
ssh_string make_bignum_string(bignum num) {
ssh_string ptr = NULL;
int pad = 0;
unsigned int len = bignum_num_bytes(num);
unsigned int bits = bignum_num_bits(num);
if (len == 0) {
return NULL;
}
/* If the first bit is set we have a negative number */
if (!(bits % 8) && bignum_is_bit_set(num, bits - 1)) {
pad++;
}
#ifdef DEBUG_CRYPTO
fprintf(stderr, "%d bits, %d bytes, %d padding\n", bits, len, pad);
#endif /* DEBUG_CRYPTO */
ptr = ssh_string_new(len + pad);
if (ptr == NULL) {
return NULL;
}
/* We have a negative number so we need a leading zero */
if (pad) {
ptr->data[0] = 0;
}
#ifdef HAVE_LIBGCRYPT
bignum_bn2bin(num, len, ptr->data + pad);
#elif HAVE_LIBCRYPTO
bignum_bn2bin(num, ptr->data + pad);
#endif
return ptr;
}
bignum make_string_bn(ssh_string string){
bignum bn = NULL;
unsigned int len = ssh_string_len(string);
#ifdef DEBUG_CRYPTO
fprintf(stderr, "Importing a %d bits, %d bytes object ...\n",
len * 8, len);
#endif /* DEBUG_CRYPTO */
#ifdef HAVE_LIBGCRYPT
bignum_bin2bn(string->data, len, &bn);
#elif defined HAVE_LIBCRYPTO
bn = bignum_bin2bn(string->data, len, NULL);
#endif
return bn;
}
void make_string_bn_inplace(ssh_string string, bignum bnout) {
unsigned int len = ssh_string_len(string);
#ifdef HAVE_LIBGCRYPT
#error "unsupported"
#elif defined HAVE_LIBCRYPTO
bignum_bin2bn(string->data, len, bnout);
#endif
}
ssh_string dh_get_e(ssh_session session) {
return make_bignum_string(session->next_crypto->e);
}
@@ -447,6 +513,10 @@ int ssh_client_dh_init(ssh_session session){
ssh_string e = NULL;
int rc;
if (buffer_add_u8(session->out_buffer, SSH2_MSG_KEXDH_INIT) < 0) {
goto error;
}
if (dh_generate_x(session) < 0) {
goto error;
}
@@ -459,11 +529,9 @@ int ssh_client_dh_init(ssh_session session){
goto error;
}
rc = ssh_buffer_pack(session->out_buffer, "bS", SSH2_MSG_KEXDH_INIT, e);
if (rc != SSH_OK) {
if (buffer_add_ssh_string(session->out_buffer, e) < 0) {
goto error;
}
ssh_string_burn(e);
ssh_string_free(e);
e=NULL;
@@ -528,180 +596,218 @@ error:
return SSH_ERROR;
}
/*
static void sha_add(ssh_string str,SHACTX ctx){
sha1_update(ctx,str,string_len(str)+4);
#ifdef DEBUG_CRYPTO
ssh_print_hexa("partial hashed sessionid",str,string_len(str)+4);
#endif
}
*/
int make_sessionid(ssh_session session) {
ssh_string num = NULL;
ssh_buffer server_hash = NULL;
ssh_buffer client_hash = NULL;
ssh_buffer buf = NULL;
int rc = SSH_ERROR;
ssh_string num = NULL;
ssh_string str = NULL;
ssh_buffer server_hash = NULL;
ssh_buffer client_hash = NULL;
ssh_buffer buf = NULL;
uint32_t len;
int rc = SSH_ERROR;
buf = ssh_buffer_new();
if (buf == NULL) {
return rc;
buf = ssh_buffer_new();
if (buf == NULL) {
return rc;
}
str = ssh_string_from_char(session->clientbanner);
if (str == NULL) {
goto error;
}
if (buffer_add_ssh_string(buf, str) < 0) {
goto error;
}
ssh_string_free(str);
str = ssh_string_from_char(session->serverbanner);
if (str == NULL) {
goto error;
}
if (buffer_add_ssh_string(buf, str) < 0) {
goto error;
}
if (session->client) {
server_hash = session->in_hashbuf;
client_hash = session->out_hashbuf;
} else {
server_hash = session->out_hashbuf;
client_hash = session->in_hashbuf;
}
if (buffer_add_u32(server_hash, 0) < 0) {
goto error;
}
if (buffer_add_u8(server_hash, 0) < 0) {
goto error;
}
if (buffer_add_u32(client_hash, 0) < 0) {
goto error;
}
if (buffer_add_u8(client_hash, 0) < 0) {
goto error;
}
len = ntohl(buffer_get_rest_len(client_hash));
if (buffer_add_u32(buf,len) < 0) {
goto error;
}
if (buffer_add_data(buf, buffer_get_rest(client_hash),
buffer_get_rest_len(client_hash)) < 0) {
goto error;
}
len = ntohl(buffer_get_rest_len(server_hash));
if (buffer_add_u32(buf, len) < 0) {
goto error;
}
if (buffer_add_data(buf, buffer_get_rest(server_hash),
buffer_get_rest_len(server_hash)) < 0) {
goto error;
}
len = ssh_string_len(session->next_crypto->server_pubkey) + 4;
if (buffer_add_data(buf, session->next_crypto->server_pubkey, len) < 0) {
goto error;
}
if(session->next_crypto->kex_type == SSH_KEX_DH_GROUP1_SHA1 ||
session->next_crypto->kex_type == SSH_KEX_DH_GROUP14_SHA1) {
num = make_bignum_string(session->next_crypto->e);
if (num == NULL) {
goto error;
}
rc = ssh_buffer_pack(buf,
"ss",
session->clientbanner,
session->serverbanner);
if (rc == SSH_ERROR) {
goto error;
len = ssh_string_len(num) + 4;
if (buffer_add_data(buf, num, len) < 0) {
goto error;
}
if (session->client) {
server_hash = session->in_hashbuf;
client_hash = session->out_hashbuf;
} else {
server_hash = session->out_hashbuf;
client_hash = session->in_hashbuf;
}
/*
* Handle the two final fields for the KEXINIT message (RFC 4253 7.1):
*
* boolean first_kex_packet_follows
* uint32 0 (reserved for future extension)
*/
rc = buffer_add_u8(server_hash, 0);
if (rc < 0) {
goto error;
}
rc = buffer_add_u32(server_hash, 0);
if (rc < 0) {
goto error;
}
/* These fields are handled for the server case in ssh_packet_kexinit. */
if (session->client) {
rc = buffer_add_u8(client_hash, 0);
if (rc < 0) {
goto error;
}
rc = buffer_add_u32(client_hash, 0);
if (rc < 0) {
goto error;
}
}
rc = ssh_buffer_pack(buf,
"dPdPS",
buffer_get_rest_len(client_hash),
buffer_get_rest_len(client_hash),
buffer_get_rest(client_hash),
buffer_get_rest_len(server_hash),
buffer_get_rest_len(server_hash),
buffer_get_rest(server_hash),
session->next_crypto->server_pubkey);
if(rc != SSH_OK){
goto error;
}
if (session->next_crypto->kex_type == SSH_KEX_DH_GROUP1_SHA1 ||
session->next_crypto->kex_type == SSH_KEX_DH_GROUP14_SHA1) {
rc = ssh_buffer_pack(buf,
"BB",
session->next_crypto->e,
session->next_crypto->f);
if (rc != SSH_OK) {
goto error;
}
#ifdef HAVE_ECDH
} else if (session->next_crypto->kex_type == SSH_KEX_ECDH_SHA2_NISTP256) {
if (session->next_crypto->ecdh_client_pubkey == NULL ||
session->next_crypto->ecdh_server_pubkey == NULL) {
SSH_LOG(SSH_LOG_WARNING, "ECDH parameted missing");
goto error;
}
rc = ssh_buffer_pack(buf,
"SS",
session->next_crypto->ecdh_client_pubkey,
session->next_crypto->ecdh_server_pubkey);
if (rc != SSH_OK) {
goto error;
}
#endif
#ifdef HAVE_CURVE25519
} else if (session->next_crypto->kex_type == SSH_KEX_CURVE25519_SHA256_LIBSSH_ORG) {
rc = ssh_buffer_pack(buf,
"dPdP",
CURVE25519_PUBKEY_SIZE,
(size_t)CURVE25519_PUBKEY_SIZE, session->next_crypto->curve25519_client_pubkey,
CURVE25519_PUBKEY_SIZE,
(size_t)CURVE25519_PUBKEY_SIZE, session->next_crypto->curve25519_server_pubkey);
if (rc != SSH_OK) {
goto error;
}
#endif
}
rc = ssh_buffer_pack(buf, "B", session->next_crypto->k);
if (rc != SSH_OK) {
goto error;
}
#ifdef DEBUG_CRYPTO
ssh_print_hexa("hash buffer", ssh_buffer_get_begin(buf), ssh_buffer_get_len(buf));
#endif
switch (session->next_crypto->kex_type) {
case SSH_KEX_DH_GROUP1_SHA1:
case SSH_KEX_DH_GROUP14_SHA1:
session->next_crypto->digest_len = SHA_DIGEST_LENGTH;
session->next_crypto->mac_type = SSH_MAC_SHA1;
session->next_crypto->secret_hash = malloc(session->next_crypto->digest_len);
if (session->next_crypto->secret_hash == NULL) {
ssh_set_error_oom(session);
goto error;
}
sha1(buffer_get_rest(buf), buffer_get_rest_len(buf),
session->next_crypto->secret_hash);
break;
case SSH_KEX_ECDH_SHA2_NISTP256:
case SSH_KEX_CURVE25519_SHA256_LIBSSH_ORG:
session->next_crypto->digest_len = SHA256_DIGEST_LENGTH;
session->next_crypto->mac_type = SSH_MAC_SHA256;
session->next_crypto->secret_hash = malloc(session->next_crypto->digest_len);
if (session->next_crypto->secret_hash == NULL) {
ssh_set_error_oom(session);
goto error;
}
sha256(buffer_get_rest(buf), buffer_get_rest_len(buf),
session->next_crypto->secret_hash);
break;
}
/* During the first kex, secret hash and session ID are equal. However, after
* a key re-exchange, a new secret hash is calculated. This hash will not replace
* but complement existing session id.
*/
if (!session->next_crypto->session_id) {
session->next_crypto->session_id = malloc(session->next_crypto->digest_len);
if (session->next_crypto->session_id == NULL) {
ssh_set_error_oom(session);
goto error;
}
memcpy(session->next_crypto->session_id, session->next_crypto->secret_hash,
session->next_crypto->digest_len);
}
#ifdef DEBUG_CRYPTO
printf("Session hash: \n");
ssh_print_hexa("secret hash", session->next_crypto->secret_hash, session->next_crypto->digest_len);
ssh_print_hexa("session id", session->next_crypto->session_id, session->next_crypto->digest_len);
#endif
rc = SSH_OK;
error:
ssh_buffer_free(buf);
ssh_buffer_free(client_hash);
ssh_buffer_free(server_hash);
session->in_hashbuf = NULL;
session->out_hashbuf = NULL;
ssh_string_free(num);
num = make_bignum_string(session->next_crypto->f);
if (num == NULL) {
goto error;
}
return rc;
len = ssh_string_len(num) + 4;
if (buffer_add_data(buf, num, len) < 0) {
goto error;
}
ssh_string_free(num);
#ifdef HAVE_ECDH
} else if (session->next_crypto->kex_type == SSH_KEX_ECDH_SHA2_NISTP256){
if(session->next_crypto->ecdh_client_pubkey == NULL ||
session->next_crypto->ecdh_server_pubkey == NULL){
SSH_LOG(SSH_LOG_WARNING, "ECDH parameted missing");
goto error;
}
rc = buffer_add_ssh_string(buf,session->next_crypto->ecdh_client_pubkey);
if (rc < 0) {
goto error;
}
rc = buffer_add_ssh_string(buf,session->next_crypto->ecdh_server_pubkey);
if (rc < 0) {
goto error;
}
#endif
#ifdef HAVE_CURVE25519
} else if(session->next_crypto->kex_type == SSH_KEX_CURVE25519_SHA256_LIBSSH_ORG){
rc = buffer_add_u32(buf, htonl(CURVE25519_PUBKEY_SIZE));
rc += buffer_add_data(buf, session->next_crypto->curve25519_client_pubkey,
CURVE25519_PUBKEY_SIZE);
rc += buffer_add_u32(buf, htonl(CURVE25519_PUBKEY_SIZE));
rc += buffer_add_data(buf, session->next_crypto->curve25519_server_pubkey,
CURVE25519_PUBKEY_SIZE);
if (rc != SSH_OK) {
goto error;
}
#endif
}
num = make_bignum_string(session->next_crypto->k);
if (num == NULL) {
goto error;
}
len = ssh_string_len(num) + 4;
if (buffer_add_data(buf, num, len) < 0) {
goto error;
}
#ifdef DEBUG_CRYPTO
ssh_print_hexa("hash buffer", ssh_buffer_get_begin(buf), ssh_buffer_get_len(buf));
#endif
switch(session->next_crypto->kex_type){
case SSH_KEX_DH_GROUP1_SHA1:
case SSH_KEX_DH_GROUP14_SHA1:
session->next_crypto->digest_len = SHA_DIGEST_LENGTH;
session->next_crypto->mac_type = SSH_MAC_SHA1;
session->next_crypto->secret_hash = malloc(session->next_crypto->digest_len);
if(session->next_crypto->secret_hash == NULL){
ssh_set_error_oom(session);
goto error;
}
sha1(buffer_get_rest(buf), buffer_get_rest_len(buf),
session->next_crypto->secret_hash);
break;
case SSH_KEX_ECDH_SHA2_NISTP256:
case SSH_KEX_CURVE25519_SHA256_LIBSSH_ORG:
session->next_crypto->digest_len = SHA256_DIGEST_LENGTH;
session->next_crypto->mac_type = SSH_MAC_SHA256;
session->next_crypto->secret_hash = malloc(session->next_crypto->digest_len);
if(session->next_crypto->secret_hash == NULL){
ssh_set_error_oom(session);
goto error;
}
sha256(buffer_get_rest(buf), buffer_get_rest_len(buf),
session->next_crypto->secret_hash);
break;
}
/* During the first kex, secret hash and session ID are equal. However, after
* a key re-exchange, a new secret hash is calculated. This hash will not replace
* but complement existing session id.
*/
if (!session->next_crypto->session_id){
session->next_crypto->session_id = malloc(session->next_crypto->digest_len);
if (session->next_crypto->session_id == NULL){
ssh_set_error_oom(session);
goto error;
}
memcpy(session->next_crypto->session_id, session->next_crypto->secret_hash,
session->next_crypto->digest_len);
}
#ifdef DEBUG_CRYPTO
printf("Session hash: \n");
ssh_print_hexa("secret hash", session->next_crypto->secret_hash, session->next_crypto->digest_len);
ssh_print_hexa("session id", session->next_crypto->session_id, session->next_crypto->digest_len);
#endif
rc = SSH_OK;
error:
ssh_buffer_free(buf);
ssh_buffer_free(client_hash);
ssh_buffer_free(server_hash);
session->in_hashbuf = NULL;
session->out_hashbuf = NULL;
ssh_string_free(str);
ssh_string_free(num);
return rc;
}
int hashbufout_add_cookie(ssh_session session) {
@@ -711,20 +817,20 @@ int hashbufout_add_cookie(ssh_session session) {
}
if (buffer_add_u8(session->out_hashbuf, 20) < 0) {
ssh_buffer_reinit(session->out_hashbuf);
buffer_reinit(session->out_hashbuf);
return -1;
}
if (session->server) {
if (ssh_buffer_add_data(session->out_hashbuf,
if (buffer_add_data(session->out_hashbuf,
session->next_crypto->server_kex.cookie, 16) < 0) {
ssh_buffer_reinit(session->out_hashbuf);
buffer_reinit(session->out_hashbuf);
return -1;
}
} else {
if (ssh_buffer_add_data(session->out_hashbuf,
if (buffer_add_data(session->out_hashbuf,
session->next_crypto->client_kex.cookie, 16) < 0) {
ssh_buffer_reinit(session->out_hashbuf);
buffer_reinit(session->out_hashbuf);
return -1;
}
}
@@ -739,11 +845,11 @@ int hashbufin_add_cookie(ssh_session session, unsigned char *cookie) {
}
if (buffer_add_u8(session->in_hashbuf, 20) < 0) {
ssh_buffer_reinit(session->in_hashbuf);
buffer_reinit(session->in_hashbuf);
return -1;
}
if (ssh_buffer_add_data(session->in_hashbuf,cookie, 16) < 0) {
ssh_buffer_reinit(session->in_hashbuf);
if (buffer_add_data(session->in_hashbuf,cookie, 16) < 0) {
buffer_reinit(session->in_hashbuf);
return -1;
}
@@ -751,10 +857,8 @@ int hashbufin_add_cookie(ssh_session session, unsigned char *cookie) {
}
static int generate_one_key(ssh_string k,
struct ssh_crypto_struct *crypto, unsigned char **output, char letter, size_t requested_size) {
struct ssh_crypto_struct *crypto, unsigned char *output, char letter) {
ssh_mac_ctx ctx;
unsigned char *tmp;
size_t size = crypto->digest_len;
ctx=ssh_mac_ctx_init(crypto->mac_type);
if (ctx == NULL) {
@@ -765,33 +869,16 @@ static int generate_one_key(ssh_string k,
ssh_mac_update(ctx, crypto->secret_hash, crypto->digest_len);
ssh_mac_update(ctx, &letter, 1);
ssh_mac_update(ctx, crypto->session_id, crypto->digest_len);
ssh_mac_final(*output, ctx);
while(requested_size > size) {
tmp = realloc(*output, size + crypto->digest_len);
if (tmp == NULL) {
return -1;
}
*output = tmp;
ctx = ssh_mac_ctx_init(crypto->mac_type);
if (ctx == NULL) {
return -1;
}
ssh_mac_update(ctx, k, ssh_string_len(k) + 4);
ssh_mac_update(ctx, crypto->secret_hash,
crypto->digest_len);
ssh_mac_update(ctx, tmp, size);
ssh_mac_final(tmp + size, ctx);
size += crypto->digest_len;
}
ssh_mac_final(output, ctx);
return 0;
}
int generate_session_keys(ssh_session session) {
ssh_string k_string = NULL;
ssh_mac_ctx ctx = NULL;
struct ssh_crypto_struct *crypto = session->next_crypto;
unsigned char *tmp;
int rc = -1;
k_string = make_bignum_string(crypto->k);
@@ -815,71 +902,96 @@ int generate_session_keys(ssh_session session) {
/* IV */
if (session->client) {
rc = generate_one_key(k_string, crypto, &crypto->encryptIV, 'A', crypto->digest_len);
if (rc < 0) {
if (generate_one_key(k_string, crypto, crypto->encryptIV, 'A') < 0) {
goto error;
}
rc = generate_one_key(k_string, crypto, &crypto->decryptIV, 'B', crypto->digest_len);
if (rc < 0) {
if (generate_one_key(k_string, crypto, crypto->decryptIV, 'B') < 0) {
goto error;
}
} else {
rc = generate_one_key(k_string, crypto, &crypto->decryptIV, 'A', crypto->digest_len);
if (rc < 0) {
if (generate_one_key(k_string, crypto, crypto->decryptIV, 'A') < 0) {
goto error;
}
rc = generate_one_key(k_string, crypto, &crypto->encryptIV, 'B', crypto->digest_len);
if (rc < 0) {
if (generate_one_key(k_string, crypto, crypto->encryptIV, 'B') < 0) {
goto error;
}
}
if (session->client) {
rc = generate_one_key(k_string, crypto, &crypto->encryptkey, 'C', crypto->out_cipher->keysize / 8);
if (rc < 0) {
if (generate_one_key(k_string, crypto, crypto->encryptkey, 'C') < 0) {
goto error;
}
rc = generate_one_key(k_string, crypto, &crypto->decryptkey, 'D', crypto->in_cipher->keysize / 8);
if (rc < 0) {
if (generate_one_key(k_string, crypto, crypto->decryptkey, 'D') < 0) {
goto error;
}
} else {
rc = generate_one_key(k_string, crypto, &crypto->decryptkey, 'C', crypto->in_cipher->keysize / 8);
if (rc < 0) {
if (generate_one_key(k_string, crypto, crypto->decryptkey, 'C') < 0) {
goto error;
}
rc = generate_one_key(k_string, crypto, &crypto->encryptkey, 'D', crypto->out_cipher->keysize / 8);
if (rc < 0) {
if (generate_one_key(k_string, crypto, crypto->encryptkey, 'D') < 0) {
goto error;
}
}
if(session->client) {
rc = generate_one_key(k_string, crypto, &crypto->encryptMAC, 'E', hmac_digest_len(crypto->out_hmac));
if (rc < 0) {
/* some ciphers need more than DIGEST_LEN bytes of input key */
if (crypto->out_cipher->keysize > crypto->digest_len * 8) {
tmp = realloc(crypto->encryptkey, crypto->digest_len * 2);
if (tmp == NULL) {
goto error;
}
crypto->encryptkey = tmp;
ctx = ssh_mac_ctx_init(crypto->mac_type);
if (ctx == NULL) {
goto error;
}
rc = generate_one_key(k_string, crypto, &crypto->decryptMAC, 'F', hmac_digest_len(crypto->in_hmac));
if (rc < 0) {
ssh_mac_update(ctx, k_string, ssh_string_len(k_string) + 4);
ssh_mac_update(ctx, crypto->secret_hash,
crypto->digest_len);
ssh_mac_update(ctx, crypto->encryptkey, crypto->digest_len);
ssh_mac_final(crypto->encryptkey + crypto->digest_len, ctx);
}
if (crypto->in_cipher->keysize > crypto->digest_len * 8) {
tmp = realloc(crypto->decryptkey, crypto->digest_len *2);
if (tmp == NULL) {
goto error;
}
crypto->decryptkey = tmp;
if(crypto->decryptkey == NULL)
goto error;
ctx = ssh_mac_ctx_init(crypto->mac_type);
ssh_mac_update(ctx, k_string, ssh_string_len(k_string) + 4);
ssh_mac_update(ctx, crypto->secret_hash,
crypto->digest_len);
ssh_mac_update(ctx, crypto->decryptkey, crypto->digest_len);
ssh_mac_final(crypto->decryptkey + crypto->digest_len, ctx);
}
if(session->client) {
if (generate_one_key(k_string, crypto, crypto->encryptMAC, 'E') < 0) {
goto error;
}
if (generate_one_key(k_string, crypto, crypto->decryptMAC, 'F') < 0) {
goto error;
}
} else {
rc = generate_one_key(k_string, crypto, &crypto->decryptMAC, 'E', hmac_digest_len(crypto->in_hmac));
if (rc < 0) {
if (generate_one_key(k_string, crypto, crypto->decryptMAC, 'E') < 0) {
goto error;
}
rc = generate_one_key(k_string, crypto, &crypto->encryptMAC, 'F', hmac_digest_len(crypto->out_hmac));
if (rc < 0) {
if (generate_one_key(k_string, crypto, crypto->encryptMAC, 'F') < 0) {
goto error;
}
}
#ifdef DEBUG_CRYPTO
ssh_print_hexa("Encrypt IV", crypto->encryptIV, crypto->digest_len);
ssh_print_hexa("Decrypt IV", crypto->decryptIV, crypto->digest_len);
ssh_print_hexa("Encryption key", crypto->encryptkey, crypto->out_cipher->keysize / 8);
ssh_print_hexa("Decryption key", crypto->decryptkey, crypto->in_cipher->keysize / 8);
ssh_print_hexa("Encryption MAC", crypto->encryptMAC, hmac_digest_len(crypto->out_hmac));
ssh_print_hexa("Decryption MAC", crypto->decryptMAC, hmac_digest_len(crypto->in_hmac));
ssh_print_hexa("Encrypt IV", crypto->encryptIV, SHA_DIGEST_LEN);
ssh_print_hexa("Decrypt IV", crypto->decryptIV, SHA_DIGEST_LEN);
ssh_print_hexa("Encryption key", crypto->encryptkey,
crypto->out_cipher->keysize);
ssh_print_hexa("Decryption key", crypto->decryptkey,
crypto->in_cipher->keysize);
ssh_print_hexa("Encryption MAC", crypto->encryptMAC, SHA_DIGEST_LEN);
ssh_print_hexa("Decryption MAC", crypto->decryptMAC, 20);
#endif
rc = 0;
@@ -1039,29 +1151,6 @@ int ssh_get_publickey_hash(const ssh_key key,
*hlen = SHA_DIGEST_LEN;
}
break;
case SSH_PUBLICKEY_HASH_SHA256:
{
SHA256CTX ctx;
h = malloc(SHA256_DIGEST_LEN);
if (h == NULL) {
rc = -1;
goto out;
}
ctx = sha256_init();
if (ctx == NULL) {
free(h);
rc = -1;
goto out;
}
sha256_update(ctx, ssh_string_data(blob), ssh_string_len(blob));
sha256_final(h, ctx);
*hlen = SHA256_DIGEST_LEN;
}
break;
case SSH_PUBLICKEY_HASH_MD5:
{
MD5CTX ctx;
@@ -1097,38 +1186,6 @@ out:
return rc;
}
/**
* @internal
*
* @brief Convert a buffer into an unpadded base64 string.
* The caller has to free the memory.
*
* @param hash What should be converted to a base64 string.
*
* @param len Length of the buffer to convert.
*
* @return The base64 string or NULL on error.
*
* @see ssh_string_free_char()
*/
static char *ssh_get_b64_unpadded(const unsigned char *hash, size_t len)
{
char *b64_padded = NULL;
char *b64_unpadded = NULL;
size_t k;
b64_padded = (char *)bin_to_base64(hash, (int)len);
if (b64_padded == NULL) {
return NULL;
}
for (k = strlen(b64_padded); k != 0 && b64_padded[k-1] == '='; k--);
b64_unpadded = strndup(b64_padded, k);
SAFE_FREE(b64_padded);
return b64_unpadded;
}
/**
* @brief Convert a buffer into a colon separated hex string.
* The caller has to free the memory.
@@ -1166,110 +1223,6 @@ char *ssh_get_hexa(const unsigned char *what, size_t len) {
return hexa;
}
/**
* @brief Get a hash as a human-readable hex- or base64-string.
*
* This gets an allocated fingerprint hash. It is a hex strings if the given
* hash is a md5 sum. If it is a SHA sum, it will return an unpadded base64
* strings. Either way, the output is prepended by the hash-type.
*
* @param type Which sort of hash is given.
*
* @param hash What should be converted to a base64 string.
*
* @param len Length of the buffer to convert.
*
* @return Returns the allocated fingerprint hash or NULL on error.
*
* @see ssh_string_free_char()
*/
char *ssh_get_fingerprint_hash(enum ssh_publickey_hash_type type,
unsigned char *hash,
size_t len)
{
const char *prefix = "UNKNOWN";
char *fingerprint = NULL;
char *str = NULL;
size_t str_len;
int rc;
switch (type) {
case SSH_PUBLICKEY_HASH_SHA1:
case SSH_PUBLICKEY_HASH_SHA256:
fingerprint = ssh_get_b64_unpadded(hash, len);
break;
case SSH_PUBLICKEY_HASH_MD5:
fingerprint = ssh_get_hexa(hash, len);
break;
}
if (fingerprint == NULL) {
return NULL;
}
switch (type) {
case SSH_PUBLICKEY_HASH_MD5:
prefix = "MD5";
break;
case SSH_PUBLICKEY_HASH_SHA1:
prefix = "SHA1";
break;
case SSH_PUBLICKEY_HASH_SHA256:
prefix = "SHA256";
break;
}
str_len = strlen(prefix);
if (str_len + 1 + strlen(fingerprint) + 1 < str_len) {
SAFE_FREE(fingerprint);
return NULL;
}
str_len += 1 + strlen(fingerprint) + 1;
str = malloc(str_len);
if (str == NULL) {
SAFE_FREE(fingerprint);
return NULL;
}
rc = snprintf(str, str_len, "%s:%s", prefix, fingerprint);
SAFE_FREE(fingerprint);
if (rc < 0 || rc < (int)(str_len - 1)) {
SAFE_FREE(str);
}
return str;
}
/**
* @brief Print a hash as a human-readable hex- or base64-string.
*
* This function prints hex strings if the given hash is a md5 sum.
* But prints unpadded base64 strings for sha sums.
* Either way, the output is prepended by the hash-type.
*
* @param type Which sort of hash is given.
*
* @param hash What should be converted to a base64 string.
*
* @param len Length of the buffer to convert.
*/
void ssh_print_hash(enum ssh_publickey_hash_type type,
unsigned char *hash,
size_t len)
{
char *fingerprint = NULL;
fingerprint = ssh_get_fingerprint_hash(type,
hash,
len);
if (fingerprint == NULL) {
return;
}
fprintf(stderr, "%s\n", fingerprint);
SAFE_FREE(fingerprint);
}
/**
* @brief Print a buffer as colon separated hex string.
*

View File

@@ -26,7 +26,6 @@
#include "libssh/buffer.h"
#include "libssh/ssh2.h"
#include "libssh/pki.h"
#include "libssh/bignum.h"
#ifdef HAVE_ECDH
#include <openssl/ecdh.h>
@@ -100,8 +99,8 @@ static int ecdh_build_k(ssh_session session) {
const EC_GROUP *group = EC_KEY_get0_group(session->next_crypto->ecdh_privkey);
EC_POINT *pubkey;
void *buffer;
int rc;
int len = (EC_GROUP_get_degree(group) + 7) / 8;
int rc;
bignum_CTX ctx = bignum_ctx_new();
if (ctx == NULL) {
return -1;
@@ -119,25 +118,12 @@ static int ecdh_build_k(ssh_session session) {
return -1;
}
if (session->server) {
rc = EC_POINT_oct2point(group,
pubkey,
ssh_string_data(session->next_crypto->ecdh_client_pubkey),
ssh_string_len(session->next_crypto->ecdh_client_pubkey),
ctx);
} else {
rc = EC_POINT_oct2point(group,
pubkey,
ssh_string_data(session->next_crypto->ecdh_server_pubkey),
ssh_string_len(session->next_crypto->ecdh_server_pubkey),
ctx);
}
bignum_ctx_free(ctx);
if (rc <= 0) {
EC_POINT_clear_free(pubkey);
return -1;
}
if (session->server)
EC_POINT_oct2point(group,pubkey,ssh_string_data(session->next_crypto->ecdh_client_pubkey),
ssh_string_len(session->next_crypto->ecdh_client_pubkey),ctx);
else
EC_POINT_oct2point(group,pubkey,ssh_string_data(session->next_crypto->ecdh_server_pubkey),
ssh_string_len(session->next_crypto->ecdh_server_pubkey),ctx);
buffer = malloc(len);
if (buffer == NULL) {
EC_POINT_clear_free(pubkey);
@@ -157,10 +143,8 @@ static int ecdh_build_k(ssh_session session) {
bignum_bin2bn(buffer, len, session->next_crypto->k);
free(buffer);
EC_KEY_free(session->next_crypto->ecdh_privkey);
session->next_crypto->ecdh_privkey = NULL;
session->next_crypto->ecdh_privkey=NULL;
#ifdef DEBUG_CRYPTO
ssh_print_hexa("Session server cookie",
session->next_crypto->server_kex.cookie, 16);
@@ -169,6 +153,10 @@ static int ecdh_build_k(ssh_session session) {
ssh_print_bignum("Shared secret key", session->next_crypto->k);
#endif
#ifdef HAVE_LIBCRYPTO
bignum_ctx_free(ctx);
#endif
return 0;
}
@@ -286,6 +274,12 @@ int ssh_server_ecdh_init(ssh_session session, ssh_buffer packet){
session->next_crypto->ecdh_privkey = ecdh_key;
session->next_crypto->ecdh_server_pubkey = q_s_string;
rc = buffer_add_u8(session->out_buffer, SSH2_MSG_KEXDH_REPLY);
if (rc < 0) {
ssh_set_error_oom(session);
return SSH_ERROR;
}
/* build k and session_id */
rc = ecdh_build_k(session);
if (rc < 0) {
@@ -305,22 +299,30 @@ int ssh_server_ecdh_init(ssh_session session, ssh_buffer packet){
return SSH_ERROR;
}
/* add host's public key */
rc = buffer_add_ssh_string(session->out_buffer,
session->next_crypto->server_pubkey);
if (rc < 0) {
ssh_set_error_oom(session);
return SSH_ERROR;
}
/* add ecdh public key */
rc = buffer_add_ssh_string(session->out_buffer, q_s_string);
if (rc < 0) {
ssh_set_error_oom(session);
return SSH_ERROR;
}
/* add signature blob */
sig_blob = ssh_srv_pki_do_sign_sessionid(session, privkey);
if (sig_blob == NULL) {
ssh_set_error(session, SSH_FATAL, "Could not sign the session id");
return SSH_ERROR;
}
rc = ssh_buffer_pack(session->out_buffer,
"bSSS",
SSH2_MSG_KEXDH_REPLY,
session->next_crypto->server_pubkey, /* host's pubkey */
q_s_string, /* ecdh public key */
sig_blob); /* signature blob */
rc = buffer_add_ssh_string(session->out_buffer, sig_blob);
ssh_string_free(sig_blob);
if (rc != SSH_OK) {
if (rc < 0) {
ssh_set_error_oom(session);
return SSH_ERROR;
}

View File

@@ -1,181 +0,0 @@
/* $OpenBSD: bcrypt_pbkdf.c,v 1.4 2013/07/29 00:55:53 tedu Exp $ */
/*
* Copyright (c) 2013 Ted Unangst <tedu@openbsd.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//#include "includes.h"
#ifndef HAVE_BCRYPT_PBKDF
#include "libssh/priv.h"
#include "libssh/wrapper.h"
#include <stdlib.h>
#include <sys/types.h>
#ifdef HAVE_SYS_PARAM_H
#include <sys/param.h>
#endif
#include "libssh/blf.h"
#include "libssh/pki_priv.h"
#ifndef SHA512_DIGEST_LENGTH
#define SHA512_DIGEST_LENGTH SHA512_DIGEST_LEN
#endif
/*
* pkcs #5 pbkdf2 implementation using the "bcrypt" hash
*
* The bcrypt hash function is derived from the bcrypt password hashing
* function with the following modifications:
* 1. The input password and salt are preprocessed with SHA512.
* 2. The output length is expanded to 256 bits.
* 3. Subsequently the magic string to be encrypted is lengthened and modifed
* to "OxychromaticBlowfishSwatDynamite"
* 4. The hash function is defined to perform 64 rounds of initial state
* expansion. (More rounds are performed by iterating the hash.)
*
* Note that this implementation pulls the SHA512 operations into the caller
* as a performance optimization.
*
* One modification from official pbkdf2. Instead of outputting key material
* linearly, we mix it. pbkdf2 has a known weakness where if one uses it to
* generate (i.e.) 512 bits of key material for use as two 256 bit keys, an
* attacker can merely run once through the outer loop below, but the user
* always runs it twice. Shuffling output bytes requires computing the
* entirety of the key material to assemble any subkey. This is something a
* wise caller could do; we just do it for you.
*/
#define BCRYPT_BLOCKS 8
#define BCRYPT_HASHSIZE (BCRYPT_BLOCKS * 4)
static void
bcrypt_hash(uint8_t *sha2pass, uint8_t *sha2salt, uint8_t *out)
{
blf_ctx state;
uint8_t ciphertext[BCRYPT_HASHSIZE] =
"OxychromaticBlowfishSwatDynamite";
uint32_t cdata[BCRYPT_BLOCKS];
int i;
uint16_t j;
size_t shalen = SHA512_DIGEST_LENGTH;
/* key expansion */
Blowfish_initstate(&state);
Blowfish_expandstate(&state, sha2salt, shalen, sha2pass, shalen);
for (i = 0; i < 64; i++) {
Blowfish_expand0state(&state, sha2salt, shalen);
Blowfish_expand0state(&state, sha2pass, shalen);
}
/* encryption */
j = 0;
for (i = 0; i < BCRYPT_BLOCKS; i++)
cdata[i] = Blowfish_stream2word(ciphertext, sizeof(ciphertext),
&j);
for (i = 0; i < 64; i++)
blf_enc(&state, cdata, sizeof(cdata) / sizeof(uint64_t));
/* copy out */
for (i = 0; i < BCRYPT_BLOCKS; i++) {
out[4 * i + 3] = (cdata[i] >> 24) & 0xff;
out[4 * i + 2] = (cdata[i] >> 16) & 0xff;
out[4 * i + 1] = (cdata[i] >> 8) & 0xff;
out[4 * i + 0] = cdata[i] & 0xff;
}
/* zap */
BURN_BUFFER(ciphertext, sizeof(ciphertext));
BURN_BUFFER(cdata, sizeof(cdata));
ZERO_STRUCT(state);
}
int
bcrypt_pbkdf(const char *pass, size_t passlen, const uint8_t *salt, size_t saltlen,
uint8_t *key, size_t keylen, unsigned int rounds)
{
uint8_t sha2pass[SHA512_DIGEST_LENGTH];
uint8_t sha2salt[SHA512_DIGEST_LENGTH];
uint8_t out[BCRYPT_HASHSIZE];
uint8_t tmpout[BCRYPT_HASHSIZE];
uint8_t *countsalt;
size_t i, j, amt, stride;
uint32_t count;
size_t origkeylen = keylen;
SHA512CTX ctx;
/* nothing crazy */
if (rounds < 1)
return -1;
if (passlen == 0 || saltlen == 0 || keylen == 0 ||
keylen > sizeof(out) * sizeof(out) || saltlen > 1<<20)
return -1;
if ((countsalt = calloc(1, saltlen + 4)) == NULL)
return -1;
stride = (keylen + sizeof(out) - 1) / sizeof(out);
amt = (keylen + stride - 1) / stride;
memcpy(countsalt, salt, saltlen);
/* collapse password */
ctx = sha512_init();
sha512_update(ctx, pass, passlen);
sha512_final(sha2pass, ctx);
/* generate key, sizeof(out) at a time */
for (count = 1; keylen > 0; count++) {
countsalt[saltlen + 0] = (count >> 24) & 0xff;
countsalt[saltlen + 1] = (count >> 16) & 0xff;
countsalt[saltlen + 2] = (count >> 8) & 0xff;
countsalt[saltlen + 3] = count & 0xff;
/* first round, salt is salt */
ctx = sha512_init();
sha512_update(ctx, countsalt, saltlen + 4);
sha512_final(sha2salt, ctx);
bcrypt_hash(sha2pass, sha2salt, tmpout);
memcpy(out, tmpout, sizeof(out));
for (i = 1; i < rounds; i++) {
/* subsequent rounds, salt is previous output */
ctx = sha512_init();
sha512_update(ctx, tmpout, sizeof(tmpout));
sha512_final(sha2salt, ctx);
bcrypt_hash(sha2pass, sha2salt, tmpout);
for (j = 0; j < sizeof(out); j++)
out[j] ^= tmpout[j];
}
/*
* pbkdf2 deviation: ouput the key material non-linearly.
*/
amt = MIN(amt, keylen);
for (i = 0; i < amt; i++) {
size_t dest = i * stride + (count - 1);
if (dest >= origkeylen) {
break;
}
key[dest] = out[i];
}
keylen -= i;
}
/* zap */
BURN_BUFFER(out, sizeof(out));
free(countsalt);
return 0;
}
#endif /* HAVE_BCRYPT_PBKDF */

View File

@@ -1,694 +0,0 @@
/* $OpenBSD: blowfish.c,v 1.18 2004/11/02 17:23:26 hshoexer Exp $ */
/*
* Blowfish block cipher for OpenBSD
* Copyright 1997 Niels Provos <provos@physnet.uni-hamburg.de>
* All rights reserved.
*
* Implementation advice by David Mazieres <dm@lcs.mit.edu>.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Niels Provos.
* 4. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
* This code is derived from section 14.3 and the given source
* in section V of Applied Cryptography, second edition.
* Blowfish is an unpatented fast block cipher designed by
* Bruce Schneier.
*/
#if !defined(HAVE_BCRYPT_PBKDF) && (!defined(HAVE_BLOWFISH_INITSTATE) || \
!defined(HAVE_BLOWFISH_EXPAND0STATE) || !defined(HAVE_BLF_ENC))
#if 0
#include <stdio.h> /* used for debugging */
#include <string.h>
#endif
#include <sys/types.h>
#include <stdint.h>
#include "libssh/blf.h"
#undef inline
#ifdef __GNUC__
#define inline __inline
#else /* !__GNUC__ */
#define inline
#endif /* !__GNUC__ */
/* Function for Feistel Networks */
#define F(s, x) ((((s)[ (((x)>>24)&0xFF)] \
+ (s)[0x100 + (((x)>>16)&0xFF)]) \
^ (s)[0x200 + (((x)>> 8)&0xFF)]) \
+ (s)[0x300 + ( (x) &0xFF)])
#define BLFRND(s,p,i,j,n) (i ^= F(s,j) ^ (p)[n])
void
Blowfish_encipher(blf_ctx *c, uint32_t *xl, uint32_t *xr)
{
uint32_t Xl;
uint32_t Xr;
uint32_t *s = c->S[0];
uint32_t *p = c->P;
Xl = *xl;
Xr = *xr;
Xl ^= p[0];
BLFRND(s, p, Xr, Xl, 1); BLFRND(s, p, Xl, Xr, 2);
BLFRND(s, p, Xr, Xl, 3); BLFRND(s, p, Xl, Xr, 4);
BLFRND(s, p, Xr, Xl, 5); BLFRND(s, p, Xl, Xr, 6);
BLFRND(s, p, Xr, Xl, 7); BLFRND(s, p, Xl, Xr, 8);
BLFRND(s, p, Xr, Xl, 9); BLFRND(s, p, Xl, Xr, 10);
BLFRND(s, p, Xr, Xl, 11); BLFRND(s, p, Xl, Xr, 12);
BLFRND(s, p, Xr, Xl, 13); BLFRND(s, p, Xl, Xr, 14);
BLFRND(s, p, Xr, Xl, 15); BLFRND(s, p, Xl, Xr, 16);
*xl = Xr ^ p[17];
*xr = Xl;
}
void
Blowfish_decipher(blf_ctx *c, uint32_t *xl, uint32_t *xr)
{
uint32_t Xl;
uint32_t Xr;
uint32_t *s = c->S[0];
uint32_t *p = c->P;
Xl = *xl;
Xr = *xr;
Xl ^= p[17];
BLFRND(s, p, Xr, Xl, 16); BLFRND(s, p, Xl, Xr, 15);
BLFRND(s, p, Xr, Xl, 14); BLFRND(s, p, Xl, Xr, 13);
BLFRND(s, p, Xr, Xl, 12); BLFRND(s, p, Xl, Xr, 11);
BLFRND(s, p, Xr, Xl, 10); BLFRND(s, p, Xl, Xr, 9);
BLFRND(s, p, Xr, Xl, 8); BLFRND(s, p, Xl, Xr, 7);
BLFRND(s, p, Xr, Xl, 6); BLFRND(s, p, Xl, Xr, 5);
BLFRND(s, p, Xr, Xl, 4); BLFRND(s, p, Xl, Xr, 3);
BLFRND(s, p, Xr, Xl, 2); BLFRND(s, p, Xl, Xr, 1);
*xl = Xr ^ p[0];
*xr = Xl;
}
void
Blowfish_initstate(blf_ctx *c)
{
/* P-box and S-box tables initialized with digits of Pi */
static const blf_ctx initstate =
{ {
{
0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7,
0xb8e1afed, 0x6a267e96, 0xba7c9045, 0xf12c7f99,
0x24a19947, 0xb3916cf7, 0x0801f2e2, 0x858efc16,
0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e,
0x0d95748f, 0x728eb658, 0x718bcd58, 0x82154aee,
0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013,
0xc5d1b023, 0x286085f0, 0xca417918, 0xb8db38ef,
0x8e79dcb0, 0x603a180e, 0x6c9e0e8b, 0xb01e8a3e,
0xd71577c1, 0xbd314b27, 0x78af2fda, 0x55605c60,
0xe65525f3, 0xaa55ab94, 0x57489862, 0x63e81440,
0x55ca396a, 0x2aab10b6, 0xb4cc5c34, 0x1141e8ce,
0xa15486af, 0x7c72e993, 0xb3ee1411, 0x636fbc2a,
0x2ba9c55d, 0x741831f6, 0xce5c3e16, 0x9b87931e,
0xafd6ba33, 0x6c24cf5c, 0x7a325381, 0x28958677,
0x3b8f4898, 0x6b4bb9af, 0xc4bfe81b, 0x66282193,
0x61d809cc, 0xfb21a991, 0x487cac60, 0x5dec8032,
0xef845d5d, 0xe98575b1, 0xdc262302, 0xeb651b88,
0x23893e81, 0xd396acc5, 0x0f6d6ff3, 0x83f44239,
0x2e0b4482, 0xa4842004, 0x69c8f04a, 0x9e1f9b5e,
0x21c66842, 0xf6e96c9a, 0x670c9c61, 0xabd388f0,
0x6a51a0d2, 0xd8542f68, 0x960fa728, 0xab5133a3,
0x6eef0b6c, 0x137a3be4, 0xba3bf050, 0x7efb2a98,
0xa1f1651d, 0x39af0176, 0x66ca593e, 0x82430e88,
0x8cee8619, 0x456f9fb4, 0x7d84a5c3, 0x3b8b5ebe,
0xe06f75d8, 0x85c12073, 0x401a449f, 0x56c16aa6,
0x4ed3aa62, 0x363f7706, 0x1bfedf72, 0x429b023d,
0x37d0d724, 0xd00a1248, 0xdb0fead3, 0x49f1c09b,
0x075372c9, 0x80991b7b, 0x25d479d8, 0xf6e8def7,
0xe3fe501a, 0xb6794c3b, 0x976ce0bd, 0x04c006ba,
0xc1a94fb6, 0x409f60c4, 0x5e5c9ec2, 0x196a2463,
0x68fb6faf, 0x3e6c53b5, 0x1339b2eb, 0x3b52ec6f,
0x6dfc511f, 0x9b30952c, 0xcc814544, 0xaf5ebd09,
0xbee3d004, 0xde334afd, 0x660f2807, 0x192e4bb3,
0xc0cba857, 0x45c8740f, 0xd20b5f39, 0xb9d3fbdb,
0x5579c0bd, 0x1a60320a, 0xd6a100c6, 0x402c7279,
0x679f25fe, 0xfb1fa3cc, 0x8ea5e9f8, 0xdb3222f8,
0x3c7516df, 0xfd616b15, 0x2f501ec8, 0xad0552ab,
0x323db5fa, 0xfd238760, 0x53317b48, 0x3e00df82,
0x9e5c57bb, 0xca6f8ca0, 0x1a87562e, 0xdf1769db,
0xd542a8f6, 0x287effc3, 0xac6732c6, 0x8c4f5573,
0x695b27b0, 0xbbca58c8, 0xe1ffa35d, 0xb8f011a0,
0x10fa3d98, 0xfd2183b8, 0x4afcb56c, 0x2dd1d35b,
0x9a53e479, 0xb6f84565, 0xd28e49bc, 0x4bfb9790,
0xe1ddf2da, 0xa4cb7e33, 0x62fb1341, 0xcee4c6e8,
0xef20cada, 0x36774c01, 0xd07e9efe, 0x2bf11fb4,
0x95dbda4d, 0xae909198, 0xeaad8e71, 0x6b93d5a0,
0xd08ed1d0, 0xafc725e0, 0x8e3c5b2f, 0x8e7594b7,
0x8ff6e2fb, 0xf2122b64, 0x8888b812, 0x900df01c,
0x4fad5ea0, 0x688fc31c, 0xd1cff191, 0xb3a8c1ad,
0x2f2f2218, 0xbe0e1777, 0xea752dfe, 0x8b021fa1,
0xe5a0cc0f, 0xb56f74e8, 0x18acf3d6, 0xce89e299,
0xb4a84fe0, 0xfd13e0b7, 0x7cc43b81, 0xd2ada8d9,
0x165fa266, 0x80957705, 0x93cc7314, 0x211a1477,
0xe6ad2065, 0x77b5fa86, 0xc75442f5, 0xfb9d35cf,
0xebcdaf0c, 0x7b3e89a0, 0xd6411bd3, 0xae1e7e49,
0x00250e2d, 0x2071b35e, 0x226800bb, 0x57b8e0af,
0x2464369b, 0xf009b91e, 0x5563911d, 0x59dfa6aa,
0x78c14389, 0xd95a537f, 0x207d5ba2, 0x02e5b9c5,
0x83260376, 0x6295cfa9, 0x11c81968, 0x4e734a41,
0xb3472dca, 0x7b14a94a, 0x1b510052, 0x9a532915,
0xd60f573f, 0xbc9bc6e4, 0x2b60a476, 0x81e67400,
0x08ba6fb5, 0x571be91f, 0xf296ec6b, 0x2a0dd915,
0xb6636521, 0xe7b9f9b6, 0xff34052e, 0xc5855664,
0x53b02d5d, 0xa99f8fa1, 0x08ba4799, 0x6e85076a},
{
0x4b7a70e9, 0xb5b32944, 0xdb75092e, 0xc4192623,
0xad6ea6b0, 0x49a7df7d, 0x9cee60b8, 0x8fedb266,
0xecaa8c71, 0x699a17ff, 0x5664526c, 0xc2b19ee1,
0x193602a5, 0x75094c29, 0xa0591340, 0xe4183a3e,
0x3f54989a, 0x5b429d65, 0x6b8fe4d6, 0x99f73fd6,
0xa1d29c07, 0xefe830f5, 0x4d2d38e6, 0xf0255dc1,
0x4cdd2086, 0x8470eb26, 0x6382e9c6, 0x021ecc5e,
0x09686b3f, 0x3ebaefc9, 0x3c971814, 0x6b6a70a1,
0x687f3584, 0x52a0e286, 0xb79c5305, 0xaa500737,
0x3e07841c, 0x7fdeae5c, 0x8e7d44ec, 0x5716f2b8,
0xb03ada37, 0xf0500c0d, 0xf01c1f04, 0x0200b3ff,
0xae0cf51a, 0x3cb574b2, 0x25837a58, 0xdc0921bd,
0xd19113f9, 0x7ca92ff6, 0x94324773, 0x22f54701,
0x3ae5e581, 0x37c2dadc, 0xc8b57634, 0x9af3dda7,
0xa9446146, 0x0fd0030e, 0xecc8c73e, 0xa4751e41,
0xe238cd99, 0x3bea0e2f, 0x3280bba1, 0x183eb331,
0x4e548b38, 0x4f6db908, 0x6f420d03, 0xf60a04bf,
0x2cb81290, 0x24977c79, 0x5679b072, 0xbcaf89af,
0xde9a771f, 0xd9930810, 0xb38bae12, 0xdccf3f2e,
0x5512721f, 0x2e6b7124, 0x501adde6, 0x9f84cd87,
0x7a584718, 0x7408da17, 0xbc9f9abc, 0xe94b7d8c,
0xec7aec3a, 0xdb851dfa, 0x63094366, 0xc464c3d2,
0xef1c1847, 0x3215d908, 0xdd433b37, 0x24c2ba16,
0x12a14d43, 0x2a65c451, 0x50940002, 0x133ae4dd,
0x71dff89e, 0x10314e55, 0x81ac77d6, 0x5f11199b,
0x043556f1, 0xd7a3c76b, 0x3c11183b, 0x5924a509,
0xf28fe6ed, 0x97f1fbfa, 0x9ebabf2c, 0x1e153c6e,
0x86e34570, 0xeae96fb1, 0x860e5e0a, 0x5a3e2ab3,
0x771fe71c, 0x4e3d06fa, 0x2965dcb9, 0x99e71d0f,
0x803e89d6, 0x5266c825, 0x2e4cc978, 0x9c10b36a,
0xc6150eba, 0x94e2ea78, 0xa5fc3c53, 0x1e0a2df4,
0xf2f74ea7, 0x361d2b3d, 0x1939260f, 0x19c27960,
0x5223a708, 0xf71312b6, 0xebadfe6e, 0xeac31f66,
0xe3bc4595, 0xa67bc883, 0xb17f37d1, 0x018cff28,
0xc332ddef, 0xbe6c5aa5, 0x65582185, 0x68ab9802,
0xeecea50f, 0xdb2f953b, 0x2aef7dad, 0x5b6e2f84,
0x1521b628, 0x29076170, 0xecdd4775, 0x619f1510,
0x13cca830, 0xeb61bd96, 0x0334fe1e, 0xaa0363cf,
0xb5735c90, 0x4c70a239, 0xd59e9e0b, 0xcbaade14,
0xeecc86bc, 0x60622ca7, 0x9cab5cab, 0xb2f3846e,
0x648b1eaf, 0x19bdf0ca, 0xa02369b9, 0x655abb50,
0x40685a32, 0x3c2ab4b3, 0x319ee9d5, 0xc021b8f7,
0x9b540b19, 0x875fa099, 0x95f7997e, 0x623d7da8,
0xf837889a, 0x97e32d77, 0x11ed935f, 0x16681281,
0x0e358829, 0xc7e61fd6, 0x96dedfa1, 0x7858ba99,
0x57f584a5, 0x1b227263, 0x9b83c3ff, 0x1ac24696,
0xcdb30aeb, 0x532e3054, 0x8fd948e4, 0x6dbc3128,
0x58ebf2ef, 0x34c6ffea, 0xfe28ed61, 0xee7c3c73,
0x5d4a14d9, 0xe864b7e3, 0x42105d14, 0x203e13e0,
0x45eee2b6, 0xa3aaabea, 0xdb6c4f15, 0xfacb4fd0,
0xc742f442, 0xef6abbb5, 0x654f3b1d, 0x41cd2105,
0xd81e799e, 0x86854dc7, 0xe44b476a, 0x3d816250,
0xcf62a1f2, 0x5b8d2646, 0xfc8883a0, 0xc1c7b6a3,
0x7f1524c3, 0x69cb7492, 0x47848a0b, 0x5692b285,
0x095bbf00, 0xad19489d, 0x1462b174, 0x23820e00,
0x58428d2a, 0x0c55f5ea, 0x1dadf43e, 0x233f7061,
0x3372f092, 0x8d937e41, 0xd65fecf1, 0x6c223bdb,
0x7cde3759, 0xcbee7460, 0x4085f2a7, 0xce77326e,
0xa6078084, 0x19f8509e, 0xe8efd855, 0x61d99735,
0xa969a7aa, 0xc50c06c2, 0x5a04abfc, 0x800bcadc,
0x9e447a2e, 0xc3453484, 0xfdd56705, 0x0e1e9ec9,
0xdb73dbd3, 0x105588cd, 0x675fda79, 0xe3674340,
0xc5c43465, 0x713e38d8, 0x3d28f89e, 0xf16dff20,
0x153e21e7, 0x8fb03d4a, 0xe6e39f2b, 0xdb83adf7},
{
0xe93d5a68, 0x948140f7, 0xf64c261c, 0x94692934,
0x411520f7, 0x7602d4f7, 0xbcf46b2e, 0xd4a20068,
0xd4082471, 0x3320f46a, 0x43b7d4b7, 0x500061af,
0x1e39f62e, 0x97244546, 0x14214f74, 0xbf8b8840,
0x4d95fc1d, 0x96b591af, 0x70f4ddd3, 0x66a02f45,
0xbfbc09ec, 0x03bd9785, 0x7fac6dd0, 0x31cb8504,
0x96eb27b3, 0x55fd3941, 0xda2547e6, 0xabca0a9a,
0x28507825, 0x530429f4, 0x0a2c86da, 0xe9b66dfb,
0x68dc1462, 0xd7486900, 0x680ec0a4, 0x27a18dee,
0x4f3ffea2, 0xe887ad8c, 0xb58ce006, 0x7af4d6b6,
0xaace1e7c, 0xd3375fec, 0xce78a399, 0x406b2a42,
0x20fe9e35, 0xd9f385b9, 0xee39d7ab, 0x3b124e8b,
0x1dc9faf7, 0x4b6d1856, 0x26a36631, 0xeae397b2,
0x3a6efa74, 0xdd5b4332, 0x6841e7f7, 0xca7820fb,
0xfb0af54e, 0xd8feb397, 0x454056ac, 0xba489527,
0x55533a3a, 0x20838d87, 0xfe6ba9b7, 0xd096954b,
0x55a867bc, 0xa1159a58, 0xcca92963, 0x99e1db33,
0xa62a4a56, 0x3f3125f9, 0x5ef47e1c, 0x9029317c,
0xfdf8e802, 0x04272f70, 0x80bb155c, 0x05282ce3,
0x95c11548, 0xe4c66d22, 0x48c1133f, 0xc70f86dc,
0x07f9c9ee, 0x41041f0f, 0x404779a4, 0x5d886e17,
0x325f51eb, 0xd59bc0d1, 0xf2bcc18f, 0x41113564,
0x257b7834, 0x602a9c60, 0xdff8e8a3, 0x1f636c1b,
0x0e12b4c2, 0x02e1329e, 0xaf664fd1, 0xcad18115,
0x6b2395e0, 0x333e92e1, 0x3b240b62, 0xeebeb922,
0x85b2a20e, 0xe6ba0d99, 0xde720c8c, 0x2da2f728,
0xd0127845, 0x95b794fd, 0x647d0862, 0xe7ccf5f0,
0x5449a36f, 0x877d48fa, 0xc39dfd27, 0xf33e8d1e,
0x0a476341, 0x992eff74, 0x3a6f6eab, 0xf4f8fd37,
0xa812dc60, 0xa1ebddf8, 0x991be14c, 0xdb6e6b0d,
0xc67b5510, 0x6d672c37, 0x2765d43b, 0xdcd0e804,
0xf1290dc7, 0xcc00ffa3, 0xb5390f92, 0x690fed0b,
0x667b9ffb, 0xcedb7d9c, 0xa091cf0b, 0xd9155ea3,
0xbb132f88, 0x515bad24, 0x7b9479bf, 0x763bd6eb,
0x37392eb3, 0xcc115979, 0x8026e297, 0xf42e312d,
0x6842ada7, 0xc66a2b3b, 0x12754ccc, 0x782ef11c,
0x6a124237, 0xb79251e7, 0x06a1bbe6, 0x4bfb6350,
0x1a6b1018, 0x11caedfa, 0x3d25bdd8, 0xe2e1c3c9,
0x44421659, 0x0a121386, 0xd90cec6e, 0xd5abea2a,
0x64af674e, 0xda86a85f, 0xbebfe988, 0x64e4c3fe,
0x9dbc8057, 0xf0f7c086, 0x60787bf8, 0x6003604d,
0xd1fd8346, 0xf6381fb0, 0x7745ae04, 0xd736fccc,
0x83426b33, 0xf01eab71, 0xb0804187, 0x3c005e5f,
0x77a057be, 0xbde8ae24, 0x55464299, 0xbf582e61,
0x4e58f48f, 0xf2ddfda2, 0xf474ef38, 0x8789bdc2,
0x5366f9c3, 0xc8b38e74, 0xb475f255, 0x46fcd9b9,
0x7aeb2661, 0x8b1ddf84, 0x846a0e79, 0x915f95e2,
0x466e598e, 0x20b45770, 0x8cd55591, 0xc902de4c,
0xb90bace1, 0xbb8205d0, 0x11a86248, 0x7574a99e,
0xb77f19b6, 0xe0a9dc09, 0x662d09a1, 0xc4324633,
0xe85a1f02, 0x09f0be8c, 0x4a99a025, 0x1d6efe10,
0x1ab93d1d, 0x0ba5a4df, 0xa186f20f, 0x2868f169,
0xdcb7da83, 0x573906fe, 0xa1e2ce9b, 0x4fcd7f52,
0x50115e01, 0xa70683fa, 0xa002b5c4, 0x0de6d027,
0x9af88c27, 0x773f8641, 0xc3604c06, 0x61a806b5,
0xf0177a28, 0xc0f586e0, 0x006058aa, 0x30dc7d62,
0x11e69ed7, 0x2338ea63, 0x53c2dd94, 0xc2c21634,
0xbbcbee56, 0x90bcb6de, 0xebfc7da1, 0xce591d76,
0x6f05e409, 0x4b7c0188, 0x39720a3d, 0x7c927c24,
0x86e3725f, 0x724d9db9, 0x1ac15bb4, 0xd39eb8fc,
0xed545578, 0x08fca5b5, 0xd83d7cd3, 0x4dad0fc4,
0x1e50ef5e, 0xb161e6f8, 0xa28514d9, 0x6c51133c,
0x6fd5c7e7, 0x56e14ec4, 0x362abfce, 0xddc6c837,
0xd79a3234, 0x92638212, 0x670efa8e, 0x406000e0},
{
0x3a39ce37, 0xd3faf5cf, 0xabc27737, 0x5ac52d1b,
0x5cb0679e, 0x4fa33742, 0xd3822740, 0x99bc9bbe,
0xd5118e9d, 0xbf0f7315, 0xd62d1c7e, 0xc700c47b,
0xb78c1b6b, 0x21a19045, 0xb26eb1be, 0x6a366eb4,
0x5748ab2f, 0xbc946e79, 0xc6a376d2, 0x6549c2c8,
0x530ff8ee, 0x468dde7d, 0xd5730a1d, 0x4cd04dc6,
0x2939bbdb, 0xa9ba4650, 0xac9526e8, 0xbe5ee304,
0xa1fad5f0, 0x6a2d519a, 0x63ef8ce2, 0x9a86ee22,
0xc089c2b8, 0x43242ef6, 0xa51e03aa, 0x9cf2d0a4,
0x83c061ba, 0x9be96a4d, 0x8fe51550, 0xba645bd6,
0x2826a2f9, 0xa73a3ae1, 0x4ba99586, 0xef5562e9,
0xc72fefd3, 0xf752f7da, 0x3f046f69, 0x77fa0a59,
0x80e4a915, 0x87b08601, 0x9b09e6ad, 0x3b3ee593,
0xe990fd5a, 0x9e34d797, 0x2cf0b7d9, 0x022b8b51,
0x96d5ac3a, 0x017da67d, 0xd1cf3ed6, 0x7c7d2d28,
0x1f9f25cf, 0xadf2b89b, 0x5ad6b472, 0x5a88f54c,
0xe029ac71, 0xe019a5e6, 0x47b0acfd, 0xed93fa9b,
0xe8d3c48d, 0x283b57cc, 0xf8d56629, 0x79132e28,
0x785f0191, 0xed756055, 0xf7960e44, 0xe3d35e8c,
0x15056dd4, 0x88f46dba, 0x03a16125, 0x0564f0bd,
0xc3eb9e15, 0x3c9057a2, 0x97271aec, 0xa93a072a,
0x1b3f6d9b, 0x1e6321f5, 0xf59c66fb, 0x26dcf319,
0x7533d928, 0xb155fdf5, 0x03563482, 0x8aba3cbb,
0x28517711, 0xc20ad9f8, 0xabcc5167, 0xccad925f,
0x4de81751, 0x3830dc8e, 0x379d5862, 0x9320f991,
0xea7a90c2, 0xfb3e7bce, 0x5121ce64, 0x774fbe32,
0xa8b6e37e, 0xc3293d46, 0x48de5369, 0x6413e680,
0xa2ae0810, 0xdd6db224, 0x69852dfd, 0x09072166,
0xb39a460a, 0x6445c0dd, 0x586cdecf, 0x1c20c8ae,
0x5bbef7dd, 0x1b588d40, 0xccd2017f, 0x6bb4e3bb,
0xdda26a7e, 0x3a59ff45, 0x3e350a44, 0xbcb4cdd5,
0x72eacea8, 0xfa6484bb, 0x8d6612ae, 0xbf3c6f47,
0xd29be463, 0x542f5d9e, 0xaec2771b, 0xf64e6370,
0x740e0d8d, 0xe75b1357, 0xf8721671, 0xaf537d5d,
0x4040cb08, 0x4eb4e2cc, 0x34d2466a, 0x0115af84,
0xe1b00428, 0x95983a1d, 0x06b89fb4, 0xce6ea048,
0x6f3f3b82, 0x3520ab82, 0x011a1d4b, 0x277227f8,
0x611560b1, 0xe7933fdc, 0xbb3a792b, 0x344525bd,
0xa08839e1, 0x51ce794b, 0x2f32c9b7, 0xa01fbac9,
0xe01cc87e, 0xbcc7d1f6, 0xcf0111c3, 0xa1e8aac7,
0x1a908749, 0xd44fbd9a, 0xd0dadecb, 0xd50ada38,
0x0339c32a, 0xc6913667, 0x8df9317c, 0xe0b12b4f,
0xf79e59b7, 0x43f5bb3a, 0xf2d519ff, 0x27d9459c,
0xbf97222c, 0x15e6fc2a, 0x0f91fc71, 0x9b941525,
0xfae59361, 0xceb69ceb, 0xc2a86459, 0x12baa8d1,
0xb6c1075e, 0xe3056a0c, 0x10d25065, 0xcb03a442,
0xe0ec6e0e, 0x1698db3b, 0x4c98a0be, 0x3278e964,
0x9f1f9532, 0xe0d392df, 0xd3a0342b, 0x8971f21e,
0x1b0a7441, 0x4ba3348c, 0xc5be7120, 0xc37632d8,
0xdf359f8d, 0x9b992f2e, 0xe60b6f47, 0x0fe3f11d,
0xe54cda54, 0x1edad891, 0xce6279cf, 0xcd3e7e6f,
0x1618b166, 0xfd2c1d05, 0x848fd2c5, 0xf6fb2299,
0xf523f357, 0xa6327623, 0x93a83531, 0x56cccd02,
0xacf08162, 0x5a75ebb5, 0x6e163697, 0x88d273cc,
0xde966292, 0x81b949d0, 0x4c50901b, 0x71c65614,
0xe6c6c7bd, 0x327a140a, 0x45e1d006, 0xc3f27b9a,
0xc9aa53fd, 0x62a80f00, 0xbb25bfe2, 0x35bdd2f6,
0x71126905, 0xb2040222, 0xb6cbcf7c, 0xcd769c2b,
0x53113ec0, 0x1640e3d3, 0x38abbd60, 0x2547adf0,
0xba38209c, 0xf746ce76, 0x77afa1c5, 0x20756060,
0x85cbfe4e, 0x8ae88dd8, 0x7aaaf9b0, 0x4cf9aa7e,
0x1948c25c, 0x02fb8a8c, 0x01c36ae4, 0xd6ebe1f9,
0x90d4f869, 0xa65cdea0, 0x3f09252d, 0xc208e69f,
0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6}
},
{
0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344,
0xa4093822, 0x299f31d0, 0x082efa98, 0xec4e6c89,
0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c,
0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917,
0x9216d5d9, 0x8979fb1b
} };
*c = initstate;
}
uint32_t
Blowfish_stream2word(const uint8_t *data, uint16_t databytes,
uint16_t *current)
{
uint8_t i;
uint16_t j;
uint32_t temp;
temp = 0x00000000;
j = *current;
for (i = 0; i < 4; i++, j++) {
if (j >= databytes)
j = 0;
temp = (temp << 8) | data[j];
}
*current = j;
return temp;
}
void
Blowfish_expand0state(blf_ctx *c, const uint8_t *key, uint16_t keybytes)
{
uint16_t i;
uint16_t j;
uint16_t k;
uint32_t temp;
uint32_t datal;
uint32_t datar;
j = 0;
for (i = 0; i < BLF_N + 2; i++) {
/* Extract 4 int8 to 1 int32 from keystream */
temp = Blowfish_stream2word(key, keybytes, &j);
c->P[i] = c->P[i] ^ temp;
}
j = 0;
datal = 0x00000000;
datar = 0x00000000;
for (i = 0; i < BLF_N + 2; i += 2) {
Blowfish_encipher(c, &datal, &datar);
c->P[i] = datal;
c->P[i + 1] = datar;
}
for (i = 0; i < 4; i++) {
for (k = 0; k < 256; k += 2) {
Blowfish_encipher(c, &datal, &datar);
c->S[i][k] = datal;
c->S[i][k + 1] = datar;
}
}
}
void
Blowfish_expandstate(blf_ctx *c, const uint8_t *data, uint16_t databytes,
const uint8_t *key, uint16_t keybytes)
{
uint16_t i;
uint16_t j;
uint16_t k;
uint32_t temp;
uint32_t datal;
uint32_t datar;
j = 0;
for (i = 0; i < BLF_N + 2; i++) {
/* Extract 4 int8 to 1 int32 from keystream */
temp = Blowfish_stream2word(key, keybytes, &j);
c->P[i] = c->P[i] ^ temp;
}
j = 0;
datal = 0x00000000;
datar = 0x00000000;
for (i = 0; i < BLF_N + 2; i += 2) {
datal ^= Blowfish_stream2word(data, databytes, &j);
datar ^= Blowfish_stream2word(data, databytes, &j);
Blowfish_encipher(c, &datal, &datar);
c->P[i] = datal;
c->P[i + 1] = datar;
}
for (i = 0; i < 4; i++) {
for (k = 0; k < 256; k += 2) {
datal ^= Blowfish_stream2word(data, databytes, &j);
datar ^= Blowfish_stream2word(data, databytes, &j);
Blowfish_encipher(c, &datal, &datar);
c->S[i][k] = datal;
c->S[i][k + 1] = datar;
}
}
}
void
blf_key(blf_ctx *c, const uint8_t *k, uint16_t len)
{
/* Initialize S-boxes and subkeys with Pi */
Blowfish_initstate(c);
/* Transform S-boxes and subkeys with key */
Blowfish_expand0state(c, k, len);
}
void
blf_enc(blf_ctx *c, uint32_t *data, uint16_t blocks)
{
uint32_t *d;
uint16_t i;
d = data;
for (i = 0; i < blocks; i++) {
Blowfish_encipher(c, d, d + 1);
d += 2;
}
}
void
blf_dec(blf_ctx *c, uint32_t *data, uint16_t blocks)
{
uint32_t *d;
uint16_t i;
d = data;
for (i = 0; i < blocks; i++) {
Blowfish_decipher(c, d, d + 1);
d += 2;
}
}
void
blf_ecb_encrypt(blf_ctx *c, uint8_t *data, uint32_t len)
{
uint32_t l, r;
uint32_t i;
for (i = 0; i < len; i += 8) {
l = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3];
r = data[4] << 24 | data[5] << 16 | data[6] << 8 | data[7];
Blowfish_encipher(c, &l, &r);
data[0] = l >> 24 & 0xff;
data[1] = l >> 16 & 0xff;
data[2] = l >> 8 & 0xff;
data[3] = l & 0xff;
data[4] = r >> 24 & 0xff;
data[5] = r >> 16 & 0xff;
data[6] = r >> 8 & 0xff;
data[7] = r & 0xff;
data += 8;
}
}
void
blf_ecb_decrypt(blf_ctx *c, uint8_t *data, uint32_t len)
{
uint32_t l, r;
uint32_t i;
for (i = 0; i < len; i += 8) {
l = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3];
r = data[4] << 24 | data[5] << 16 | data[6] << 8 | data[7];
Blowfish_decipher(c, &l, &r);
data[0] = l >> 24 & 0xff;
data[1] = l >> 16 & 0xff;
data[2] = l >> 8 & 0xff;
data[3] = l & 0xff;
data[4] = r >> 24 & 0xff;
data[5] = r >> 16 & 0xff;
data[6] = r >> 8 & 0xff;
data[7] = r & 0xff;
data += 8;
}
}
void
blf_cbc_encrypt(blf_ctx *c, uint8_t *iv, uint8_t *data, uint32_t len)
{
uint32_t l, r;
uint32_t i, j;
for (i = 0; i < len; i += 8) {
for (j = 0; j < 8; j++)
data[j] ^= iv[j];
l = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3];
r = data[4] << 24 | data[5] << 16 | data[6] << 8 | data[7];
Blowfish_encipher(c, &l, &r);
data[0] = l >> 24 & 0xff;
data[1] = l >> 16 & 0xff;
data[2] = l >> 8 & 0xff;
data[3] = l & 0xff;
data[4] = r >> 24 & 0xff;
data[5] = r >> 16 & 0xff;
data[6] = r >> 8 & 0xff;
data[7] = r & 0xff;
iv = data;
data += 8;
}
}
void
blf_cbc_decrypt(blf_ctx *c, uint8_t *iva, uint8_t *data, uint32_t len)
{
uint32_t l, r;
uint8_t *iv;
uint32_t i, j;
iv = data + len - 16;
data = data + len - 8;
for (i = len - 8; i >= 8; i -= 8) {
l = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3];
r = data[4] << 24 | data[5] << 16 | data[6] << 8 | data[7];
Blowfish_decipher(c, &l, &r);
data[0] = l >> 24 & 0xff;
data[1] = l >> 16 & 0xff;
data[2] = l >> 8 & 0xff;
data[3] = l & 0xff;
data[4] = r >> 24 & 0xff;
data[5] = r >> 16 & 0xff;
data[6] = r >> 8 & 0xff;
data[7] = r & 0xff;
for (j = 0; j < 8; j++)
data[j] ^= iv[j];
iv -= 8;
data -= 8;
}
l = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3];
r = data[4] << 24 | data[5] << 16 | data[6] << 8 | data[7];
Blowfish_decipher(c, &l, &r);
data[0] = l >> 24 & 0xff;
data[1] = l >> 16 & 0xff;
data[2] = l >> 8 & 0xff;
data[3] = l & 0xff;
data[4] = r >> 24 & 0xff;
data[5] = r >> 16 & 0xff;
data[6] = r >> 8 & 0xff;
data[7] = r & 0xff;
for (j = 0; j < 8; j++)
data[j] ^= iva[j];
}
#if 0
void
report(uint32_t data[], uint16_t len)
{
uint16_t i;
for (i = 0; i < len; i += 2)
printf("Block %0hd: %08lx %08lx.\n",
i / 2, data[i], data[i + 1]);
}
void
main(void)
{
blf_ctx c;
char key[] = "AAAAA";
char key2[] = "abcdefghijklmnopqrstuvwxyz";
uint32_t data[10];
uint32_t data2[] =
{0x424c4f57l, 0x46495348l};
uint16_t i;
/* First test */
for (i = 0; i < 10; i++)
data[i] = i;
blf_key(&c, (uint8_t *) key, 5);
blf_enc(&c, data, 5);
blf_dec(&c, data, 1);
blf_dec(&c, data + 2, 4);
printf("Should read as 0 - 9.\n");
report(data, 10);
/* Second test */
blf_key(&c, (uint8_t *) key2, strlen(key2));
blf_enc(&c, data2, 1);
printf("\nShould read as: 0x324ed0fe 0xf413a203.\n");
report(data2, 2);
blf_dec(&c, data2, 1);
report(data2, 2);
}
#endif
#endif /* !defined(HAVE_BCRYPT_PBKDF) && (!defined(HAVE_BLOWFISH_INITSTATE) || \
!defined(HAVE_BLOWFISH_EXPAND0STATE) || !defined(HAVE_BLF_ENC)) */

222
src/external/ed25519.c vendored
View File

@@ -1,222 +0,0 @@
/* $OpenBSD: ed25519.c,v 1.3 2013/12/09 11:03:45 markus Exp $ */
/*
* Public Domain, Authors: Daniel J. Bernstein, Niels Duif, Tanja Lange,
* Peter Schwabe, Bo-Yin Yang.
* Copied from supercop-20130419/crypto_sign/ed25519/ref/ed25519.c
*/
#include "config.h"
#include "libssh/libcrypto.h"
#include "libssh/wrapper.h"
#include "libssh/ge25519.h"
#include "libssh/sc25519.h"
#include "libssh/ed25519.h"
/*
* Public Domain, Author: Daniel J. Bernstein
* Copied from nacl-20110221/crypto_verify/32/ref/verify.c
*/
static int crypto_verify_32(const unsigned char *x,const unsigned char *y)
{
unsigned int differentbits = 0;
#define F(i) differentbits |= x[i] ^ y[i];
F(0)
F(1)
F(2)
F(3)
F(4)
F(5)
F(6)
F(7)
F(8)
F(9)
F(10)
F(11)
F(12)
F(13)
F(14)
F(15)
F(16)
F(17)
F(18)
F(19)
F(20)
F(21)
F(22)
F(23)
F(24)
F(25)
F(26)
F(27)
F(28)
F(29)
F(30)
F(31)
return (1 & ((differentbits - 1) >> 8)) - 1;
}
static void get_hram(unsigned char *hram,
const unsigned char *sm,
const unsigned char *pk,
unsigned char *playground,
unsigned long long smlen)
{
unsigned long long i;
SHA512CTX ctx;
for (i = 0;i < 32;++i) playground[i] = sm[i];
for (i = 32;i < 64;++i) playground[i] = pk[i-32];
for (i = 64;i < smlen;++i) playground[i] = sm[i];
ctx = sha512_init();
sha512_update(ctx, playground, smlen);
sha512_final(hram, ctx);
}
int crypto_sign_ed25519_keypair(unsigned char *pk,
unsigned char *sk)
{
sc25519 scsk;
ge25519 gepk;
SHA512CTX ctx;
unsigned char extsk[64];
int i;
int rc;
rc = ssh_get_random(sk, 32, 0);
if (rc < 0){
return -1;
}
ctx = sha512_init();
sha512_update(ctx, sk, 32);
sha512_final(extsk, ctx);
extsk[0] &= 248;
extsk[31] &= 127;
extsk[31] |= 64;
sc25519_from32bytes(&scsk,extsk);
ge25519_scalarmult_base(&gepk, &scsk);
ge25519_pack(pk, &gepk);
for(i=0;i<32;i++) {
sk[32 + i] = pk[i];
}
return 0;
}
int crypto_sign_ed25519(unsigned char *sm,
unsigned long long *smlen,
const unsigned char *m,
unsigned long long mlen,
const unsigned char *sk)
{
sc25519 sck, scs, scsk;
ge25519 ger;
SHA512CTX ctx;
unsigned char r[32];
unsigned char s[32];
unsigned char extsk[64];
unsigned long long i;
unsigned char hmg[SHA512_DIGEST_LEN];
unsigned char hram[SHA512_DIGEST_LEN];
ctx = sha512_init();
sha512_update(ctx, sk, 32);
sha512_final(extsk, ctx);
extsk[0] &= 248;
extsk[31] &= 127;
extsk[31] |= 64;
*smlen = mlen + 64;
for (i = 0;i < mlen; i++) {
sm[64 + i] = m[i];
}
for (i = 0;i < 32; i++) {
sm[32 + i] = extsk[32+i];
}
/* Generate k as h(extsk[32],...,extsk[63],m) */
ctx = sha512_init();
sha512_update(ctx, sm + 32, mlen + 32);
sha512_final(hmg, ctx);
/* Computation of R */
sc25519_from64bytes(&sck, hmg);
ge25519_scalarmult_base(&ger, &sck);
ge25519_pack(r, &ger);
/* Computation of s */
for (i = 0; i < 32; i++) {
sm[i] = r[i];
}
get_hram(hram, sm, sk+32, sm, mlen+64);
sc25519_from64bytes(&scs, hram);
sc25519_from32bytes(&scsk, extsk);
sc25519_mul(&scs, &scs, &scsk);
sc25519_add(&scs, &scs, &sck);
sc25519_to32bytes(s,&scs); /* cat s */
for (i = 0;i < 32; i++) {
sm[32 + i] = s[i];
}
return 0;
}
int crypto_sign_ed25519_open(unsigned char *m,
unsigned long long *mlen,
const unsigned char *sm,
unsigned long long smlen,
const unsigned char *pk)
{
unsigned int i;
int ret;
unsigned char t2[32];
ge25519 get1, get2;
sc25519 schram, scs;
unsigned char hram[SHA512_DIGEST_LEN];
*mlen = (unsigned long long) -1;
if (smlen < 64) return -1;
if (ge25519_unpackneg_vartime(&get1, pk)) {
return -1;
}
get_hram(hram,sm,pk,m,smlen);
sc25519_from64bytes(&schram, hram);
sc25519_from32bytes(&scs, sm+32);
ge25519_double_scalarmult_vartime(&get2,
&get1,
&schram,
&ge25519_base,
&scs);
ge25519_pack(t2, &get2);
ret = crypto_verify_32(sm, t2);
if (ret != 0) {
for (i = 0; i < smlen - 64; i++) {
m[i] = sm[i + 64];
}
*mlen = smlen-64;
} else {
for (i = 0; i < smlen - 64; i++) {
m[i] = 0;
}
}
return ret;
}

416
src/external/fe25519.c vendored
View File

@@ -1,416 +0,0 @@
/*
* Public Domain, Authors: Daniel J. Bernstein, Niels Duif, Tanja Lange,
* Peter Schwabe, Bo-Yin Yang.
* Copied from supercop-20130419/crypto_sign/ed25519/ref/fe25519.c
*/
#define WINDOWSIZE 1 /* Should be 1,2, or 4 */
#define WINDOWMASK ((1<<WINDOWSIZE)-1)
#include "libssh/fe25519.h"
static uint32_t equal(uint32_t a,uint32_t b) /* 16-bit inputs */
{
uint32_t x = a ^ b; /* 0: yes; 1..65535: no */
x -= 1; /* 4294967295: yes; 0..65534: no */
x >>= 31; /* 1: yes; 0: no */
return x;
}
static uint32_t ge(uint32_t a,uint32_t b) /* 16-bit inputs */
{
unsigned int x = a;
x -= (unsigned int) b; /* 0..65535: yes; 4294901761..4294967295: no */
x >>= 31; /* 0: yes; 1: no */
x ^= 1; /* 1: yes; 0: no */
return x;
}
static uint32_t times19(uint32_t a)
{
return (a << 4) + (a << 1) + a;
}
static uint32_t times38(uint32_t a)
{
return (a << 5) + (a << 2) + (a << 1);
}
static void reduce_add_sub(fe25519 *r)
{
uint32_t t;
int i,rep;
for(rep = 0; rep < 4; rep++) {
t = r->v[31] >> 7;
r->v[31] &= 127;
t = times19(t);
r->v[0] += t;
for(i = 0; i < 31; i++) {
t = r->v[i] >> 8;
r->v[i+1] += t;
r->v[i] &= 255;
}
}
}
static void reduce_mul(fe25519 *r)
{
uint32_t t;
int i,rep;
for(rep = 0; rep < 2; rep++) {
t = r->v[31] >> 7;
r->v[31] &= 127;
t = times19(t);
r->v[0] += t;
for(i = 0; i < 31; i++) {
t = r->v[i] >> 8;
r->v[i+1] += t;
r->v[i] &= 255;
}
}
}
/* reduction modulo 2^255-19 */
void fe25519_freeze(fe25519 *r)
{
int i;
uint32_t m = equal(r->v[31],127);
for (i = 30; i > 0; i--) {
m &= equal(r->v[i],255);
}
m &= ge(r->v[0],237);
m = -m;
r->v[31] -= m&127;
for (i = 30; i > 0; i--) {
r->v[i] -= m&255;
}
r->v[0] -= m&237;
}
void fe25519_unpack(fe25519 *r, const unsigned char x[32])
{
int i;
for (i = 0;i < 32; i++) {
r->v[i] = x[i];
}
r->v[31] &= 127;
}
/* Assumes input x being reduced below 2^255 */
void fe25519_pack(unsigned char r[32], const fe25519 *x)
{
int i;
fe25519 y = *x;
fe25519_freeze(&y);
for (i = 0; i < 32; i++) {
r[i] = y.v[i];
}
}
int fe25519_iszero(const fe25519 *x)
{
int i;
int r;
fe25519 t = *x;
fe25519_freeze(&t);
r = equal(t.v[0],0);
for (i = 1; i < 32; i++) {
r &= equal(t.v[i],0);
}
return r;
}
int fe25519_iseq_vartime(const fe25519 *x, const fe25519 *y)
{
int i;
fe25519 t1 = *x;
fe25519 t2 = *y;
fe25519_freeze(&t1);
fe25519_freeze(&t2);
for (i = 0; i < 32; i++) {
if(t1.v[i] != t2.v[i]) {
return 0;
}
}
return 1;
}
void fe25519_cmov(fe25519 *r, const fe25519 *x, unsigned char b)
{
int i;
uint32_t mask = b;
mask = -mask;
for (i = 0; i < 32; i++) {
r->v[i] ^= mask & (x->v[i] ^ r->v[i]);
}
}
unsigned char fe25519_getparity(const fe25519 *x)
{
fe25519 t = *x;
fe25519_freeze(&t);
return t.v[0] & 1;
}
void fe25519_setone(fe25519 *r)
{
int i;
r->v[0] = 1;
for (i = 1; i < 32; i++) {
r->v[i]=0;
}
}
void fe25519_setzero(fe25519 *r)
{
int i;
for (i = 0; i < 32; i++) {
r->v[i]=0;
}
}
void fe25519_neg(fe25519 *r, const fe25519 *x)
{
fe25519 t;
int i;
for (i = 0; i < 32; i++) {
t.v[i]=x->v[i];
}
fe25519_setzero(r);
fe25519_sub(r, r, &t);
}
void fe25519_add(fe25519 *r, const fe25519 *x, const fe25519 *y)
{
int i;
for (i = 0; i < 32; i++) {
r->v[i] = x->v[i] + y->v[i];
}
reduce_add_sub(r);
}
void fe25519_sub(fe25519 *r, const fe25519 *x, const fe25519 *y)
{
int i;
uint32_t t[32];
t[0] = x->v[0] + 0x1da;
t[31] = x->v[31] + 0xfe;
for (i = 1; i < 31; i++) {
t[i] = x->v[i] + 0x1fe;
}
for (i = 0; i < 32; i++) {
r->v[i] = t[i] - y->v[i];
}
reduce_add_sub(r);
}
void fe25519_mul(fe25519 *r, const fe25519 *x, const fe25519 *y)
{
int i,j;
uint32_t t[63];
for (i = 0; i < 63; i++) {
t[i] = 0;
}
for (i = 0; i < 32; i++) {
for (j = 0; j < 32; j++) {
t[i+j] += x->v[i] * y->v[j];
}
}
for (i = 32; i < 63; i++) {
r->v[i-32] = t[i-32] + times38(t[i]);
}
r->v[31] = t[31]; /* result now in r[0]...r[31] */
reduce_mul(r);
}
void fe25519_square(fe25519 *r, const fe25519 *x)
{
fe25519_mul(r, x, x);
}
void fe25519_invert(fe25519 *r, const fe25519 *x)
{
fe25519 z2;
fe25519 z9;
fe25519 z11;
fe25519 z2_5_0;
fe25519 z2_10_0;
fe25519 z2_20_0;
fe25519 z2_50_0;
fe25519 z2_100_0;
fe25519 t0;
fe25519 t1;
int i;
/* 2 */ fe25519_square(&z2, x);
/* 4 */ fe25519_square(&t1, &z2);
/* 8 */ fe25519_square(&t0, &t1);
/* 9 */ fe25519_mul(&z9, &t0, x);
/* 11 */ fe25519_mul(&z11, &z9, &z2);
/* 22 */ fe25519_square(&t0, &z11);
/* 2^5 - 2^0 = 31 */ fe25519_mul(&z2_5_0, &t0, &z9);
/* 2^6 - 2^1 */ fe25519_square(&t0, &z2_5_0);
/* 2^7 - 2^2 */ fe25519_square(&t1, &t0);
/* 2^8 - 2^3 */ fe25519_square(&t0, &t1);
/* 2^9 - 2^4 */ fe25519_square(&t1, &t0);
/* 2^10 - 2^5 */ fe25519_square(&t0, &t1);
/* 2^10 - 2^0 */ fe25519_mul(&z2_10_0, &t0, &z2_5_0);
/* 2^11 - 2^1 */ fe25519_square(&t0, &z2_10_0);
/* 2^12 - 2^2 */ fe25519_square(&t1, &t0);
/* 2^20 - 2^10 */ for (i = 2;i < 10;i += 2) {
fe25519_square(&t0, &t1);
fe25519_square(&t1, &t0);
}
/* 2^20 - 2^0 */ fe25519_mul(&z2_20_0, &t1, &z2_10_0);
/* 2^21 - 2^1 */ fe25519_square(&t0, &z2_20_0);
/* 2^22 - 2^2 */ fe25519_square(&t1, &t0);
/* 2^40 - 2^20 */ for (i = 2;i < 20;i += 2) {
fe25519_square(&t0, &t1);
fe25519_square(&t1,&t0);
}
/* 2^40 - 2^0 */ fe25519_mul(&t0, &t1, &z2_20_0);
/* 2^41 - 2^1 */ fe25519_square(&t1, &t0);
/* 2^42 - 2^2 */ fe25519_square(&t0, &t1);
/* 2^50 - 2^10 */ for (i = 2; i < 10;i += 2) {
fe25519_square(&t1, &t0);
fe25519_square(&t0, &t1);
}
/* 2^50 - 2^0 */ fe25519_mul(&z2_50_0,&t0,&z2_10_0);
/* 2^51 - 2^1 */ fe25519_square(&t0, &z2_50_0);
/* 2^52 - 2^2 */ fe25519_square(&t1, &t0);
/* 2^100 - 2^50 */ for (i = 2; i < 50; i += 2) {
fe25519_square(&t0, &t1);
fe25519_square(&t1,&t0);
}
/* 2^100 - 2^0 */ fe25519_mul(&z2_100_0, &t1, &z2_50_0);
/* 2^101 - 2^1 */ fe25519_square(&t1, &z2_100_0);
/* 2^102 - 2^2 */ fe25519_square(&t0, &t1);
/* 2^200 - 2^100 */ for (i = 2; i < 100; i += 2) {
fe25519_square(&t1, &t0);
fe25519_square(&t0,&t1);
}
/* 2^200 - 2^0 */ fe25519_mul(&t1, &t0, &z2_100_0);
/* 2^201 - 2^1 */ fe25519_square(&t0, &t1);
/* 2^202 - 2^2 */ fe25519_square(&t1, &t0);
/* 2^250 - 2^50 */ for (i = 2;i < 50;i += 2) {
fe25519_square(&t0, &t1);
fe25519_square(&t1,&t0);
}
/* 2^250 - 2^0 */ fe25519_mul(&t0, &t1, &z2_50_0);
/* 2^251 - 2^1 */ fe25519_square(&t1, &t0);
/* 2^252 - 2^2 */ fe25519_square(&t0, &t1);
/* 2^253 - 2^3 */ fe25519_square(&t1, &t0);
/* 2^254 - 2^4 */ fe25519_square(&t0, &t1);
/* 2^255 - 2^5 */ fe25519_square(&t1, &t0);
/* 2^255 - 21 */ fe25519_mul(r, &t1, &z11);
}
void fe25519_pow2523(fe25519 *r, const fe25519 *x)
{
fe25519 z2;
fe25519 z9;
fe25519 z11;
fe25519 z2_5_0;
fe25519 z2_10_0;
fe25519 z2_20_0;
fe25519 z2_50_0;
fe25519 z2_100_0;
fe25519 t;
int i;
/* 2 */ fe25519_square(&z2, x);
/* 4 */ fe25519_square(&t, &z2);
/* 8 */ fe25519_square(&t, &t);
/* 9 */ fe25519_mul(&z9, &t, x);
/* 11 */ fe25519_mul(&z11, &z9, &z2);
/* 22 */ fe25519_square(&t, &z11);
/* 2^5 - 2^0 = 31 */ fe25519_mul(&z2_5_0, &t, &z9);
/* 2^6 - 2^1 */ fe25519_square(&t, &z2_5_0);
/* 2^10 - 2^5 */ for (i = 1; i < 5; i++) {
fe25519_square(&t,&t);
}
/* 2^10 - 2^0 */ fe25519_mul(&z2_10_0, &t, &z2_5_0);
/* 2^11 - 2^1 */ fe25519_square(&t, &z2_10_0);
/* 2^20 - 2^10 */ for (i = 1; i < 10; i++) {
fe25519_square(&t, &t);
}
/* 2^20 - 2^0 */ fe25519_mul(&z2_20_0, &t, &z2_10_0);
/* 2^21 - 2^1 */ fe25519_square(&t, &z2_20_0);
/* 2^40 - 2^20 */ for (i = 1; i < 20; i++) {
fe25519_square(&t,&t);
}
/* 2^40 - 2^0 */ fe25519_mul(&t, &t, &z2_20_0);
/* 2^41 - 2^1 */ fe25519_square(&t, &t);
/* 2^50 - 2^10 */ for (i = 1; i < 10; i++) {
fe25519_square(&t,&t);
}
/* 2^50 - 2^0 */ fe25519_mul(&z2_50_0, &t, &z2_10_0);
/* 2^51 - 2^1 */ fe25519_square(&t, &z2_50_0);
/* 2^100 - 2^50 */ for (i = 1; i < 50; i++) {
fe25519_square(&t, &t);
}
/* 2^100 - 2^0 */ fe25519_mul(&z2_100_0, &t, &z2_50_0);
/* 2^101 - 2^1 */ fe25519_square(&t, &z2_100_0);
/* 2^200 - 2^100 */ for (i = 1; i < 100; i++) {
fe25519_square(&t, &t);
}
/* 2^200 - 2^0 */ fe25519_mul(&t, &t, &z2_100_0);
/* 2^201 - 2^1 */ fe25519_square(&t, &t);
/* 2^250 - 2^50 */ for (i = 1; i < 50; i++) {
fe25519_square(&t, &t);
}
/* 2^250 - 2^0 */ fe25519_mul(&t, &t, &z2_50_0);
/* 2^251 - 2^1 */ fe25519_square(&t, &t);
/* 2^252 - 2^2 */ fe25519_square(&t, &t);
/* 2^252 - 3 */ fe25519_mul(r, &t, x);
}

367
src/external/ge25519.c vendored
View File

@@ -1,367 +0,0 @@
/* $OpenBSD: ge25519.c,v 1.3 2013/12/09 11:03:45 markus Exp $ */
/*
* Public Domain, Authors: Daniel J. Bernstein, Niels Duif, Tanja Lange,
* Peter Schwabe, Bo-Yin Yang.
* Copied from supercop-20130419/crypto_sign/ed25519/ref/ge25519.c
*/
#include "libssh/fe25519.h"
#include "libssh/sc25519.h"
#include "libssh/ge25519.h"
/*
* Arithmetic on the twisted Edwards curve -x^2 + y^2 = 1 + dx^2y^2
* with d = -(121665/121666) = 37095705934669439343138083508754565189542113879843219016388785533085940283555
* Base point: (15112221349535400772501151409588531511454012693041857206046113283949847762202,46316835694926478169428394003475163141307993866256225615783033603165251855960);
*/
/* d */
static const fe25519 ge25519_ecd = {
{0xA3, 0x78, 0x59, 0x13, 0xCA, 0x4D, 0xEB, 0x75,
0xAB, 0xD8, 0x41, 0x41, 0x4D, 0x0A, 0x70, 0x00,
0x98, 0xE8, 0x79, 0x77, 0x79, 0x40, 0xC7, 0x8C,
0x73, 0xFE, 0x6F, 0x2B, 0xEE, 0x6C, 0x03, 0x52}
};
/* 2*d */
static const fe25519 ge25519_ec2d = {
{0x59, 0xF1, 0xB2, 0x26, 0x94, 0x9B, 0xD6, 0xEB,
0x56, 0xB1, 0x83, 0x82, 0x9A, 0x14, 0xE0, 0x00,
0x30, 0xD1, 0xF3, 0xEE, 0xF2, 0x80, 0x8E, 0x19,
0xE7, 0xFC, 0xDF, 0x56, 0xDC, 0xD9, 0x06, 0x24}
};
/* sqrt(-1) */
static const fe25519 ge25519_sqrtm1 = {
{0xB0, 0xA0, 0x0E, 0x4A, 0x27, 0x1B, 0xEE, 0xC4,
0x78, 0xE4, 0x2F, 0xAD, 0x06, 0x18, 0x43, 0x2F,
0xA7, 0xD7, 0xFB, 0x3D, 0x99, 0x00, 0x4D, 0x2B,
0x0B, 0xDF, 0xC1, 0x4F, 0x80, 0x24, 0x83, 0x2B}
};
#define ge25519_p3 ge25519
typedef struct {
fe25519 x;
fe25519 z;
fe25519 y;
fe25519 t;
} ge25519_p1p1;
typedef struct {
fe25519 x;
fe25519 y;
fe25519 z;
} ge25519_p2;
typedef struct {
fe25519 x;
fe25519 y;
} ge25519_aff;
/* Packed coordinates of the base point */
const ge25519 ge25519_base = {
{{0x1A, 0xD5, 0x25, 0x8F, 0x60, 0x2D, 0x56, 0xC9,
0xB2, 0xA7, 0x25, 0x95, 0x60, 0xC7, 0x2C, 0x69,
0x5C, 0xDC, 0xD6, 0xFD, 0x31, 0xE2, 0xA4, 0xC0,
0xFE, 0x53, 0x6E, 0xCD, 0xD3, 0x36, 0x69, 0x21}},
{{0x58, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66}},
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
{{0xA3, 0xDD, 0xB7, 0xA5, 0xB3, 0x8A, 0xDE, 0x6D,
0xF5, 0x52, 0x51, 0x77, 0x80, 0x9F, 0xF0, 0x20,
0x7D, 0xE3, 0xAB, 0x64, 0x8E, 0x4E, 0xEA, 0x66,
0x65, 0x76, 0x8B, 0xD7, 0x0F, 0x5F, 0x87, 0x67}}
};
/* Multiples of the base point in affine representation */
static const ge25519_aff ge25519_base_multiples_affine[425] = {
#include "ge25519_base.data"
};
static void p1p1_to_p2(ge25519_p2 *r, const ge25519_p1p1 *p)
{
fe25519_mul(&r->x, &p->x, &p->t);
fe25519_mul(&r->y, &p->y, &p->z);
fe25519_mul(&r->z, &p->z, &p->t);
}
static void p1p1_to_p3(ge25519_p3 *r, const ge25519_p1p1 *p)
{
p1p1_to_p2((ge25519_p2 *)r, p);
fe25519_mul(&r->t, &p->x, &p->y);
}
static void ge25519_mixadd2(ge25519_p3 *r, const ge25519_aff *q)
{
fe25519 a,b,t1,t2,c,d,e,f,g,h,qt;
fe25519_mul(&qt, &q->x, &q->y);
fe25519_sub(&a, &r->y, &r->x); /* A = (Y1-X1)*(Y2-X2) */
fe25519_add(&b, &r->y, &r->x); /* B = (Y1+X1)*(Y2+X2) */
fe25519_sub(&t1, &q->y, &q->x);
fe25519_add(&t2, &q->y, &q->x);
fe25519_mul(&a, &a, &t1);
fe25519_mul(&b, &b, &t2);
fe25519_sub(&e, &b, &a); /* E = B-A */
fe25519_add(&h, &b, &a); /* H = B+A */
fe25519_mul(&c, &r->t, &qt); /* C = T1*k*T2 */
fe25519_mul(&c, &c, &ge25519_ec2d);
fe25519_add(&d, &r->z, &r->z); /* D = Z1*2 */
fe25519_sub(&f, &d, &c); /* F = D-C */
fe25519_add(&g, &d, &c); /* G = D+C */
fe25519_mul(&r->x, &e, &f);
fe25519_mul(&r->y, &h, &g);
fe25519_mul(&r->z, &g, &f);
fe25519_mul(&r->t, &e, &h);
}
static void add_p1p1(ge25519_p1p1 *r, const ge25519_p3 *p, const ge25519_p3 *q)
{
fe25519 a, b, c, d, t;
fe25519_sub(&a, &p->y, &p->x); /* A = (Y1-X1)*(Y2-X2) */
fe25519_sub(&t, &q->y, &q->x);
fe25519_mul(&a, &a, &t);
fe25519_add(&b, &p->x, &p->y); /* B = (Y1+X1)*(Y2+X2) */
fe25519_add(&t, &q->x, &q->y);
fe25519_mul(&b, &b, &t);
fe25519_mul(&c, &p->t, &q->t); /* C = T1*k*T2 */
fe25519_mul(&c, &c, &ge25519_ec2d);
fe25519_mul(&d, &p->z, &q->z); /* D = Z1*2*Z2 */
fe25519_add(&d, &d, &d);
fe25519_sub(&r->x, &b, &a); /* E = B-A */
fe25519_sub(&r->t, &d, &c); /* F = D-C */
fe25519_add(&r->z, &d, &c); /* G = D+C */
fe25519_add(&r->y, &b, &a); /* H = B+A */
}
/* See http://www.hyperelliptic.org/EFD/g1p/auto-twisted-extended-1.html#doubling-dbl-2008-hwcd */
static void dbl_p1p1(ge25519_p1p1 *r, const ge25519_p2 *p)
{
fe25519 a,b,c,d;
fe25519_square(&a, &p->x);
fe25519_square(&b, &p->y);
fe25519_square(&c, &p->z);
fe25519_add(&c, &c, &c);
fe25519_neg(&d, &a);
fe25519_add(&r->x, &p->x, &p->y);
fe25519_square(&r->x, &r->x);
fe25519_sub(&r->x, &r->x, &a);
fe25519_sub(&r->x, &r->x, &b);
fe25519_add(&r->z, &d, &b);
fe25519_sub(&r->t, &r->z, &c);
fe25519_sub(&r->y, &d, &b);
}
/* Constant-time version of: if(b) r = p */
static void cmov_aff(ge25519_aff *r, const ge25519_aff *p, unsigned char b)
{
fe25519_cmov(&r->x, &p->x, b);
fe25519_cmov(&r->y, &p->y, b);
}
static unsigned char equal(signed char b,signed char c)
{
unsigned char ub = b;
unsigned char uc = c;
unsigned char x = ub ^ uc; /* 0: yes; 1..255: no */
uint32_t y = x; /* 0: yes; 1..255: no */
y -= 1; /* 4294967295: yes; 0..254: no */
y >>= 31; /* 1: yes; 0: no */
return y;
}
static unsigned char negative(signed char b)
{
unsigned long long x = b; /* 18446744073709551361..18446744073709551615: yes; 0..255: no */
x >>= 63; /* 1: yes; 0: no */
return x;
}
static void choose_t(ge25519_aff *t, unsigned long long pos, signed char b)
{
/* constant time */
fe25519 v;
*t = ge25519_base_multiples_affine[5 * pos + 0];
cmov_aff(t, &ge25519_base_multiples_affine[5 * pos + 1],
equal(b,1) | equal(b,-1));
cmov_aff(t, &ge25519_base_multiples_affine[5 * pos + 2],
equal(b,2) | equal(b,-2));
cmov_aff(t, &ge25519_base_multiples_affine[5 * pos + 3],
equal(b,3) | equal(b,-3));
cmov_aff(t, &ge25519_base_multiples_affine[5 * pos + 4],
equal(b,-4));
fe25519_neg(&v, &t->x);
fe25519_cmov(&t->x, &v, negative(b));
}
static void setneutral(ge25519 *r)
{
fe25519_setzero(&r->x);
fe25519_setone(&r->y);
fe25519_setone(&r->z);
fe25519_setzero(&r->t);
}
/* ********************************************************************
* EXPORTED FUNCTIONS
******************************************************************** */
/* return 0 on success, -1 otherwise */
int ge25519_unpackneg_vartime(ge25519_p3 *r, const unsigned char p[32])
{
unsigned char par;
fe25519 t, chk, num, den, den2, den4, den6;
fe25519_setone(&r->z);
par = p[31] >> 7;
fe25519_unpack(&r->y, p);
fe25519_square(&num, &r->y); /* x = y^2 */
fe25519_mul(&den, &num, &ge25519_ecd); /* den = dy^2 */
fe25519_sub(&num, &num, &r->z); /* x = y^2-1 */
fe25519_add(&den, &r->z, &den); /* den = dy^2+1 */
/* Computation of sqrt(num/den) */
/* 1.: computation of num^((p-5)/8)*den^((7p-35)/8) = (num*den^7)^((p-5)/8) */
fe25519_square(&den2, &den);
fe25519_square(&den4, &den2);
fe25519_mul(&den6, &den4, &den2);
fe25519_mul(&t, &den6, &num);
fe25519_mul(&t, &t, &den);
fe25519_pow2523(&t, &t);
/* 2. computation of r->x = t * num * den^3 */
fe25519_mul(&t, &t, &num);
fe25519_mul(&t, &t, &den);
fe25519_mul(&t, &t, &den);
fe25519_mul(&r->x, &t, &den);
/* 3. Check whether sqrt computation gave correct result, multiply by sqrt(-1) if not: */
fe25519_square(&chk, &r->x);
fe25519_mul(&chk, &chk, &den);
if (!fe25519_iseq_vartime(&chk, &num)) {
fe25519_mul(&r->x, &r->x, &ge25519_sqrtm1);
}
/* 4. Now we have one of the two square roots, except if input was not a square */
fe25519_square(&chk, &r->x);
fe25519_mul(&chk, &chk, &den);
if (!fe25519_iseq_vartime(&chk, &num)) {
return -1;
}
/* 5. Choose the desired square root according to parity: */
if(fe25519_getparity(&r->x) != (1-par)) {
fe25519_neg(&r->x, &r->x);
}
fe25519_mul(&r->t, &r->x, &r->y);
return 0;
}
void ge25519_pack(unsigned char r[32], const ge25519_p3 *p)
{
fe25519 tx, ty, zi;
fe25519_invert(&zi, &p->z);
fe25519_mul(&tx, &p->x, &zi);
fe25519_mul(&ty, &p->y, &zi);
fe25519_pack(r, &ty);
r[31] ^= fe25519_getparity(&tx) << 7;
}
int ge25519_isneutral_vartime(const ge25519_p3 *p)
{
int ret = 1;
if (!fe25519_iszero(&p->x)) {
ret = 0;
}
if (!fe25519_iseq_vartime(&p->y, &p->z)) {
ret = 0;
}
return ret;
}
/* computes [s1]p1 + [s2]p2 */
void ge25519_double_scalarmult_vartime(ge25519_p3 *r, const ge25519_p3 *p1, const sc25519 *s1, const ge25519_p3 *p2, const sc25519 *s2)
{
ge25519_p1p1 tp1p1;
ge25519_p3 pre[16];
unsigned char b[127];
int i;
/* precomputation s2 s1 */
setneutral(pre); /* 00 00 */
pre[1] = *p1; /* 00 01 */
dbl_p1p1(&tp1p1,(ge25519_p2 *)p1); p1p1_to_p3( &pre[2], &tp1p1); /* 00 10 */
add_p1p1(&tp1p1,&pre[1], &pre[2]); p1p1_to_p3( &pre[3], &tp1p1); /* 00 11 */
pre[4] = *p2; /* 01 00 */
add_p1p1(&tp1p1,&pre[1], &pre[4]); p1p1_to_p3( &pre[5], &tp1p1); /* 01 01 */
add_p1p1(&tp1p1,&pre[2], &pre[4]); p1p1_to_p3( &pre[6], &tp1p1); /* 01 10 */
add_p1p1(&tp1p1,&pre[3], &pre[4]); p1p1_to_p3( &pre[7], &tp1p1); /* 01 11 */
dbl_p1p1(&tp1p1,(ge25519_p2 *)p2); p1p1_to_p3( &pre[8], &tp1p1); /* 10 00 */
add_p1p1(&tp1p1,&pre[1], &pre[8]); p1p1_to_p3( &pre[9], &tp1p1); /* 10 01 */
dbl_p1p1(&tp1p1,(ge25519_p2 *)&pre[5]); p1p1_to_p3(&pre[10], &tp1p1); /* 10 10 */
add_p1p1(&tp1p1,&pre[3], &pre[8]); p1p1_to_p3(&pre[11], &tp1p1); /* 10 11 */
add_p1p1(&tp1p1,&pre[4], &pre[8]); p1p1_to_p3(&pre[12], &tp1p1); /* 11 00 */
add_p1p1(&tp1p1,&pre[1],&pre[12]); p1p1_to_p3(&pre[13], &tp1p1); /* 11 01 */
add_p1p1(&tp1p1,&pre[2],&pre[12]); p1p1_to_p3(&pre[14], &tp1p1); /* 11 10 */
add_p1p1(&tp1p1,&pre[3],&pre[12]); p1p1_to_p3(&pre[15], &tp1p1); /* 11 11 */
sc25519_2interleave2(b,s1,s2);
/* scalar multiplication */
*r = pre[b[126]];
for (i = 125; i >= 0; i--) {
dbl_p1p1(&tp1p1, (ge25519_p2 *)r);
p1p1_to_p2((ge25519_p2 *) r, &tp1p1);
dbl_p1p1(&tp1p1, (ge25519_p2 *)r);
if(b[i] != 0) {
p1p1_to_p3(r, &tp1p1);
add_p1p1(&tp1p1, r, &pre[b[i]]);
}
if (i != 0) {
p1p1_to_p2((ge25519_p2 *)r, &tp1p1);
} else {
p1p1_to_p3(r, &tp1p1);
}
}
}
void ge25519_scalarmult_base(ge25519_p3 *r, const sc25519 *s)
{
signed char b[85];
int i;
ge25519_aff t;
sc25519_window3(b,s);
choose_t((ge25519_aff *)r, 0, b[0]);
fe25519_setone(&r->z);
fe25519_mul(&r->t, &r->x, &r->y);
for (i = 1; i < 85; i++) {
choose_t(&t, (unsigned long long) i, b[i]);
ge25519_mixadd2(r, &t);
}
}

View File

@@ -1,858 +0,0 @@
/* $OpenBSD: ge25519_base.data,v 1.3 2013/12/09 11:03:45 markus Exp $ */
/*
* Public Domain, Authors: Daniel J. Bernstein, Niels Duif, Tanja Lange,
* Peter Schwabe, Bo-Yin Yang.
* Copied from supercop-20130419/crypto_sign/ed25519/ref/ge25519_base.data
*/
{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
{{{0x1a, 0xd5, 0x25, 0x8f, 0x60, 0x2d, 0x56, 0xc9, 0xb2, 0xa7, 0x25, 0x95, 0x60, 0xc7, 0x2c, 0x69, 0x5c, 0xdc, 0xd6, 0xfd, 0x31, 0xe2, 0xa4, 0xc0, 0xfe, 0x53, 0x6e, 0xcd, 0xd3, 0x36, 0x69, 0x21}} ,
{{0x58, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66}}},
{{{0x0e, 0xce, 0x43, 0x28, 0x4e, 0xa1, 0xc5, 0x83, 0x5f, 0xa4, 0xd7, 0x15, 0x45, 0x8e, 0x0d, 0x08, 0xac, 0xe7, 0x33, 0x18, 0x7d, 0x3b, 0x04, 0x3d, 0x6c, 0x04, 0x5a, 0x9f, 0x4c, 0x38, 0xab, 0x36}} ,
{{0xc9, 0xa3, 0xf8, 0x6a, 0xae, 0x46, 0x5f, 0x0e, 0x56, 0x51, 0x38, 0x64, 0x51, 0x0f, 0x39, 0x97, 0x56, 0x1f, 0xa2, 0xc9, 0xe8, 0x5e, 0xa2, 0x1d, 0xc2, 0x29, 0x23, 0x09, 0xf3, 0xcd, 0x60, 0x22}}},
{{{0x5c, 0xe2, 0xf8, 0xd3, 0x5f, 0x48, 0x62, 0xac, 0x86, 0x48, 0x62, 0x81, 0x19, 0x98, 0x43, 0x63, 0x3a, 0xc8, 0xda, 0x3e, 0x74, 0xae, 0xf4, 0x1f, 0x49, 0x8f, 0x92, 0x22, 0x4a, 0x9c, 0xae, 0x67}} ,
{{0xd4, 0xb4, 0xf5, 0x78, 0x48, 0x68, 0xc3, 0x02, 0x04, 0x03, 0x24, 0x67, 0x17, 0xec, 0x16, 0x9f, 0xf7, 0x9e, 0x26, 0x60, 0x8e, 0xa1, 0x26, 0xa1, 0xab, 0x69, 0xee, 0x77, 0xd1, 0xb1, 0x67, 0x12}}},
{{{0x70, 0xf8, 0xc9, 0xc4, 0x57, 0xa6, 0x3a, 0x49, 0x47, 0x15, 0xce, 0x93, 0xc1, 0x9e, 0x73, 0x1a, 0xf9, 0x20, 0x35, 0x7a, 0xb8, 0xd4, 0x25, 0x83, 0x46, 0xf1, 0xcf, 0x56, 0xdb, 0xa8, 0x3d, 0x20}} ,
{{0x2f, 0x11, 0x32, 0xca, 0x61, 0xab, 0x38, 0xdf, 0xf0, 0x0f, 0x2f, 0xea, 0x32, 0x28, 0xf2, 0x4c, 0x6c, 0x71, 0xd5, 0x80, 0x85, 0xb8, 0x0e, 0x47, 0xe1, 0x95, 0x15, 0xcb, 0x27, 0xe8, 0xd0, 0x47}}},
{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
{{{0xc8, 0x84, 0xa5, 0x08, 0xbc, 0xfd, 0x87, 0x3b, 0x99, 0x8b, 0x69, 0x80, 0x7b, 0xc6, 0x3a, 0xeb, 0x93, 0xcf, 0x4e, 0xf8, 0x5c, 0x2d, 0x86, 0x42, 0xb6, 0x71, 0xd7, 0x97, 0x5f, 0xe1, 0x42, 0x67}} ,
{{0xb4, 0xb9, 0x37, 0xfc, 0xa9, 0x5b, 0x2f, 0x1e, 0x93, 0xe4, 0x1e, 0x62, 0xfc, 0x3c, 0x78, 0x81, 0x8f, 0xf3, 0x8a, 0x66, 0x09, 0x6f, 0xad, 0x6e, 0x79, 0x73, 0xe5, 0xc9, 0x00, 0x06, 0xd3, 0x21}}},
{{{0xf8, 0xf9, 0x28, 0x6c, 0x6d, 0x59, 0xb2, 0x59, 0x74, 0x23, 0xbf, 0xe7, 0x33, 0x8d, 0x57, 0x09, 0x91, 0x9c, 0x24, 0x08, 0x15, 0x2b, 0xe2, 0xb8, 0xee, 0x3a, 0xe5, 0x27, 0x06, 0x86, 0xa4, 0x23}} ,
{{0xeb, 0x27, 0x67, 0xc1, 0x37, 0xab, 0x7a, 0xd8, 0x27, 0x9c, 0x07, 0x8e, 0xff, 0x11, 0x6a, 0xb0, 0x78, 0x6e, 0xad, 0x3a, 0x2e, 0x0f, 0x98, 0x9f, 0x72, 0xc3, 0x7f, 0x82, 0xf2, 0x96, 0x96, 0x70}}},
{{{0x81, 0x6b, 0x88, 0xe8, 0x1e, 0xc7, 0x77, 0x96, 0x0e, 0xa1, 0xa9, 0x52, 0xe0, 0xd8, 0x0e, 0x61, 0x9e, 0x79, 0x2d, 0x95, 0x9c, 0x8d, 0x96, 0xe0, 0x06, 0x40, 0x5d, 0x87, 0x28, 0x5f, 0x98, 0x70}} ,
{{0xf1, 0x79, 0x7b, 0xed, 0x4f, 0x44, 0xb2, 0xe7, 0x08, 0x0d, 0xc2, 0x08, 0x12, 0xd2, 0x9f, 0xdf, 0xcd, 0x93, 0x20, 0x8a, 0xcf, 0x33, 0xca, 0x6d, 0x89, 0xb9, 0x77, 0xc8, 0x93, 0x1b, 0x4e, 0x60}}},
{{{0x26, 0x4f, 0x7e, 0x97, 0xf6, 0x40, 0xdd, 0x4f, 0xfc, 0x52, 0x78, 0xf9, 0x90, 0x31, 0x03, 0xe6, 0x7d, 0x56, 0x39, 0x0b, 0x1d, 0x56, 0x82, 0x85, 0xf9, 0x1a, 0x42, 0x17, 0x69, 0x6c, 0xcf, 0x39}} ,
{{0x69, 0xd2, 0x06, 0x3a, 0x4f, 0x39, 0x2d, 0xf9, 0x38, 0x40, 0x8c, 0x4c, 0xe7, 0x05, 0x12, 0xb4, 0x78, 0x8b, 0xf8, 0xc0, 0xec, 0x93, 0xde, 0x7a, 0x6b, 0xce, 0x2c, 0xe1, 0x0e, 0xa9, 0x34, 0x44}}},
{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
{{{0x0b, 0xa4, 0x3c, 0xb0, 0x0f, 0x7a, 0x51, 0xf1, 0x78, 0xd6, 0xd9, 0x6a, 0xfd, 0x46, 0xe8, 0xb8, 0xa8, 0x79, 0x1d, 0x87, 0xf9, 0x90, 0xf2, 0x9c, 0x13, 0x29, 0xf8, 0x0b, 0x20, 0x64, 0xfa, 0x05}} ,
{{0x26, 0x09, 0xda, 0x17, 0xaf, 0x95, 0xd6, 0xfb, 0x6a, 0x19, 0x0d, 0x6e, 0x5e, 0x12, 0xf1, 0x99, 0x4c, 0xaa, 0xa8, 0x6f, 0x79, 0x86, 0xf4, 0x72, 0x28, 0x00, 0x26, 0xf9, 0xea, 0x9e, 0x19, 0x3d}}},
{{{0x87, 0xdd, 0xcf, 0xf0, 0x5b, 0x49, 0xa2, 0x5d, 0x40, 0x7a, 0x23, 0x26, 0xa4, 0x7a, 0x83, 0x8a, 0xb7, 0x8b, 0xd2, 0x1a, 0xbf, 0xea, 0x02, 0x24, 0x08, 0x5f, 0x7b, 0xa9, 0xb1, 0xbe, 0x9d, 0x37}} ,
{{0xfc, 0x86, 0x4b, 0x08, 0xee, 0xe7, 0xa0, 0xfd, 0x21, 0x45, 0x09, 0x34, 0xc1, 0x61, 0x32, 0x23, 0xfc, 0x9b, 0x55, 0x48, 0x53, 0x99, 0xf7, 0x63, 0xd0, 0x99, 0xce, 0x01, 0xe0, 0x9f, 0xeb, 0x28}}},
{{{0x47, 0xfc, 0xab, 0x5a, 0x17, 0xf0, 0x85, 0x56, 0x3a, 0x30, 0x86, 0x20, 0x28, 0x4b, 0x8e, 0x44, 0x74, 0x3a, 0x6e, 0x02, 0xf1, 0x32, 0x8f, 0x9f, 0x3f, 0x08, 0x35, 0xe9, 0xca, 0x16, 0x5f, 0x6e}} ,
{{0x1c, 0x59, 0x1c, 0x65, 0x5d, 0x34, 0xa4, 0x09, 0xcd, 0x13, 0x9c, 0x70, 0x7d, 0xb1, 0x2a, 0xc5, 0x88, 0xaf, 0x0b, 0x60, 0xc7, 0x9f, 0x34, 0x8d, 0xd6, 0xb7, 0x7f, 0xea, 0x78, 0x65, 0x8d, 0x77}}},
{{{0x56, 0xa5, 0xc2, 0x0c, 0xdd, 0xbc, 0xb8, 0x20, 0x6d, 0x57, 0x61, 0xb5, 0xfb, 0x78, 0xb5, 0xd4, 0x49, 0x54, 0x90, 0x26, 0xc1, 0xcb, 0xe9, 0xe6, 0xbf, 0xec, 0x1d, 0x4e, 0xed, 0x07, 0x7e, 0x5e}} ,
{{0xc7, 0xf6, 0x6c, 0x56, 0x31, 0x20, 0x14, 0x0e, 0xa8, 0xd9, 0x27, 0xc1, 0x9a, 0x3d, 0x1b, 0x7d, 0x0e, 0x26, 0xd3, 0x81, 0xaa, 0xeb, 0xf5, 0x6b, 0x79, 0x02, 0xf1, 0x51, 0x5c, 0x75, 0x55, 0x0f}}},
{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
{{{0x0a, 0x34, 0xcd, 0x82, 0x3c, 0x33, 0x09, 0x54, 0xd2, 0x61, 0x39, 0x30, 0x9b, 0xfd, 0xef, 0x21, 0x26, 0xd4, 0x70, 0xfa, 0xee, 0xf9, 0x31, 0x33, 0x73, 0x84, 0xd0, 0xb3, 0x81, 0xbf, 0xec, 0x2e}} ,
{{0xe8, 0x93, 0x8b, 0x00, 0x64, 0xf7, 0x9c, 0xb8, 0x74, 0xe0, 0xe6, 0x49, 0x48, 0x4d, 0x4d, 0x48, 0xb6, 0x19, 0xa1, 0x40, 0xb7, 0xd9, 0x32, 0x41, 0x7c, 0x82, 0x37, 0xa1, 0x2d, 0xdc, 0xd2, 0x54}}},
{{{0x68, 0x2b, 0x4a, 0x5b, 0xd5, 0xc7, 0x51, 0x91, 0x1d, 0xe1, 0x2a, 0x4b, 0xc4, 0x47, 0xf1, 0xbc, 0x7a, 0xb3, 0xcb, 0xc8, 0xb6, 0x7c, 0xac, 0x90, 0x05, 0xfd, 0xf3, 0xf9, 0x52, 0x3a, 0x11, 0x6b}} ,
{{0x3d, 0xc1, 0x27, 0xf3, 0x59, 0x43, 0x95, 0x90, 0xc5, 0x96, 0x79, 0xf5, 0xf4, 0x95, 0x65, 0x29, 0x06, 0x9c, 0x51, 0x05, 0x18, 0xda, 0xb8, 0x2e, 0x79, 0x7e, 0x69, 0x59, 0x71, 0x01, 0xeb, 0x1a}}},
{{{0x15, 0x06, 0x49, 0xb6, 0x8a, 0x3c, 0xea, 0x2f, 0x34, 0x20, 0x14, 0xc3, 0xaa, 0xd6, 0xaf, 0x2c, 0x3e, 0xbd, 0x65, 0x20, 0xe2, 0x4d, 0x4b, 0x3b, 0xeb, 0x9f, 0x4a, 0xc3, 0xad, 0xa4, 0x3b, 0x60}} ,
{{0xbc, 0x58, 0xe6, 0xc0, 0x95, 0x2a, 0x2a, 0x81, 0x9a, 0x7a, 0xf3, 0xd2, 0x06, 0xbe, 0x48, 0xbc, 0x0c, 0xc5, 0x46, 0xe0, 0x6a, 0xd4, 0xac, 0x0f, 0xd9, 0xcc, 0x82, 0x34, 0x2c, 0xaf, 0xdb, 0x1f}}},
{{{0xf7, 0x17, 0x13, 0xbd, 0xfb, 0xbc, 0xd2, 0xec, 0x45, 0xb3, 0x15, 0x31, 0xe9, 0xaf, 0x82, 0x84, 0x3d, 0x28, 0xc6, 0xfc, 0x11, 0xf5, 0x41, 0xb5, 0x8b, 0xd3, 0x12, 0x76, 0x52, 0xe7, 0x1a, 0x3c}} ,
{{0x4e, 0x36, 0x11, 0x07, 0xa2, 0x15, 0x20, 0x51, 0xc4, 0x2a, 0xc3, 0x62, 0x8b, 0x5e, 0x7f, 0xa6, 0x0f, 0xf9, 0x45, 0x85, 0x6c, 0x11, 0x86, 0xb7, 0x7e, 0xe5, 0xd7, 0xf9, 0xc3, 0x91, 0x1c, 0x05}}},
{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
{{{0xea, 0xd6, 0xde, 0x29, 0x3a, 0x00, 0xb9, 0x02, 0x59, 0xcb, 0x26, 0xc4, 0xba, 0x99, 0xb1, 0x97, 0x2f, 0x8e, 0x00, 0x92, 0x26, 0x4f, 0x52, 0xeb, 0x47, 0x1b, 0x89, 0x8b, 0x24, 0xc0, 0x13, 0x7d}} ,
{{0xd5, 0x20, 0x5b, 0x80, 0xa6, 0x80, 0x20, 0x95, 0xc3, 0xe9, 0x9f, 0x8e, 0x87, 0x9e, 0x1e, 0x9e, 0x7a, 0xc7, 0xcc, 0x75, 0x6c, 0xa5, 0xf1, 0x91, 0x1a, 0xa8, 0x01, 0x2c, 0xab, 0x76, 0xa9, 0x59}}},
{{{0xde, 0xc9, 0xb1, 0x31, 0x10, 0x16, 0xaa, 0x35, 0x14, 0x6a, 0xd4, 0xb5, 0x34, 0x82, 0x71, 0xd2, 0x4a, 0x5d, 0x9a, 0x1f, 0x53, 0x26, 0x3c, 0xe5, 0x8e, 0x8d, 0x33, 0x7f, 0xff, 0xa9, 0xd5, 0x17}} ,
{{0x89, 0xaf, 0xf6, 0xa4, 0x64, 0xd5, 0x10, 0xe0, 0x1d, 0xad, 0xef, 0x44, 0xbd, 0xda, 0x83, 0xac, 0x7a, 0xa8, 0xf0, 0x1c, 0x07, 0xf9, 0xc3, 0x43, 0x6c, 0x3f, 0xb7, 0xd3, 0x87, 0x22, 0x02, 0x73}}},
{{{0x64, 0x1d, 0x49, 0x13, 0x2f, 0x71, 0xec, 0x69, 0x87, 0xd0, 0x42, 0xee, 0x13, 0xec, 0xe3, 0xed, 0x56, 0x7b, 0xbf, 0xbd, 0x8c, 0x2f, 0x7d, 0x7b, 0x9d, 0x28, 0xec, 0x8e, 0x76, 0x2f, 0x6f, 0x08}} ,
{{0x22, 0xf5, 0x5f, 0x4d, 0x15, 0xef, 0xfc, 0x4e, 0x57, 0x03, 0x36, 0x89, 0xf0, 0xeb, 0x5b, 0x91, 0xd6, 0xe2, 0xca, 0x01, 0xa5, 0xee, 0x52, 0xec, 0xa0, 0x3c, 0x8f, 0x33, 0x90, 0x5a, 0x94, 0x72}}},
{{{0x8a, 0x4b, 0xe7, 0x38, 0xbc, 0xda, 0xc2, 0xb0, 0x85, 0xe1, 0x4a, 0xfe, 0x2d, 0x44, 0x84, 0xcb, 0x20, 0x6b, 0x2d, 0xbf, 0x11, 0x9c, 0xd7, 0xbe, 0xd3, 0x3e, 0x5f, 0xbf, 0x68, 0xbc, 0xa8, 0x07}} ,
{{0x01, 0x89, 0x28, 0x22, 0x6a, 0x78, 0xaa, 0x29, 0x03, 0xc8, 0x74, 0x95, 0x03, 0x3e, 0xdc, 0xbd, 0x07, 0x13, 0xa8, 0xa2, 0x20, 0x2d, 0xb3, 0x18, 0x70, 0x42, 0xfd, 0x7a, 0xc4, 0xd7, 0x49, 0x72}}},
{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
{{{0x02, 0xff, 0x32, 0x2b, 0x5c, 0x93, 0x54, 0x32, 0xe8, 0x57, 0x54, 0x1a, 0x8b, 0x33, 0x60, 0x65, 0xd3, 0x67, 0xa4, 0xc1, 0x26, 0xc4, 0xa4, 0x34, 0x1f, 0x9b, 0xa7, 0xa9, 0xf4, 0xd9, 0x4f, 0x5b}} ,
{{0x46, 0x8d, 0xb0, 0x33, 0x54, 0x26, 0x5b, 0x68, 0xdf, 0xbb, 0xc5, 0xec, 0xc2, 0xf9, 0x3c, 0x5a, 0x37, 0xc1, 0x8e, 0x27, 0x47, 0xaa, 0x49, 0x5a, 0xf8, 0xfb, 0x68, 0x04, 0x23, 0xd1, 0xeb, 0x40}}},
{{{0x65, 0xa5, 0x11, 0x84, 0x8a, 0x67, 0x9d, 0x9e, 0xd1, 0x44, 0x68, 0x7a, 0x34, 0xe1, 0x9f, 0xa3, 0x54, 0xcd, 0x07, 0xca, 0x79, 0x1f, 0x54, 0x2f, 0x13, 0x70, 0x4e, 0xee, 0xa2, 0xfa, 0xe7, 0x5d}} ,
{{0x36, 0xec, 0x54, 0xf8, 0xce, 0xe4, 0x85, 0xdf, 0xf6, 0x6f, 0x1d, 0x90, 0x08, 0xbc, 0xe8, 0xc0, 0x92, 0x2d, 0x43, 0x6b, 0x92, 0xa9, 0x8e, 0xab, 0x0a, 0x2e, 0x1c, 0x1e, 0x64, 0x23, 0x9f, 0x2c}}},
{{{0xa7, 0xd6, 0x2e, 0xd5, 0xcc, 0xd4, 0xcb, 0x5a, 0x3b, 0xa7, 0xf9, 0x46, 0x03, 0x1d, 0xad, 0x2b, 0x34, 0x31, 0x90, 0x00, 0x46, 0x08, 0x82, 0x14, 0xc4, 0xe0, 0x9c, 0xf0, 0xe3, 0x55, 0x43, 0x31}} ,
{{0x60, 0xd6, 0xdd, 0x78, 0xe6, 0xd4, 0x22, 0x42, 0x1f, 0x00, 0xf9, 0xb1, 0x6a, 0x63, 0xe2, 0x92, 0x59, 0xd1, 0x1a, 0xb7, 0x00, 0x54, 0x29, 0xc9, 0xc1, 0xf6, 0x6f, 0x7a, 0xc5, 0x3c, 0x5f, 0x65}}},
{{{0x27, 0x4f, 0xd0, 0x72, 0xb1, 0x11, 0x14, 0x27, 0x15, 0x94, 0x48, 0x81, 0x7e, 0x74, 0xd8, 0x32, 0xd5, 0xd1, 0x11, 0x28, 0x60, 0x63, 0x36, 0x32, 0x37, 0xb5, 0x13, 0x1c, 0xa0, 0x37, 0xe3, 0x74}} ,
{{0xf1, 0x25, 0x4e, 0x11, 0x96, 0x67, 0xe6, 0x1c, 0xc2, 0xb2, 0x53, 0xe2, 0xda, 0x85, 0xee, 0xb2, 0x9f, 0x59, 0xf3, 0xba, 0xbd, 0xfa, 0xcf, 0x6e, 0xf9, 0xda, 0xa4, 0xb3, 0x02, 0x8f, 0x64, 0x08}}},
{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
{{{0x34, 0x94, 0xf2, 0x64, 0x54, 0x47, 0x37, 0x07, 0x40, 0x8a, 0x20, 0xba, 0x4a, 0x55, 0xd7, 0x3f, 0x47, 0xba, 0x25, 0x23, 0x14, 0xb0, 0x2c, 0xe8, 0x55, 0xa8, 0xa6, 0xef, 0x51, 0xbd, 0x6f, 0x6a}} ,
{{0x71, 0xd6, 0x16, 0x76, 0xb2, 0x06, 0xea, 0x79, 0xf5, 0xc4, 0xc3, 0x52, 0x7e, 0x61, 0xd1, 0xe1, 0xad, 0x70, 0x78, 0x1d, 0x16, 0x11, 0xf8, 0x7c, 0x2b, 0xfc, 0x55, 0x9f, 0x52, 0xf8, 0xf5, 0x16}}},
{{{0x34, 0x96, 0x9a, 0xf6, 0xc5, 0xe0, 0x14, 0x03, 0x24, 0x0e, 0x4c, 0xad, 0x9e, 0x9a, 0x70, 0x23, 0x96, 0xb2, 0xf1, 0x2e, 0x9d, 0xc3, 0x32, 0x9b, 0x54, 0xa5, 0x73, 0xde, 0x88, 0xb1, 0x3e, 0x24}} ,
{{0xf6, 0xe2, 0x4c, 0x1f, 0x5b, 0xb2, 0xaf, 0x82, 0xa5, 0xcf, 0x81, 0x10, 0x04, 0xef, 0xdb, 0xa2, 0xcc, 0x24, 0xb2, 0x7e, 0x0b, 0x7a, 0xeb, 0x01, 0xd8, 0x52, 0xf4, 0x51, 0x89, 0x29, 0x79, 0x37}}},
{{{0x74, 0xde, 0x12, 0xf3, 0x68, 0xb7, 0x66, 0xc3, 0xee, 0x68, 0xdc, 0x81, 0xb5, 0x55, 0x99, 0xab, 0xd9, 0x28, 0x63, 0x6d, 0x8b, 0x40, 0x69, 0x75, 0x6c, 0xcd, 0x5c, 0x2a, 0x7e, 0x32, 0x7b, 0x29}} ,
{{0x02, 0xcc, 0x22, 0x74, 0x4d, 0x19, 0x07, 0xc0, 0xda, 0xb5, 0x76, 0x51, 0x2a, 0xaa, 0xa6, 0x0a, 0x5f, 0x26, 0xd4, 0xbc, 0xaf, 0x48, 0x88, 0x7f, 0x02, 0xbc, 0xf2, 0xe1, 0xcf, 0xe9, 0xdd, 0x15}}},
{{{0xed, 0xb5, 0x9a, 0x8c, 0x9a, 0xdd, 0x27, 0xf4, 0x7f, 0x47, 0xd9, 0x52, 0xa7, 0xcd, 0x65, 0xa5, 0x31, 0x22, 0xed, 0xa6, 0x63, 0x5b, 0x80, 0x4a, 0xad, 0x4d, 0xed, 0xbf, 0xee, 0x49, 0xb3, 0x06}} ,
{{0xf8, 0x64, 0x8b, 0x60, 0x90, 0xe9, 0xde, 0x44, 0x77, 0xb9, 0x07, 0x36, 0x32, 0xc2, 0x50, 0xf5, 0x65, 0xdf, 0x48, 0x4c, 0x37, 0xaa, 0x68, 0xab, 0x9a, 0x1f, 0x3e, 0xff, 0x89, 0x92, 0xa0, 0x07}}},
{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
{{{0x7d, 0x4f, 0x9c, 0x19, 0xc0, 0x4a, 0x31, 0xec, 0xf9, 0xaa, 0xeb, 0xb2, 0x16, 0x9c, 0xa3, 0x66, 0x5f, 0xd1, 0xd4, 0xed, 0xb8, 0x92, 0x1c, 0xab, 0xda, 0xea, 0xd9, 0x57, 0xdf, 0x4c, 0x2a, 0x48}} ,
{{0x4b, 0xb0, 0x4e, 0x6e, 0x11, 0x3b, 0x51, 0xbd, 0x6a, 0xfd, 0xe4, 0x25, 0xa5, 0x5f, 0x11, 0x3f, 0x98, 0x92, 0x51, 0x14, 0xc6, 0x5f, 0x3c, 0x0b, 0xa8, 0xf7, 0xc2, 0x81, 0x43, 0xde, 0x91, 0x73}}},
{{{0x3c, 0x8f, 0x9f, 0x33, 0x2a, 0x1f, 0x43, 0x33, 0x8f, 0x68, 0xff, 0x1f, 0x3d, 0x73, 0x6b, 0xbf, 0x68, 0xcc, 0x7d, 0x13, 0x6c, 0x24, 0x4b, 0xcc, 0x4d, 0x24, 0x0d, 0xfe, 0xde, 0x86, 0xad, 0x3b}} ,
{{0x79, 0x51, 0x81, 0x01, 0xdc, 0x73, 0x53, 0xe0, 0x6e, 0x9b, 0xea, 0x68, 0x3f, 0x5c, 0x14, 0x84, 0x53, 0x8d, 0x4b, 0xc0, 0x9f, 0x9f, 0x89, 0x2b, 0x8c, 0xba, 0x86, 0xfa, 0xf2, 0xcd, 0xe3, 0x2d}}},
{{{0x06, 0xf9, 0x29, 0x5a, 0xdb, 0x3d, 0x84, 0x52, 0xab, 0xcc, 0x6b, 0x60, 0x9d, 0xb7, 0x4a, 0x0e, 0x36, 0x63, 0x91, 0xad, 0xa0, 0x95, 0xb0, 0x97, 0x89, 0x4e, 0xcf, 0x7d, 0x3c, 0xe5, 0x7c, 0x28}} ,
{{0x2e, 0x69, 0x98, 0xfd, 0xc6, 0xbd, 0xcc, 0xca, 0xdf, 0x9a, 0x44, 0x7e, 0x9d, 0xca, 0x89, 0x6d, 0xbf, 0x27, 0xc2, 0xf8, 0xcd, 0x46, 0x00, 0x2b, 0xb5, 0x58, 0x4e, 0xb7, 0x89, 0x09, 0xe9, 0x2d}}},
{{{0x54, 0xbe, 0x75, 0xcb, 0x05, 0xb0, 0x54, 0xb7, 0xe7, 0x26, 0x86, 0x4a, 0xfc, 0x19, 0xcf, 0x27, 0x46, 0xd4, 0x22, 0x96, 0x5a, 0x11, 0xe8, 0xd5, 0x1b, 0xed, 0x71, 0xc5, 0x5d, 0xc8, 0xaf, 0x45}} ,
{{0x40, 0x7b, 0x77, 0x57, 0x49, 0x9e, 0x80, 0x39, 0x23, 0xee, 0x81, 0x0b, 0x22, 0xcf, 0xdb, 0x7a, 0x2f, 0x14, 0xb8, 0x57, 0x8f, 0xa1, 0x39, 0x1e, 0x77, 0xfc, 0x0b, 0xa6, 0xbf, 0x8a, 0x0c, 0x6c}}},
{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
{{{0x77, 0x3a, 0xd4, 0xd8, 0x27, 0xcf, 0xe8, 0xa1, 0x72, 0x9d, 0xca, 0xdd, 0x0d, 0x96, 0xda, 0x79, 0xed, 0x56, 0x42, 0x15, 0x60, 0xc7, 0x1c, 0x6b, 0x26, 0x30, 0xf6, 0x6a, 0x95, 0x67, 0xf3, 0x0a}} ,
{{0xc5, 0x08, 0xa4, 0x2b, 0x2f, 0xbd, 0x31, 0x81, 0x2a, 0xa6, 0xb6, 0xe4, 0x00, 0x91, 0xda, 0x3d, 0xb2, 0xb0, 0x96, 0xce, 0x8a, 0xd2, 0x8d, 0x70, 0xb3, 0xd3, 0x34, 0x01, 0x90, 0x8d, 0x10, 0x21}}},
{{{0x33, 0x0d, 0xe7, 0xba, 0x4f, 0x07, 0xdf, 0x8d, 0xea, 0x7d, 0xa0, 0xc5, 0xd6, 0xb1, 0xb0, 0xe5, 0x57, 0x1b, 0x5b, 0xf5, 0x45, 0x13, 0x14, 0x64, 0x5a, 0xeb, 0x5c, 0xfc, 0x54, 0x01, 0x76, 0x2b}} ,
{{0x02, 0x0c, 0xc2, 0xaf, 0x96, 0x36, 0xfe, 0x4a, 0xe2, 0x54, 0x20, 0x6a, 0xeb, 0xb2, 0x9f, 0x62, 0xd7, 0xce, 0xa2, 0x3f, 0x20, 0x11, 0x34, 0x37, 0xe0, 0x42, 0xed, 0x6f, 0xf9, 0x1a, 0xc8, 0x7d}}},
{{{0xd8, 0xb9, 0x11, 0xe8, 0x36, 0x3f, 0x42, 0xc1, 0xca, 0xdc, 0xd3, 0xf1, 0xc8, 0x23, 0x3d, 0x4f, 0x51, 0x7b, 0x9d, 0x8d, 0xd8, 0xe4, 0xa0, 0xaa, 0xf3, 0x04, 0xd6, 0x11, 0x93, 0xc8, 0x35, 0x45}} ,
{{0x61, 0x36, 0xd6, 0x08, 0x90, 0xbf, 0xa7, 0x7a, 0x97, 0x6c, 0x0f, 0x84, 0xd5, 0x33, 0x2d, 0x37, 0xc9, 0x6a, 0x80, 0x90, 0x3d, 0x0a, 0xa2, 0xaa, 0xe1, 0xb8, 0x84, 0xba, 0x61, 0x36, 0xdd, 0x69}}},
{{{0x6b, 0xdb, 0x5b, 0x9c, 0xc6, 0x92, 0xbc, 0x23, 0xaf, 0xc5, 0xb8, 0x75, 0xf8, 0x42, 0xfa, 0xd6, 0xb6, 0x84, 0x94, 0x63, 0x98, 0x93, 0x48, 0x78, 0x38, 0xcd, 0xbb, 0x18, 0x34, 0xc3, 0xdb, 0x67}} ,
{{0x96, 0xf3, 0x3a, 0x09, 0x56, 0xb0, 0x6f, 0x7c, 0x51, 0x1e, 0x1b, 0x39, 0x48, 0xea, 0xc9, 0x0c, 0x25, 0xa2, 0x7a, 0xca, 0xe7, 0x92, 0xfc, 0x59, 0x30, 0xa3, 0x89, 0x85, 0xdf, 0x6f, 0x43, 0x38}}},
{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
{{{0x79, 0x84, 0x44, 0x19, 0xbd, 0xe9, 0x54, 0xc4, 0xc0, 0x6e, 0x2a, 0xa8, 0xa8, 0x9b, 0x43, 0xd5, 0x71, 0x22, 0x5f, 0xdc, 0x01, 0xfa, 0xdf, 0xb3, 0xb8, 0x47, 0x4b, 0x0a, 0xa5, 0x44, 0xea, 0x29}} ,
{{0x05, 0x90, 0x50, 0xaf, 0x63, 0x5f, 0x9d, 0x9e, 0xe1, 0x9d, 0x38, 0x97, 0x1f, 0x6c, 0xac, 0x30, 0x46, 0xb2, 0x6a, 0x19, 0xd1, 0x4b, 0xdb, 0xbb, 0x8c, 0xda, 0x2e, 0xab, 0xc8, 0x5a, 0x77, 0x6c}}},
{{{0x2b, 0xbe, 0xaf, 0xa1, 0x6d, 0x2f, 0x0b, 0xb1, 0x8f, 0xe3, 0xe0, 0x38, 0xcd, 0x0b, 0x41, 0x1b, 0x4a, 0x15, 0x07, 0xf3, 0x6f, 0xdc, 0xb8, 0xe9, 0xde, 0xb2, 0xa3, 0x40, 0x01, 0xa6, 0x45, 0x1e}} ,
{{0x76, 0x0a, 0xda, 0x8d, 0x2c, 0x07, 0x3f, 0x89, 0x7d, 0x04, 0xad, 0x43, 0x50, 0x6e, 0xd2, 0x47, 0xcb, 0x8a, 0xe6, 0x85, 0x1a, 0x24, 0xf3, 0xd2, 0x60, 0xfd, 0xdf, 0x73, 0xa4, 0x0d, 0x73, 0x0e}}},
{{{0xfd, 0x67, 0x6b, 0x71, 0x9b, 0x81, 0x53, 0x39, 0x39, 0xf4, 0xb8, 0xd5, 0xc3, 0x30, 0x9b, 0x3b, 0x7c, 0xa3, 0xf0, 0xd0, 0x84, 0x21, 0xd6, 0xbf, 0xb7, 0x4c, 0x87, 0x13, 0x45, 0x2d, 0xa7, 0x55}} ,
{{0x5d, 0x04, 0xb3, 0x40, 0x28, 0x95, 0x2d, 0x30, 0x83, 0xec, 0x5e, 0xe4, 0xff, 0x75, 0xfe, 0x79, 0x26, 0x9d, 0x1d, 0x36, 0xcd, 0x0a, 0x15, 0xd2, 0x24, 0x14, 0x77, 0x71, 0xd7, 0x8a, 0x1b, 0x04}}},
{{{0x5d, 0x93, 0xc9, 0xbe, 0xaa, 0x90, 0xcd, 0x9b, 0xfb, 0x73, 0x7e, 0xb0, 0x64, 0x98, 0x57, 0x44, 0x42, 0x41, 0xb1, 0xaf, 0xea, 0xc1, 0xc3, 0x22, 0xff, 0x60, 0x46, 0xcb, 0x61, 0x81, 0x70, 0x61}} ,
{{0x0d, 0x82, 0xb9, 0xfe, 0x21, 0xcd, 0xc4, 0xf5, 0x98, 0x0c, 0x4e, 0x72, 0xee, 0x87, 0x49, 0xf8, 0xa1, 0x95, 0xdf, 0x8f, 0x2d, 0xbd, 0x21, 0x06, 0x7c, 0x15, 0xe8, 0x12, 0x6d, 0x93, 0xd6, 0x38}}},
{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
{{{0x91, 0xf7, 0x51, 0xd9, 0xef, 0x7d, 0x42, 0x01, 0x13, 0xe9, 0xb8, 0x7f, 0xa6, 0x49, 0x17, 0x64, 0x21, 0x80, 0x83, 0x2c, 0x63, 0x4c, 0x60, 0x09, 0x59, 0x91, 0x92, 0x77, 0x39, 0x51, 0xf4, 0x48}} ,
{{0x60, 0xd5, 0x22, 0x83, 0x08, 0x2f, 0xff, 0x99, 0x3e, 0x69, 0x6d, 0x88, 0xda, 0xe7, 0x5b, 0x52, 0x26, 0x31, 0x2a, 0xe5, 0x89, 0xde, 0x68, 0x90, 0xb6, 0x22, 0x5a, 0xbd, 0xd3, 0x85, 0x53, 0x31}}},
{{{0xd8, 0xce, 0xdc, 0xf9, 0x3c, 0x4b, 0xa2, 0x1d, 0x2c, 0x2f, 0x36, 0xbe, 0x7a, 0xfc, 0xcd, 0xbc, 0xdc, 0xf9, 0x30, 0xbd, 0xff, 0x05, 0xc7, 0xe4, 0x8e, 0x17, 0x62, 0xf8, 0x4d, 0xa0, 0x56, 0x79}} ,
{{0x82, 0xe7, 0xf6, 0xba, 0x53, 0x84, 0x0a, 0xa3, 0x34, 0xff, 0x3c, 0xa3, 0x6a, 0xa1, 0x37, 0xea, 0xdd, 0xb6, 0x95, 0xb3, 0x78, 0x19, 0x76, 0x1e, 0x55, 0x2f, 0x77, 0x2e, 0x7f, 0xc1, 0xea, 0x5e}}},
{{{0x83, 0xe1, 0x6e, 0xa9, 0x07, 0x33, 0x3e, 0x83, 0xff, 0xcb, 0x1c, 0x9f, 0xb1, 0xa3, 0xb4, 0xc9, 0xe1, 0x07, 0x97, 0xff, 0xf8, 0x23, 0x8f, 0xce, 0x40, 0xfd, 0x2e, 0x5e, 0xdb, 0x16, 0x43, 0x2d}} ,
{{0xba, 0x38, 0x02, 0xf7, 0x81, 0x43, 0x83, 0xa3, 0x20, 0x4f, 0x01, 0x3b, 0x8a, 0x04, 0x38, 0x31, 0xc6, 0x0f, 0xc8, 0xdf, 0xd7, 0xfa, 0x2f, 0x88, 0x3f, 0xfc, 0x0c, 0x76, 0xc4, 0xa6, 0x45, 0x72}}},
{{{0xbb, 0x0c, 0xbc, 0x6a, 0xa4, 0x97, 0x17, 0x93, 0x2d, 0x6f, 0xde, 0x72, 0x10, 0x1c, 0x08, 0x2c, 0x0f, 0x80, 0x32, 0x68, 0x27, 0xd4, 0xab, 0xdd, 0xc5, 0x58, 0x61, 0x13, 0x6d, 0x11, 0x1e, 0x4d}} ,
{{0x1a, 0xb9, 0xc9, 0x10, 0xfb, 0x1e, 0x4e, 0xf4, 0x84, 0x4b, 0x8a, 0x5e, 0x7b, 0x4b, 0xe8, 0x43, 0x8c, 0x8f, 0x00, 0xb5, 0x54, 0x13, 0xc5, 0x5c, 0xb6, 0x35, 0x4e, 0x9d, 0xe4, 0x5b, 0x41, 0x6d}}},
{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
{{{0x15, 0x7d, 0x12, 0x48, 0x82, 0x14, 0x42, 0xcd, 0x32, 0xd4, 0x4b, 0xc1, 0x72, 0x61, 0x2a, 0x8c, 0xec, 0xe2, 0xf8, 0x24, 0x45, 0x94, 0xe3, 0xbe, 0xdd, 0x67, 0xa8, 0x77, 0x5a, 0xae, 0x5b, 0x4b}} ,
{{0xcb, 0x77, 0x9a, 0x20, 0xde, 0xb8, 0x23, 0xd9, 0xa0, 0x0f, 0x8c, 0x7b, 0xa5, 0xcb, 0xae, 0xb6, 0xec, 0x42, 0x67, 0x0e, 0x58, 0xa4, 0x75, 0x98, 0x21, 0x71, 0x84, 0xb3, 0xe0, 0x76, 0x94, 0x73}}},
{{{0xdf, 0xfc, 0x69, 0x28, 0x23, 0x3f, 0x5b, 0xf8, 0x3b, 0x24, 0x37, 0xf3, 0x1d, 0xd5, 0x22, 0x6b, 0xd0, 0x98, 0xa8, 0x6c, 0xcf, 0xff, 0x06, 0xe1, 0x13, 0xdf, 0xb9, 0xc1, 0x0c, 0xa9, 0xbf, 0x33}} ,
{{0xd9, 0x81, 0xda, 0xb2, 0x4f, 0x82, 0x9d, 0x43, 0x81, 0x09, 0xf1, 0xd2, 0x01, 0xef, 0xac, 0xf4, 0x2d, 0x7d, 0x01, 0x09, 0xf1, 0xff, 0xa5, 0x9f, 0xe5, 0xca, 0x27, 0x63, 0xdb, 0x20, 0xb1, 0x53}}},
{{{0x67, 0x02, 0xe8, 0xad, 0xa9, 0x34, 0xd4, 0xf0, 0x15, 0x81, 0xaa, 0xc7, 0x4d, 0x87, 0x94, 0xea, 0x75, 0xe7, 0x4c, 0x94, 0x04, 0x0e, 0x69, 0x87, 0xe7, 0x51, 0x91, 0x10, 0x03, 0xc7, 0xbe, 0x56}} ,
{{0x32, 0xfb, 0x86, 0xec, 0x33, 0x6b, 0x2e, 0x51, 0x2b, 0xc8, 0xfa, 0x6c, 0x70, 0x47, 0x7e, 0xce, 0x05, 0x0c, 0x71, 0xf3, 0xb4, 0x56, 0xa6, 0xdc, 0xcc, 0x78, 0x07, 0x75, 0xd0, 0xdd, 0xb2, 0x6a}}},
{{{0xc6, 0xef, 0xb9, 0xc0, 0x2b, 0x22, 0x08, 0x1e, 0x71, 0x70, 0xb3, 0x35, 0x9c, 0x7a, 0x01, 0x92, 0x44, 0x9a, 0xf6, 0xb0, 0x58, 0x95, 0xc1, 0x9b, 0x02, 0xed, 0x2d, 0x7c, 0x34, 0x29, 0x49, 0x44}} ,
{{0x45, 0x62, 0x1d, 0x2e, 0xff, 0x2a, 0x1c, 0x21, 0xa4, 0x25, 0x7b, 0x0d, 0x8c, 0x15, 0x39, 0xfc, 0x8f, 0x7c, 0xa5, 0x7d, 0x1e, 0x25, 0xa3, 0x45, 0xd6, 0xab, 0xbd, 0xcb, 0xc5, 0x5e, 0x78, 0x77}}},
{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
{{{0xd0, 0xd3, 0x42, 0xed, 0x1d, 0x00, 0x3c, 0x15, 0x2c, 0x9c, 0x77, 0x81, 0xd2, 0x73, 0xd1, 0x06, 0xd5, 0xc4, 0x7f, 0x94, 0xbb, 0x92, 0x2d, 0x2c, 0x4b, 0x45, 0x4b, 0xe9, 0x2a, 0x89, 0x6b, 0x2b}} ,
{{0xd2, 0x0c, 0x88, 0xc5, 0x48, 0x4d, 0xea, 0x0d, 0x4a, 0xc9, 0x52, 0x6a, 0x61, 0x79, 0xe9, 0x76, 0xf3, 0x85, 0x52, 0x5c, 0x1b, 0x2c, 0xe1, 0xd6, 0xc4, 0x0f, 0x18, 0x0e, 0x4e, 0xf6, 0x1c, 0x7f}}},
{{{0xb4, 0x04, 0x2e, 0x42, 0xcb, 0x1f, 0x2b, 0x11, 0x51, 0x7b, 0x08, 0xac, 0xaa, 0x3e, 0x9e, 0x52, 0x60, 0xb7, 0xc2, 0x61, 0x57, 0x8c, 0x84, 0xd5, 0x18, 0xa6, 0x19, 0xfc, 0xb7, 0x75, 0x91, 0x1b}} ,
{{0xe8, 0x68, 0xca, 0x44, 0xc8, 0x38, 0x38, 0xcc, 0x53, 0x0a, 0x32, 0x35, 0xcc, 0x52, 0xcb, 0x0e, 0xf7, 0xc5, 0xe7, 0xec, 0x3d, 0x85, 0xcc, 0x58, 0xe2, 0x17, 0x47, 0xff, 0x9f, 0xa5, 0x30, 0x17}}},
{{{0xe3, 0xae, 0xc8, 0xc1, 0x71, 0x75, 0x31, 0x00, 0x37, 0x41, 0x5c, 0x0e, 0x39, 0xda, 0x73, 0xa0, 0xc7, 0x97, 0x36, 0x6c, 0x5b, 0xf2, 0xee, 0x64, 0x0a, 0x3d, 0x89, 0x1e, 0x1d, 0x49, 0x8c, 0x37}} ,
{{0x4c, 0xe6, 0xb0, 0xc1, 0xa5, 0x2a, 0x82, 0x09, 0x08, 0xad, 0x79, 0x9c, 0x56, 0xf6, 0xf9, 0xc1, 0xd7, 0x7c, 0x39, 0x7f, 0x93, 0xca, 0x11, 0x55, 0xbf, 0x07, 0x1b, 0x82, 0x29, 0x69, 0x95, 0x5c}}},
{{{0x87, 0xee, 0xa6, 0x56, 0x9e, 0xc2, 0x9a, 0x56, 0x24, 0x42, 0x85, 0x4d, 0x98, 0x31, 0x1e, 0x60, 0x4d, 0x87, 0x85, 0x04, 0xae, 0x46, 0x12, 0xf9, 0x8e, 0x7f, 0xe4, 0x7f, 0xf6, 0x1c, 0x37, 0x01}} ,
{{0x73, 0x4c, 0xb6, 0xc5, 0xc4, 0xe9, 0x6c, 0x85, 0x48, 0x4a, 0x5a, 0xac, 0xd9, 0x1f, 0x43, 0xf8, 0x62, 0x5b, 0xee, 0x98, 0x2a, 0x33, 0x8e, 0x79, 0xce, 0x61, 0x06, 0x35, 0xd8, 0xd7, 0xca, 0x71}}},
{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
{{{0x72, 0xd3, 0xae, 0xa6, 0xca, 0x8f, 0xcd, 0xcc, 0x78, 0x8e, 0x19, 0x4d, 0xa7, 0xd2, 0x27, 0xe9, 0xa4, 0x3c, 0x16, 0x5b, 0x84, 0x80, 0xf9, 0xd0, 0xcc, 0x6a, 0x1e, 0xca, 0x1e, 0x67, 0xbd, 0x63}} ,
{{0x7b, 0x6e, 0x2a, 0xd2, 0x87, 0x48, 0xff, 0xa1, 0xca, 0xe9, 0x15, 0x85, 0xdc, 0xdb, 0x2c, 0x39, 0x12, 0x91, 0xa9, 0x20, 0xaa, 0x4f, 0x29, 0xf4, 0x15, 0x7a, 0xd2, 0xf5, 0x32, 0xcc, 0x60, 0x04}}},
{{{0xe5, 0x10, 0x47, 0x3b, 0xfa, 0x90, 0xfc, 0x30, 0xb5, 0xea, 0x6f, 0x56, 0x8f, 0xfb, 0x0e, 0xa7, 0x3b, 0xc8, 0xb2, 0xff, 0x02, 0x7a, 0x33, 0x94, 0x93, 0x2a, 0x03, 0xe0, 0x96, 0x3a, 0x6c, 0x0f}} ,
{{0x5a, 0x63, 0x67, 0xe1, 0x9b, 0x47, 0x78, 0x9f, 0x38, 0x79, 0xac, 0x97, 0x66, 0x1d, 0x5e, 0x51, 0xee, 0x24, 0x42, 0xe8, 0x58, 0x4b, 0x8a, 0x03, 0x75, 0x86, 0x37, 0x86, 0xe2, 0x97, 0x4e, 0x3d}}},
{{{0x3f, 0x75, 0x8e, 0xb4, 0xff, 0xd8, 0xdd, 0xd6, 0x37, 0x57, 0x9d, 0x6d, 0x3b, 0xbd, 0xd5, 0x60, 0x88, 0x65, 0x9a, 0xb9, 0x4a, 0x68, 0x84, 0xa2, 0x67, 0xdd, 0x17, 0x25, 0x97, 0x04, 0x8b, 0x5e}} ,
{{0xbb, 0x40, 0x5e, 0xbc, 0x16, 0x92, 0x05, 0xc4, 0xc0, 0x4e, 0x72, 0x90, 0x0e, 0xab, 0xcf, 0x8a, 0xed, 0xef, 0xb9, 0x2d, 0x3b, 0xf8, 0x43, 0x5b, 0xba, 0x2d, 0xeb, 0x2f, 0x52, 0xd2, 0xd1, 0x5a}}},
{{{0x40, 0xb4, 0xab, 0xe6, 0xad, 0x9f, 0x46, 0x69, 0x4a, 0xb3, 0x8e, 0xaa, 0xea, 0x9c, 0x8a, 0x20, 0x16, 0x5d, 0x8c, 0x13, 0xbd, 0xf6, 0x1d, 0xc5, 0x24, 0xbd, 0x90, 0x2a, 0x1c, 0xc7, 0x13, 0x3b}} ,
{{0x54, 0xdc, 0x16, 0x0d, 0x18, 0xbe, 0x35, 0x64, 0x61, 0x52, 0x02, 0x80, 0xaf, 0x05, 0xf7, 0xa6, 0x42, 0xd3, 0x8f, 0x2e, 0x79, 0x26, 0xa8, 0xbb, 0xb2, 0x17, 0x48, 0xb2, 0x7a, 0x0a, 0x89, 0x14}}},
{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
{{{0x20, 0xa8, 0x88, 0xe3, 0x91, 0xc0, 0x6e, 0xbb, 0x8a, 0x27, 0x82, 0x51, 0x83, 0xb2, 0x28, 0xa9, 0x83, 0xeb, 0xa6, 0xa9, 0x4d, 0x17, 0x59, 0x22, 0x54, 0x00, 0x50, 0x45, 0xcb, 0x48, 0x4b, 0x18}} ,
{{0x33, 0x7c, 0xe7, 0x26, 0xba, 0x4d, 0x32, 0xfe, 0x53, 0xf4, 0xfa, 0x83, 0xe3, 0xa5, 0x79, 0x66, 0x73, 0xef, 0x80, 0x23, 0x68, 0xc2, 0x60, 0xdd, 0xa9, 0x33, 0xdc, 0x03, 0x7a, 0xe0, 0xe0, 0x3e}}},
{{{0x34, 0x5c, 0x13, 0xfb, 0xc0, 0xe3, 0x78, 0x2b, 0x54, 0x58, 0x22, 0x9b, 0x76, 0x81, 0x7f, 0x93, 0x9c, 0x25, 0x3c, 0xd2, 0xe9, 0x96, 0x21, 0x26, 0x08, 0xf5, 0xed, 0x95, 0x11, 0xae, 0x04, 0x5a}} ,
{{0xb9, 0xe8, 0xc5, 0x12, 0x97, 0x1f, 0x83, 0xfe, 0x3e, 0x94, 0x99, 0xd4, 0x2d, 0xf9, 0x52, 0x59, 0x5c, 0x82, 0xa6, 0xf0, 0x75, 0x7e, 0xe8, 0xec, 0xcc, 0xac, 0x18, 0x21, 0x09, 0x67, 0x66, 0x67}}},
{{{0xb3, 0x40, 0x29, 0xd1, 0xcb, 0x1b, 0x08, 0x9e, 0x9c, 0xb7, 0x53, 0xb9, 0x3b, 0x71, 0x08, 0x95, 0x12, 0x1a, 0x58, 0xaf, 0x7e, 0x82, 0x52, 0x43, 0x4f, 0x11, 0x39, 0xf4, 0x93, 0x1a, 0x26, 0x05}} ,
{{0x6e, 0x44, 0xa3, 0xf9, 0x64, 0xaf, 0xe7, 0x6d, 0x7d, 0xdf, 0x1e, 0xac, 0x04, 0xea, 0x3b, 0x5f, 0x9b, 0xe8, 0x24, 0x9d, 0x0e, 0xe5, 0x2e, 0x3e, 0xdf, 0xa9, 0xf7, 0xd4, 0x50, 0x71, 0xf0, 0x78}}},
{{{0x3e, 0xa8, 0x38, 0xc2, 0x57, 0x56, 0x42, 0x9a, 0xb1, 0xe2, 0xf8, 0x45, 0xaa, 0x11, 0x48, 0x5f, 0x17, 0xc4, 0x54, 0x27, 0xdc, 0x5d, 0xaa, 0xdd, 0x41, 0xbc, 0xdf, 0x81, 0xb9, 0x53, 0xee, 0x52}} ,
{{0xc3, 0xf1, 0xa7, 0x6d, 0xb3, 0x5f, 0x92, 0x6f, 0xcc, 0x91, 0xb8, 0x95, 0x05, 0xdf, 0x3c, 0x64, 0x57, 0x39, 0x61, 0x51, 0xad, 0x8c, 0x38, 0x7b, 0xc8, 0xde, 0x00, 0x34, 0xbe, 0xa1, 0xb0, 0x7e}}},
{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
{{{0x25, 0x24, 0x1d, 0x8a, 0x67, 0x20, 0xee, 0x42, 0xeb, 0x38, 0xed, 0x0b, 0x8b, 0xcd, 0x46, 0x9d, 0x5e, 0x6b, 0x1e, 0x24, 0x9d, 0x12, 0x05, 0x1a, 0xcc, 0x05, 0x4e, 0x92, 0x38, 0xe1, 0x1f, 0x50}} ,
{{0x4e, 0xee, 0x1c, 0x91, 0xe6, 0x11, 0xbd, 0x8e, 0x55, 0x1a, 0x18, 0x75, 0x66, 0xaf, 0x4d, 0x7b, 0x0f, 0xae, 0x6d, 0x85, 0xca, 0x82, 0x58, 0x21, 0x9c, 0x18, 0xe0, 0xed, 0xec, 0x22, 0x80, 0x2f}}},
{{{0x68, 0x3b, 0x0a, 0x39, 0x1d, 0x6a, 0x15, 0x57, 0xfc, 0xf0, 0x63, 0x54, 0xdb, 0x39, 0xdb, 0xe8, 0x5c, 0x64, 0xff, 0xa0, 0x09, 0x4f, 0x3b, 0xb7, 0x32, 0x60, 0x99, 0x94, 0xfd, 0x94, 0x82, 0x2d}} ,
{{0x24, 0xf6, 0x5a, 0x44, 0xf1, 0x55, 0x2c, 0xdb, 0xea, 0x7c, 0x84, 0x7c, 0x01, 0xac, 0xe3, 0xfd, 0xc9, 0x27, 0xc1, 0x5a, 0xb9, 0xde, 0x4f, 0x5a, 0x90, 0xdd, 0xc6, 0x67, 0xaa, 0x6f, 0x8a, 0x3a}}},
{{{0x78, 0x52, 0x87, 0xc9, 0x97, 0x63, 0xb1, 0xdd, 0x54, 0x5f, 0xc1, 0xf8, 0xf1, 0x06, 0xa6, 0xa8, 0xa3, 0x88, 0x82, 0xd4, 0xcb, 0xa6, 0x19, 0xdd, 0xd1, 0x11, 0x87, 0x08, 0x17, 0x4c, 0x37, 0x2a}} ,
{{0xa1, 0x0c, 0xf3, 0x08, 0x43, 0xd9, 0x24, 0x1e, 0x83, 0xa7, 0xdf, 0x91, 0xca, 0xbd, 0x69, 0x47, 0x8d, 0x1b, 0xe2, 0xb9, 0x4e, 0xb5, 0xe1, 0x76, 0xb3, 0x1c, 0x93, 0x03, 0xce, 0x5f, 0xb3, 0x5a}}},
{{{0x1d, 0xda, 0xe4, 0x61, 0x03, 0x50, 0xa9, 0x8b, 0x68, 0x18, 0xef, 0xb2, 0x1c, 0x84, 0x3b, 0xa2, 0x44, 0x95, 0xa3, 0x04, 0x3b, 0xd6, 0x99, 0x00, 0xaf, 0x76, 0x42, 0x67, 0x02, 0x7d, 0x85, 0x56}} ,
{{0xce, 0x72, 0x0e, 0x29, 0x84, 0xb2, 0x7d, 0xd2, 0x45, 0xbe, 0x57, 0x06, 0xed, 0x7f, 0xcf, 0xed, 0xcd, 0xef, 0x19, 0xd6, 0xbc, 0x15, 0x79, 0x64, 0xd2, 0x18, 0xe3, 0x20, 0x67, 0x3a, 0x54, 0x0b}}},
{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
{{{0x52, 0xfd, 0x04, 0xc5, 0xfb, 0x99, 0xe7, 0xe8, 0xfb, 0x8c, 0xe1, 0x42, 0x03, 0xef, 0x9d, 0xd9, 0x9e, 0x4d, 0xf7, 0x80, 0xcf, 0x2e, 0xcc, 0x9b, 0x45, 0xc9, 0x7b, 0x7a, 0xbc, 0x37, 0xa8, 0x52}} ,
{{0x96, 0x11, 0x41, 0x8a, 0x47, 0x91, 0xfe, 0xb6, 0xda, 0x7a, 0x54, 0x63, 0xd1, 0x14, 0x35, 0x05, 0x86, 0x8c, 0xa9, 0x36, 0x3f, 0xf2, 0x85, 0x54, 0x4e, 0x92, 0xd8, 0x85, 0x01, 0x46, 0xd6, 0x50}}},
{{{0x53, 0xcd, 0xf3, 0x86, 0x40, 0xe6, 0x39, 0x42, 0x95, 0xd6, 0xcb, 0x45, 0x1a, 0x20, 0xc8, 0x45, 0x4b, 0x32, 0x69, 0x04, 0xb1, 0xaf, 0x20, 0x46, 0xc7, 0x6b, 0x23, 0x5b, 0x69, 0xee, 0x30, 0x3f}} ,
{{0x70, 0x83, 0x47, 0xc0, 0xdb, 0x55, 0x08, 0xa8, 0x7b, 0x18, 0x6d, 0xf5, 0x04, 0x5a, 0x20, 0x0c, 0x4a, 0x8c, 0x60, 0xae, 0xae, 0x0f, 0x64, 0x55, 0x55, 0x2e, 0xd5, 0x1d, 0x53, 0x31, 0x42, 0x41}}},
{{{0xca, 0xfc, 0x88, 0x6b, 0x96, 0x78, 0x0a, 0x8b, 0x83, 0xdc, 0xbc, 0xaf, 0x40, 0xb6, 0x8d, 0x7f, 0xef, 0xb4, 0xd1, 0x3f, 0xcc, 0xa2, 0x74, 0xc9, 0xc2, 0x92, 0x55, 0x00, 0xab, 0xdb, 0xbf, 0x4f}} ,
{{0x93, 0x1c, 0x06, 0x2d, 0x66, 0x65, 0x02, 0xa4, 0x97, 0x18, 0xfd, 0x00, 0xe7, 0xab, 0x03, 0xec, 0xce, 0xc1, 0xbf, 0x37, 0xf8, 0x13, 0x53, 0xa5, 0xe5, 0x0c, 0x3a, 0xa8, 0x55, 0xb9, 0xff, 0x68}}},
{{{0xe4, 0xe6, 0x6d, 0x30, 0x7d, 0x30, 0x35, 0xc2, 0x78, 0x87, 0xf9, 0xfc, 0x6b, 0x5a, 0xc3, 0xb7, 0x65, 0xd8, 0x2e, 0xc7, 0xa5, 0x0c, 0xc6, 0xdc, 0x12, 0xaa, 0xd6, 0x4f, 0xc5, 0x38, 0xbc, 0x0e}} ,
{{0xe2, 0x3c, 0x76, 0x86, 0x38, 0xf2, 0x7b, 0x2c, 0x16, 0x78, 0x8d, 0xf5, 0xa4, 0x15, 0xda, 0xdb, 0x26, 0x85, 0xa0, 0x56, 0xdd, 0x1d, 0xe3, 0xb3, 0xfd, 0x40, 0xef, 0xf2, 0xd9, 0xa1, 0xb3, 0x04}}},
{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
{{{0xdb, 0x49, 0x0e, 0xe6, 0x58, 0x10, 0x7a, 0x52, 0xda, 0xb5, 0x7d, 0x37, 0x6a, 0x3e, 0xa1, 0x78, 0xce, 0xc7, 0x1c, 0x24, 0x23, 0xdb, 0x7d, 0xfb, 0x8c, 0x8d, 0xdc, 0x30, 0x67, 0x69, 0x75, 0x3b}} ,
{{0xa9, 0xea, 0x6d, 0x16, 0x16, 0x60, 0xf4, 0x60, 0x87, 0x19, 0x44, 0x8c, 0x4a, 0x8b, 0x3e, 0xfb, 0x16, 0x00, 0x00, 0x54, 0xa6, 0x9e, 0x9f, 0xef, 0xcf, 0xd9, 0xd2, 0x4c, 0x74, 0x31, 0xd0, 0x34}}},
{{{0xa4, 0xeb, 0x04, 0xa4, 0x8c, 0x8f, 0x71, 0x27, 0x95, 0x85, 0x5d, 0x55, 0x4b, 0xb1, 0x26, 0x26, 0xc8, 0xae, 0x6a, 0x7d, 0xa2, 0x21, 0xca, 0xce, 0x38, 0xab, 0x0f, 0xd0, 0xd5, 0x2b, 0x6b, 0x00}} ,
{{0xe5, 0x67, 0x0c, 0xf1, 0x3a, 0x9a, 0xea, 0x09, 0x39, 0xef, 0xd1, 0x30, 0xbc, 0x33, 0xba, 0xb1, 0x6a, 0xc5, 0x27, 0x08, 0x7f, 0x54, 0x80, 0x3d, 0xab, 0xf6, 0x15, 0x7a, 0xc2, 0x40, 0x73, 0x72}}},
{{{0x84, 0x56, 0x82, 0xb6, 0x12, 0x70, 0x7f, 0xf7, 0xf0, 0xbd, 0x5b, 0xa9, 0xd5, 0xc5, 0x5f, 0x59, 0xbf, 0x7f, 0xb3, 0x55, 0x22, 0x02, 0xc9, 0x44, 0x55, 0x87, 0x8f, 0x96, 0x98, 0x64, 0x6d, 0x15}} ,
{{0xb0, 0x8b, 0xaa, 0x1e, 0xec, 0xc7, 0xa5, 0x8f, 0x1f, 0x92, 0x04, 0xc6, 0x05, 0xf6, 0xdf, 0xa1, 0xcc, 0x1f, 0x81, 0xf5, 0x0e, 0x9c, 0x57, 0xdc, 0xe3, 0xbb, 0x06, 0x87, 0x1e, 0xfe, 0x23, 0x6c}}},
{{{0xd8, 0x2b, 0x5b, 0x16, 0xea, 0x20, 0xf1, 0xd3, 0x68, 0x8f, 0xae, 0x5b, 0xd0, 0xa9, 0x1a, 0x19, 0xa8, 0x36, 0xfb, 0x2b, 0x57, 0x88, 0x7d, 0x90, 0xd5, 0xa6, 0xf3, 0xdc, 0x38, 0x89, 0x4e, 0x1f}} ,
{{0xcc, 0x19, 0xda, 0x9b, 0x3b, 0x43, 0x48, 0x21, 0x2e, 0x23, 0x4d, 0x3d, 0xae, 0xf8, 0x8c, 0xfc, 0xdd, 0xa6, 0x74, 0x37, 0x65, 0xca, 0xee, 0x1a, 0x19, 0x8e, 0x9f, 0x64, 0x6f, 0x0c, 0x8b, 0x5a}}},
{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
{{{0x25, 0xb9, 0xc2, 0xf0, 0x72, 0xb8, 0x15, 0x16, 0xcc, 0x8d, 0x3c, 0x6f, 0x25, 0xed, 0xf4, 0x46, 0x2e, 0x0c, 0x60, 0x0f, 0xe2, 0x84, 0x34, 0x55, 0x89, 0x59, 0x34, 0x1b, 0xf5, 0x8d, 0xfe, 0x08}} ,
{{0xf8, 0xab, 0x93, 0xbc, 0x44, 0xba, 0x1b, 0x75, 0x4b, 0x49, 0x6f, 0xd0, 0x54, 0x2e, 0x63, 0xba, 0xb5, 0xea, 0xed, 0x32, 0x14, 0xc9, 0x94, 0xd8, 0xc5, 0xce, 0xf4, 0x10, 0x68, 0xe0, 0x38, 0x27}}},
{{{0x74, 0x1c, 0x14, 0x9b, 0xd4, 0x64, 0x61, 0x71, 0x5a, 0xb6, 0x21, 0x33, 0x4f, 0xf7, 0x8e, 0xba, 0xa5, 0x48, 0x9a, 0xc7, 0xfa, 0x9a, 0xf0, 0xb4, 0x62, 0xad, 0xf2, 0x5e, 0xcc, 0x03, 0x24, 0x1a}} ,
{{0xf5, 0x76, 0xfd, 0xe4, 0xaf, 0xb9, 0x03, 0x59, 0xce, 0x63, 0xd2, 0x3b, 0x1f, 0xcd, 0x21, 0x0c, 0xad, 0x44, 0xa5, 0x97, 0xac, 0x80, 0x11, 0x02, 0x9b, 0x0c, 0xe5, 0x8b, 0xcd, 0xfb, 0x79, 0x77}}},
{{{0x15, 0xbe, 0x9a, 0x0d, 0xba, 0x38, 0x72, 0x20, 0x8a, 0xf5, 0xbe, 0x59, 0x93, 0x79, 0xb7, 0xf6, 0x6a, 0x0c, 0x38, 0x27, 0x1a, 0x60, 0xf4, 0x86, 0x3b, 0xab, 0x5a, 0x00, 0xa0, 0xce, 0x21, 0x7d}} ,
{{0x6c, 0xba, 0x14, 0xc5, 0xea, 0x12, 0x9e, 0x2e, 0x82, 0x63, 0xce, 0x9b, 0x4a, 0xe7, 0x1d, 0xec, 0xf1, 0x2e, 0x51, 0x1c, 0xf4, 0xd0, 0x69, 0x15, 0x42, 0x9d, 0xa3, 0x3f, 0x0e, 0xbf, 0xe9, 0x5c}}},
{{{0xe4, 0x0d, 0xf4, 0xbd, 0xee, 0x31, 0x10, 0xed, 0xcb, 0x12, 0x86, 0xad, 0xd4, 0x2f, 0x90, 0x37, 0x32, 0xc3, 0x0b, 0x73, 0xec, 0x97, 0x85, 0xa4, 0x01, 0x1c, 0x76, 0x35, 0xfe, 0x75, 0xdd, 0x71}} ,
{{0x11, 0xa4, 0x88, 0x9f, 0x3e, 0x53, 0x69, 0x3b, 0x1b, 0xe0, 0xf7, 0xba, 0x9b, 0xad, 0x4e, 0x81, 0x5f, 0xb5, 0x5c, 0xae, 0xbe, 0x67, 0x86, 0x37, 0x34, 0x8e, 0x07, 0x32, 0x45, 0x4a, 0x67, 0x39}}},
{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
{{{0x90, 0x70, 0x58, 0x20, 0x03, 0x1e, 0x67, 0xb2, 0xc8, 0x9b, 0x58, 0xc5, 0xb1, 0xeb, 0x2d, 0x4a, 0xde, 0x82, 0x8c, 0xf2, 0xd2, 0x14, 0xb8, 0x70, 0x61, 0x4e, 0x73, 0xd6, 0x0b, 0x6b, 0x0d, 0x30}} ,
{{0x81, 0xfc, 0x55, 0x5c, 0xbf, 0xa7, 0xc4, 0xbd, 0xe2, 0xf0, 0x4b, 0x8f, 0xe9, 0x7d, 0x99, 0xfa, 0xd3, 0xab, 0xbc, 0xc7, 0x83, 0x2b, 0x04, 0x7f, 0x0c, 0x19, 0x43, 0x03, 0x3d, 0x07, 0xca, 0x40}}},
{{{0xf9, 0xc8, 0xbe, 0x8c, 0x16, 0x81, 0x39, 0x96, 0xf6, 0x17, 0x58, 0xc8, 0x30, 0x58, 0xfb, 0xc2, 0x03, 0x45, 0xd2, 0x52, 0x76, 0xe0, 0x6a, 0x26, 0x28, 0x5c, 0x88, 0x59, 0x6a, 0x5a, 0x54, 0x42}} ,
{{0x07, 0xb5, 0x2e, 0x2c, 0x67, 0x15, 0x9b, 0xfb, 0x83, 0x69, 0x1e, 0x0f, 0xda, 0xd6, 0x29, 0xb1, 0x60, 0xe0, 0xb2, 0xba, 0x69, 0xa2, 0x9e, 0xbd, 0xbd, 0xe0, 0x1c, 0xbd, 0xcd, 0x06, 0x64, 0x70}}},
{{{0x41, 0xfa, 0x8c, 0xe1, 0x89, 0x8f, 0x27, 0xc8, 0x25, 0x8f, 0x6f, 0x5f, 0x55, 0xf8, 0xde, 0x95, 0x6d, 0x2f, 0x75, 0x16, 0x2b, 0x4e, 0x44, 0xfd, 0x86, 0x6e, 0xe9, 0x70, 0x39, 0x76, 0x97, 0x7e}} ,
{{0x17, 0x62, 0x6b, 0x14, 0xa1, 0x7c, 0xd0, 0x79, 0x6e, 0xd8, 0x8a, 0xa5, 0x6d, 0x8c, 0x93, 0xd2, 0x3f, 0xec, 0x44, 0x8d, 0x6e, 0x91, 0x01, 0x8c, 0x8f, 0xee, 0x01, 0x8f, 0xc0, 0xb4, 0x85, 0x0e}}},
{{{0x02, 0x3a, 0x70, 0x41, 0xe4, 0x11, 0x57, 0x23, 0xac, 0xe6, 0xfc, 0x54, 0x7e, 0xcd, 0xd7, 0x22, 0xcb, 0x76, 0x9f, 0x20, 0xce, 0xa0, 0x73, 0x76, 0x51, 0x3b, 0xa4, 0xf8, 0xe3, 0x62, 0x12, 0x6c}} ,
{{0x7f, 0x00, 0x9c, 0x26, 0x0d, 0x6f, 0x48, 0x7f, 0x3a, 0x01, 0xed, 0xc5, 0x96, 0xb0, 0x1f, 0x4f, 0xa8, 0x02, 0x62, 0x27, 0x8a, 0x50, 0x8d, 0x9a, 0x8b, 0x52, 0x0f, 0x1e, 0xcf, 0x41, 0x38, 0x19}}},
{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
{{{0xf5, 0x6c, 0xd4, 0x2f, 0x0f, 0x69, 0x0f, 0x87, 0x3f, 0x61, 0x65, 0x1e, 0x35, 0x34, 0x85, 0xba, 0x02, 0x30, 0xac, 0x25, 0x3d, 0xe2, 0x62, 0xf1, 0xcc, 0xe9, 0x1b, 0xc2, 0xef, 0x6a, 0x42, 0x57}} ,
{{0x34, 0x1f, 0x2e, 0xac, 0xd1, 0xc7, 0x04, 0x52, 0x32, 0x66, 0xb2, 0x33, 0x73, 0x21, 0x34, 0x54, 0xf7, 0x71, 0xed, 0x06, 0xb0, 0xff, 0xa6, 0x59, 0x6f, 0x8a, 0x4e, 0xfb, 0x02, 0xb0, 0x45, 0x6b}}},
{{{0xf5, 0x48, 0x0b, 0x03, 0xc5, 0x22, 0x7d, 0x80, 0x08, 0x53, 0xfe, 0x32, 0xb1, 0xa1, 0x8a, 0x74, 0x6f, 0xbd, 0x3f, 0x85, 0xf4, 0xcf, 0xf5, 0x60, 0xaf, 0x41, 0x7e, 0x3e, 0x46, 0xa3, 0x5a, 0x20}} ,
{{0xaa, 0x35, 0x87, 0x44, 0x63, 0x66, 0x97, 0xf8, 0x6e, 0x55, 0x0c, 0x04, 0x3e, 0x35, 0x50, 0xbf, 0x93, 0x69, 0xd2, 0x8b, 0x05, 0x55, 0x99, 0xbe, 0xe2, 0x53, 0x61, 0xec, 0xe8, 0x08, 0x0b, 0x32}}},
{{{0xb3, 0x10, 0x45, 0x02, 0x69, 0x59, 0x2e, 0x97, 0xd9, 0x64, 0xf8, 0xdb, 0x25, 0x80, 0xdc, 0xc4, 0xd5, 0x62, 0x3c, 0xed, 0x65, 0x91, 0xad, 0xd1, 0x57, 0x81, 0x94, 0xaa, 0xa1, 0x29, 0xfc, 0x68}} ,
{{0xdd, 0xb5, 0x7d, 0xab, 0x5a, 0x21, 0x41, 0x53, 0xbb, 0x17, 0x79, 0x0d, 0xd1, 0xa8, 0x0c, 0x0c, 0x20, 0x88, 0x09, 0xe9, 0x84, 0xe8, 0x25, 0x11, 0x67, 0x7a, 0x8b, 0x1a, 0xe4, 0x5d, 0xe1, 0x5d}}},
{{{0x37, 0xea, 0xfe, 0x65, 0x3b, 0x25, 0xe8, 0xe1, 0xc2, 0xc5, 0x02, 0xa4, 0xbe, 0x98, 0x0a, 0x2b, 0x61, 0xc1, 0x9b, 0xe2, 0xd5, 0x92, 0xe6, 0x9e, 0x7d, 0x1f, 0xca, 0x43, 0x88, 0x8b, 0x2c, 0x59}} ,
{{0xe0, 0xb5, 0x00, 0x1d, 0x2a, 0x6f, 0xaf, 0x79, 0x86, 0x2f, 0xa6, 0x5a, 0x93, 0xd1, 0xfe, 0xae, 0x3a, 0xee, 0xdb, 0x7c, 0x61, 0xbe, 0x7c, 0x01, 0xf9, 0xfe, 0x52, 0xdc, 0xd8, 0x52, 0xa3, 0x42}}},
{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
{{{0x22, 0xaf, 0x13, 0x37, 0xbd, 0x37, 0x71, 0xac, 0x04, 0x46, 0x63, 0xac, 0xa4, 0x77, 0xed, 0x25, 0x38, 0xe0, 0x15, 0xa8, 0x64, 0x00, 0x0d, 0xce, 0x51, 0x01, 0xa9, 0xbc, 0x0f, 0x03, 0x1c, 0x04}} ,
{{0x89, 0xf9, 0x80, 0x07, 0xcf, 0x3f, 0xb3, 0xe9, 0xe7, 0x45, 0x44, 0x3d, 0x2a, 0x7c, 0xe9, 0xe4, 0x16, 0x5c, 0x5e, 0x65, 0x1c, 0xc7, 0x7d, 0xc6, 0x7a, 0xfb, 0x43, 0xee, 0x25, 0x76, 0x46, 0x72}}},
{{{0x02, 0xa2, 0xed, 0xf4, 0x8f, 0x6b, 0x0b, 0x3e, 0xeb, 0x35, 0x1a, 0xd5, 0x7e, 0xdb, 0x78, 0x00, 0x96, 0x8a, 0xa0, 0xb4, 0xcf, 0x60, 0x4b, 0xd4, 0xd5, 0xf9, 0x2d, 0xbf, 0x88, 0xbd, 0x22, 0x62}} ,
{{0x13, 0x53, 0xe4, 0x82, 0x57, 0xfa, 0x1e, 0x8f, 0x06, 0x2b, 0x90, 0xba, 0x08, 0xb6, 0x10, 0x54, 0x4f, 0x7c, 0x1b, 0x26, 0xed, 0xda, 0x6b, 0xdd, 0x25, 0xd0, 0x4e, 0xea, 0x42, 0xbb, 0x25, 0x03}}},
{{{0x51, 0x16, 0x50, 0x7c, 0xd5, 0x5d, 0xf6, 0x99, 0xe8, 0x77, 0x72, 0x4e, 0xfa, 0x62, 0xcb, 0x76, 0x75, 0x0c, 0xe2, 0x71, 0x98, 0x92, 0xd5, 0xfa, 0x45, 0xdf, 0x5c, 0x6f, 0x1e, 0x9e, 0x28, 0x69}} ,
{{0x0d, 0xac, 0x66, 0x6d, 0xc3, 0x8b, 0xba, 0x16, 0xb5, 0xe2, 0xa0, 0x0d, 0x0c, 0xbd, 0xa4, 0x8e, 0x18, 0x6c, 0xf2, 0xdc, 0xf9, 0xdc, 0x4a, 0x86, 0x25, 0x95, 0x14, 0xcb, 0xd8, 0x1a, 0x04, 0x0f}}},
{{{0x97, 0xa5, 0xdb, 0x8b, 0x2d, 0xaa, 0x42, 0x11, 0x09, 0xf2, 0x93, 0xbb, 0xd9, 0x06, 0x84, 0x4e, 0x11, 0xa8, 0xa0, 0x25, 0x2b, 0xa6, 0x5f, 0xae, 0xc4, 0xb4, 0x4c, 0xc8, 0xab, 0xc7, 0x3b, 0x02}} ,
{{0xee, 0xc9, 0x29, 0x0f, 0xdf, 0x11, 0x85, 0xed, 0xce, 0x0d, 0x62, 0x2c, 0x8f, 0x4b, 0xf9, 0x04, 0xe9, 0x06, 0x72, 0x1d, 0x37, 0x20, 0x50, 0xc9, 0x14, 0xeb, 0xec, 0x39, 0xa7, 0x97, 0x2b, 0x4d}}},
{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
{{{0x69, 0xd1, 0x39, 0xbd, 0xfb, 0x33, 0xbe, 0xc4, 0xf0, 0x5c, 0xef, 0xf0, 0x56, 0x68, 0xfc, 0x97, 0x47, 0xc8, 0x72, 0xb6, 0x53, 0xa4, 0x0a, 0x98, 0xa5, 0xb4, 0x37, 0x71, 0xcf, 0x66, 0x50, 0x6d}} ,
{{0x17, 0xa4, 0x19, 0x52, 0x11, 0x47, 0xb3, 0x5c, 0x5b, 0xa9, 0x2e, 0x22, 0xb4, 0x00, 0x52, 0xf9, 0x57, 0x18, 0xb8, 0xbe, 0x5a, 0xe3, 0xab, 0x83, 0xc8, 0x87, 0x0a, 0x2a, 0xd8, 0x8c, 0xbb, 0x54}}},
{{{0xa9, 0x62, 0x93, 0x85, 0xbe, 0xe8, 0x73, 0x4a, 0x0e, 0xb0, 0xb5, 0x2d, 0x94, 0x50, 0xaa, 0xd3, 0xb2, 0xea, 0x9d, 0x62, 0x76, 0x3b, 0x07, 0x34, 0x4e, 0x2d, 0x70, 0xc8, 0x9a, 0x15, 0x66, 0x6b}} ,
{{0xc5, 0x96, 0xca, 0xc8, 0x22, 0x1a, 0xee, 0x5f, 0xe7, 0x31, 0x60, 0x22, 0x83, 0x08, 0x63, 0xce, 0xb9, 0x32, 0x44, 0x58, 0x5d, 0x3a, 0x9b, 0xe4, 0x04, 0xd5, 0xef, 0x38, 0xef, 0x4b, 0xdd, 0x19}}},
{{{0x4d, 0xc2, 0x17, 0x75, 0xa1, 0x68, 0xcd, 0xc3, 0xc6, 0x03, 0x44, 0xe3, 0x78, 0x09, 0x91, 0x47, 0x3f, 0x0f, 0xe4, 0x92, 0x58, 0xfa, 0x7d, 0x1f, 0x20, 0x94, 0x58, 0x5e, 0xbc, 0x19, 0x02, 0x6f}} ,
{{0x20, 0xd6, 0xd8, 0x91, 0x54, 0xa7, 0xf3, 0x20, 0x4b, 0x34, 0x06, 0xfa, 0x30, 0xc8, 0x6f, 0x14, 0x10, 0x65, 0x74, 0x13, 0x4e, 0xf0, 0x69, 0x26, 0xce, 0xcf, 0x90, 0xf4, 0xd0, 0xc5, 0xc8, 0x64}}},
{{{0x26, 0xa2, 0x50, 0x02, 0x24, 0x72, 0xf1, 0xf0, 0x4e, 0x2d, 0x93, 0xd5, 0x08, 0xe7, 0xae, 0x38, 0xf7, 0x18, 0xa5, 0x32, 0x34, 0xc2, 0xf0, 0xa6, 0xec, 0xb9, 0x61, 0x7b, 0x64, 0x99, 0xac, 0x71}} ,
{{0x25, 0xcf, 0x74, 0x55, 0x1b, 0xaa, 0xa9, 0x38, 0x41, 0x40, 0xd5, 0x95, 0x95, 0xab, 0x1c, 0x5e, 0xbc, 0x41, 0x7e, 0x14, 0x30, 0xbe, 0x13, 0x89, 0xf4, 0xe5, 0xeb, 0x28, 0xc0, 0xc2, 0x96, 0x3a}}},
{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
{{{0x2b, 0x77, 0x45, 0xec, 0x67, 0x76, 0x32, 0x4c, 0xb9, 0xdf, 0x25, 0x32, 0x6b, 0xcb, 0xe7, 0x14, 0x61, 0x43, 0xee, 0xba, 0x9b, 0x71, 0xef, 0xd2, 0x48, 0x65, 0xbb, 0x1b, 0x8a, 0x13, 0x1b, 0x22}} ,
{{0x84, 0xad, 0x0c, 0x18, 0x38, 0x5a, 0xba, 0xd0, 0x98, 0x59, 0xbf, 0x37, 0xb0, 0x4f, 0x97, 0x60, 0x20, 0xb3, 0x9b, 0x97, 0xf6, 0x08, 0x6c, 0xa4, 0xff, 0xfb, 0xb7, 0xfa, 0x95, 0xb2, 0x51, 0x79}}},
{{{0x28, 0x5c, 0x3f, 0xdb, 0x6b, 0x18, 0x3b, 0x5c, 0xd1, 0x04, 0x28, 0xde, 0x85, 0x52, 0x31, 0xb5, 0xbb, 0xf6, 0xa9, 0xed, 0xbe, 0x28, 0x4f, 0xb3, 0x7e, 0x05, 0x6a, 0xdb, 0x95, 0x0d, 0x1b, 0x1c}} ,
{{0xd5, 0xc5, 0xc3, 0x9a, 0x0a, 0xd0, 0x31, 0x3e, 0x07, 0x36, 0x8e, 0xc0, 0x8a, 0x62, 0xb1, 0xca, 0xd6, 0x0e, 0x1e, 0x9d, 0xef, 0xab, 0x98, 0x4d, 0xbb, 0x6c, 0x05, 0xe0, 0xe4, 0x5d, 0xbd, 0x57}}},
{{{0xcc, 0x21, 0x27, 0xce, 0xfd, 0xa9, 0x94, 0x8e, 0xe1, 0xab, 0x49, 0xe0, 0x46, 0x26, 0xa1, 0xa8, 0x8c, 0xa1, 0x99, 0x1d, 0xb4, 0x27, 0x6d, 0x2d, 0xc8, 0x39, 0x30, 0x5e, 0x37, 0x52, 0xc4, 0x6e}} ,
{{0xa9, 0x85, 0xf4, 0xe7, 0xb0, 0x15, 0x33, 0x84, 0x1b, 0x14, 0x1a, 0x02, 0xd9, 0x3b, 0xad, 0x0f, 0x43, 0x6c, 0xea, 0x3e, 0x0f, 0x7e, 0xda, 0xdd, 0x6b, 0x4c, 0x7f, 0x6e, 0xd4, 0x6b, 0xbf, 0x0f}}},
{{{0x47, 0x9f, 0x7c, 0x56, 0x7c, 0x43, 0x91, 0x1c, 0xbb, 0x4e, 0x72, 0x3e, 0x64, 0xab, 0xa0, 0xa0, 0xdf, 0xb4, 0xd8, 0x87, 0x3a, 0xbd, 0xa8, 0x48, 0xc9, 0xb8, 0xef, 0x2e, 0xad, 0x6f, 0x84, 0x4f}} ,
{{0x2d, 0x2d, 0xf0, 0x1b, 0x7e, 0x2a, 0x6c, 0xf8, 0xa9, 0x6a, 0xe1, 0xf0, 0x99, 0xa1, 0x67, 0x9a, 0xd4, 0x13, 0xca, 0xca, 0xba, 0x27, 0x92, 0xaa, 0xa1, 0x5d, 0x50, 0xde, 0xcc, 0x40, 0x26, 0x0a}}},
{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
{{{0x9f, 0x3e, 0xf2, 0xb2, 0x90, 0xce, 0xdb, 0x64, 0x3e, 0x03, 0xdd, 0x37, 0x36, 0x54, 0x70, 0x76, 0x24, 0xb5, 0x69, 0x03, 0xfc, 0xa0, 0x2b, 0x74, 0xb2, 0x05, 0x0e, 0xcc, 0xd8, 0x1f, 0x6a, 0x1f}} ,
{{0x19, 0x5e, 0x60, 0x69, 0x58, 0x86, 0xa0, 0x31, 0xbd, 0x32, 0xe9, 0x2c, 0x5c, 0xd2, 0x85, 0xba, 0x40, 0x64, 0xa8, 0x74, 0xf8, 0x0e, 0x1c, 0xb3, 0xa9, 0x69, 0xe8, 0x1e, 0x40, 0x64, 0x99, 0x77}}},
{{{0x6c, 0x32, 0x4f, 0xfd, 0xbb, 0x5c, 0xbb, 0x8d, 0x64, 0x66, 0x4a, 0x71, 0x1f, 0x79, 0xa3, 0xad, 0x8d, 0xf9, 0xd4, 0xec, 0xcf, 0x67, 0x70, 0xfa, 0x05, 0x4a, 0x0f, 0x6e, 0xaf, 0x87, 0x0a, 0x6f}} ,
{{0xc6, 0x36, 0x6e, 0x6c, 0x8c, 0x24, 0x09, 0x60, 0xbe, 0x26, 0xd2, 0x4c, 0x5e, 0x17, 0xca, 0x5f, 0x1d, 0xcc, 0x87, 0xe8, 0x42, 0x6a, 0xcb, 0xcb, 0x7d, 0x92, 0x05, 0x35, 0x81, 0x13, 0x60, 0x6b}}},
{{{0xf4, 0x15, 0xcd, 0x0f, 0x0a, 0xaf, 0x4e, 0x6b, 0x51, 0xfd, 0x14, 0xc4, 0x2e, 0x13, 0x86, 0x74, 0x44, 0xcb, 0x66, 0x6b, 0xb6, 0x9d, 0x74, 0x56, 0x32, 0xac, 0x8d, 0x8e, 0x8c, 0x8c, 0x8c, 0x39}} ,
{{0xca, 0x59, 0x74, 0x1a, 0x11, 0xef, 0x6d, 0xf7, 0x39, 0x5c, 0x3b, 0x1f, 0xfa, 0xe3, 0x40, 0x41, 0x23, 0x9e, 0xf6, 0xd1, 0x21, 0xa2, 0xbf, 0xad, 0x65, 0x42, 0x6b, 0x59, 0x8a, 0xe8, 0xc5, 0x7f}}},
{{{0x64, 0x05, 0x7a, 0x84, 0x4a, 0x13, 0xc3, 0xf6, 0xb0, 0x6e, 0x9a, 0x6b, 0x53, 0x6b, 0x32, 0xda, 0xd9, 0x74, 0x75, 0xc4, 0xba, 0x64, 0x3d, 0x3b, 0x08, 0xdd, 0x10, 0x46, 0xef, 0xc7, 0x90, 0x1f}} ,
{{0x7b, 0x2f, 0x3a, 0xce, 0xc8, 0xa1, 0x79, 0x3c, 0x30, 0x12, 0x44, 0x28, 0xf6, 0xbc, 0xff, 0xfd, 0xf4, 0xc0, 0x97, 0xb0, 0xcc, 0xc3, 0x13, 0x7a, 0xb9, 0x9a, 0x16, 0xe4, 0xcb, 0x4c, 0x34, 0x63}}},
{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
{{{0x07, 0x4e, 0xd3, 0x2d, 0x09, 0x33, 0x0e, 0xd2, 0x0d, 0xbe, 0x3e, 0xe7, 0xe4, 0xaa, 0xb7, 0x00, 0x8b, 0xe8, 0xad, 0xaa, 0x7a, 0x8d, 0x34, 0x28, 0xa9, 0x81, 0x94, 0xc5, 0xe7, 0x42, 0xac, 0x47}} ,
{{0x24, 0x89, 0x7a, 0x8f, 0xb5, 0x9b, 0xf0, 0xc2, 0x03, 0x64, 0xd0, 0x1e, 0xf5, 0xa4, 0xb2, 0xf3, 0x74, 0xe9, 0x1a, 0x16, 0xfd, 0xcb, 0x15, 0xea, 0xeb, 0x10, 0x6c, 0x35, 0xd1, 0xc1, 0xa6, 0x28}}},
{{{0xcc, 0xd5, 0x39, 0xfc, 0xa5, 0xa4, 0xad, 0x32, 0x15, 0xce, 0x19, 0xe8, 0x34, 0x2b, 0x1c, 0x60, 0x91, 0xfc, 0x05, 0xa9, 0xb3, 0xdc, 0x80, 0x29, 0xc4, 0x20, 0x79, 0x06, 0x39, 0xc0, 0xe2, 0x22}} ,
{{0xbb, 0xa8, 0xe1, 0x89, 0x70, 0x57, 0x18, 0x54, 0x3c, 0xf6, 0x0d, 0x82, 0x12, 0x05, 0x87, 0x96, 0x06, 0x39, 0xe3, 0xf8, 0xb3, 0x95, 0xe5, 0xd7, 0x26, 0xbf, 0x09, 0x5a, 0x94, 0xf9, 0x1c, 0x63}}},
{{{0x2b, 0x8c, 0x2d, 0x9a, 0x8b, 0x84, 0xf2, 0x56, 0xfb, 0xad, 0x2e, 0x7f, 0xb7, 0xfc, 0x30, 0xe1, 0x35, 0x89, 0xba, 0x4d, 0xa8, 0x6d, 0xce, 0x8c, 0x8b, 0x30, 0xe0, 0xda, 0x29, 0x18, 0x11, 0x17}} ,
{{0x19, 0xa6, 0x5a, 0x65, 0x93, 0xc3, 0xb5, 0x31, 0x22, 0x4f, 0xf3, 0xf6, 0x0f, 0xeb, 0x28, 0xc3, 0x7c, 0xeb, 0xce, 0x86, 0xec, 0x67, 0x76, 0x6e, 0x35, 0x45, 0x7b, 0xd8, 0x6b, 0x92, 0x01, 0x65}}},
{{{0x3d, 0xd5, 0x9a, 0x64, 0x73, 0x36, 0xb1, 0xd6, 0x86, 0x98, 0x42, 0x3f, 0x8a, 0xf1, 0xc7, 0xf5, 0x42, 0xa8, 0x9c, 0x52, 0xa8, 0xdc, 0xf9, 0x24, 0x3f, 0x4a, 0xa1, 0xa4, 0x5b, 0xe8, 0x62, 0x1a}} ,
{{0xc5, 0xbd, 0xc8, 0x14, 0xd5, 0x0d, 0xeb, 0xe1, 0xa5, 0xe6, 0x83, 0x11, 0x09, 0x00, 0x1d, 0x55, 0x83, 0x51, 0x7e, 0x75, 0x00, 0x81, 0xb9, 0xcb, 0xd8, 0xc5, 0xe5, 0xa1, 0xd9, 0x17, 0x6d, 0x1f}}},
{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
{{{0xea, 0xf9, 0xe4, 0xe9, 0xe1, 0x52, 0x3f, 0x51, 0x19, 0x0d, 0xdd, 0xd9, 0x9d, 0x93, 0x31, 0x87, 0x23, 0x09, 0xd5, 0x83, 0xeb, 0x92, 0x09, 0x76, 0x6e, 0xe3, 0xf8, 0xc0, 0xa2, 0x66, 0xb5, 0x36}} ,
{{0x3a, 0xbb, 0x39, 0xed, 0x32, 0x02, 0xe7, 0x43, 0x7a, 0x38, 0x14, 0x84, 0xe3, 0x44, 0xd2, 0x5e, 0x94, 0xdd, 0x78, 0x89, 0x55, 0x4c, 0x73, 0x9e, 0xe1, 0xe4, 0x3e, 0x43, 0xd0, 0x4a, 0xde, 0x1b}}},
{{{0xb2, 0xe7, 0x8f, 0xe3, 0xa3, 0xc5, 0xcb, 0x72, 0xee, 0x79, 0x41, 0xf8, 0xdf, 0xee, 0x65, 0xc5, 0x45, 0x77, 0x27, 0x3c, 0xbd, 0x58, 0xd3, 0x75, 0xe2, 0x04, 0x4b, 0xbb, 0x65, 0xf3, 0xc8, 0x0f}} ,
{{0x24, 0x7b, 0x93, 0x34, 0xb5, 0xe2, 0x74, 0x48, 0xcd, 0xa0, 0x0b, 0x92, 0x97, 0x66, 0x39, 0xf4, 0xb0, 0xe2, 0x5d, 0x39, 0x6a, 0x5b, 0x45, 0x17, 0x78, 0x1e, 0xdb, 0x91, 0x81, 0x1c, 0xf9, 0x16}}},
{{{0x16, 0xdf, 0xd1, 0x5a, 0xd5, 0xe9, 0x4e, 0x58, 0x95, 0x93, 0x5f, 0x51, 0x09, 0xc3, 0x2a, 0xc9, 0xd4, 0x55, 0x48, 0x79, 0xa4, 0xa3, 0xb2, 0xc3, 0x62, 0xaa, 0x8c, 0xe8, 0xad, 0x47, 0x39, 0x1b}} ,
{{0x46, 0xda, 0x9e, 0x51, 0x3a, 0xe6, 0xd1, 0xa6, 0xbb, 0x4d, 0x7b, 0x08, 0xbe, 0x8c, 0xd5, 0xf3, 0x3f, 0xfd, 0xf7, 0x44, 0x80, 0x2d, 0x53, 0x4b, 0xd0, 0x87, 0x68, 0xc1, 0xb5, 0xd8, 0xf7, 0x07}}},
{{{0xf4, 0x10, 0x46, 0xbe, 0xb7, 0xd2, 0xd1, 0xce, 0x5e, 0x76, 0xa2, 0xd7, 0x03, 0xdc, 0xe4, 0x81, 0x5a, 0xf6, 0x3c, 0xde, 0xae, 0x7a, 0x9d, 0x21, 0x34, 0xa5, 0xf6, 0xa9, 0x73, 0xe2, 0x8d, 0x60}} ,
{{0xfa, 0x44, 0x71, 0xf6, 0x41, 0xd8, 0xc6, 0x58, 0x13, 0x37, 0xeb, 0x84, 0x0f, 0x96, 0xc7, 0xdc, 0xc8, 0xa9, 0x7a, 0x83, 0xb2, 0x2f, 0x31, 0xb1, 0x1a, 0xd8, 0x98, 0x3f, 0x11, 0xd0, 0x31, 0x3b}}},
{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
{{{0x81, 0xd5, 0x34, 0x16, 0x01, 0xa3, 0x93, 0xea, 0x52, 0x94, 0xec, 0x93, 0xb7, 0x81, 0x11, 0x2d, 0x58, 0xf9, 0xb5, 0x0a, 0xaa, 0x4f, 0xf6, 0x2e, 0x3f, 0x36, 0xbf, 0x33, 0x5a, 0xe7, 0xd1, 0x08}} ,
{{0x1a, 0xcf, 0x42, 0xae, 0xcc, 0xb5, 0x77, 0x39, 0xc4, 0x5b, 0x5b, 0xd0, 0x26, 0x59, 0x27, 0xd0, 0x55, 0x71, 0x12, 0x9d, 0x88, 0x3d, 0x9c, 0xea, 0x41, 0x6a, 0xf0, 0x50, 0x93, 0x93, 0xdd, 0x47}}},
{{{0x6f, 0xc9, 0x51, 0x6d, 0x1c, 0xaa, 0xf5, 0xa5, 0x90, 0x3f, 0x14, 0xe2, 0x6e, 0x8e, 0x64, 0xfd, 0xac, 0xe0, 0x4e, 0x22, 0xe5, 0xc1, 0xbc, 0x29, 0x0a, 0x6a, 0x9e, 0xa1, 0x60, 0xcb, 0x2f, 0x0b}} ,
{{0xdc, 0x39, 0x32, 0xf3, 0xa1, 0x44, 0xe9, 0xc5, 0xc3, 0x78, 0xfb, 0x95, 0x47, 0x34, 0x35, 0x34, 0xe8, 0x25, 0xde, 0x93, 0xc6, 0xb4, 0x76, 0x6d, 0x86, 0x13, 0xc6, 0xe9, 0x68, 0xb5, 0x01, 0x63}}},
{{{0x1f, 0x9a, 0x52, 0x64, 0x97, 0xd9, 0x1c, 0x08, 0x51, 0x6f, 0x26, 0x9d, 0xaa, 0x93, 0x33, 0x43, 0xfa, 0x77, 0xe9, 0x62, 0x9b, 0x5d, 0x18, 0x75, 0xeb, 0x78, 0xf7, 0x87, 0x8f, 0x41, 0xb4, 0x4d}} ,
{{0x13, 0xa8, 0x82, 0x3e, 0xe9, 0x13, 0xad, 0xeb, 0x01, 0xca, 0xcf, 0xda, 0xcd, 0xf7, 0x6c, 0xc7, 0x7a, 0xdc, 0x1e, 0x6e, 0xc8, 0x4e, 0x55, 0x62, 0x80, 0xea, 0x78, 0x0c, 0x86, 0xb9, 0x40, 0x51}}},
{{{0x27, 0xae, 0xd3, 0x0d, 0x4c, 0x8f, 0x34, 0xea, 0x7d, 0x3c, 0xe5, 0x8a, 0xcf, 0x5b, 0x92, 0xd8, 0x30, 0x16, 0xb4, 0xa3, 0x75, 0xff, 0xeb, 0x27, 0xc8, 0x5c, 0x6c, 0xc2, 0xee, 0x6c, 0x21, 0x0b}} ,
{{0xc3, 0xba, 0x12, 0x53, 0x2a, 0xaa, 0x77, 0xad, 0x19, 0x78, 0x55, 0x8a, 0x2e, 0x60, 0x87, 0xc2, 0x6e, 0x91, 0x38, 0x91, 0x3f, 0x7a, 0xc5, 0x24, 0x8f, 0x51, 0xc5, 0xde, 0xb0, 0x53, 0x30, 0x56}}},
{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
{{{0x02, 0xfe, 0x54, 0x12, 0x18, 0xca, 0x7d, 0xa5, 0x68, 0x43, 0xa3, 0x6d, 0x14, 0x2a, 0x6a, 0xa5, 0x8e, 0x32, 0xe7, 0x63, 0x4f, 0xe3, 0xc6, 0x44, 0x3e, 0xab, 0x63, 0xca, 0x17, 0x86, 0x74, 0x3f}} ,
{{0x1e, 0x64, 0xc1, 0x7d, 0x52, 0xdc, 0x13, 0x5a, 0xa1, 0x9c, 0x4e, 0xee, 0x99, 0x28, 0xbb, 0x4c, 0xee, 0xac, 0xa9, 0x1b, 0x89, 0xa2, 0x38, 0x39, 0x7b, 0xc4, 0x0f, 0x42, 0xe6, 0x89, 0xed, 0x0f}}},
{{{0xf3, 0x3c, 0x8c, 0x80, 0x83, 0x10, 0x8a, 0x37, 0x50, 0x9c, 0xb4, 0xdf, 0x3f, 0x8c, 0xf7, 0x23, 0x07, 0xd6, 0xff, 0xa0, 0x82, 0x6c, 0x75, 0x3b, 0xe4, 0xb5, 0xbb, 0xe4, 0xe6, 0x50, 0xf0, 0x08}} ,
{{0x62, 0xee, 0x75, 0x48, 0x92, 0x33, 0xf2, 0xf4, 0xad, 0x15, 0x7a, 0xa1, 0x01, 0x46, 0xa9, 0x32, 0x06, 0x88, 0xb6, 0x36, 0x47, 0x35, 0xb9, 0xb4, 0x42, 0x85, 0x76, 0xf0, 0x48, 0x00, 0x90, 0x38}}},
{{{0x51, 0x15, 0x9d, 0xc3, 0x95, 0xd1, 0x39, 0xbb, 0x64, 0x9d, 0x15, 0x81, 0xc1, 0x68, 0xd0, 0xb6, 0xa4, 0x2c, 0x7d, 0x5e, 0x02, 0x39, 0x00, 0xe0, 0x3b, 0xa4, 0xcc, 0xca, 0x1d, 0x81, 0x24, 0x10}} ,
{{0xe7, 0x29, 0xf9, 0x37, 0xd9, 0x46, 0x5a, 0xcd, 0x70, 0xfe, 0x4d, 0x5b, 0xbf, 0xa5, 0xcf, 0x91, 0xf4, 0xef, 0xee, 0x8a, 0x29, 0xd0, 0xe7, 0xc4, 0x25, 0x92, 0x8a, 0xff, 0x36, 0xfc, 0xe4, 0x49}}},
{{{0xbd, 0x00, 0xb9, 0x04, 0x7d, 0x35, 0xfc, 0xeb, 0xd0, 0x0b, 0x05, 0x32, 0x52, 0x7a, 0x89, 0x24, 0x75, 0x50, 0xe1, 0x63, 0x02, 0x82, 0x8e, 0xe7, 0x85, 0x0c, 0xf2, 0x56, 0x44, 0x37, 0x83, 0x25}} ,
{{0x8f, 0xa1, 0xce, 0xcb, 0x60, 0xda, 0x12, 0x02, 0x1e, 0x29, 0x39, 0x2a, 0x03, 0xb7, 0xeb, 0x77, 0x40, 0xea, 0xc9, 0x2b, 0x2c, 0xd5, 0x7d, 0x7e, 0x2c, 0xc7, 0x5a, 0xfd, 0xff, 0xc4, 0xd1, 0x62}}},
{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
{{{0x1d, 0x88, 0x98, 0x5b, 0x4e, 0xfc, 0x41, 0x24, 0x05, 0xe6, 0x50, 0x2b, 0xae, 0x96, 0x51, 0xd9, 0x6b, 0x72, 0xb2, 0x33, 0x42, 0x98, 0x68, 0xbb, 0x10, 0x5a, 0x7a, 0x8c, 0x9d, 0x07, 0xb4, 0x05}} ,
{{0x2f, 0x61, 0x9f, 0xd7, 0xa8, 0x3f, 0x83, 0x8c, 0x10, 0x69, 0x90, 0xe6, 0xcf, 0xd2, 0x63, 0xa3, 0xe4, 0x54, 0x7e, 0xe5, 0x69, 0x13, 0x1c, 0x90, 0x57, 0xaa, 0xe9, 0x53, 0x22, 0x43, 0x29, 0x23}}},
{{{0xe5, 0x1c, 0xf8, 0x0a, 0xfd, 0x2d, 0x7e, 0xf5, 0xf5, 0x70, 0x7d, 0x41, 0x6b, 0x11, 0xfe, 0xbe, 0x99, 0xd1, 0x55, 0x29, 0x31, 0xbf, 0xc0, 0x97, 0x6c, 0xd5, 0x35, 0xcc, 0x5e, 0x8b, 0xd9, 0x69}} ,
{{0x8e, 0x4e, 0x9f, 0x25, 0xf8, 0x81, 0x54, 0x2d, 0x0e, 0xd5, 0x54, 0x81, 0x9b, 0xa6, 0x92, 0xce, 0x4b, 0xe9, 0x8f, 0x24, 0x3b, 0xca, 0xe0, 0x44, 0xab, 0x36, 0xfe, 0xfb, 0x87, 0xd4, 0x26, 0x3e}}},
{{{0x0f, 0x93, 0x9c, 0x11, 0xe7, 0xdb, 0xf1, 0xf0, 0x85, 0x43, 0x28, 0x15, 0x37, 0xdd, 0xde, 0x27, 0xdf, 0xad, 0x3e, 0x49, 0x4f, 0xe0, 0x5b, 0xf6, 0x80, 0x59, 0x15, 0x3c, 0x85, 0xb7, 0x3e, 0x12}} ,
{{0xf5, 0xff, 0xcc, 0xf0, 0xb4, 0x12, 0x03, 0x5f, 0xc9, 0x84, 0xcb, 0x1d, 0x17, 0xe0, 0xbc, 0xcc, 0x03, 0x62, 0xa9, 0x8b, 0x94, 0xa6, 0xaa, 0x18, 0xcb, 0x27, 0x8d, 0x49, 0xa6, 0x17, 0x15, 0x07}}},
{{{0xd9, 0xb6, 0xd4, 0x9d, 0xd4, 0x6a, 0xaf, 0x70, 0x07, 0x2c, 0x10, 0x9e, 0xbd, 0x11, 0xad, 0xe4, 0x26, 0x33, 0x70, 0x92, 0x78, 0x1c, 0x74, 0x9f, 0x75, 0x60, 0x56, 0xf4, 0x39, 0xa8, 0xa8, 0x62}} ,
{{0x3b, 0xbf, 0x55, 0x35, 0x61, 0x8b, 0x44, 0x97, 0xe8, 0x3a, 0x55, 0xc1, 0xc8, 0x3b, 0xfd, 0x95, 0x29, 0x11, 0x60, 0x96, 0x1e, 0xcb, 0x11, 0x9d, 0xc2, 0x03, 0x8a, 0x1b, 0xc6, 0xd6, 0x45, 0x3d}}},
{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
{{{0x7e, 0x0e, 0x50, 0xb2, 0xcc, 0x0d, 0x6b, 0xa6, 0x71, 0x5b, 0x42, 0xed, 0xbd, 0xaf, 0xac, 0xf0, 0xfc, 0x12, 0xa2, 0x3f, 0x4e, 0xda, 0xe8, 0x11, 0xf3, 0x23, 0xe1, 0x04, 0x62, 0x03, 0x1c, 0x4e}} ,
{{0xc8, 0xb1, 0x1b, 0x6f, 0x73, 0x61, 0x3d, 0x27, 0x0d, 0x7d, 0x7a, 0x25, 0x5f, 0x73, 0x0e, 0x2f, 0x93, 0xf6, 0x24, 0xd8, 0x4f, 0x90, 0xac, 0xa2, 0x62, 0x0a, 0xf0, 0x61, 0xd9, 0x08, 0x59, 0x6a}}},
{{{0x6f, 0x2d, 0x55, 0xf8, 0x2f, 0x8e, 0xf0, 0x18, 0x3b, 0xea, 0xdd, 0x26, 0x72, 0xd1, 0xf5, 0xfe, 0xe5, 0xb8, 0xe6, 0xd3, 0x10, 0x48, 0x46, 0x49, 0x3a, 0x9f, 0x5e, 0x45, 0x6b, 0x90, 0xe8, 0x7f}} ,
{{0xd3, 0x76, 0x69, 0x33, 0x7b, 0xb9, 0x40, 0x70, 0xee, 0xa6, 0x29, 0x6b, 0xdd, 0xd0, 0x5d, 0x8d, 0xc1, 0x3e, 0x4a, 0xea, 0x37, 0xb1, 0x03, 0x02, 0x03, 0x35, 0xf1, 0x28, 0x9d, 0xff, 0x00, 0x13}}},
{{{0x7a, 0xdb, 0x12, 0xd2, 0x8a, 0x82, 0x03, 0x1b, 0x1e, 0xaf, 0xf9, 0x4b, 0x9c, 0xbe, 0xae, 0x7c, 0xe4, 0x94, 0x2a, 0x23, 0xb3, 0x62, 0x86, 0xe7, 0xfd, 0x23, 0xaa, 0x99, 0xbd, 0x2b, 0x11, 0x6c}} ,
{{0x8d, 0xa6, 0xd5, 0xac, 0x9d, 0xcc, 0x68, 0x75, 0x7f, 0xc3, 0x4d, 0x4b, 0xdd, 0x6c, 0xbb, 0x11, 0x5a, 0x60, 0xe5, 0xbd, 0x7d, 0x27, 0x8b, 0xda, 0xb4, 0x95, 0xf6, 0x03, 0x27, 0xa4, 0x92, 0x3f}}},
{{{0x22, 0xd6, 0xb5, 0x17, 0x84, 0xbf, 0x12, 0xcc, 0x23, 0x14, 0x4a, 0xdf, 0x14, 0x31, 0xbc, 0xa1, 0xac, 0x6e, 0xab, 0xfa, 0x57, 0x11, 0x53, 0xb3, 0x27, 0xe6, 0xf9, 0x47, 0x33, 0x44, 0x34, 0x1e}} ,
{{0x79, 0xfc, 0xa6, 0xb4, 0x0b, 0x35, 0x20, 0xc9, 0x4d, 0x22, 0x84, 0xc4, 0xa9, 0x20, 0xec, 0x89, 0x94, 0xba, 0x66, 0x56, 0x48, 0xb9, 0x87, 0x7f, 0xca, 0x1e, 0x06, 0xed, 0xa5, 0x55, 0x59, 0x29}}},
{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
{{{0x56, 0xe1, 0xf5, 0xf1, 0xd5, 0xab, 0xa8, 0x2b, 0xae, 0x89, 0xf3, 0xcf, 0x56, 0x9f, 0xf2, 0x4b, 0x31, 0xbc, 0x18, 0xa9, 0x06, 0x5b, 0xbe, 0xb4, 0x61, 0xf8, 0xb2, 0x06, 0x9c, 0x81, 0xab, 0x4c}} ,
{{0x1f, 0x68, 0x76, 0x01, 0x16, 0x38, 0x2b, 0x0f, 0x77, 0x97, 0x92, 0x67, 0x4e, 0x86, 0x6a, 0x8b, 0xe5, 0xe8, 0x0c, 0xf7, 0x36, 0x39, 0xb5, 0x33, 0xe6, 0xcf, 0x5e, 0xbd, 0x18, 0xfb, 0x10, 0x1f}}},
{{{0x83, 0xf0, 0x0d, 0x63, 0xef, 0x53, 0x6b, 0xb5, 0x6b, 0xf9, 0x83, 0xcf, 0xde, 0x04, 0x22, 0x9b, 0x2c, 0x0a, 0xe0, 0xa5, 0xd8, 0xc7, 0x9c, 0xa5, 0xa3, 0xf6, 0x6f, 0xcf, 0x90, 0x6b, 0x68, 0x7c}} ,
{{0x33, 0x15, 0xd7, 0x7f, 0x1a, 0xd5, 0x21, 0x58, 0xc4, 0x18, 0xa5, 0xf0, 0xcc, 0x73, 0xa8, 0xfd, 0xfa, 0x18, 0xd1, 0x03, 0x91, 0x8d, 0x52, 0xd2, 0xa3, 0xa4, 0xd3, 0xb1, 0xea, 0x1d, 0x0f, 0x00}}},
{{{0xcc, 0x48, 0x83, 0x90, 0xe5, 0xfd, 0x3f, 0x84, 0xaa, 0xf9, 0x8b, 0x82, 0x59, 0x24, 0x34, 0x68, 0x4f, 0x1c, 0x23, 0xd9, 0xcc, 0x71, 0xe1, 0x7f, 0x8c, 0xaf, 0xf1, 0xee, 0x00, 0xb6, 0xa0, 0x77}} ,
{{0xf5, 0x1a, 0x61, 0xf7, 0x37, 0x9d, 0x00, 0xf4, 0xf2, 0x69, 0x6f, 0x4b, 0x01, 0x85, 0x19, 0x45, 0x4d, 0x7f, 0x02, 0x7c, 0x6a, 0x05, 0x47, 0x6c, 0x1f, 0x81, 0x20, 0xd4, 0xe8, 0x50, 0x27, 0x72}}},
{{{0x2c, 0x3a, 0xe5, 0xad, 0xf4, 0xdd, 0x2d, 0xf7, 0x5c, 0x44, 0xb5, 0x5b, 0x21, 0xa3, 0x89, 0x5f, 0x96, 0x45, 0xca, 0x4d, 0xa4, 0x21, 0x99, 0x70, 0xda, 0xc4, 0xc4, 0xa0, 0xe5, 0xf4, 0xec, 0x0a}} ,
{{0x07, 0x68, 0x21, 0x65, 0xe9, 0x08, 0xa0, 0x0b, 0x6a, 0x4a, 0xba, 0xb5, 0x80, 0xaf, 0xd0, 0x1b, 0xc5, 0xf5, 0x4b, 0x73, 0x50, 0x60, 0x2d, 0x71, 0x69, 0x61, 0x0e, 0xc0, 0x20, 0x40, 0x30, 0x19}}},
{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
{{{0xd0, 0x75, 0x57, 0x3b, 0xeb, 0x5c, 0x14, 0x56, 0x50, 0xc9, 0x4f, 0xb8, 0xb8, 0x1e, 0xa3, 0xf4, 0xab, 0xf5, 0xa9, 0x20, 0x15, 0x94, 0x82, 0xda, 0x96, 0x1c, 0x9b, 0x59, 0x8c, 0xff, 0xf4, 0x51}} ,
{{0xc1, 0x3a, 0x86, 0xd7, 0xb0, 0x06, 0x84, 0x7f, 0x1b, 0xbd, 0xd4, 0x07, 0x78, 0x80, 0x2e, 0xb1, 0xb4, 0xee, 0x52, 0x38, 0xee, 0x9a, 0xf9, 0xf6, 0xf3, 0x41, 0x6e, 0xd4, 0x88, 0x95, 0xac, 0x35}}},
{{{0x41, 0x97, 0xbf, 0x71, 0x6a, 0x9b, 0x72, 0xec, 0xf3, 0xf8, 0x6b, 0xe6, 0x0e, 0x6c, 0x69, 0xa5, 0x2f, 0x68, 0x52, 0xd8, 0x61, 0x81, 0xc0, 0x63, 0x3f, 0xa6, 0x3c, 0x13, 0x90, 0xe6, 0x8d, 0x56}} ,
{{0xe8, 0x39, 0x30, 0x77, 0x23, 0xb1, 0xfd, 0x1b, 0x3d, 0x3e, 0x74, 0x4d, 0x7f, 0xae, 0x5b, 0x3a, 0xb4, 0x65, 0x0e, 0x3a, 0x43, 0xdc, 0xdc, 0x41, 0x47, 0xe6, 0xe8, 0x92, 0x09, 0x22, 0x48, 0x4c}}},
{{{0x85, 0x57, 0x9f, 0xb5, 0xc8, 0x06, 0xb2, 0x9f, 0x47, 0x3f, 0xf0, 0xfa, 0xe6, 0xa9, 0xb1, 0x9b, 0x6f, 0x96, 0x7d, 0xf9, 0xa4, 0x65, 0x09, 0x75, 0x32, 0xa6, 0x6c, 0x7f, 0x47, 0x4b, 0x2f, 0x4f}} ,
{{0x34, 0xe9, 0x59, 0x93, 0x9d, 0x26, 0x80, 0x54, 0xf2, 0xcc, 0x3c, 0xc2, 0x25, 0x85, 0xe3, 0x6a, 0xc1, 0x62, 0x04, 0xa7, 0x08, 0x32, 0x6d, 0xa1, 0x39, 0x84, 0x8a, 0x3b, 0x87, 0x5f, 0x11, 0x13}}},
{{{0xda, 0x03, 0x34, 0x66, 0xc4, 0x0c, 0x73, 0x6e, 0xbc, 0x24, 0xb5, 0xf9, 0x70, 0x81, 0x52, 0xe9, 0xf4, 0x7c, 0x23, 0xdd, 0x9f, 0xb8, 0x46, 0xef, 0x1d, 0x22, 0x55, 0x7d, 0x71, 0xc4, 0x42, 0x33}} ,
{{0xc5, 0x37, 0x69, 0x5b, 0xa8, 0xc6, 0x9d, 0xa4, 0xfc, 0x61, 0x6e, 0x68, 0x46, 0xea, 0xd7, 0x1c, 0x67, 0xd2, 0x7d, 0xfa, 0xf1, 0xcc, 0x54, 0x8d, 0x36, 0x35, 0xc9, 0x00, 0xdf, 0x6c, 0x67, 0x50}}},
{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
{{{0x9a, 0x4d, 0x42, 0x29, 0x5d, 0xa4, 0x6b, 0x6f, 0xa8, 0x8a, 0x4d, 0x91, 0x7b, 0xd2, 0xdf, 0x36, 0xef, 0x01, 0x22, 0xc5, 0xcc, 0x8d, 0xeb, 0x58, 0x3d, 0xb3, 0x50, 0xfc, 0x8b, 0x97, 0x96, 0x33}} ,
{{0x93, 0x33, 0x07, 0xc8, 0x4a, 0xca, 0xd0, 0xb1, 0xab, 0xbd, 0xdd, 0xa7, 0x7c, 0xac, 0x3e, 0x45, 0xcb, 0xcc, 0x07, 0x91, 0xbf, 0x35, 0x9d, 0xcb, 0x7d, 0x12, 0x3c, 0x11, 0x59, 0x13, 0xcf, 0x5c}}},
{{{0x45, 0xb8, 0x41, 0xd7, 0xab, 0x07, 0x15, 0x00, 0x8e, 0xce, 0xdf, 0xb2, 0x43, 0x5c, 0x01, 0xdc, 0xf4, 0x01, 0x51, 0x95, 0x10, 0x5a, 0xf6, 0x24, 0x24, 0xa0, 0x19, 0x3a, 0x09, 0x2a, 0xaa, 0x3f}} ,
{{0xdc, 0x8e, 0xeb, 0xc6, 0xbf, 0xdd, 0x11, 0x7b, 0xe7, 0x47, 0xe6, 0xce, 0xe7, 0xb6, 0xc5, 0xe8, 0x8a, 0xdc, 0x4b, 0x57, 0x15, 0x3b, 0x66, 0xca, 0x89, 0xa3, 0xfd, 0xac, 0x0d, 0xe1, 0x1d, 0x7a}}},
{{{0x89, 0xef, 0xbf, 0x03, 0x75, 0xd0, 0x29, 0x50, 0xcb, 0x7d, 0xd6, 0xbe, 0xad, 0x5f, 0x7b, 0x00, 0x32, 0xaa, 0x98, 0xed, 0x3f, 0x8f, 0x92, 0xcb, 0x81, 0x56, 0x01, 0x63, 0x64, 0xa3, 0x38, 0x39}} ,
{{0x8b, 0xa4, 0xd6, 0x50, 0xb4, 0xaa, 0x5d, 0x64, 0x64, 0x76, 0x2e, 0xa1, 0xa6, 0xb3, 0xb8, 0x7c, 0x7a, 0x56, 0xf5, 0x5c, 0x4e, 0x84, 0x5c, 0xfb, 0xdd, 0xca, 0x48, 0x8b, 0x48, 0xb9, 0xba, 0x34}}},
{{{0xc5, 0xe3, 0xe8, 0xae, 0x17, 0x27, 0xe3, 0x64, 0x60, 0x71, 0x47, 0x29, 0x02, 0x0f, 0x92, 0x5d, 0x10, 0x93, 0xc8, 0x0e, 0xa1, 0xed, 0xba, 0xa9, 0x96, 0x1c, 0xc5, 0x76, 0x30, 0xcd, 0xf9, 0x30}} ,
{{0x95, 0xb0, 0xbd, 0x8c, 0xbc, 0xa7, 0x4f, 0x7e, 0xfd, 0x4e, 0x3a, 0xbf, 0x5f, 0x04, 0x79, 0x80, 0x2b, 0x5a, 0x9f, 0x4f, 0x68, 0x21, 0x19, 0x71, 0xc6, 0x20, 0x01, 0x42, 0xaa, 0xdf, 0xae, 0x2c}}},
{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
{{{0x90, 0x6e, 0x7e, 0x4b, 0x71, 0x93, 0xc0, 0x72, 0xed, 0xeb, 0x71, 0x24, 0x97, 0x26, 0x9c, 0xfe, 0xcb, 0x3e, 0x59, 0x19, 0xa8, 0x0f, 0x75, 0x7d, 0xbe, 0x18, 0xe6, 0x96, 0x1e, 0x95, 0x70, 0x60}} ,
{{0x89, 0x66, 0x3e, 0x1d, 0x4c, 0x5f, 0xfe, 0xc0, 0x04, 0x43, 0xd6, 0x44, 0x19, 0xb5, 0xad, 0xc7, 0x22, 0xdc, 0x71, 0x28, 0x64, 0xde, 0x41, 0x38, 0x27, 0x8f, 0x2c, 0x6b, 0x08, 0xb8, 0xb8, 0x7b}}},
{{{0x3d, 0x70, 0x27, 0x9d, 0xd9, 0xaf, 0xb1, 0x27, 0xaf, 0xe3, 0x5d, 0x1e, 0x3a, 0x30, 0x54, 0x61, 0x60, 0xe8, 0xc3, 0x26, 0x3a, 0xbc, 0x7e, 0xf5, 0x81, 0xdd, 0x64, 0x01, 0x04, 0xeb, 0xc0, 0x1e}} ,
{{0xda, 0x2c, 0xa4, 0xd1, 0xa1, 0xc3, 0x5c, 0x6e, 0x32, 0x07, 0x1f, 0xb8, 0x0e, 0x19, 0x9e, 0x99, 0x29, 0x33, 0x9a, 0xae, 0x7a, 0xed, 0x68, 0x42, 0x69, 0x7c, 0x07, 0xb3, 0x38, 0x2c, 0xf6, 0x3d}}},
{{{0x64, 0xaa, 0xb5, 0x88, 0x79, 0x65, 0x38, 0x8c, 0x94, 0xd6, 0x62, 0x37, 0x7d, 0x64, 0xcd, 0x3a, 0xeb, 0xff, 0xe8, 0x81, 0x09, 0xc7, 0x6a, 0x50, 0x09, 0x0d, 0x28, 0x03, 0x0d, 0x9a, 0x93, 0x0a}} ,
{{0x42, 0xa3, 0xf1, 0xc5, 0xb4, 0x0f, 0xd8, 0xc8, 0x8d, 0x15, 0x31, 0xbd, 0xf8, 0x07, 0x8b, 0xcd, 0x08, 0x8a, 0xfb, 0x18, 0x07, 0xfe, 0x8e, 0x52, 0x86, 0xef, 0xbe, 0xec, 0x49, 0x52, 0x99, 0x08}}},
{{{0x0f, 0xa9, 0xd5, 0x01, 0xaa, 0x48, 0x4f, 0x28, 0x66, 0x32, 0x1a, 0xba, 0x7c, 0xea, 0x11, 0x80, 0x17, 0x18, 0x9b, 0x56, 0x88, 0x25, 0x06, 0x69, 0x12, 0x2c, 0xea, 0x56, 0x69, 0x41, 0x24, 0x19}} ,
{{0xde, 0x21, 0xf0, 0xda, 0x8a, 0xfb, 0xb1, 0xb8, 0xcd, 0xc8, 0x6a, 0x82, 0x19, 0x73, 0xdb, 0xc7, 0xcf, 0x88, 0xeb, 0x96, 0xee, 0x6f, 0xfb, 0x06, 0xd2, 0xcd, 0x7d, 0x7b, 0x12, 0x28, 0x8e, 0x0c}}},
{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
{{{0x93, 0x44, 0x97, 0xce, 0x28, 0xff, 0x3a, 0x40, 0xc4, 0xf5, 0xf6, 0x9b, 0xf4, 0x6b, 0x07, 0x84, 0xfb, 0x98, 0xd8, 0xec, 0x8c, 0x03, 0x57, 0xec, 0x49, 0xed, 0x63, 0xb6, 0xaa, 0xff, 0x98, 0x28}} ,
{{0x3d, 0x16, 0x35, 0xf3, 0x46, 0xbc, 0xb3, 0xf4, 0xc6, 0xb6, 0x4f, 0xfa, 0xf4, 0xa0, 0x13, 0xe6, 0x57, 0x45, 0x93, 0xb9, 0xbc, 0xd6, 0x59, 0xe7, 0x77, 0x94, 0x6c, 0xab, 0x96, 0x3b, 0x4f, 0x09}}},
{{{0x5a, 0xf7, 0x6b, 0x01, 0x12, 0x4f, 0x51, 0xc1, 0x70, 0x84, 0x94, 0x47, 0xb2, 0x01, 0x6c, 0x71, 0xd7, 0xcc, 0x17, 0x66, 0x0f, 0x59, 0x5d, 0x5d, 0x10, 0x01, 0x57, 0x11, 0xf5, 0xdd, 0xe2, 0x34}} ,
{{0x26, 0xd9, 0x1f, 0x5c, 0x58, 0xac, 0x8b, 0x03, 0xd2, 0xc3, 0x85, 0x0f, 0x3a, 0xc3, 0x7f, 0x6d, 0x8e, 0x86, 0xcd, 0x52, 0x74, 0x8f, 0x55, 0x77, 0x17, 0xb7, 0x8e, 0xb7, 0x88, 0xea, 0xda, 0x1b}}},
{{{0xb6, 0xea, 0x0e, 0x40, 0x93, 0x20, 0x79, 0x35, 0x6a, 0x61, 0x84, 0x5a, 0x07, 0x6d, 0xf9, 0x77, 0x6f, 0xed, 0x69, 0x1c, 0x0d, 0x25, 0x76, 0xcc, 0xf0, 0xdb, 0xbb, 0xc5, 0xad, 0xe2, 0x26, 0x57}} ,
{{0xcf, 0xe8, 0x0e, 0x6b, 0x96, 0x7d, 0xed, 0x27, 0xd1, 0x3c, 0xa9, 0xd9, 0x50, 0xa9, 0x98, 0x84, 0x5e, 0x86, 0xef, 0xd6, 0xf0, 0xf8, 0x0e, 0x89, 0x05, 0x2f, 0xd9, 0x5f, 0x15, 0x5f, 0x73, 0x79}}},
{{{0xc8, 0x5c, 0x16, 0xfe, 0xed, 0x9f, 0x26, 0x56, 0xf6, 0x4b, 0x9f, 0xa7, 0x0a, 0x85, 0xfe, 0xa5, 0x8c, 0x87, 0xdd, 0x98, 0xce, 0x4e, 0xc3, 0x58, 0x55, 0xb2, 0x7b, 0x3d, 0xd8, 0x6b, 0xb5, 0x4c}} ,
{{0x65, 0x38, 0xa0, 0x15, 0xfa, 0xa7, 0xb4, 0x8f, 0xeb, 0xc4, 0x86, 0x9b, 0x30, 0xa5, 0x5e, 0x4d, 0xea, 0x8a, 0x9a, 0x9f, 0x1a, 0xd8, 0x5b, 0x53, 0x14, 0x19, 0x25, 0x63, 0xb4, 0x6f, 0x1f, 0x5d}}},
{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
{{{0xac, 0x8f, 0xbc, 0x1e, 0x7d, 0x8b, 0x5a, 0x0b, 0x8d, 0xaf, 0x76, 0x2e, 0x71, 0xe3, 0x3b, 0x6f, 0x53, 0x2f, 0x3e, 0x90, 0x95, 0xd4, 0x35, 0x14, 0x4f, 0x8c, 0x3c, 0xce, 0x57, 0x1c, 0x76, 0x49}} ,
{{0xa8, 0x50, 0xe1, 0x61, 0x6b, 0x57, 0x35, 0xeb, 0x44, 0x0b, 0x0c, 0x6e, 0xf9, 0x25, 0x80, 0x74, 0xf2, 0x8f, 0x6f, 0x7a, 0x3e, 0x7f, 0x2d, 0xf3, 0x4e, 0x09, 0x65, 0x10, 0x5e, 0x03, 0x25, 0x32}}},
{{{0xa9, 0x60, 0xdc, 0x0f, 0x64, 0xe5, 0x1d, 0xe2, 0x8d, 0x4f, 0x79, 0x2f, 0x0e, 0x24, 0x02, 0x00, 0x05, 0x77, 0x43, 0x25, 0x3d, 0x6a, 0xc7, 0xb7, 0xbf, 0x04, 0x08, 0x65, 0xf4, 0x39, 0x4b, 0x65}} ,
{{0x96, 0x19, 0x12, 0x6b, 0x6a, 0xb7, 0xe3, 0xdc, 0x45, 0x9b, 0xdb, 0xb4, 0xa8, 0xae, 0xdc, 0xa8, 0x14, 0x44, 0x65, 0x62, 0xce, 0x34, 0x9a, 0x84, 0x18, 0x12, 0x01, 0xf1, 0xe2, 0x7b, 0xce, 0x50}}},
{{{0x41, 0x21, 0x30, 0x53, 0x1b, 0x47, 0x01, 0xb7, 0x18, 0xd8, 0x82, 0x57, 0xbd, 0xa3, 0x60, 0xf0, 0x32, 0xf6, 0x5b, 0xf0, 0x30, 0x88, 0x91, 0x59, 0xfd, 0x90, 0xa2, 0xb9, 0x55, 0x93, 0x21, 0x34}} ,
{{0x97, 0x67, 0x9e, 0xeb, 0x6a, 0xf9, 0x6e, 0xd6, 0x73, 0xe8, 0x6b, 0x29, 0xec, 0x63, 0x82, 0x00, 0xa8, 0x99, 0x1c, 0x1d, 0x30, 0xc8, 0x90, 0x52, 0x90, 0xb6, 0x6a, 0x80, 0x4e, 0xff, 0x4b, 0x51}}},
{{{0x0f, 0x7d, 0x63, 0x8c, 0x6e, 0x5c, 0xde, 0x30, 0xdf, 0x65, 0xfa, 0x2e, 0xb0, 0xa3, 0x25, 0x05, 0x54, 0xbd, 0x25, 0xba, 0x06, 0xae, 0xdf, 0x8b, 0xd9, 0x1b, 0xea, 0x38, 0xb3, 0x05, 0x16, 0x09}} ,
{{0xc7, 0x8c, 0xbf, 0x64, 0x28, 0xad, 0xf8, 0xa5, 0x5a, 0x6f, 0xc9, 0xba, 0xd5, 0x7f, 0xd5, 0xd6, 0xbd, 0x66, 0x2f, 0x3d, 0xaa, 0x54, 0xf6, 0xba, 0x32, 0x22, 0x9a, 0x1e, 0x52, 0x05, 0xf4, 0x1d}}},
{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
{{{0xaa, 0x1f, 0xbb, 0xeb, 0xfe, 0xe4, 0x87, 0xfc, 0xb1, 0x2c, 0xb7, 0x88, 0xf4, 0xc6, 0xb9, 0xf5, 0x24, 0x46, 0xf2, 0xa5, 0x9f, 0x8f, 0x8a, 0x93, 0x70, 0x69, 0xd4, 0x56, 0xec, 0xfd, 0x06, 0x46}} ,
{{0x4e, 0x66, 0xcf, 0x4e, 0x34, 0xce, 0x0c, 0xd9, 0xa6, 0x50, 0xd6, 0x5e, 0x95, 0xaf, 0xe9, 0x58, 0xfa, 0xee, 0x9b, 0xb8, 0xa5, 0x0f, 0x35, 0xe0, 0x43, 0x82, 0x6d, 0x65, 0xe6, 0xd9, 0x00, 0x0f}}},
{{{0x7b, 0x75, 0x3a, 0xfc, 0x64, 0xd3, 0x29, 0x7e, 0xdd, 0x49, 0x9a, 0x59, 0x53, 0xbf, 0xb4, 0xa7, 0x52, 0xb3, 0x05, 0xab, 0xc3, 0xaf, 0x16, 0x1a, 0x85, 0x42, 0x32, 0xa2, 0x86, 0xfa, 0x39, 0x43}} ,
{{0x0e, 0x4b, 0xa3, 0x63, 0x8a, 0xfe, 0xa5, 0x58, 0xf1, 0x13, 0xbd, 0x9d, 0xaa, 0x7f, 0x76, 0x40, 0x70, 0x81, 0x10, 0x75, 0x99, 0xbb, 0xbe, 0x0b, 0x16, 0xe9, 0xba, 0x62, 0x34, 0xcc, 0x07, 0x6d}}},
{{{0xc3, 0xf1, 0xc6, 0x93, 0x65, 0xee, 0x0b, 0xbc, 0xea, 0x14, 0xf0, 0xc1, 0xf8, 0x84, 0x89, 0xc2, 0xc9, 0xd7, 0xea, 0x34, 0xca, 0xa7, 0xc4, 0x99, 0xd5, 0x50, 0x69, 0xcb, 0xd6, 0x21, 0x63, 0x7c}} ,
{{0x99, 0xeb, 0x7c, 0x31, 0x73, 0x64, 0x67, 0x7f, 0x0c, 0x66, 0xaa, 0x8c, 0x69, 0x91, 0xe2, 0x26, 0xd3, 0x23, 0xe2, 0x76, 0x5d, 0x32, 0x52, 0xdf, 0x5d, 0xc5, 0x8f, 0xb7, 0x7c, 0x84, 0xb3, 0x70}}},
{{{0xeb, 0x01, 0xc7, 0x36, 0x97, 0x4e, 0xb6, 0xab, 0x5f, 0x0d, 0x2c, 0xba, 0x67, 0x64, 0x55, 0xde, 0xbc, 0xff, 0xa6, 0xec, 0x04, 0xd3, 0x8d, 0x39, 0x56, 0x5e, 0xee, 0xf8, 0xe4, 0x2e, 0x33, 0x62}} ,
{{0x65, 0xef, 0xb8, 0x9f, 0xc8, 0x4b, 0xa7, 0xfd, 0x21, 0x49, 0x9b, 0x92, 0x35, 0x82, 0xd6, 0x0a, 0x9b, 0xf2, 0x79, 0xf1, 0x47, 0x2f, 0x6a, 0x7e, 0x9f, 0xcf, 0x18, 0x02, 0x3c, 0xfb, 0x1b, 0x3e}}},
{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
{{{0x2f, 0x8b, 0xc8, 0x40, 0x51, 0xd1, 0xac, 0x1a, 0x0b, 0xe4, 0xa9, 0xa2, 0x42, 0x21, 0x19, 0x2f, 0x7b, 0x97, 0xbf, 0xf7, 0x57, 0x6d, 0x3f, 0x3d, 0x4f, 0x0f, 0xe2, 0xb2, 0x81, 0x00, 0x9e, 0x7b}} ,
{{0x8c, 0x85, 0x2b, 0xc4, 0xfc, 0xf1, 0xab, 0xe8, 0x79, 0x22, 0xc4, 0x84, 0x17, 0x3a, 0xfa, 0x86, 0xa6, 0x7d, 0xf9, 0xf3, 0x6f, 0x03, 0x57, 0x20, 0x4d, 0x79, 0xf9, 0x6e, 0x71, 0x54, 0x38, 0x09}}},
{{{0x40, 0x29, 0x74, 0xa8, 0x2f, 0x5e, 0xf9, 0x79, 0xa4, 0xf3, 0x3e, 0xb9, 0xfd, 0x33, 0x31, 0xac, 0x9a, 0x69, 0x88, 0x1e, 0x77, 0x21, 0x2d, 0xf3, 0x91, 0x52, 0x26, 0x15, 0xb2, 0xa6, 0xcf, 0x7e}} ,
{{0xc6, 0x20, 0x47, 0x6c, 0xa4, 0x7d, 0xcb, 0x63, 0xea, 0x5b, 0x03, 0xdf, 0x3e, 0x88, 0x81, 0x6d, 0xce, 0x07, 0x42, 0x18, 0x60, 0x7e, 0x7b, 0x55, 0xfe, 0x6a, 0xf3, 0xda, 0x5c, 0x8b, 0x95, 0x10}}},
{{{0x62, 0xe4, 0x0d, 0x03, 0xb4, 0xd7, 0xcd, 0xfa, 0xbd, 0x46, 0xdf, 0x93, 0x71, 0x10, 0x2c, 0xa8, 0x3b, 0xb6, 0x09, 0x05, 0x70, 0x84, 0x43, 0x29, 0xa8, 0x59, 0xf5, 0x8e, 0x10, 0xe4, 0xd7, 0x20}} ,
{{0x57, 0x82, 0x1c, 0xab, 0xbf, 0x62, 0x70, 0xe8, 0xc4, 0xcf, 0xf0, 0x28, 0x6e, 0x16, 0x3c, 0x08, 0x78, 0x89, 0x85, 0x46, 0x0f, 0xf6, 0x7f, 0xcf, 0xcb, 0x7e, 0xb8, 0x25, 0xe9, 0x5a, 0xfa, 0x03}}},
{{{0xfb, 0x95, 0x92, 0x63, 0x50, 0xfc, 0x62, 0xf0, 0xa4, 0x5e, 0x8c, 0x18, 0xc2, 0x17, 0x24, 0xb7, 0x78, 0xc2, 0xa9, 0xe7, 0x6a, 0x32, 0xd6, 0x29, 0x85, 0xaf, 0xcb, 0x8d, 0x91, 0x13, 0xda, 0x6b}} ,
{{0x36, 0x0a, 0xc2, 0xb6, 0x4b, 0xa5, 0x5d, 0x07, 0x17, 0x41, 0x31, 0x5f, 0x62, 0x46, 0xf8, 0x92, 0xf9, 0x66, 0x48, 0x73, 0xa6, 0x97, 0x0d, 0x7d, 0x88, 0xee, 0x62, 0xb1, 0x03, 0xa8, 0x3f, 0x2c}}},
{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
{{{0x4a, 0xb1, 0x70, 0x8a, 0xa9, 0xe8, 0x63, 0x79, 0x00, 0xe2, 0x25, 0x16, 0xca, 0x4b, 0x0f, 0xa4, 0x66, 0xad, 0x19, 0x9f, 0x88, 0x67, 0x0c, 0x8b, 0xc2, 0x4a, 0x5b, 0x2b, 0x6d, 0x95, 0xaf, 0x19}} ,
{{0x8b, 0x9d, 0xb6, 0xcc, 0x60, 0xb4, 0x72, 0x4f, 0x17, 0x69, 0x5a, 0x4a, 0x68, 0x34, 0xab, 0xa1, 0x45, 0x32, 0x3c, 0x83, 0x87, 0x72, 0x30, 0x54, 0x77, 0x68, 0xae, 0xfb, 0xb5, 0x8b, 0x22, 0x5e}}},
{{{0xf1, 0xb9, 0x87, 0x35, 0xc5, 0xbb, 0xb9, 0xcf, 0xf5, 0xd6, 0xcd, 0xd5, 0x0c, 0x7c, 0x0e, 0xe6, 0x90, 0x34, 0xfb, 0x51, 0x42, 0x1e, 0x6d, 0xac, 0x9a, 0x46, 0xc4, 0x97, 0x29, 0x32, 0xbf, 0x45}} ,
{{0x66, 0x9e, 0xc6, 0x24, 0xc0, 0xed, 0xa5, 0x5d, 0x88, 0xd4, 0xf0, 0x73, 0x97, 0x7b, 0xea, 0x7f, 0x42, 0xff, 0x21, 0xa0, 0x9b, 0x2f, 0x9a, 0xfd, 0x53, 0x57, 0x07, 0x84, 0x48, 0x88, 0x9d, 0x52}}},
{{{0xc6, 0x96, 0x48, 0x34, 0x2a, 0x06, 0xaf, 0x94, 0x3d, 0xf4, 0x1a, 0xcf, 0xf2, 0xc0, 0x21, 0xc2, 0x42, 0x5e, 0xc8, 0x2f, 0x35, 0xa2, 0x3e, 0x29, 0xfa, 0x0c, 0x84, 0xe5, 0x89, 0x72, 0x7c, 0x06}} ,
{{0x32, 0x65, 0x03, 0xe5, 0x89, 0xa6, 0x6e, 0xb3, 0x5b, 0x8e, 0xca, 0xeb, 0xfe, 0x22, 0x56, 0x8b, 0x5d, 0x14, 0x4b, 0x4d, 0xf9, 0xbe, 0xb5, 0xf5, 0xe6, 0x5c, 0x7b, 0x8b, 0xf4, 0x13, 0x11, 0x34}}},
{{{0x07, 0xc6, 0x22, 0x15, 0xe2, 0x9c, 0x60, 0xa2, 0x19, 0xd9, 0x27, 0xae, 0x37, 0x4e, 0xa6, 0xc9, 0x80, 0xa6, 0x91, 0x8f, 0x12, 0x49, 0xe5, 0x00, 0x18, 0x47, 0xd1, 0xd7, 0x28, 0x22, 0x63, 0x39}} ,
{{0xe8, 0xe2, 0x00, 0x7e, 0xf2, 0x9e, 0x1e, 0x99, 0x39, 0x95, 0x04, 0xbd, 0x1e, 0x67, 0x7b, 0xb2, 0x26, 0xac, 0xe6, 0xaa, 0xe2, 0x46, 0xd5, 0xe4, 0xe8, 0x86, 0xbd, 0xab, 0x7c, 0x55, 0x59, 0x6f}}},
{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
{{{0x24, 0x64, 0x6e, 0x9b, 0x35, 0x71, 0x78, 0xce, 0x33, 0x03, 0x21, 0x33, 0x36, 0xf1, 0x73, 0x9b, 0xb9, 0x15, 0x8b, 0x2c, 0x69, 0xcf, 0x4d, 0xed, 0x4f, 0x4d, 0x57, 0x14, 0x13, 0x82, 0xa4, 0x4d}} ,
{{0x65, 0x6e, 0x0a, 0xa4, 0x59, 0x07, 0x17, 0xf2, 0x6b, 0x4a, 0x1f, 0x6e, 0xf6, 0xb5, 0xbc, 0x62, 0xe4, 0xb6, 0xda, 0xa2, 0x93, 0xbc, 0x29, 0x05, 0xd2, 0xd2, 0x73, 0x46, 0x03, 0x16, 0x40, 0x31}}},
{{{0x4c, 0x73, 0x6d, 0x15, 0xbd, 0xa1, 0x4d, 0x5c, 0x13, 0x0b, 0x24, 0x06, 0x98, 0x78, 0x1c, 0x5b, 0xeb, 0x1f, 0x18, 0x54, 0x43, 0xd9, 0x55, 0x66, 0xda, 0x29, 0x21, 0xe8, 0xb8, 0x3c, 0x42, 0x22}} ,
{{0xb4, 0xcd, 0x08, 0x6f, 0x15, 0x23, 0x1a, 0x0b, 0x22, 0xed, 0xd1, 0xf1, 0xa7, 0xc7, 0x73, 0x45, 0xf3, 0x9e, 0xce, 0x76, 0xb7, 0xf6, 0x39, 0xb6, 0x8e, 0x79, 0xbe, 0xe9, 0x9b, 0xcf, 0x7d, 0x62}}},
{{{0x92, 0x5b, 0xfc, 0x72, 0xfd, 0xba, 0xf1, 0xfd, 0xa6, 0x7c, 0x95, 0xe3, 0x61, 0x3f, 0xe9, 0x03, 0xd4, 0x2b, 0xd4, 0x20, 0xd9, 0xdb, 0x4d, 0x32, 0x3e, 0xf5, 0x11, 0x64, 0xe3, 0xb4, 0xbe, 0x32}} ,
{{0x86, 0x17, 0x90, 0xe7, 0xc9, 0x1f, 0x10, 0xa5, 0x6a, 0x2d, 0x39, 0xd0, 0x3b, 0xc4, 0xa6, 0xe9, 0x59, 0x13, 0xda, 0x1a, 0xe6, 0xa0, 0xb9, 0x3c, 0x50, 0xb8, 0x40, 0x7c, 0x15, 0x36, 0x5a, 0x42}}},
{{{0xb4, 0x0b, 0x32, 0xab, 0xdc, 0x04, 0x51, 0x55, 0x21, 0x1e, 0x0b, 0x75, 0x99, 0x89, 0x73, 0x35, 0x3a, 0x91, 0x2b, 0xfe, 0xe7, 0x49, 0xea, 0x76, 0xc1, 0xf9, 0x46, 0xb9, 0x53, 0x02, 0x23, 0x04}} ,
{{0xfc, 0x5a, 0x1e, 0x1d, 0x74, 0x58, 0x95, 0xa6, 0x8f, 0x7b, 0x97, 0x3e, 0x17, 0x3b, 0x79, 0x2d, 0xa6, 0x57, 0xef, 0x45, 0x02, 0x0b, 0x4d, 0x6e, 0x9e, 0x93, 0x8d, 0x2f, 0xd9, 0x9d, 0xdb, 0x04}}},
{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
{{{0xc0, 0xd7, 0x56, 0x97, 0x58, 0x91, 0xde, 0x09, 0x4f, 0x9f, 0xbe, 0x63, 0xb0, 0x83, 0x86, 0x43, 0x5d, 0xbc, 0xe0, 0xf3, 0xc0, 0x75, 0xbf, 0x8b, 0x8e, 0xaa, 0xf7, 0x8b, 0x64, 0x6e, 0xb0, 0x63}} ,
{{0x16, 0xae, 0x8b, 0xe0, 0x9b, 0x24, 0x68, 0x5c, 0x44, 0xc2, 0xd0, 0x08, 0xb7, 0x7b, 0x62, 0xfd, 0x7f, 0xd8, 0xd4, 0xb7, 0x50, 0xfd, 0x2c, 0x1b, 0xbf, 0x41, 0x95, 0xd9, 0x8e, 0xd8, 0x17, 0x1b}}},
{{{0x86, 0x55, 0x37, 0x8e, 0xc3, 0x38, 0x48, 0x14, 0xb5, 0x97, 0xd2, 0xa7, 0x54, 0x45, 0xf1, 0x35, 0x44, 0x38, 0x9e, 0xf1, 0x1b, 0xb6, 0x34, 0x00, 0x3c, 0x96, 0xee, 0x29, 0x00, 0xea, 0x2c, 0x0b}} ,
{{0xea, 0xda, 0x99, 0x9e, 0x19, 0x83, 0x66, 0x6d, 0xe9, 0x76, 0x87, 0x50, 0xd1, 0xfd, 0x3c, 0x60, 0x87, 0xc6, 0x41, 0xd9, 0x8e, 0xdb, 0x5e, 0xde, 0xaa, 0x9a, 0xd3, 0x28, 0xda, 0x95, 0xea, 0x47}}},
{{{0xd0, 0x80, 0xba, 0x19, 0xae, 0x1d, 0xa9, 0x79, 0xf6, 0x3f, 0xac, 0x5d, 0x6f, 0x96, 0x1f, 0x2a, 0xce, 0x29, 0xb2, 0xff, 0x37, 0xf1, 0x94, 0x8f, 0x0c, 0xb5, 0x28, 0xba, 0x9a, 0x21, 0xf6, 0x66}} ,
{{0x02, 0xfb, 0x54, 0xb8, 0x05, 0xf3, 0x81, 0x52, 0x69, 0x34, 0x46, 0x9d, 0x86, 0x76, 0x8f, 0xd7, 0xf8, 0x6a, 0x66, 0xff, 0xe6, 0xa7, 0x90, 0xf7, 0x5e, 0xcd, 0x6a, 0x9b, 0x55, 0xfc, 0x9d, 0x48}}},
{{{0xbd, 0xaa, 0x13, 0xe6, 0xcd, 0x45, 0x4a, 0xa4, 0x59, 0x0a, 0x64, 0xb1, 0x98, 0xd6, 0x34, 0x13, 0x04, 0xe6, 0x97, 0x94, 0x06, 0xcb, 0xd4, 0x4e, 0xbb, 0x96, 0xcd, 0xd1, 0x57, 0xd1, 0xe3, 0x06}} ,
{{0x7a, 0x6c, 0x45, 0x27, 0xc4, 0x93, 0x7f, 0x7d, 0x7c, 0x62, 0x50, 0x38, 0x3a, 0x6b, 0xb5, 0x88, 0xc6, 0xd9, 0xf1, 0x78, 0x19, 0xb9, 0x39, 0x93, 0x3d, 0xc9, 0xe0, 0x9c, 0x3c, 0xce, 0xf5, 0x72}}},
{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
{{{0x24, 0xea, 0x23, 0x7d, 0x56, 0x2c, 0xe2, 0x59, 0x0e, 0x85, 0x60, 0x04, 0x88, 0x5a, 0x74, 0x1e, 0x4b, 0xef, 0x13, 0xda, 0x4c, 0xff, 0x83, 0x45, 0x85, 0x3f, 0x08, 0x95, 0x2c, 0x20, 0x13, 0x1f}} ,
{{0x48, 0x5f, 0x27, 0x90, 0x5c, 0x02, 0x42, 0xad, 0x78, 0x47, 0x5c, 0xb5, 0x7e, 0x08, 0x85, 0x00, 0xfa, 0x7f, 0xfd, 0xfd, 0xe7, 0x09, 0x11, 0xf2, 0x7e, 0x1b, 0x38, 0x6c, 0x35, 0x6d, 0x33, 0x66}}},
{{{0x93, 0x03, 0x36, 0x81, 0xac, 0xe4, 0x20, 0x09, 0x35, 0x4c, 0x45, 0xb2, 0x1e, 0x4c, 0x14, 0x21, 0xe6, 0xe9, 0x8a, 0x7b, 0x8d, 0xfe, 0x1e, 0xc6, 0x3e, 0xc1, 0x35, 0xfa, 0xe7, 0x70, 0x4e, 0x1d}} ,
{{0x61, 0x2e, 0xc2, 0xdd, 0x95, 0x57, 0xd1, 0xab, 0x80, 0xe8, 0x63, 0x17, 0xb5, 0x48, 0xe4, 0x8a, 0x11, 0x9e, 0x72, 0xbe, 0x85, 0x8d, 0x51, 0x0a, 0xf2, 0x9f, 0xe0, 0x1c, 0xa9, 0x07, 0x28, 0x7b}}},
{{{0xbb, 0x71, 0x14, 0x5e, 0x26, 0x8c, 0x3d, 0xc8, 0xe9, 0x7c, 0xd3, 0xd6, 0xd1, 0x2f, 0x07, 0x6d, 0xe6, 0xdf, 0xfb, 0x79, 0xd6, 0x99, 0x59, 0x96, 0x48, 0x40, 0x0f, 0x3a, 0x7b, 0xb2, 0xa0, 0x72}} ,
{{0x4e, 0x3b, 0x69, 0xc8, 0x43, 0x75, 0x51, 0x6c, 0x79, 0x56, 0xe4, 0xcb, 0xf7, 0xa6, 0x51, 0xc2, 0x2c, 0x42, 0x0b, 0xd4, 0x82, 0x20, 0x1c, 0x01, 0x08, 0x66, 0xd7, 0xbf, 0x04, 0x56, 0xfc, 0x02}}},
{{{0x24, 0xe8, 0xb7, 0x60, 0xae, 0x47, 0x80, 0xfc, 0xe5, 0x23, 0xe7, 0xc2, 0xc9, 0x85, 0xe6, 0x98, 0xa0, 0x29, 0x4e, 0xe1, 0x84, 0x39, 0x2d, 0x95, 0x2c, 0xf3, 0x45, 0x3c, 0xff, 0xaf, 0x27, 0x4c}} ,
{{0x6b, 0xa6, 0xf5, 0x4b, 0x11, 0xbd, 0xba, 0x5b, 0x9e, 0xc4, 0xa4, 0x51, 0x1e, 0xbe, 0xd0, 0x90, 0x3a, 0x9c, 0xc2, 0x26, 0xb6, 0x1e, 0xf1, 0x95, 0x7d, 0xc8, 0x6d, 0x52, 0xe6, 0x99, 0x2c, 0x5f}}},
{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
{{{0x85, 0xe0, 0x24, 0x32, 0xb4, 0xd1, 0xef, 0xfc, 0x69, 0xa2, 0xbf, 0x8f, 0x72, 0x2c, 0x95, 0xf6, 0xe4, 0x6e, 0x7d, 0x90, 0xf7, 0x57, 0x81, 0xa0, 0xf7, 0xda, 0xef, 0x33, 0x07, 0xe3, 0x6b, 0x78}} ,
{{0x36, 0x27, 0x3e, 0xc6, 0x12, 0x07, 0xab, 0x4e, 0xbe, 0x69, 0x9d, 0xb3, 0xbe, 0x08, 0x7c, 0x2a, 0x47, 0x08, 0xfd, 0xd4, 0xcd, 0x0e, 0x27, 0x34, 0x5b, 0x98, 0x34, 0x2f, 0x77, 0x5f, 0x3a, 0x65}}},
{{{0x13, 0xaa, 0x2e, 0x4c, 0xf0, 0x22, 0xb8, 0x6c, 0xb3, 0x19, 0x4d, 0xeb, 0x6b, 0xd0, 0xa4, 0xc6, 0x9c, 0xdd, 0xc8, 0x5b, 0x81, 0x57, 0x89, 0xdf, 0x33, 0xa9, 0x68, 0x49, 0x80, 0xe4, 0xfe, 0x21}} ,
{{0x00, 0x17, 0x90, 0x30, 0xe9, 0xd3, 0x60, 0x30, 0x31, 0xc2, 0x72, 0x89, 0x7a, 0x36, 0xa5, 0xbd, 0x39, 0x83, 0x85, 0x50, 0xa1, 0x5d, 0x6c, 0x41, 0x1d, 0xb5, 0x2c, 0x07, 0x40, 0x77, 0x0b, 0x50}}},
{{{0x64, 0x34, 0xec, 0xc0, 0x9e, 0x44, 0x41, 0xaf, 0xa0, 0x36, 0x05, 0x6d, 0xea, 0x30, 0x25, 0x46, 0x35, 0x24, 0x9d, 0x86, 0xbd, 0x95, 0xf1, 0x6a, 0x46, 0xd7, 0x94, 0x54, 0xf9, 0x3b, 0xbd, 0x5d}} ,
{{0x77, 0x5b, 0xe2, 0x37, 0xc7, 0xe1, 0x7c, 0x13, 0x8c, 0x9f, 0x7b, 0x7b, 0x2a, 0xce, 0x42, 0xa3, 0xb9, 0x2a, 0x99, 0xa8, 0xc0, 0xd8, 0x3c, 0x86, 0xb0, 0xfb, 0xe9, 0x76, 0x77, 0xf7, 0xf5, 0x56}}},
{{{0xdf, 0xb3, 0x46, 0x11, 0x6e, 0x13, 0xb7, 0x28, 0x4e, 0x56, 0xdd, 0xf1, 0xac, 0xad, 0x58, 0xc3, 0xf8, 0x88, 0x94, 0x5e, 0x06, 0x98, 0xa1, 0xe4, 0x6a, 0xfb, 0x0a, 0x49, 0x5d, 0x8a, 0xfe, 0x77}} ,
{{0x46, 0x02, 0xf5, 0xa5, 0xaf, 0xc5, 0x75, 0x6d, 0xba, 0x45, 0x35, 0x0a, 0xfe, 0xc9, 0xac, 0x22, 0x91, 0x8d, 0x21, 0x95, 0x33, 0x03, 0xc0, 0x8a, 0x16, 0xf3, 0x39, 0xe0, 0x01, 0x0f, 0x53, 0x3c}}},
{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
{{{0x34, 0x75, 0x37, 0x1f, 0x34, 0x4e, 0xa9, 0x1d, 0x68, 0x67, 0xf8, 0x49, 0x98, 0x96, 0xfc, 0x4c, 0x65, 0x97, 0xf7, 0x02, 0x4a, 0x52, 0x6c, 0x01, 0xbd, 0x48, 0xbb, 0x1b, 0xed, 0xa4, 0xe2, 0x53}} ,
{{0x59, 0xd5, 0x9b, 0x5a, 0xa2, 0x90, 0xd3, 0xb8, 0x37, 0x4c, 0x55, 0x82, 0x28, 0x08, 0x0f, 0x7f, 0xaa, 0x81, 0x65, 0xe0, 0x0c, 0x52, 0xc9, 0xa3, 0x32, 0x27, 0x64, 0xda, 0xfd, 0x34, 0x23, 0x5a}}},
{{{0xb5, 0xb0, 0x0c, 0x4d, 0xb3, 0x7b, 0x23, 0xc8, 0x1f, 0x8a, 0x39, 0x66, 0xe6, 0xba, 0x4c, 0x10, 0x37, 0xca, 0x9c, 0x7c, 0x05, 0x9e, 0xff, 0xc0, 0xf8, 0x8e, 0xb1, 0x8f, 0x6f, 0x67, 0x18, 0x26}} ,
{{0x4b, 0x41, 0x13, 0x54, 0x23, 0x1a, 0xa4, 0x4e, 0xa9, 0x8b, 0x1e, 0x4b, 0xfc, 0x15, 0x24, 0xbb, 0x7e, 0xcb, 0xb6, 0x1e, 0x1b, 0xf5, 0xf2, 0xc8, 0x56, 0xec, 0x32, 0xa2, 0x60, 0x5b, 0xa0, 0x2a}}},
{{{0xa4, 0x29, 0x47, 0x86, 0x2e, 0x92, 0x4f, 0x11, 0x4f, 0xf3, 0xb2, 0x5c, 0xd5, 0x3e, 0xa6, 0xb9, 0xc8, 0xe2, 0x33, 0x11, 0x1f, 0x01, 0x8f, 0xb0, 0x9b, 0xc7, 0xa5, 0xff, 0x83, 0x0f, 0x1e, 0x28}} ,
{{0x1d, 0x29, 0x7a, 0xa1, 0xec, 0x8e, 0xb5, 0xad, 0xea, 0x02, 0x68, 0x60, 0x74, 0x29, 0x1c, 0xa5, 0xcf, 0xc8, 0x3b, 0x7d, 0x8b, 0x2b, 0x7c, 0xad, 0xa4, 0x40, 0x17, 0x51, 0x59, 0x7c, 0x2e, 0x5d}}},
{{{0x0a, 0x6c, 0x4f, 0xbc, 0x3e, 0x32, 0xe7, 0x4a, 0x1a, 0x13, 0xc1, 0x49, 0x38, 0xbf, 0xf7, 0xc2, 0xd3, 0x8f, 0x6b, 0xad, 0x52, 0xf7, 0xcf, 0xbc, 0x27, 0xcb, 0x40, 0x67, 0x76, 0xcd, 0x6d, 0x56}} ,
{{0xe5, 0xb0, 0x27, 0xad, 0xbe, 0x9b, 0xf2, 0xb5, 0x63, 0xde, 0x3a, 0x23, 0x95, 0xb7, 0x0a, 0x7e, 0xf3, 0x9e, 0x45, 0x6f, 0x19, 0x39, 0x75, 0x8f, 0x39, 0x3d, 0x0f, 0xc0, 0x9f, 0xf1, 0xe9, 0x51}}},
{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
{{{0x88, 0xaa, 0x14, 0x24, 0x86, 0x94, 0x11, 0x12, 0x3e, 0x1a, 0xb5, 0xcc, 0xbb, 0xe0, 0x9c, 0xd5, 0x9c, 0x6d, 0xba, 0x58, 0x72, 0x8d, 0xfb, 0x22, 0x7b, 0x9f, 0x7c, 0x94, 0x30, 0xb3, 0x51, 0x21}} ,
{{0xf6, 0x74, 0x3d, 0xf2, 0xaf, 0xd0, 0x1e, 0x03, 0x7c, 0x23, 0x6b, 0xc9, 0xfc, 0x25, 0x70, 0x90, 0xdc, 0x9a, 0xa4, 0xfb, 0x49, 0xfc, 0x3d, 0x0a, 0x35, 0x38, 0x6f, 0xe4, 0x7e, 0x50, 0x01, 0x2a}}},
{{{0xd6, 0xe3, 0x96, 0x61, 0x3a, 0xfd, 0xef, 0x9b, 0x1f, 0x90, 0xa4, 0x24, 0x14, 0x5b, 0xc8, 0xde, 0x50, 0xb1, 0x1d, 0xaf, 0xe8, 0x55, 0x8a, 0x87, 0x0d, 0xfe, 0xaa, 0x3b, 0x82, 0x2c, 0x8d, 0x7b}} ,
{{0x85, 0x0c, 0xaf, 0xf8, 0x83, 0x44, 0x49, 0xd9, 0x45, 0xcf, 0xf7, 0x48, 0xd9, 0x53, 0xb4, 0xf1, 0x65, 0xa0, 0xe1, 0xc3, 0xb3, 0x15, 0xed, 0x89, 0x9b, 0x4f, 0x62, 0xb3, 0x57, 0xa5, 0x45, 0x1c}}},
{{{0x8f, 0x12, 0xea, 0xaf, 0xd1, 0x1f, 0x79, 0x10, 0x0b, 0xf6, 0xa3, 0x7b, 0xea, 0xac, 0x8b, 0x57, 0x32, 0x62, 0xe7, 0x06, 0x12, 0x51, 0xa0, 0x3b, 0x43, 0x5e, 0xa4, 0x20, 0x78, 0x31, 0xce, 0x0d}} ,
{{0x84, 0x7c, 0xc2, 0xa6, 0x91, 0x23, 0xce, 0xbd, 0xdc, 0xf9, 0xce, 0xd5, 0x75, 0x30, 0x22, 0xe6, 0xf9, 0x43, 0x62, 0x0d, 0xf7, 0x75, 0x9d, 0x7f, 0x8c, 0xff, 0x7d, 0xe4, 0x72, 0xac, 0x9f, 0x1c}}},
{{{0x88, 0xc1, 0x99, 0xd0, 0x3c, 0x1c, 0x5d, 0xb4, 0xef, 0x13, 0x0f, 0x90, 0xb9, 0x36, 0x2f, 0x95, 0x95, 0xc6, 0xdc, 0xde, 0x0a, 0x51, 0xe2, 0x8d, 0xf3, 0xbc, 0x51, 0xec, 0xdf, 0xb1, 0xa2, 0x5f}} ,
{{0x2e, 0x68, 0xa1, 0x23, 0x7d, 0x9b, 0x40, 0x69, 0x85, 0x7b, 0x42, 0xbf, 0x90, 0x4b, 0xd6, 0x40, 0x2f, 0xd7, 0x52, 0x52, 0xb2, 0x21, 0xde, 0x64, 0xbd, 0x88, 0xc3, 0x6d, 0xa5, 0xfa, 0x81, 0x3f}}},
{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
{{{0xfb, 0xfd, 0x47, 0x7b, 0x8a, 0x66, 0x9e, 0x79, 0x2e, 0x64, 0x82, 0xef, 0xf7, 0x21, 0xec, 0xf6, 0xd8, 0x86, 0x09, 0x31, 0x7c, 0xdd, 0x03, 0x6a, 0x58, 0xa0, 0x77, 0xb7, 0x9b, 0x8c, 0x87, 0x1f}} ,
{{0x55, 0x47, 0xe4, 0xa8, 0x3d, 0x55, 0x21, 0x34, 0xab, 0x1d, 0xae, 0xe0, 0xf4, 0xea, 0xdb, 0xc5, 0xb9, 0x58, 0xbf, 0xc4, 0x2a, 0x89, 0x31, 0x1a, 0xf4, 0x2d, 0xe1, 0xca, 0x37, 0x99, 0x47, 0x59}}},
{{{0xc7, 0xca, 0x63, 0xc1, 0x49, 0xa9, 0x35, 0x45, 0x55, 0x7e, 0xda, 0x64, 0x32, 0x07, 0x50, 0xf7, 0x32, 0xac, 0xde, 0x75, 0x58, 0x9b, 0x11, 0xb2, 0x3a, 0x1f, 0xf5, 0xf7, 0x79, 0x04, 0xe6, 0x08}} ,
{{0x46, 0xfa, 0x22, 0x4b, 0xfa, 0xe1, 0xfe, 0x96, 0xfc, 0x67, 0xba, 0x67, 0x97, 0xc4, 0xe7, 0x1b, 0x86, 0x90, 0x5f, 0xee, 0xf4, 0x5b, 0x11, 0xb2, 0xcd, 0xad, 0xee, 0xc2, 0x48, 0x6c, 0x2b, 0x1b}}},
{{{0xe3, 0x39, 0x62, 0xb4, 0x4f, 0x31, 0x04, 0xc9, 0xda, 0xd5, 0x73, 0x51, 0x57, 0xc5, 0xb8, 0xf3, 0xa3, 0x43, 0x70, 0xe4, 0x61, 0x81, 0x84, 0xe2, 0xbb, 0xbf, 0x4f, 0x9e, 0xa4, 0x5e, 0x74, 0x06}} ,
{{0x29, 0xac, 0xff, 0x27, 0xe0, 0x59, 0xbe, 0x39, 0x9c, 0x0d, 0x83, 0xd7, 0x10, 0x0b, 0x15, 0xb7, 0xe1, 0xc2, 0x2c, 0x30, 0x73, 0x80, 0x3a, 0x7d, 0x5d, 0xab, 0x58, 0x6b, 0xc1, 0xf0, 0xf4, 0x22}}},
{{{0xfe, 0x7f, 0xfb, 0x35, 0x7d, 0xc6, 0x01, 0x23, 0x28, 0xc4, 0x02, 0xac, 0x1f, 0x42, 0xb4, 0x9d, 0xfc, 0x00, 0x94, 0xa5, 0xee, 0xca, 0xda, 0x97, 0x09, 0x41, 0x77, 0x87, 0x5d, 0x7b, 0x87, 0x78}} ,
{{0xf5, 0xfb, 0x90, 0x2d, 0x81, 0x19, 0x9e, 0x2f, 0x6d, 0x85, 0x88, 0x8c, 0x40, 0x5c, 0x77, 0x41, 0x4d, 0x01, 0x19, 0x76, 0x60, 0xe8, 0x4c, 0x48, 0xe4, 0x33, 0x83, 0x32, 0x6c, 0xb4, 0x41, 0x03}}},
{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
{{{0xff, 0x10, 0xc2, 0x09, 0x4f, 0x6e, 0xf4, 0xd2, 0xdf, 0x7e, 0xca, 0x7b, 0x1c, 0x1d, 0xba, 0xa3, 0xb6, 0xda, 0x67, 0x33, 0xd4, 0x87, 0x36, 0x4b, 0x11, 0x20, 0x05, 0xa6, 0x29, 0xc1, 0x87, 0x17}} ,
{{0xf6, 0x96, 0xca, 0x2f, 0xda, 0x38, 0xa7, 0x1b, 0xfc, 0xca, 0x7d, 0xfe, 0x08, 0x89, 0xe2, 0x47, 0x2b, 0x6a, 0x5d, 0x4b, 0xfa, 0xa1, 0xb4, 0xde, 0xb6, 0xc2, 0x31, 0x51, 0xf5, 0xe0, 0xa4, 0x0b}}},
{{{0x5c, 0xe5, 0xc6, 0x04, 0x8e, 0x2b, 0x57, 0xbe, 0x38, 0x85, 0x23, 0xcb, 0xb7, 0xbe, 0x4f, 0xa9, 0xd3, 0x6e, 0x12, 0xaa, 0xd5, 0xb2, 0x2e, 0x93, 0x29, 0x9a, 0x4a, 0x88, 0x18, 0x43, 0xf5, 0x01}} ,
{{0x50, 0xfc, 0xdb, 0xa2, 0x59, 0x21, 0x8d, 0xbd, 0x7e, 0x33, 0xae, 0x2f, 0x87, 0x1a, 0xd0, 0x97, 0xc7, 0x0d, 0x4d, 0x63, 0x01, 0xef, 0x05, 0x84, 0xec, 0x40, 0xdd, 0xa8, 0x0a, 0x4f, 0x70, 0x0b}}},
{{{0x41, 0x69, 0x01, 0x67, 0x5c, 0xd3, 0x8a, 0xc5, 0xcf, 0x3f, 0xd1, 0x57, 0xd1, 0x67, 0x3e, 0x01, 0x39, 0xb5, 0xcb, 0x81, 0x56, 0x96, 0x26, 0xb6, 0xc2, 0xe7, 0x5c, 0xfb, 0x63, 0x97, 0x58, 0x06}} ,
{{0x0c, 0x0e, 0xf3, 0xba, 0xf0, 0xe5, 0xba, 0xb2, 0x57, 0x77, 0xc6, 0x20, 0x9b, 0x89, 0x24, 0xbe, 0xf2, 0x9c, 0x8a, 0xba, 0x69, 0xc1, 0xf1, 0xb0, 0x4f, 0x2a, 0x05, 0x9a, 0xee, 0x10, 0x7e, 0x36}}},
{{{0x3f, 0x26, 0xe9, 0x40, 0xe9, 0x03, 0xad, 0x06, 0x69, 0x91, 0xe0, 0xd1, 0x89, 0x60, 0x84, 0x79, 0xde, 0x27, 0x6d, 0xe6, 0x76, 0xbd, 0xea, 0xe6, 0xae, 0x48, 0xc3, 0x67, 0xc0, 0x57, 0xcd, 0x2f}} ,
{{0x7f, 0xc1, 0xdc, 0xb9, 0xc7, 0xbc, 0x86, 0x3d, 0x55, 0x4b, 0x28, 0x7a, 0xfb, 0x4d, 0xc7, 0xf8, 0xbc, 0x67, 0x2a, 0x60, 0x4d, 0x8f, 0x07, 0x0b, 0x1a, 0x17, 0xbf, 0xfa, 0xac, 0xa7, 0x3d, 0x1a}}},
{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
{{{0x91, 0x3f, 0xed, 0x5e, 0x18, 0x78, 0x3f, 0x23, 0x2c, 0x0d, 0x8c, 0x44, 0x00, 0xe8, 0xfb, 0xe9, 0x8e, 0xd6, 0xd1, 0x36, 0x58, 0x57, 0x9e, 0xae, 0x4b, 0x5c, 0x0b, 0x07, 0xbc, 0x6b, 0x55, 0x2b}} ,
{{0x6f, 0x4d, 0x17, 0xd7, 0xe1, 0x84, 0xd9, 0x78, 0xb1, 0x90, 0xfd, 0x2e, 0xb3, 0xb5, 0x19, 0x3f, 0x1b, 0xfa, 0xc0, 0x68, 0xb3, 0xdd, 0x00, 0x2e, 0x89, 0xbd, 0x7e, 0x80, 0x32, 0x13, 0xa0, 0x7b}}},
{{{0x1a, 0x6f, 0x40, 0xaf, 0x44, 0x44, 0xb0, 0x43, 0x8f, 0x0d, 0xd0, 0x1e, 0xc4, 0x0b, 0x19, 0x5d, 0x8e, 0xfe, 0xc1, 0xf3, 0xc5, 0x5c, 0x91, 0xf8, 0x04, 0x4e, 0xbe, 0x90, 0xb4, 0x47, 0x5c, 0x3f}} ,
{{0xb0, 0x3b, 0x2c, 0xf3, 0xfe, 0x32, 0x71, 0x07, 0x3f, 0xaa, 0xba, 0x45, 0x60, 0xa8, 0x8d, 0xea, 0x54, 0xcb, 0x39, 0x10, 0xb4, 0xf2, 0x8b, 0xd2, 0x14, 0x82, 0x42, 0x07, 0x8e, 0xe9, 0x7c, 0x53}}},
{{{0xb0, 0xae, 0xc1, 0x8d, 0xc9, 0x8f, 0xb9, 0x7a, 0x77, 0xef, 0xba, 0x79, 0xa0, 0x3c, 0xa8, 0xf5, 0x6a, 0xe2, 0x3f, 0x5d, 0x00, 0xe3, 0x4b, 0x45, 0x24, 0x7b, 0x43, 0x78, 0x55, 0x1d, 0x2b, 0x1e}} ,
{{0x01, 0xb8, 0xd6, 0x16, 0x67, 0xa0, 0x15, 0xb9, 0xe1, 0x58, 0xa4, 0xa7, 0x31, 0x37, 0x77, 0x2f, 0x8b, 0x12, 0x9f, 0xf4, 0x3f, 0xc7, 0x36, 0x66, 0xd2, 0xa8, 0x56, 0xf7, 0x7f, 0x74, 0xc6, 0x41}}},
{{{0x5d, 0xf8, 0xb4, 0xa8, 0x30, 0xdd, 0xcc, 0x38, 0xa5, 0xd3, 0xca, 0xd8, 0xd1, 0xf8, 0xb2, 0x31, 0x91, 0xd4, 0x72, 0x05, 0x57, 0x4a, 0x3b, 0x82, 0x4a, 0xc6, 0x68, 0x20, 0xe2, 0x18, 0x41, 0x61}} ,
{{0x19, 0xd4, 0x8d, 0x47, 0x29, 0x12, 0x65, 0xb0, 0x11, 0x78, 0x47, 0xb5, 0xcb, 0xa3, 0xa5, 0xfa, 0x05, 0x85, 0x54, 0xa9, 0x33, 0x97, 0x8d, 0x2b, 0xc2, 0xfe, 0x99, 0x35, 0x28, 0xe5, 0xeb, 0x63}}},
{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
{{{0xb1, 0x3f, 0x3f, 0xef, 0xd8, 0xf4, 0xfc, 0xb3, 0xa0, 0x60, 0x50, 0x06, 0x2b, 0x29, 0x52, 0x70, 0x15, 0x0b, 0x24, 0x24, 0xf8, 0x5f, 0x79, 0x18, 0xcc, 0xff, 0x89, 0x99, 0x84, 0xa1, 0xae, 0x13}} ,
{{0x44, 0x1f, 0xb8, 0xc2, 0x01, 0xc1, 0x30, 0x19, 0x55, 0x05, 0x60, 0x10, 0xa4, 0x6c, 0x2d, 0x67, 0x70, 0xe5, 0x25, 0x1b, 0xf2, 0xbf, 0xdd, 0xfb, 0x70, 0x2b, 0xa1, 0x8c, 0x9c, 0x94, 0x84, 0x08}}},
{{{0xe7, 0xc4, 0x43, 0x4d, 0xc9, 0x2b, 0x69, 0x5d, 0x1d, 0x3c, 0xaf, 0xbb, 0x43, 0x38, 0x4e, 0x98, 0x3d, 0xed, 0x0d, 0x21, 0x03, 0xfd, 0xf0, 0x99, 0x47, 0x04, 0xb0, 0x98, 0x69, 0x55, 0x72, 0x0f}} ,
{{0x5e, 0xdf, 0x15, 0x53, 0x3b, 0x86, 0x80, 0xb0, 0xf1, 0x70, 0x68, 0x8f, 0x66, 0x7c, 0x0e, 0x49, 0x1a, 0xd8, 0x6b, 0xfe, 0x4e, 0xef, 0xca, 0x47, 0xd4, 0x03, 0xc1, 0x37, 0x50, 0x9c, 0xc1, 0x16}}},
{{{0xcd, 0x24, 0xc6, 0x3e, 0x0c, 0x82, 0x9b, 0x91, 0x2b, 0x61, 0x4a, 0xb2, 0x0f, 0x88, 0x55, 0x5f, 0x5a, 0x57, 0xff, 0xe5, 0x74, 0x0b, 0x13, 0x43, 0x00, 0xd8, 0x6b, 0xcf, 0xd2, 0x15, 0x03, 0x2c}} ,
{{0xdc, 0xff, 0x15, 0x61, 0x2f, 0x4a, 0x2f, 0x62, 0xf2, 0x04, 0x2f, 0xb5, 0x0c, 0xb7, 0x1e, 0x3f, 0x74, 0x1a, 0x0f, 0xd7, 0xea, 0xcd, 0xd9, 0x7d, 0xf6, 0x12, 0x0e, 0x2f, 0xdb, 0x5a, 0x3b, 0x16}}},
{{{0x1b, 0x37, 0x47, 0xe3, 0xf5, 0x9e, 0xea, 0x2c, 0x2a, 0xe7, 0x82, 0x36, 0xf4, 0x1f, 0x81, 0x47, 0x92, 0x4b, 0x69, 0x0e, 0x11, 0x8c, 0x5d, 0x53, 0x5b, 0x81, 0x27, 0x08, 0xbc, 0xa0, 0xae, 0x25}} ,
{{0x69, 0x32, 0xa1, 0x05, 0x11, 0x42, 0x00, 0xd2, 0x59, 0xac, 0x4d, 0x62, 0x8b, 0x13, 0xe2, 0x50, 0x5d, 0xa0, 0x9d, 0x9b, 0xfd, 0xbb, 0x12, 0x41, 0x75, 0x41, 0x9e, 0xcc, 0xdc, 0xc7, 0xdc, 0x5d}}},
{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
{{{0xd9, 0xe3, 0x38, 0x06, 0x46, 0x70, 0x82, 0x5e, 0x28, 0x49, 0x79, 0xff, 0x25, 0xd2, 0x4e, 0x29, 0x8d, 0x06, 0xb0, 0x23, 0xae, 0x9b, 0x66, 0xe4, 0x7d, 0xc0, 0x70, 0x91, 0xa3, 0xfc, 0xec, 0x4e}} ,
{{0x62, 0x12, 0x37, 0x6a, 0x30, 0xf6, 0x1e, 0xfb, 0x14, 0x5c, 0x0d, 0x0e, 0xb7, 0x81, 0x6a, 0xe7, 0x08, 0x05, 0xac, 0xaa, 0x38, 0x46, 0xe2, 0x73, 0xea, 0x4b, 0x07, 0x81, 0x43, 0x7c, 0x9e, 0x5e}}},
{{{0xfc, 0xf9, 0x21, 0x4f, 0x2e, 0x76, 0x9b, 0x1f, 0x28, 0x60, 0x77, 0x43, 0x32, 0x9d, 0xbe, 0x17, 0x30, 0x2a, 0xc6, 0x18, 0x92, 0x66, 0x62, 0x30, 0x98, 0x40, 0x11, 0xa6, 0x7f, 0x18, 0x84, 0x28}} ,
{{0x3f, 0xab, 0xd3, 0xf4, 0x8a, 0x76, 0xa1, 0x3c, 0xca, 0x2d, 0x49, 0xc3, 0xea, 0x08, 0x0b, 0x85, 0x17, 0x2a, 0xc3, 0x6c, 0x08, 0xfd, 0x57, 0x9f, 0x3d, 0x5f, 0xdf, 0x67, 0x68, 0x42, 0x00, 0x32}}},
{{{0x51, 0x60, 0x1b, 0x06, 0x4f, 0x8a, 0x21, 0xba, 0x38, 0xa8, 0xba, 0xd6, 0x40, 0xf6, 0xe9, 0x9b, 0x76, 0x4d, 0x56, 0x21, 0x5b, 0x0a, 0x9b, 0x2e, 0x4f, 0x3d, 0x81, 0x32, 0x08, 0x9f, 0x97, 0x5b}} ,
{{0xe5, 0x44, 0xec, 0x06, 0x9d, 0x90, 0x79, 0x9f, 0xd3, 0xe0, 0x79, 0xaf, 0x8f, 0x10, 0xfd, 0xdd, 0x04, 0xae, 0x27, 0x97, 0x46, 0x33, 0x79, 0xea, 0xb8, 0x4e, 0xca, 0x5a, 0x59, 0x57, 0xe1, 0x0e}}},
{{{0x1a, 0xda, 0xf3, 0xa5, 0x41, 0x43, 0x28, 0xfc, 0x7e, 0xe7, 0x71, 0xea, 0xc6, 0x3b, 0x59, 0xcc, 0x2e, 0xd3, 0x40, 0xec, 0xb3, 0x13, 0x6f, 0x44, 0xcd, 0x13, 0xb2, 0x37, 0xf2, 0x6e, 0xd9, 0x1c}} ,
{{0xe3, 0xdb, 0x60, 0xcd, 0x5c, 0x4a, 0x18, 0x0f, 0xef, 0x73, 0x36, 0x71, 0x8c, 0xf6, 0x11, 0xb4, 0xd8, 0xce, 0x17, 0x5e, 0x4f, 0x26, 0x77, 0x97, 0x5f, 0xcb, 0xef, 0x91, 0xeb, 0x6a, 0x62, 0x7a}}},
{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
{{{0x18, 0x4a, 0xa2, 0x97, 0x08, 0x81, 0x2d, 0x83, 0xc4, 0xcc, 0xf0, 0x83, 0x7e, 0xec, 0x0d, 0x95, 0x4c, 0x5b, 0xfb, 0xfa, 0x98, 0x80, 0x4a, 0x66, 0x56, 0x0c, 0x51, 0xb3, 0xf2, 0x04, 0x5d, 0x27}} ,
{{0x3b, 0xb9, 0xb8, 0x06, 0x5a, 0x2e, 0xfe, 0xc3, 0x82, 0x37, 0x9c, 0xa3, 0x11, 0x1f, 0x9c, 0xa6, 0xda, 0x63, 0x48, 0x9b, 0xad, 0xde, 0x2d, 0xa6, 0xbc, 0x6e, 0x32, 0xda, 0x27, 0x65, 0xdd, 0x57}}},
{{{0x84, 0x4f, 0x37, 0x31, 0x7d, 0x2e, 0xbc, 0xad, 0x87, 0x07, 0x2a, 0x6b, 0x37, 0xfc, 0x5f, 0xeb, 0x4e, 0x75, 0x35, 0xa6, 0xde, 0xab, 0x0a, 0x19, 0x3a, 0xb7, 0xb1, 0xef, 0x92, 0x6a, 0x3b, 0x3c}} ,
{{0x3b, 0xb2, 0x94, 0x6d, 0x39, 0x60, 0xac, 0xee, 0xe7, 0x81, 0x1a, 0x3b, 0x76, 0x87, 0x5c, 0x05, 0x94, 0x2a, 0x45, 0xb9, 0x80, 0xe9, 0x22, 0xb1, 0x07, 0xcb, 0x40, 0x9e, 0x70, 0x49, 0x6d, 0x12}}},
{{{0xfd, 0x18, 0x78, 0x84, 0xa8, 0x4c, 0x7d, 0x6e, 0x59, 0xa6, 0xe5, 0x74, 0xf1, 0x19, 0xa6, 0x84, 0x2e, 0x51, 0xc1, 0x29, 0x13, 0xf2, 0x14, 0x6b, 0x5d, 0x53, 0x51, 0xf7, 0xef, 0xbf, 0x01, 0x22}} ,
{{0xa4, 0x4b, 0x62, 0x4c, 0xe6, 0xfd, 0x72, 0x07, 0xf2, 0x81, 0xfc, 0xf2, 0xbd, 0x12, 0x7c, 0x68, 0x76, 0x2a, 0xba, 0xf5, 0x65, 0xb1, 0x1f, 0x17, 0x0a, 0x38, 0xb0, 0xbf, 0xc0, 0xf8, 0xf4, 0x2a}}},
{{{0x55, 0x60, 0x55, 0x5b, 0xe4, 0x1d, 0x71, 0x4c, 0x9d, 0x5b, 0x9f, 0x70, 0xa6, 0x85, 0x9a, 0x2c, 0xa0, 0xe2, 0x32, 0x48, 0xce, 0x9e, 0x2a, 0xa5, 0x07, 0x3b, 0xc7, 0x6c, 0x86, 0x77, 0xde, 0x3c}} ,
{{0xf7, 0x18, 0x7a, 0x96, 0x7e, 0x43, 0x57, 0xa9, 0x55, 0xfc, 0x4e, 0xb6, 0x72, 0x00, 0xf2, 0xe4, 0xd7, 0x52, 0xd3, 0xd3, 0xb6, 0x85, 0xf6, 0x71, 0xc7, 0x44, 0x3f, 0x7f, 0xd7, 0xb3, 0xf2, 0x79}}},
{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
{{{0x46, 0xca, 0xa7, 0x55, 0x7b, 0x79, 0xf3, 0xca, 0x5a, 0x65, 0xf6, 0xed, 0x50, 0x14, 0x7b, 0xe4, 0xc4, 0x2a, 0x65, 0x9e, 0xe2, 0xf9, 0xca, 0xa7, 0x22, 0x26, 0x53, 0xcb, 0x21, 0x5b, 0xa7, 0x31}} ,
{{0x90, 0xd7, 0xc5, 0x26, 0x08, 0xbd, 0xb0, 0x53, 0x63, 0x58, 0xc3, 0x31, 0x5e, 0x75, 0x46, 0x15, 0x91, 0xa6, 0xf8, 0x2f, 0x1a, 0x08, 0x65, 0x88, 0x2f, 0x98, 0x04, 0xf1, 0x7c, 0x6e, 0x00, 0x77}}},
{{{0x81, 0x21, 0x61, 0x09, 0xf6, 0x4e, 0xf1, 0x92, 0xee, 0x63, 0x61, 0x73, 0x87, 0xc7, 0x54, 0x0e, 0x42, 0x4b, 0xc9, 0x47, 0xd1, 0xb8, 0x7e, 0x91, 0x75, 0x37, 0x99, 0x28, 0xb8, 0xdd, 0x7f, 0x50}} ,
{{0x89, 0x8f, 0xc0, 0xbe, 0x5d, 0xd6, 0x9f, 0xa0, 0xf0, 0x9d, 0x81, 0xce, 0x3a, 0x7b, 0x98, 0x58, 0xbb, 0xd7, 0x78, 0xc8, 0x3f, 0x13, 0xf1, 0x74, 0x19, 0xdf, 0xf8, 0x98, 0x89, 0x5d, 0xfa, 0x5f}}},
{{{0x9e, 0x35, 0x85, 0x94, 0x47, 0x1f, 0x90, 0x15, 0x26, 0xd0, 0x84, 0xed, 0x8a, 0x80, 0xf7, 0x63, 0x42, 0x86, 0x27, 0xd7, 0xf4, 0x75, 0x58, 0xdc, 0x9c, 0xc0, 0x22, 0x7e, 0x20, 0x35, 0xfd, 0x1f}} ,
{{0x68, 0x0e, 0x6f, 0x97, 0xba, 0x70, 0xbb, 0xa3, 0x0e, 0xe5, 0x0b, 0x12, 0xf4, 0xa2, 0xdc, 0x47, 0xf8, 0xe6, 0xd0, 0x23, 0x6c, 0x33, 0xa8, 0x99, 0x46, 0x6e, 0x0f, 0x44, 0xba, 0x76, 0x48, 0x0f}}},
{{{0xa3, 0x2a, 0x61, 0x37, 0xe2, 0x59, 0x12, 0x0e, 0x27, 0xba, 0x64, 0x43, 0xae, 0xc0, 0x42, 0x69, 0x79, 0xa4, 0x1e, 0x29, 0x8b, 0x15, 0xeb, 0xf8, 0xaf, 0xd4, 0xa2, 0x68, 0x33, 0xb5, 0x7a, 0x24}} ,
{{0x2c, 0x19, 0x33, 0xdd, 0x1b, 0xab, 0xec, 0x01, 0xb0, 0x23, 0xf8, 0x42, 0x2b, 0x06, 0x88, 0xea, 0x3d, 0x2d, 0x00, 0x2a, 0x78, 0x45, 0x4d, 0x38, 0xed, 0x2e, 0x2e, 0x44, 0x49, 0xed, 0xcb, 0x33}}},
{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
{{{0xa0, 0x68, 0xe8, 0x41, 0x8f, 0x91, 0xf8, 0x11, 0x13, 0x90, 0x2e, 0xa7, 0xab, 0x30, 0xef, 0xad, 0xa0, 0x61, 0x00, 0x88, 0xef, 0xdb, 0xce, 0x5b, 0x5c, 0xbb, 0x62, 0xc8, 0x56, 0xf9, 0x00, 0x73}} ,
{{0x3f, 0x60, 0xc1, 0x82, 0x2d, 0xa3, 0x28, 0x58, 0x24, 0x9e, 0x9f, 0xe3, 0x70, 0xcc, 0x09, 0x4e, 0x1a, 0x3f, 0x11, 0x11, 0x15, 0x07, 0x3c, 0xa4, 0x41, 0xe0, 0x65, 0xa3, 0x0a, 0x41, 0x6d, 0x11}}},
{{{0x31, 0x40, 0x01, 0x52, 0x56, 0x94, 0x5b, 0x28, 0x8a, 0xaa, 0x52, 0xee, 0xd8, 0x0a, 0x05, 0x8d, 0xcd, 0xb5, 0xaa, 0x2e, 0x38, 0xaa, 0xb7, 0x87, 0xf7, 0x2b, 0xfb, 0x04, 0xcb, 0x84, 0x3d, 0x54}} ,
{{0x20, 0xef, 0x59, 0xde, 0xa4, 0x2b, 0x93, 0x6e, 0x2e, 0xec, 0x42, 0x9a, 0xd4, 0x2d, 0xf4, 0x46, 0x58, 0x27, 0x2b, 0x18, 0x8f, 0x83, 0x3d, 0x69, 0x9e, 0xd4, 0x3e, 0xb6, 0xc5, 0xfd, 0x58, 0x03}}},
{{{0x33, 0x89, 0xc9, 0x63, 0x62, 0x1c, 0x17, 0xb4, 0x60, 0xc4, 0x26, 0x68, 0x09, 0xc3, 0x2e, 0x37, 0x0f, 0x7b, 0xb4, 0x9c, 0xb6, 0xf9, 0xfb, 0xd4, 0x51, 0x78, 0xc8, 0x63, 0xea, 0x77, 0x47, 0x07}} ,
{{0x32, 0xb4, 0x18, 0x47, 0x79, 0xcb, 0xd4, 0x5a, 0x07, 0x14, 0x0f, 0xa0, 0xd5, 0xac, 0xd0, 0x41, 0x40, 0xab, 0x61, 0x23, 0xe5, 0x2a, 0x2a, 0x6f, 0xf7, 0xa8, 0xd4, 0x76, 0xef, 0xe7, 0x45, 0x6c}}},
{{{0xa1, 0x5e, 0x60, 0x4f, 0xfb, 0xe1, 0x70, 0x6a, 0x1f, 0x55, 0x4f, 0x09, 0xb4, 0x95, 0x33, 0x36, 0xc6, 0x81, 0x01, 0x18, 0x06, 0x25, 0x27, 0xa4, 0xb4, 0x24, 0xa4, 0x86, 0x03, 0x4c, 0xac, 0x02}} ,
{{0x77, 0x38, 0xde, 0xd7, 0x60, 0x48, 0x07, 0xf0, 0x74, 0xa8, 0xff, 0x54, 0xe5, 0x30, 0x43, 0xff, 0x77, 0xfb, 0x21, 0x07, 0xff, 0xb2, 0x07, 0x6b, 0xe4, 0xe5, 0x30, 0xfc, 0x19, 0x6c, 0xa3, 0x01}}},
{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
{{{0x13, 0xc5, 0x2c, 0xac, 0xd3, 0x83, 0x82, 0x7c, 0x29, 0xf7, 0x05, 0xa5, 0x00, 0xb6, 0x1f, 0x86, 0x55, 0xf4, 0xd6, 0x2f, 0x0c, 0x99, 0xd0, 0x65, 0x9b, 0x6b, 0x46, 0x0d, 0x43, 0xf8, 0x16, 0x28}} ,
{{0x1e, 0x7f, 0xb4, 0x74, 0x7e, 0xb1, 0x89, 0x4f, 0x18, 0x5a, 0xab, 0x64, 0x06, 0xdf, 0x45, 0x87, 0xe0, 0x6a, 0xc6, 0xf0, 0x0e, 0xc9, 0x24, 0x35, 0x38, 0xea, 0x30, 0x54, 0xb4, 0xc4, 0x52, 0x54}}},
{{{0xe9, 0x9f, 0xdc, 0x3f, 0xc1, 0x89, 0x44, 0x74, 0x27, 0xe4, 0xc1, 0x90, 0xff, 0x4a, 0xa7, 0x3c, 0xee, 0xcd, 0xf4, 0x1d, 0x25, 0x94, 0x7f, 0x63, 0x16, 0x48, 0xbc, 0x64, 0xfe, 0x95, 0xc4, 0x0c}} ,
{{0x8b, 0x19, 0x75, 0x6e, 0x03, 0x06, 0x5e, 0x6a, 0x6f, 0x1a, 0x8c, 0xe3, 0xd3, 0x28, 0xf2, 0xe0, 0xb9, 0x7a, 0x43, 0x69, 0xe6, 0xd3, 0xc0, 0xfe, 0x7e, 0x97, 0xab, 0x6c, 0x7b, 0x8e, 0x13, 0x42}}},
{{{0xd4, 0xca, 0x70, 0x3d, 0xab, 0xfb, 0x5f, 0x5e, 0x00, 0x0c, 0xcc, 0x77, 0x22, 0xf8, 0x78, 0x55, 0xae, 0x62, 0x35, 0xfb, 0x9a, 0xc6, 0x03, 0xe4, 0x0c, 0xee, 0xab, 0xc7, 0xc0, 0x89, 0x87, 0x54}} ,
{{0x32, 0xad, 0xae, 0x85, 0x58, 0x43, 0xb8, 0xb1, 0xe6, 0x3e, 0x00, 0x9c, 0x78, 0x88, 0x56, 0xdb, 0x9c, 0xfc, 0x79, 0xf6, 0xf9, 0x41, 0x5f, 0xb7, 0xbc, 0x11, 0xf9, 0x20, 0x36, 0x1c, 0x53, 0x2b}}},
{{{0x5a, 0x20, 0x5b, 0xa1, 0xa5, 0x44, 0x91, 0x24, 0x02, 0x63, 0x12, 0x64, 0xb8, 0x55, 0xf6, 0xde, 0x2c, 0xdb, 0x47, 0xb8, 0xc6, 0x0a, 0xc3, 0x00, 0x78, 0x93, 0xd8, 0xf5, 0xf5, 0x18, 0x28, 0x0a}} ,
{{0xd6, 0x1b, 0x9a, 0x6c, 0xe5, 0x46, 0xea, 0x70, 0x96, 0x8d, 0x4e, 0x2a, 0x52, 0x21, 0x26, 0x4b, 0xb1, 0xbb, 0x0f, 0x7c, 0xa9, 0x9b, 0x04, 0xbb, 0x51, 0x08, 0xf1, 0x9a, 0xa4, 0x76, 0x7c, 0x18}}},
{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
{{{0xfa, 0x94, 0xf7, 0x40, 0xd0, 0xd7, 0xeb, 0xa9, 0x82, 0x36, 0xd5, 0x15, 0xb9, 0x33, 0x7a, 0xbf, 0x8a, 0xf2, 0x63, 0xaa, 0x37, 0xf5, 0x59, 0xac, 0xbd, 0xbb, 0x32, 0x36, 0xbe, 0x73, 0x99, 0x38}} ,
{{0x2c, 0xb3, 0xda, 0x7a, 0xd8, 0x3d, 0x99, 0xca, 0xd2, 0xf4, 0xda, 0x99, 0x8e, 0x4f, 0x98, 0xb7, 0xf4, 0xae, 0x3e, 0x9f, 0x8e, 0x35, 0x60, 0xa4, 0x33, 0x75, 0xa4, 0x04, 0x93, 0xb1, 0x6b, 0x4d}}},
{{{0x97, 0x9d, 0xa8, 0xcd, 0x97, 0x7b, 0x9d, 0xb9, 0xe7, 0xa5, 0xef, 0xfd, 0xa8, 0x42, 0x6b, 0xc3, 0x62, 0x64, 0x7d, 0xa5, 0x1b, 0xc9, 0x9e, 0xd2, 0x45, 0xb9, 0xee, 0x03, 0xb0, 0xbf, 0xc0, 0x68}} ,
{{0xed, 0xb7, 0x84, 0x2c, 0xf6, 0xd3, 0xa1, 0x6b, 0x24, 0x6d, 0x87, 0x56, 0x97, 0x59, 0x79, 0x62, 0x9f, 0xac, 0xed, 0xf3, 0xc9, 0x89, 0x21, 0x2e, 0x04, 0xb3, 0xcc, 0x2f, 0xbe, 0xd6, 0x0a, 0x4b}}},
{{{0x39, 0x61, 0x05, 0xed, 0x25, 0x89, 0x8b, 0x5d, 0x1b, 0xcb, 0x0c, 0x55, 0xf4, 0x6a, 0x00, 0x8a, 0x46, 0xe8, 0x1e, 0xc6, 0x83, 0xc8, 0x5a, 0x76, 0xdb, 0xcc, 0x19, 0x7a, 0xcc, 0x67, 0x46, 0x0b}} ,
{{0x53, 0xcf, 0xc2, 0xa1, 0xad, 0x6a, 0xf3, 0xcd, 0x8f, 0xc9, 0xde, 0x1c, 0xf8, 0x6c, 0x8f, 0xf8, 0x76, 0x42, 0xe7, 0xfe, 0xb2, 0x72, 0x21, 0x0a, 0x66, 0x74, 0x8f, 0xb7, 0xeb, 0xe4, 0x6f, 0x01}}},
{{{0x22, 0x8c, 0x6b, 0xbe, 0xfc, 0x4d, 0x70, 0x62, 0x6e, 0x52, 0x77, 0x99, 0x88, 0x7e, 0x7b, 0x57, 0x7a, 0x0d, 0xfe, 0xdc, 0x72, 0x92, 0xf1, 0x68, 0x1d, 0x97, 0xd7, 0x7c, 0x8d, 0x53, 0x10, 0x37}} ,
{{0x53, 0x88, 0x77, 0x02, 0xca, 0x27, 0xa8, 0xe5, 0x45, 0xe2, 0xa8, 0x48, 0x2a, 0xab, 0x18, 0xca, 0xea, 0x2d, 0x2a, 0x54, 0x17, 0x37, 0x32, 0x09, 0xdc, 0xe0, 0x4a, 0xb7, 0x7d, 0x82, 0x10, 0x7d}}},
{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
{{{0x8a, 0x64, 0x1e, 0x14, 0x0a, 0x57, 0xd4, 0xda, 0x5c, 0x96, 0x9b, 0x01, 0x4c, 0x67, 0xbf, 0x8b, 0x30, 0xfe, 0x08, 0xdb, 0x0d, 0xd5, 0xa8, 0xd7, 0x09, 0x11, 0x85, 0xa2, 0xd3, 0x45, 0xfb, 0x7e}} ,
{{0xda, 0x8c, 0xc2, 0xd0, 0xac, 0x18, 0xe8, 0x52, 0x36, 0xd4, 0x21, 0xa3, 0xdd, 0x57, 0x22, 0x79, 0xb7, 0xf8, 0x71, 0x9d, 0xc6, 0x91, 0x70, 0x86, 0x56, 0xbf, 0xa1, 0x11, 0x8b, 0x19, 0xe1, 0x0f}}},
{{{0x18, 0x32, 0x98, 0x2c, 0x8f, 0x91, 0xae, 0x12, 0xf0, 0x8c, 0xea, 0xf3, 0x3c, 0xb9, 0x5d, 0xe4, 0x69, 0xed, 0xb2, 0x47, 0x18, 0xbd, 0xce, 0x16, 0x52, 0x5c, 0x23, 0xe2, 0xa5, 0x25, 0x52, 0x5d}} ,
{{0xb9, 0xb1, 0xe7, 0x5d, 0x4e, 0xbc, 0xee, 0xbb, 0x40, 0x81, 0x77, 0x82, 0x19, 0xab, 0xb5, 0xc6, 0xee, 0xab, 0x5b, 0x6b, 0x63, 0x92, 0x8a, 0x34, 0x8d, 0xcd, 0xee, 0x4f, 0x49, 0xe5, 0xc9, 0x7e}}},
{{{0x21, 0xac, 0x8b, 0x22, 0xcd, 0xc3, 0x9a, 0xe9, 0x5e, 0x78, 0xbd, 0xde, 0xba, 0xad, 0xab, 0xbf, 0x75, 0x41, 0x09, 0xc5, 0x58, 0xa4, 0x7d, 0x92, 0xb0, 0x7f, 0xf2, 0xa1, 0xd1, 0xc0, 0xb3, 0x6d}} ,
{{0x62, 0x4f, 0xd0, 0x75, 0x77, 0xba, 0x76, 0x77, 0xd7, 0xb8, 0xd8, 0x92, 0x6f, 0x98, 0x34, 0x3d, 0xd6, 0x4e, 0x1c, 0x0f, 0xf0, 0x8f, 0x2e, 0xf1, 0xb3, 0xbd, 0xb1, 0xb9, 0xec, 0x99, 0xb4, 0x07}}},
{{{0x60, 0x57, 0x2e, 0x9a, 0x72, 0x1d, 0x6b, 0x6e, 0x58, 0x33, 0x24, 0x8c, 0x48, 0x39, 0x46, 0x8e, 0x89, 0x6a, 0x88, 0x51, 0x23, 0x62, 0xb5, 0x32, 0x09, 0x36, 0xe3, 0x57, 0xf5, 0x98, 0xde, 0x6f}} ,
{{0x8b, 0x2c, 0x00, 0x48, 0x4a, 0xf9, 0x5b, 0x87, 0x69, 0x52, 0xe5, 0x5b, 0xd1, 0xb1, 0xe5, 0x25, 0x25, 0xe0, 0x9c, 0xc2, 0x13, 0x44, 0xe8, 0xb9, 0x0a, 0x70, 0xad, 0xbd, 0x0f, 0x51, 0x94, 0x69}}},
{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
{{{0xa2, 0xdc, 0xab, 0xa9, 0x25, 0x2d, 0xac, 0x5f, 0x03, 0x33, 0x08, 0xe7, 0x7e, 0xfe, 0x95, 0x36, 0x3c, 0x5b, 0x3a, 0xd3, 0x05, 0x82, 0x1c, 0x95, 0x2d, 0xd8, 0x77, 0x7e, 0x02, 0xd9, 0x5b, 0x70}} ,
{{0xc2, 0xfe, 0x1b, 0x0c, 0x67, 0xcd, 0xd6, 0xe0, 0x51, 0x8e, 0x2c, 0xe0, 0x79, 0x88, 0xf0, 0xcf, 0x41, 0x4a, 0xad, 0x23, 0xd4, 0x46, 0xca, 0x94, 0xa1, 0xc3, 0xeb, 0x28, 0x06, 0xfa, 0x17, 0x14}}},
{{{0x7b, 0xaa, 0x70, 0x0a, 0x4b, 0xfb, 0xf5, 0xbf, 0x80, 0xc5, 0xcf, 0x08, 0x7a, 0xdd, 0xa1, 0xf4, 0x9d, 0x54, 0x50, 0x53, 0x23, 0x77, 0x23, 0xf5, 0x34, 0xa5, 0x22, 0xd1, 0x0d, 0x96, 0x2e, 0x47}} ,
{{0xcc, 0xb7, 0x32, 0x89, 0x57, 0xd0, 0x98, 0x75, 0xe4, 0x37, 0x99, 0xa9, 0xe8, 0xba, 0xed, 0xba, 0xeb, 0xc7, 0x4f, 0x15, 0x76, 0x07, 0x0c, 0x4c, 0xef, 0x9f, 0x52, 0xfc, 0x04, 0x5d, 0x58, 0x10}}},
{{{0xce, 0x82, 0xf0, 0x8f, 0x79, 0x02, 0xa8, 0xd1, 0xda, 0x14, 0x09, 0x48, 0xee, 0x8a, 0x40, 0x98, 0x76, 0x60, 0x54, 0x5a, 0xde, 0x03, 0x24, 0xf5, 0xe6, 0x2f, 0xe1, 0x03, 0xbf, 0x68, 0x82, 0x7f}} ,
{{0x64, 0xe9, 0x28, 0xc7, 0xa4, 0xcf, 0x2a, 0xf9, 0x90, 0x64, 0x72, 0x2c, 0x8b, 0xeb, 0xec, 0xa0, 0xf2, 0x7d, 0x35, 0xb5, 0x90, 0x4d, 0x7f, 0x5b, 0x4a, 0x49, 0xe4, 0xb8, 0x3b, 0xc8, 0xa1, 0x2f}}},
{{{0x8b, 0xc5, 0xcc, 0x3d, 0x69, 0xa6, 0xa1, 0x18, 0x44, 0xbc, 0x4d, 0x77, 0x37, 0xc7, 0x86, 0xec, 0x0c, 0xc9, 0xd6, 0x44, 0xa9, 0x23, 0x27, 0xb9, 0x03, 0x34, 0xa7, 0x0a, 0xd5, 0xc7, 0x34, 0x37}} ,
{{0xf9, 0x7e, 0x3e, 0x66, 0xee, 0xf9, 0x99, 0x28, 0xff, 0xad, 0x11, 0xd8, 0xe2, 0x66, 0xc5, 0xcd, 0x0f, 0x0d, 0x0b, 0x6a, 0xfc, 0x7c, 0x24, 0xa8, 0x4f, 0xa8, 0x5e, 0x80, 0x45, 0x8b, 0x6c, 0x41}}},
{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
{{{0xef, 0x1e, 0xec, 0xf7, 0x8d, 0x77, 0xf2, 0xea, 0xdb, 0x60, 0x03, 0x21, 0xc0, 0xff, 0x5e, 0x67, 0xc3, 0x71, 0x0b, 0x21, 0xb4, 0x41, 0xa0, 0x68, 0x38, 0xc6, 0x01, 0xa3, 0xd3, 0x51, 0x3c, 0x3c}} ,
{{0x92, 0xf8, 0xd6, 0x4b, 0xef, 0x42, 0x13, 0xb2, 0x4a, 0xc4, 0x2e, 0x72, 0x3f, 0xc9, 0x11, 0xbd, 0x74, 0x02, 0x0e, 0xf5, 0x13, 0x9d, 0x83, 0x1a, 0x1b, 0xd5, 0x54, 0xde, 0xc4, 0x1e, 0x16, 0x6c}}},
{{{0x27, 0x52, 0xe4, 0x63, 0xaa, 0x94, 0xe6, 0xc3, 0x28, 0x9c, 0xc6, 0x56, 0xac, 0xfa, 0xb6, 0xbd, 0xe2, 0xcc, 0x76, 0xc6, 0x27, 0x27, 0xa2, 0x8e, 0x78, 0x2b, 0x84, 0x72, 0x10, 0xbd, 0x4e, 0x2a}} ,
{{0xea, 0xa7, 0x23, 0xef, 0x04, 0x61, 0x80, 0x50, 0xc9, 0x6e, 0xa5, 0x96, 0xd1, 0xd1, 0xc8, 0xc3, 0x18, 0xd7, 0x2d, 0xfd, 0x26, 0xbd, 0xcb, 0x7b, 0x92, 0x51, 0x0e, 0x4a, 0x65, 0x57, 0xb8, 0x49}}},
{{{0xab, 0x55, 0x36, 0xc3, 0xec, 0x63, 0x55, 0x11, 0x55, 0xf6, 0xa5, 0xc7, 0x01, 0x5f, 0xfe, 0x79, 0xd8, 0x0a, 0xf7, 0x03, 0xd8, 0x98, 0x99, 0xf5, 0xd0, 0x00, 0x54, 0x6b, 0x66, 0x28, 0xf5, 0x25}} ,
{{0x7a, 0x8d, 0xa1, 0x5d, 0x70, 0x5d, 0x51, 0x27, 0xee, 0x30, 0x65, 0x56, 0x95, 0x46, 0xde, 0xbd, 0x03, 0x75, 0xb4, 0x57, 0x59, 0x89, 0xeb, 0x02, 0x9e, 0xcc, 0x89, 0x19, 0xa7, 0xcb, 0x17, 0x67}}},
{{{0x6a, 0xeb, 0xfc, 0x9a, 0x9a, 0x10, 0xce, 0xdb, 0x3a, 0x1c, 0x3c, 0x6a, 0x9d, 0xea, 0x46, 0xbc, 0x45, 0x49, 0xac, 0xe3, 0x41, 0x12, 0x7c, 0xf0, 0xf7, 0x4f, 0xf9, 0xf7, 0xff, 0x2c, 0x89, 0x04}} ,
{{0x30, 0x31, 0x54, 0x1a, 0x46, 0xca, 0xe6, 0xc6, 0xcb, 0xe2, 0xc3, 0xc1, 0x8b, 0x75, 0x81, 0xbe, 0xee, 0xf8, 0xa3, 0x11, 0x1c, 0x25, 0xa3, 0xa7, 0x35, 0x51, 0x55, 0xe2, 0x25, 0xaa, 0xe2, 0x3a}}},
{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
{{{0xb4, 0x48, 0x10, 0x9f, 0x8a, 0x09, 0x76, 0xfa, 0xf0, 0x7a, 0xb0, 0x70, 0xf7, 0x83, 0x80, 0x52, 0x84, 0x2b, 0x26, 0xa2, 0xc4, 0x5d, 0x4f, 0xba, 0xb1, 0xc8, 0x40, 0x0d, 0x78, 0x97, 0xc4, 0x60}} ,
{{0xd4, 0xb1, 0x6c, 0x08, 0xc7, 0x40, 0x38, 0x73, 0x5f, 0x0b, 0xf3, 0x76, 0x5d, 0xb2, 0xa5, 0x2f, 0x57, 0x57, 0x07, 0xed, 0x08, 0xa2, 0x6c, 0x4f, 0x08, 0x02, 0xb5, 0x0e, 0xee, 0x44, 0xfa, 0x22}}},
{{{0x0f, 0x00, 0x3f, 0xa6, 0x04, 0x19, 0x56, 0x65, 0x31, 0x7f, 0x8b, 0xeb, 0x0d, 0xe1, 0x47, 0x89, 0x97, 0x16, 0x53, 0xfa, 0x81, 0xa7, 0xaa, 0xb2, 0xbf, 0x67, 0xeb, 0x72, 0x60, 0x81, 0x0d, 0x48}} ,
{{0x7e, 0x13, 0x33, 0xcd, 0xa8, 0x84, 0x56, 0x1e, 0x67, 0xaf, 0x6b, 0x43, 0xac, 0x17, 0xaf, 0x16, 0xc0, 0x52, 0x99, 0x49, 0x5b, 0x87, 0x73, 0x7e, 0xb5, 0x43, 0xda, 0x6b, 0x1d, 0x0f, 0x2d, 0x55}}},
{{{0xe9, 0x58, 0x1f, 0xff, 0x84, 0x3f, 0x93, 0x1c, 0xcb, 0xe1, 0x30, 0x69, 0xa5, 0x75, 0x19, 0x7e, 0x14, 0x5f, 0xf8, 0xfc, 0x09, 0xdd, 0xa8, 0x78, 0x9d, 0xca, 0x59, 0x8b, 0xd1, 0x30, 0x01, 0x13}} ,
{{0xff, 0x76, 0x03, 0xc5, 0x4b, 0x89, 0x99, 0x70, 0x00, 0x59, 0x70, 0x9c, 0xd5, 0xd9, 0x11, 0x89, 0x5a, 0x46, 0xfe, 0xef, 0xdc, 0xd9, 0x55, 0x2b, 0x45, 0xa7, 0xb0, 0x2d, 0xfb, 0x24, 0xc2, 0x29}}},
{{{0x38, 0x06, 0xf8, 0x0b, 0xac, 0x82, 0xc4, 0x97, 0x2b, 0x90, 0xe0, 0xf7, 0xa8, 0xab, 0x6c, 0x08, 0x80, 0x66, 0x90, 0x46, 0xf7, 0x26, 0x2d, 0xf8, 0xf1, 0xc4, 0x6b, 0x4a, 0x82, 0x98, 0x8e, 0x37}} ,
{{0x8e, 0xb4, 0xee, 0xb8, 0xd4, 0x3f, 0xb2, 0x1b, 0xe0, 0x0a, 0x3d, 0x75, 0x34, 0x28, 0xa2, 0x8e, 0xc4, 0x92, 0x7b, 0xfe, 0x60, 0x6e, 0x6d, 0xb8, 0x31, 0x1d, 0x62, 0x0d, 0x78, 0x14, 0x42, 0x11}}},
{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
{{{0x5e, 0xa8, 0xd8, 0x04, 0x9b, 0x73, 0xc9, 0xc9, 0xdc, 0x0d, 0x73, 0xbf, 0x0a, 0x0a, 0x73, 0xff, 0x18, 0x1f, 0x9c, 0x51, 0xaa, 0xc6, 0xf1, 0x83, 0x25, 0xfd, 0xab, 0xa3, 0x11, 0xd3, 0x01, 0x24}} ,
{{0x4d, 0xe3, 0x7e, 0x38, 0x62, 0x5e, 0x64, 0xbb, 0x2b, 0x53, 0xb5, 0x03, 0x68, 0xc4, 0xf2, 0x2b, 0x5a, 0x03, 0x32, 0x99, 0x4a, 0x41, 0x9a, 0xe1, 0x1a, 0xae, 0x8c, 0x48, 0xf3, 0x24, 0x32, 0x65}}},
{{{0xe8, 0xdd, 0xad, 0x3a, 0x8c, 0xea, 0xf4, 0xb3, 0xb2, 0xe5, 0x73, 0xf2, 0xed, 0x8b, 0xbf, 0xed, 0xb1, 0x0c, 0x0c, 0xfb, 0x2b, 0xf1, 0x01, 0x48, 0xe8, 0x26, 0x03, 0x8e, 0x27, 0x4d, 0x96, 0x72}} ,
{{0xc8, 0x09, 0x3b, 0x60, 0xc9, 0x26, 0x4d, 0x7c, 0xf2, 0x9c, 0xd4, 0xa1, 0x3b, 0x26, 0xc2, 0x04, 0x33, 0x44, 0x76, 0x3c, 0x02, 0xbb, 0x11, 0x42, 0x0c, 0x22, 0xb7, 0xc6, 0xe1, 0xac, 0xb4, 0x0e}}},
{{{0x6f, 0x85, 0xe7, 0xef, 0xde, 0x67, 0x30, 0xfc, 0xbf, 0x5a, 0xe0, 0x7b, 0x7a, 0x2a, 0x54, 0x6b, 0x5d, 0x62, 0x85, 0xa1, 0xf8, 0x16, 0x88, 0xec, 0x61, 0xb9, 0x96, 0xb5, 0xef, 0x2d, 0x43, 0x4d}} ,
{{0x7c, 0x31, 0x33, 0xcc, 0xe4, 0xcf, 0x6c, 0xff, 0x80, 0x47, 0x77, 0xd1, 0xd8, 0xe9, 0x69, 0x97, 0x98, 0x7f, 0x20, 0x57, 0x1d, 0x1d, 0x4f, 0x08, 0x27, 0xc8, 0x35, 0x57, 0x40, 0xc6, 0x21, 0x0c}}},
{{{0xd2, 0x8e, 0x9b, 0xfa, 0x42, 0x8e, 0xdf, 0x8f, 0xc7, 0x86, 0xf9, 0xa4, 0xca, 0x70, 0x00, 0x9d, 0x21, 0xbf, 0xec, 0x57, 0x62, 0x30, 0x58, 0x8c, 0x0d, 0x35, 0xdb, 0x5d, 0x8b, 0x6a, 0xa0, 0x5a}} ,
{{0xc1, 0x58, 0x7c, 0x0d, 0x20, 0xdd, 0x11, 0x26, 0x5f, 0x89, 0x3b, 0x97, 0x58, 0xf8, 0x8b, 0xe3, 0xdf, 0x32, 0xe2, 0xfc, 0xd8, 0x67, 0xf2, 0xa5, 0x37, 0x1e, 0x6d, 0xec, 0x7c, 0x27, 0x20, 0x79}}},
{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
{{{0xd0, 0xe9, 0xc0, 0xfa, 0x95, 0x45, 0x23, 0x96, 0xf1, 0x2c, 0x79, 0x25, 0x14, 0xce, 0x40, 0x14, 0x44, 0x2c, 0x36, 0x50, 0xd9, 0x63, 0x56, 0xb7, 0x56, 0x3b, 0x9e, 0xa7, 0xef, 0x89, 0xbb, 0x0e}} ,
{{0xce, 0x7f, 0xdc, 0x0a, 0xcc, 0x82, 0x1c, 0x0a, 0x78, 0x71, 0xe8, 0x74, 0x8d, 0x01, 0x30, 0x0f, 0xa7, 0x11, 0x4c, 0xdf, 0x38, 0xd7, 0xa7, 0x0d, 0xf8, 0x48, 0x52, 0x00, 0x80, 0x7b, 0x5f, 0x0e}}},
{{{0x25, 0x83, 0xe6, 0x94, 0x7b, 0x81, 0xb2, 0x91, 0xae, 0x0e, 0x05, 0xc9, 0xa3, 0x68, 0x2d, 0xd9, 0x88, 0x25, 0x19, 0x2a, 0x61, 0x61, 0x21, 0x97, 0x15, 0xa1, 0x35, 0xa5, 0x46, 0xc8, 0xa2, 0x0e}} ,
{{0x1b, 0x03, 0x0d, 0x8b, 0x5a, 0x1b, 0x97, 0x4b, 0xf2, 0x16, 0x31, 0x3d, 0x1f, 0x33, 0xa0, 0x50, 0x3a, 0x18, 0xbe, 0x13, 0xa1, 0x76, 0xc1, 0xba, 0x1b, 0xf1, 0x05, 0x7b, 0x33, 0xa8, 0x82, 0x3b}}},
{{{0xba, 0x36, 0x7b, 0x6d, 0xa9, 0xea, 0x14, 0x12, 0xc5, 0xfa, 0x91, 0x00, 0xba, 0x9b, 0x99, 0xcc, 0x56, 0x02, 0xe9, 0xa0, 0x26, 0x40, 0x66, 0x8c, 0xc4, 0xf8, 0x85, 0x33, 0x68, 0xe7, 0x03, 0x20}} ,
{{0x50, 0x5b, 0xff, 0xa9, 0xb2, 0xf1, 0xf1, 0x78, 0xcf, 0x14, 0xa4, 0xa9, 0xfc, 0x09, 0x46, 0x94, 0x54, 0x65, 0x0d, 0x9c, 0x5f, 0x72, 0x21, 0xe2, 0x97, 0xa5, 0x2d, 0x81, 0xce, 0x4a, 0x5f, 0x79}}},
{{{0x3d, 0x5f, 0x5c, 0xd2, 0xbc, 0x7d, 0x77, 0x0e, 0x2a, 0x6d, 0x22, 0x45, 0x84, 0x06, 0xc4, 0xdd, 0xc6, 0xa6, 0xc6, 0xd7, 0x49, 0xad, 0x6d, 0x87, 0x91, 0x0e, 0x3a, 0x67, 0x1d, 0x2c, 0x1d, 0x56}} ,
{{0xfe, 0x7a, 0x74, 0xcf, 0xd4, 0xd2, 0xe5, 0x19, 0xde, 0xd0, 0xdb, 0x70, 0x23, 0x69, 0xe6, 0x6d, 0xec, 0xec, 0xcc, 0x09, 0x33, 0x6a, 0x77, 0xdc, 0x6b, 0x22, 0x76, 0x5d, 0x92, 0x09, 0xac, 0x2d}}},
{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
{{{0x23, 0x15, 0x17, 0xeb, 0xd3, 0xdb, 0x12, 0x5e, 0x01, 0xf0, 0x91, 0xab, 0x2c, 0x41, 0xce, 0xac, 0xed, 0x1b, 0x4b, 0x2d, 0xbc, 0xdb, 0x17, 0x66, 0x89, 0x46, 0xad, 0x4b, 0x1e, 0x6f, 0x0b, 0x14}} ,
{{0x11, 0xce, 0xbf, 0xb6, 0x77, 0x2d, 0x48, 0x22, 0x18, 0x4f, 0xa3, 0x5d, 0x4a, 0xb0, 0x70, 0x12, 0x3e, 0x54, 0xd7, 0xd8, 0x0e, 0x2b, 0x27, 0xdc, 0x53, 0xff, 0xca, 0x8c, 0x59, 0xb3, 0x4e, 0x44}}},
{{{0x07, 0x76, 0x61, 0x0f, 0x66, 0xb2, 0x21, 0x39, 0x7e, 0xc0, 0xec, 0x45, 0x28, 0x82, 0xa1, 0x29, 0x32, 0x44, 0x35, 0x13, 0x5e, 0x61, 0x5e, 0x54, 0xcb, 0x7c, 0xef, 0xf6, 0x41, 0xcf, 0x9f, 0x0a}} ,
{{0xdd, 0xf9, 0xda, 0x84, 0xc3, 0xe6, 0x8a, 0x9f, 0x24, 0xd2, 0x96, 0x5d, 0x39, 0x6f, 0x58, 0x8c, 0xc1, 0x56, 0x93, 0xab, 0xb5, 0x79, 0x3b, 0xd2, 0xa8, 0x73, 0x16, 0xed, 0xfa, 0xb4, 0x2f, 0x73}}},
{{{0x8b, 0xb1, 0x95, 0xe5, 0x92, 0x50, 0x35, 0x11, 0x76, 0xac, 0xf4, 0x4d, 0x24, 0xc3, 0x32, 0xe6, 0xeb, 0xfe, 0x2c, 0x87, 0xc4, 0xf1, 0x56, 0xc4, 0x75, 0x24, 0x7a, 0x56, 0x85, 0x5a, 0x3a, 0x13}} ,
{{0x0d, 0x16, 0xac, 0x3c, 0x4a, 0x58, 0x86, 0x3a, 0x46, 0x7f, 0x6c, 0xa3, 0x52, 0x6e, 0x37, 0xe4, 0x96, 0x9c, 0xe9, 0x5c, 0x66, 0x41, 0x67, 0xe4, 0xfb, 0x79, 0x0c, 0x05, 0xf6, 0x64, 0xd5, 0x7c}}},
{{{0x28, 0xc1, 0xe1, 0x54, 0x73, 0xf2, 0xbf, 0x76, 0x74, 0x19, 0x19, 0x1b, 0xe4, 0xb9, 0xa8, 0x46, 0x65, 0x73, 0xf3, 0x77, 0x9b, 0x29, 0x74, 0x5b, 0xc6, 0x89, 0x6c, 0x2c, 0x7c, 0xf8, 0xb3, 0x0f}} ,
{{0xf7, 0xd5, 0xe9, 0x74, 0x5d, 0xb8, 0x25, 0x16, 0xb5, 0x30, 0xbc, 0x84, 0xc5, 0xf0, 0xad, 0xca, 0x12, 0x28, 0xbc, 0x9d, 0xd4, 0xfa, 0x82, 0xe6, 0xe3, 0xbf, 0xa2, 0x15, 0x2c, 0xd4, 0x34, 0x10}}},
{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
{{{0x61, 0xb1, 0x46, 0xba, 0x0e, 0x31, 0xa5, 0x67, 0x6c, 0x7f, 0xd6, 0xd9, 0x27, 0x85, 0x0f, 0x79, 0x14, 0xc8, 0x6c, 0x2f, 0x5f, 0x5b, 0x9c, 0x35, 0x3d, 0x38, 0x86, 0x77, 0x65, 0x55, 0x6a, 0x7b}} ,
{{0xd3, 0xb0, 0x3a, 0x66, 0x60, 0x1b, 0x43, 0xf1, 0x26, 0x58, 0x99, 0x09, 0x8f, 0x2d, 0xa3, 0x14, 0x71, 0x85, 0xdb, 0xed, 0xf6, 0x26, 0xd5, 0x61, 0x9a, 0x73, 0xac, 0x0e, 0xea, 0xac, 0xb7, 0x0c}}},
{{{0x5e, 0xf4, 0xe5, 0x17, 0x0e, 0x10, 0x9f, 0xe7, 0x43, 0x5f, 0x67, 0x5c, 0xac, 0x4b, 0xe5, 0x14, 0x41, 0xd2, 0xbf, 0x48, 0xf5, 0x14, 0xb0, 0x71, 0xc6, 0x61, 0xc1, 0xb2, 0x70, 0x58, 0xd2, 0x5a}} ,
{{0x2d, 0xba, 0x16, 0x07, 0x92, 0x94, 0xdc, 0xbd, 0x50, 0x2b, 0xc9, 0x7f, 0x42, 0x00, 0xba, 0x61, 0xed, 0xf8, 0x43, 0xed, 0xf5, 0xf9, 0x40, 0x60, 0xb2, 0xb0, 0x82, 0xcb, 0xed, 0x75, 0xc7, 0x65}}},
{{{0x80, 0xba, 0x0d, 0x09, 0x40, 0xa7, 0x39, 0xa6, 0x67, 0x34, 0x7e, 0x66, 0xbe, 0x56, 0xfb, 0x53, 0x78, 0xc4, 0x46, 0xe8, 0xed, 0x68, 0x6c, 0x7f, 0xce, 0xe8, 0x9f, 0xce, 0xa2, 0x64, 0x58, 0x53}} ,
{{0xe8, 0xc1, 0xa9, 0xc2, 0x7b, 0x59, 0x21, 0x33, 0xe2, 0x43, 0x73, 0x2b, 0xac, 0x2d, 0xc1, 0x89, 0x3b, 0x15, 0xe2, 0xd5, 0xc0, 0x97, 0x8a, 0xfd, 0x6f, 0x36, 0x33, 0xb7, 0xb9, 0xc3, 0x88, 0x09}}},
{{{0xd0, 0xb6, 0x56, 0x30, 0x5c, 0xae, 0xb3, 0x75, 0x44, 0xa4, 0x83, 0x51, 0x6e, 0x01, 0x65, 0xef, 0x45, 0x76, 0xe6, 0xf5, 0xa2, 0x0d, 0xd4, 0x16, 0x3b, 0x58, 0x2f, 0xf2, 0x2f, 0x36, 0x18, 0x3f}} ,
{{0xfd, 0x2f, 0xe0, 0x9b, 0x1e, 0x8c, 0xc5, 0x18, 0xa9, 0xca, 0xd4, 0x2b, 0x35, 0xb6, 0x95, 0x0a, 0x9f, 0x7e, 0xfb, 0xc4, 0xef, 0x88, 0x7b, 0x23, 0x43, 0xec, 0x2f, 0x0d, 0x0f, 0x7a, 0xfc, 0x5c}}},
{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
{{{0x8d, 0xd2, 0xda, 0xc7, 0x44, 0xd6, 0x7a, 0xdb, 0x26, 0x7d, 0x1d, 0xb8, 0xe1, 0xde, 0x9d, 0x7a, 0x7d, 0x17, 0x7e, 0x1c, 0x37, 0x04, 0x8d, 0x2d, 0x7c, 0x5e, 0x18, 0x38, 0x1e, 0xaf, 0xc7, 0x1b}} ,
{{0x33, 0x48, 0x31, 0x00, 0x59, 0xf6, 0xf2, 0xca, 0x0f, 0x27, 0x1b, 0x63, 0x12, 0x7e, 0x02, 0x1d, 0x49, 0xc0, 0x5d, 0x79, 0x87, 0xef, 0x5e, 0x7a, 0x2f, 0x1f, 0x66, 0x55, 0xd8, 0x09, 0xd9, 0x61}}},
{{{0x54, 0x83, 0x02, 0x18, 0x82, 0x93, 0x99, 0x07, 0xd0, 0xa7, 0xda, 0xd8, 0x75, 0x89, 0xfa, 0xf2, 0xd9, 0xa3, 0xb8, 0x6b, 0x5a, 0x35, 0x28, 0xd2, 0x6b, 0x59, 0xc2, 0xf8, 0x45, 0xe2, 0xbc, 0x06}} ,
{{0x65, 0xc0, 0xa3, 0x88, 0x51, 0x95, 0xfc, 0x96, 0x94, 0x78, 0xe8, 0x0d, 0x8b, 0x41, 0xc9, 0xc2, 0x58, 0x48, 0x75, 0x10, 0x2f, 0xcd, 0x2a, 0xc9, 0xa0, 0x6d, 0x0f, 0xdd, 0x9c, 0x98, 0x26, 0x3d}}},
{{{0x2f, 0x66, 0x29, 0x1b, 0x04, 0x89, 0xbd, 0x7e, 0xee, 0x6e, 0xdd, 0xb7, 0x0e, 0xef, 0xb0, 0x0c, 0xb4, 0xfc, 0x7f, 0xc2, 0xc9, 0x3a, 0x3c, 0x64, 0xef, 0x45, 0x44, 0xaf, 0x8a, 0x90, 0x65, 0x76}} ,
{{0xa1, 0x4c, 0x70, 0x4b, 0x0e, 0xa0, 0x83, 0x70, 0x13, 0xa4, 0xaf, 0xb8, 0x38, 0x19, 0x22, 0x65, 0x09, 0xb4, 0x02, 0x4f, 0x06, 0xf8, 0x17, 0xce, 0x46, 0x45, 0xda, 0x50, 0x7c, 0x8a, 0xd1, 0x4e}}},
{{{0xf7, 0xd4, 0x16, 0x6c, 0x4e, 0x95, 0x9d, 0x5d, 0x0f, 0x91, 0x2b, 0x52, 0xfe, 0x5c, 0x34, 0xe5, 0x30, 0xe6, 0xa4, 0x3b, 0xf3, 0xf3, 0x34, 0x08, 0xa9, 0x4a, 0xa0, 0xb5, 0x6e, 0xb3, 0x09, 0x0a}} ,
{{0x26, 0xd9, 0x5e, 0xa3, 0x0f, 0xeb, 0xa2, 0xf3, 0x20, 0x3b, 0x37, 0xd4, 0xe4, 0x9e, 0xce, 0x06, 0x3d, 0x53, 0xed, 0xae, 0x2b, 0xeb, 0xb6, 0x24, 0x0a, 0x11, 0xa3, 0x0f, 0xd6, 0x7f, 0xa4, 0x3a}}},
{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
{{{0xdb, 0x9f, 0x2c, 0xfc, 0xd6, 0xb2, 0x1e, 0x2e, 0x52, 0x7a, 0x06, 0x87, 0x2d, 0x86, 0x72, 0x2b, 0x6d, 0x90, 0x77, 0x46, 0x43, 0xb5, 0x7a, 0xf8, 0x60, 0x7d, 0x91, 0x60, 0x5b, 0x9d, 0x9e, 0x07}} ,
{{0x97, 0x87, 0xc7, 0x04, 0x1c, 0x38, 0x01, 0x39, 0x58, 0xc7, 0x85, 0xa3, 0xfc, 0x64, 0x00, 0x64, 0x25, 0xa2, 0xbf, 0x50, 0x94, 0xca, 0x26, 0x31, 0x45, 0x0a, 0x24, 0xd2, 0x51, 0x29, 0x51, 0x16}}},
{{{0x4d, 0x4a, 0xd7, 0x98, 0x71, 0x57, 0xac, 0x7d, 0x8b, 0x37, 0xbd, 0x63, 0xff, 0x87, 0xb1, 0x49, 0x95, 0x20, 0x7c, 0xcf, 0x7c, 0x59, 0xc4, 0x91, 0x9c, 0xef, 0xd0, 0xdb, 0x60, 0x09, 0x9d, 0x46}} ,
{{0xcb, 0x78, 0x94, 0x90, 0xe4, 0x45, 0xb3, 0xf6, 0xd9, 0xf6, 0x57, 0x74, 0xd5, 0xf8, 0x83, 0x4f, 0x39, 0xc9, 0xbd, 0x88, 0xc2, 0x57, 0x21, 0x1f, 0x24, 0x32, 0x68, 0xf8, 0xc7, 0x21, 0x5f, 0x0b}}},
{{{0x2a, 0x36, 0x68, 0xfc, 0x5f, 0xb6, 0x4f, 0xa5, 0xe3, 0x9d, 0x24, 0x2f, 0xc0, 0x93, 0x61, 0xcf, 0xf8, 0x0a, 0xed, 0xe1, 0xdb, 0x27, 0xec, 0x0e, 0x14, 0x32, 0x5f, 0x8e, 0xa1, 0x62, 0x41, 0x16}} ,
{{0x95, 0x21, 0x01, 0xce, 0x95, 0x5b, 0x0e, 0x57, 0xc7, 0xb9, 0x62, 0xb5, 0x28, 0xca, 0x11, 0xec, 0xb4, 0x46, 0x06, 0x73, 0x26, 0xff, 0xfb, 0x66, 0x7d, 0xee, 0x5f, 0xb2, 0x56, 0xfd, 0x2a, 0x08}}},
{{{0x92, 0x67, 0x77, 0x56, 0xa1, 0xff, 0xc4, 0xc5, 0x95, 0xf0, 0xe3, 0x3a, 0x0a, 0xca, 0x94, 0x4d, 0x9e, 0x7e, 0x3d, 0xb9, 0x6e, 0xb6, 0xb0, 0xce, 0xa4, 0x30, 0x89, 0x99, 0xe9, 0xad, 0x11, 0x59}} ,
{{0xf6, 0x48, 0x95, 0xa1, 0x6f, 0x5f, 0xb7, 0xa5, 0xbb, 0x30, 0x00, 0x1c, 0xd2, 0x8a, 0xd6, 0x25, 0x26, 0x1b, 0xb2, 0x0d, 0x37, 0x6a, 0x05, 0xf4, 0x9d, 0x3e, 0x17, 0x2a, 0x43, 0xd2, 0x3a, 0x06}}},
{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
{{{0x32, 0x99, 0x93, 0xd1, 0x9a, 0x72, 0xf3, 0xa9, 0x16, 0xbd, 0xb4, 0x4c, 0xdd, 0xf9, 0xd4, 0xb2, 0x64, 0x9a, 0xd3, 0x05, 0xe4, 0xa3, 0x73, 0x1c, 0xcb, 0x7e, 0x57, 0x67, 0xff, 0x04, 0xb3, 0x10}} ,
{{0xb9, 0x4b, 0xa4, 0xad, 0xd0, 0x6d, 0x61, 0x23, 0xb4, 0xaf, 0x34, 0xa9, 0xaa, 0x65, 0xec, 0xd9, 0x69, 0xe3, 0x85, 0xcd, 0xcc, 0xe7, 0xb0, 0x9b, 0x41, 0xc1, 0x1c, 0xf9, 0xa0, 0xfa, 0xb7, 0x13}}},
{{{0x04, 0xfd, 0x88, 0x3c, 0x0c, 0xd0, 0x09, 0x52, 0x51, 0x4f, 0x06, 0x19, 0xcc, 0xc3, 0xbb, 0xde, 0x80, 0xc5, 0x33, 0xbc, 0xf9, 0xf3, 0x17, 0x36, 0xdd, 0xc6, 0xde, 0xe8, 0x9b, 0x5d, 0x79, 0x1b}} ,
{{0x65, 0x0a, 0xbe, 0x51, 0x57, 0xad, 0x50, 0x79, 0x08, 0x71, 0x9b, 0x07, 0x95, 0x8f, 0xfb, 0xae, 0x4b, 0x38, 0xba, 0xcf, 0x53, 0x2a, 0x86, 0x1e, 0xc0, 0x50, 0x5c, 0x67, 0x1b, 0xf6, 0x87, 0x6c}}},
{{{0x4f, 0x00, 0xb2, 0x66, 0x55, 0xed, 0x4a, 0xed, 0x8d, 0xe1, 0x66, 0x18, 0xb2, 0x14, 0x74, 0x8d, 0xfd, 0x1a, 0x36, 0x0f, 0x26, 0x5c, 0x8b, 0x89, 0xf3, 0xab, 0xf2, 0xf3, 0x24, 0x67, 0xfd, 0x70}} ,
{{0xfd, 0x4e, 0x2a, 0xc1, 0x3a, 0xca, 0x8f, 0x00, 0xd8, 0xec, 0x74, 0x67, 0xef, 0x61, 0xe0, 0x28, 0xd0, 0x96, 0xf4, 0x48, 0xde, 0x81, 0xe3, 0xef, 0xdc, 0xaa, 0x7d, 0xf3, 0xb6, 0x55, 0xa6, 0x65}}},
{{{0xeb, 0xcb, 0xc5, 0x70, 0x91, 0x31, 0x10, 0x93, 0x0d, 0xc8, 0xd0, 0xef, 0x62, 0xe8, 0x6f, 0x82, 0xe3, 0x69, 0x3d, 0x91, 0x7f, 0x31, 0xe1, 0x26, 0x35, 0x3c, 0x4a, 0x2f, 0xab, 0xc4, 0x9a, 0x5e}} ,
{{0xab, 0x1b, 0xb5, 0xe5, 0x2b, 0xc3, 0x0e, 0x29, 0xb0, 0xd0, 0x73, 0xe6, 0x4f, 0x64, 0xf2, 0xbc, 0xe4, 0xe4, 0xe1, 0x9a, 0x52, 0x33, 0x2f, 0xbd, 0xcc, 0x03, 0xee, 0x8a, 0xfa, 0x00, 0x5f, 0x50}}},
{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
{{{0xf6, 0xdb, 0x0d, 0x22, 0x3d, 0xb5, 0x14, 0x75, 0x31, 0xf0, 0x81, 0xe2, 0xb9, 0x37, 0xa2, 0xa9, 0x84, 0x11, 0x9a, 0x07, 0xb5, 0x53, 0x89, 0x78, 0xa9, 0x30, 0x27, 0xa1, 0xf1, 0x4e, 0x5c, 0x2e}} ,
{{0x8b, 0x00, 0x54, 0xfb, 0x4d, 0xdc, 0xcb, 0x17, 0x35, 0x40, 0xff, 0xb7, 0x8c, 0xfe, 0x4a, 0xe4, 0x4e, 0x99, 0x4e, 0xa8, 0x74, 0x54, 0x5d, 0x5c, 0x96, 0xa3, 0x12, 0x55, 0x36, 0x31, 0x17, 0x5c}}},
{{{0xce, 0x24, 0xef, 0x7b, 0x86, 0xf2, 0x0f, 0x77, 0xe8, 0x5c, 0x7d, 0x87, 0x38, 0x2d, 0xef, 0xaf, 0xf2, 0x8c, 0x72, 0x2e, 0xeb, 0xb6, 0x55, 0x4b, 0x6e, 0xf1, 0x4e, 0x8a, 0x0e, 0x9a, 0x6c, 0x4c}} ,
{{0x25, 0xea, 0x86, 0xc2, 0xd1, 0x4f, 0xb7, 0x3e, 0xa8, 0x5c, 0x8d, 0x66, 0x81, 0x25, 0xed, 0xc5, 0x4c, 0x05, 0xb9, 0xd8, 0xd6, 0x70, 0xbe, 0x73, 0x82, 0xe8, 0xa1, 0xe5, 0x1e, 0x71, 0xd5, 0x26}}},
{{{0x4e, 0x6d, 0xc3, 0xa7, 0x4f, 0x22, 0x45, 0x26, 0xa2, 0x7e, 0x16, 0xf7, 0xf7, 0x63, 0xdc, 0x86, 0x01, 0x2a, 0x71, 0x38, 0x5c, 0x33, 0xc3, 0xce, 0x30, 0xff, 0xf9, 0x2c, 0x91, 0x71, 0x8a, 0x72}} ,
{{0x8c, 0x44, 0x09, 0x28, 0xd5, 0x23, 0xc9, 0x8f, 0xf3, 0x84, 0x45, 0xc6, 0x9a, 0x5e, 0xff, 0xd2, 0xc7, 0x57, 0x93, 0xa3, 0xc1, 0x69, 0xdd, 0x62, 0x0f, 0xda, 0x5c, 0x30, 0x59, 0x5d, 0xe9, 0x4c}}},
{{{0x92, 0x7e, 0x50, 0x27, 0x72, 0xd7, 0x0c, 0xd6, 0x69, 0x96, 0x81, 0x35, 0x84, 0x94, 0x35, 0x8b, 0x6c, 0xaa, 0x62, 0x86, 0x6e, 0x1c, 0x15, 0xf3, 0x6c, 0xb3, 0xff, 0x65, 0x1b, 0xa2, 0x9b, 0x59}} ,
{{0xe2, 0xa9, 0x65, 0x88, 0xc4, 0x50, 0xfa, 0xbb, 0x3b, 0x6e, 0x5f, 0x44, 0x01, 0xca, 0x97, 0xd4, 0xdd, 0xf6, 0xcd, 0x3f, 0x3f, 0xe5, 0x97, 0x67, 0x2b, 0x8c, 0x66, 0x0f, 0x35, 0x9b, 0xf5, 0x07}}},
{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
{{{0xf1, 0x59, 0x27, 0xd8, 0xdb, 0x5a, 0x11, 0x5e, 0x82, 0xf3, 0x38, 0xff, 0x1c, 0xed, 0xfe, 0x3f, 0x64, 0x54, 0x3f, 0x7f, 0xd1, 0x81, 0xed, 0xef, 0x65, 0xc5, 0xcb, 0xfd, 0xe1, 0x80, 0xcd, 0x11}} ,
{{0xe0, 0xdb, 0x22, 0x28, 0xe6, 0xff, 0x61, 0x9d, 0x41, 0x14, 0x2d, 0x3b, 0x26, 0x22, 0xdf, 0xf1, 0x34, 0x81, 0xe9, 0x45, 0xee, 0x0f, 0x98, 0x8b, 0xa6, 0x3f, 0xef, 0xf7, 0x43, 0x19, 0xf1, 0x43}}},
{{{0xee, 0xf3, 0x00, 0xa1, 0x50, 0xde, 0xc0, 0xb6, 0x01, 0xe3, 0x8c, 0x3c, 0x4d, 0x31, 0xd2, 0xb0, 0x58, 0xcd, 0xed, 0x10, 0x4a, 0x7a, 0xef, 0x80, 0xa9, 0x19, 0x32, 0xf3, 0xd8, 0x33, 0x8c, 0x06}} ,
{{0xcb, 0x7d, 0x4f, 0xff, 0x30, 0xd8, 0x12, 0x3b, 0x39, 0x1c, 0x06, 0xf9, 0x4c, 0x34, 0x35, 0x71, 0xb5, 0x16, 0x94, 0x67, 0xdf, 0xee, 0x11, 0xde, 0xa4, 0x1d, 0x88, 0x93, 0x35, 0xa9, 0x32, 0x10}}},
{{{0xe9, 0xc3, 0xbc, 0x7b, 0x5c, 0xfc, 0xb2, 0xf9, 0xc9, 0x2f, 0xe5, 0xba, 0x3a, 0x0b, 0xab, 0x64, 0x38, 0x6f, 0x5b, 0x4b, 0x93, 0xda, 0x64, 0xec, 0x4d, 0x3d, 0xa0, 0xf5, 0xbb, 0xba, 0x47, 0x48}} ,
{{0x60, 0xbc, 0x45, 0x1f, 0x23, 0xa2, 0x3b, 0x70, 0x76, 0xe6, 0x97, 0x99, 0x4f, 0x77, 0x54, 0x67, 0x30, 0x9a, 0xe7, 0x66, 0xd6, 0xcd, 0x2e, 0x51, 0x24, 0x2c, 0x42, 0x4a, 0x11, 0xfe, 0x6f, 0x7e}}},
{{{0x87, 0xc0, 0xb1, 0xf0, 0xa3, 0x6f, 0x0c, 0x93, 0xa9, 0x0a, 0x72, 0xef, 0x5c, 0xbe, 0x65, 0x35, 0xa7, 0x6a, 0x4e, 0x2c, 0xbf, 0x21, 0x23, 0xe8, 0x2f, 0x97, 0xc7, 0x3e, 0xc8, 0x17, 0xac, 0x1e}} ,
{{0x7b, 0xef, 0x21, 0xe5, 0x40, 0xcc, 0x1e, 0xdc, 0xd6, 0xbd, 0x97, 0x7a, 0x7c, 0x75, 0x86, 0x7a, 0x25, 0x5a, 0x6e, 0x7c, 0xe5, 0x51, 0x3c, 0x1b, 0x5b, 0x82, 0x9a, 0x07, 0x60, 0xa1, 0x19, 0x04}}},
{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
{{{0x96, 0x88, 0xa6, 0xab, 0x8f, 0xe3, 0x3a, 0x49, 0xf8, 0xfe, 0x34, 0xe7, 0x6a, 0xb2, 0xfe, 0x40, 0x26, 0x74, 0x57, 0x4c, 0xf6, 0xd4, 0x99, 0xce, 0x5d, 0x7b, 0x2f, 0x67, 0xd6, 0x5a, 0xe4, 0x4e}} ,
{{0x5c, 0x82, 0xb3, 0xbd, 0x55, 0x25, 0xf6, 0x6a, 0x93, 0xa4, 0x02, 0xc6, 0x7d, 0x5c, 0xb1, 0x2b, 0x5b, 0xff, 0xfb, 0x56, 0xf8, 0x01, 0x41, 0x90, 0xc6, 0xb6, 0xac, 0x4f, 0xfe, 0xa7, 0x41, 0x70}}},
{{{0xdb, 0xfa, 0x9b, 0x2c, 0xd4, 0x23, 0x67, 0x2c, 0x8a, 0x63, 0x6c, 0x07, 0x26, 0x48, 0x4f, 0xc2, 0x03, 0xd2, 0x53, 0x20, 0x28, 0xed, 0x65, 0x71, 0x47, 0xa9, 0x16, 0x16, 0x12, 0xbc, 0x28, 0x33}} ,
{{0x39, 0xc0, 0xfa, 0xfa, 0xcd, 0x33, 0x43, 0xc7, 0x97, 0x76, 0x9b, 0x93, 0x91, 0x72, 0xeb, 0xc5, 0x18, 0x67, 0x4c, 0x11, 0xf0, 0xf4, 0xe5, 0x73, 0xb2, 0x5c, 0x1b, 0xc2, 0x26, 0x3f, 0xbf, 0x2b}}},
{{{0x86, 0xe6, 0x8c, 0x1d, 0xdf, 0xca, 0xfc, 0xd5, 0xf8, 0x3a, 0xc3, 0x44, 0x72, 0xe6, 0x78, 0x9d, 0x2b, 0x97, 0xf8, 0x28, 0x45, 0xb4, 0x20, 0xc9, 0x2a, 0x8c, 0x67, 0xaa, 0x11, 0xc5, 0x5b, 0x2f}} ,
{{0x17, 0x0f, 0x86, 0x52, 0xd7, 0x9d, 0xc3, 0x44, 0x51, 0x76, 0x32, 0x65, 0xb4, 0x37, 0x81, 0x99, 0x46, 0x37, 0x62, 0xed, 0xcf, 0x64, 0x9d, 0x72, 0x40, 0x7a, 0x4c, 0x0b, 0x76, 0x2a, 0xfb, 0x56}}},
{{{0x33, 0xa7, 0x90, 0x7c, 0xc3, 0x6f, 0x17, 0xa5, 0xa0, 0x67, 0x72, 0x17, 0xea, 0x7e, 0x63, 0x14, 0x83, 0xde, 0xc1, 0x71, 0x2d, 0x41, 0x32, 0x7a, 0xf3, 0xd1, 0x2b, 0xd8, 0x2a, 0xa6, 0x46, 0x36}} ,
{{0xac, 0xcc, 0x6b, 0x7c, 0xf9, 0xb8, 0x8b, 0x08, 0x5c, 0xd0, 0x7d, 0x8f, 0x73, 0xea, 0x20, 0xda, 0x86, 0xca, 0x00, 0xc7, 0xad, 0x73, 0x4d, 0xe9, 0xe8, 0xa9, 0xda, 0x1f, 0x03, 0x06, 0xdd, 0x24}}},
{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
{{{0x9c, 0xb2, 0x61, 0x0a, 0x98, 0x2a, 0xa5, 0xd7, 0xee, 0xa9, 0xac, 0x65, 0xcb, 0x0a, 0x1e, 0xe2, 0xbe, 0xdc, 0x85, 0x59, 0x0f, 0x9c, 0xa6, 0x57, 0x34, 0xa5, 0x87, 0xeb, 0x7b, 0x1e, 0x0c, 0x3c}} ,
{{0x2f, 0xbd, 0x84, 0x63, 0x0d, 0xb5, 0xa0, 0xf0, 0x4b, 0x9e, 0x93, 0xc6, 0x34, 0x9a, 0x34, 0xff, 0x73, 0x19, 0x2f, 0x6e, 0x54, 0x45, 0x2c, 0x92, 0x31, 0x76, 0x34, 0xf1, 0xb2, 0x26, 0xe8, 0x74}}},
{{{0x0a, 0x67, 0x90, 0x6d, 0x0c, 0x4c, 0xcc, 0xc0, 0xe6, 0xbd, 0xa7, 0x5e, 0x55, 0x8c, 0xcd, 0x58, 0x9b, 0x11, 0xa2, 0xbb, 0x4b, 0xb1, 0x43, 0x04, 0x3c, 0x55, 0xed, 0x23, 0xfe, 0xcd, 0xb1, 0x53}} ,
{{0x05, 0xfb, 0x75, 0xf5, 0x01, 0xaf, 0x38, 0x72, 0x58, 0xfc, 0x04, 0x29, 0x34, 0x7a, 0x67, 0xa2, 0x08, 0x50, 0x6e, 0xd0, 0x2b, 0x73, 0xd5, 0xb8, 0xe4, 0x30, 0x96, 0xad, 0x45, 0xdf, 0xa6, 0x5c}}},
{{{0x0d, 0x88, 0x1a, 0x90, 0x7e, 0xdc, 0xd8, 0xfe, 0xc1, 0x2f, 0x5d, 0x67, 0xee, 0x67, 0x2f, 0xed, 0x6f, 0x55, 0x43, 0x5f, 0x87, 0x14, 0x35, 0x42, 0xd3, 0x75, 0xae, 0xd5, 0xd3, 0x85, 0x1a, 0x76}} ,
{{0x87, 0xc8, 0xa0, 0x6e, 0xe1, 0xb0, 0xad, 0x6a, 0x4a, 0x34, 0x71, 0xed, 0x7c, 0xd6, 0x44, 0x03, 0x65, 0x4a, 0x5c, 0x5c, 0x04, 0xf5, 0x24, 0x3f, 0xb0, 0x16, 0x5e, 0x8c, 0xb2, 0xd2, 0xc5, 0x20}}},
{{{0x98, 0x83, 0xc2, 0x37, 0xa0, 0x41, 0xa8, 0x48, 0x5c, 0x5f, 0xbf, 0xc8, 0xfa, 0x24, 0xe0, 0x59, 0x2c, 0xbd, 0xf6, 0x81, 0x7e, 0x88, 0xe6, 0xca, 0x04, 0xd8, 0x5d, 0x60, 0xbb, 0x74, 0xa7, 0x0b}} ,
{{0x21, 0x13, 0x91, 0xbf, 0x77, 0x7a, 0x33, 0xbc, 0xe9, 0x07, 0x39, 0x0a, 0xdd, 0x7d, 0x06, 0x10, 0x9a, 0xee, 0x47, 0x73, 0x1b, 0x15, 0x5a, 0xfb, 0xcd, 0x4d, 0xd0, 0xd2, 0x3a, 0x01, 0xba, 0x54}}},
{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
{{{0x48, 0xd5, 0x39, 0x4a, 0x0b, 0x20, 0x6a, 0x43, 0xa0, 0x07, 0x82, 0x5e, 0x49, 0x7c, 0xc9, 0x47, 0xf1, 0x7c, 0x37, 0xb9, 0x23, 0xef, 0x6b, 0x46, 0x45, 0x8c, 0x45, 0x76, 0xdf, 0x14, 0x6b, 0x6e}} ,
{{0x42, 0xc9, 0xca, 0x29, 0x4c, 0x76, 0x37, 0xda, 0x8a, 0x2d, 0x7c, 0x3a, 0x58, 0xf2, 0x03, 0xb4, 0xb5, 0xb9, 0x1a, 0x13, 0x2d, 0xde, 0x5f, 0x6b, 0x9d, 0xba, 0x52, 0xc9, 0x5d, 0xb3, 0xf3, 0x30}}},
{{{0x4c, 0x6f, 0xfe, 0x6b, 0x0c, 0x62, 0xd7, 0x48, 0x71, 0xef, 0xb1, 0x85, 0x79, 0xc0, 0xed, 0x24, 0xb1, 0x08, 0x93, 0x76, 0x8e, 0xf7, 0x38, 0x8e, 0xeb, 0xfe, 0x80, 0x40, 0xaf, 0x90, 0x64, 0x49}} ,
{{0x4a, 0x88, 0xda, 0xc1, 0x98, 0x44, 0x3c, 0x53, 0x4e, 0xdb, 0x4b, 0xb9, 0x12, 0x5f, 0xcd, 0x08, 0x04, 0xef, 0x75, 0xe7, 0xb1, 0x3a, 0xe5, 0x07, 0xfa, 0xca, 0x65, 0x7b, 0x72, 0x10, 0x64, 0x7f}}},
{{{0x3d, 0x81, 0xf0, 0xeb, 0x16, 0xfd, 0x58, 0x33, 0x8d, 0x7c, 0x1a, 0xfb, 0x20, 0x2c, 0x8a, 0xee, 0x90, 0xbb, 0x33, 0x6d, 0x45, 0xe9, 0x8e, 0x99, 0x85, 0xe1, 0x08, 0x1f, 0xc5, 0xf1, 0xb5, 0x46}} ,
{{0xe4, 0xe7, 0x43, 0x4b, 0xa0, 0x3f, 0x2b, 0x06, 0xba, 0x17, 0xae, 0x3d, 0xe6, 0xce, 0xbd, 0xb8, 0xed, 0x74, 0x11, 0x35, 0xec, 0x96, 0xfe, 0x31, 0xe3, 0x0e, 0x7a, 0x4e, 0xc9, 0x1d, 0xcb, 0x20}}},
{{{0xe0, 0x67, 0xe9, 0x7b, 0xdb, 0x96, 0x5c, 0xb0, 0x32, 0xd0, 0x59, 0x31, 0x90, 0xdc, 0x92, 0x97, 0xac, 0x09, 0x38, 0x31, 0x0f, 0x7e, 0xd6, 0x5d, 0xd0, 0x06, 0xb6, 0x1f, 0xea, 0xf0, 0x5b, 0x07}} ,
{{0x81, 0x9f, 0xc7, 0xde, 0x6b, 0x41, 0x22, 0x35, 0x14, 0x67, 0x77, 0x3e, 0x90, 0x81, 0xb0, 0xd9, 0x85, 0x4c, 0xca, 0x9b, 0x3f, 0x04, 0x59, 0xd6, 0xaa, 0x17, 0xc3, 0x88, 0x34, 0x37, 0xba, 0x43}}},
{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
{{{0x4c, 0xb6, 0x69, 0xc8, 0x81, 0x95, 0x94, 0x33, 0x92, 0x34, 0xe9, 0x3c, 0x84, 0x0d, 0x3d, 0x5a, 0x37, 0x9c, 0x22, 0xa0, 0xaa, 0x65, 0xce, 0xb4, 0xc2, 0x2d, 0x66, 0x67, 0x02, 0xff, 0x74, 0x10}} ,
{{0x22, 0xb0, 0xd5, 0xe6, 0xc7, 0xef, 0xb1, 0xa7, 0x13, 0xda, 0x60, 0xb4, 0x80, 0xc1, 0x42, 0x7d, 0x10, 0x70, 0x97, 0x04, 0x4d, 0xda, 0x23, 0x89, 0xc2, 0x0e, 0x68, 0xcb, 0xde, 0xe0, 0x9b, 0x29}}},
{{{0x33, 0xfe, 0x42, 0x2a, 0x36, 0x2b, 0x2e, 0x36, 0x64, 0x5c, 0x8b, 0xcc, 0x81, 0x6a, 0x15, 0x08, 0xa1, 0x27, 0xe8, 0x57, 0xe5, 0x78, 0x8e, 0xf2, 0x58, 0x19, 0x12, 0x42, 0xae, 0xc4, 0x63, 0x3e}} ,
{{0x78, 0x96, 0x9c, 0xa7, 0xca, 0x80, 0xae, 0x02, 0x85, 0xb1, 0x7c, 0x04, 0x5c, 0xc1, 0x5b, 0x26, 0xc1, 0xba, 0xed, 0xa5, 0x59, 0x70, 0x85, 0x8c, 0x8c, 0xe8, 0x87, 0xac, 0x6a, 0x28, 0x99, 0x35}}},
{{{0x9f, 0x04, 0x08, 0x28, 0xbe, 0x87, 0xda, 0x80, 0x28, 0x38, 0xde, 0x9f, 0xcd, 0xe4, 0xe3, 0x62, 0xfb, 0x2e, 0x46, 0x8d, 0x01, 0xb3, 0x06, 0x51, 0xd4, 0x19, 0x3b, 0x11, 0xfa, 0xe2, 0xad, 0x1e}} ,
{{0xa0, 0x20, 0x99, 0x69, 0x0a, 0xae, 0xa3, 0x70, 0x4e, 0x64, 0x80, 0xb7, 0x85, 0x9c, 0x87, 0x54, 0x43, 0x43, 0x55, 0x80, 0x6d, 0x8d, 0x7c, 0xa9, 0x64, 0xca, 0x6c, 0x2e, 0x21, 0xd8, 0xc8, 0x6c}}},
{{{0x91, 0x4a, 0x07, 0xad, 0x08, 0x75, 0xc1, 0x4f, 0xa4, 0xb2, 0xc3, 0x6f, 0x46, 0x3e, 0xb1, 0xce, 0x52, 0xab, 0x67, 0x09, 0x54, 0x48, 0x6b, 0x6c, 0xd7, 0x1d, 0x71, 0x76, 0xcb, 0xff, 0xdd, 0x31}} ,
{{0x36, 0x88, 0xfa, 0xfd, 0xf0, 0x36, 0x6f, 0x07, 0x74, 0x88, 0x50, 0xd0, 0x95, 0x38, 0x4a, 0x48, 0x2e, 0x07, 0x64, 0x97, 0x11, 0x76, 0x01, 0x1a, 0x27, 0x4d, 0x8e, 0x25, 0x9a, 0x9b, 0x1c, 0x22}}},
{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
{{{0xbe, 0x57, 0xbd, 0x0e, 0x0f, 0xac, 0x5e, 0x76, 0xa3, 0x71, 0xad, 0x2b, 0x10, 0x45, 0x02, 0xec, 0x59, 0xd5, 0x5d, 0xa9, 0x44, 0xcc, 0x25, 0x4c, 0xb3, 0x3c, 0x5b, 0x69, 0x07, 0x55, 0x26, 0x6b}} ,
{{0x30, 0x6b, 0xd4, 0xa7, 0x51, 0x29, 0xe3, 0xf9, 0x7a, 0x75, 0x2a, 0x82, 0x2f, 0xd6, 0x1d, 0x99, 0x2b, 0x80, 0xd5, 0x67, 0x1e, 0x15, 0x9d, 0xca, 0xfd, 0xeb, 0xac, 0x97, 0x35, 0x09, 0x7f, 0x3f}}},
{{{0x35, 0x0d, 0x34, 0x0a, 0xb8, 0x67, 0x56, 0x29, 0x20, 0xf3, 0x19, 0x5f, 0xe2, 0x83, 0x42, 0x73, 0x53, 0xa8, 0xc5, 0x02, 0x19, 0x33, 0xb4, 0x64, 0xbd, 0xc3, 0x87, 0x8c, 0xd7, 0x76, 0xed, 0x25}} ,
{{0x47, 0x39, 0x37, 0x76, 0x0d, 0x1d, 0x0c, 0xf5, 0x5a, 0x6d, 0x43, 0x88, 0x99, 0x15, 0xb4, 0x52, 0x0f, 0x2a, 0xb3, 0xb0, 0x3f, 0xa6, 0xb3, 0x26, 0xb3, 0xc7, 0x45, 0xf5, 0x92, 0x5f, 0x9b, 0x17}}},
{{{0x9d, 0x23, 0xbd, 0x15, 0xfe, 0x52, 0x52, 0x15, 0x26, 0x79, 0x86, 0xba, 0x06, 0x56, 0x66, 0xbb, 0x8c, 0x2e, 0x10, 0x11, 0xd5, 0x4a, 0x18, 0x52, 0xda, 0x84, 0x44, 0xf0, 0x3e, 0xe9, 0x8c, 0x35}} ,
{{0xad, 0xa0, 0x41, 0xec, 0xc8, 0x4d, 0xb9, 0xd2, 0x6e, 0x96, 0x4e, 0x5b, 0xc5, 0xc2, 0xa0, 0x1b, 0xcf, 0x0c, 0xbf, 0x17, 0x66, 0x57, 0xc1, 0x17, 0x90, 0x45, 0x71, 0xc2, 0xe1, 0x24, 0xeb, 0x27}}},
{{{0x2c, 0xb9, 0x42, 0xa4, 0xaf, 0x3b, 0x42, 0x0e, 0xc2, 0x0f, 0xf2, 0xea, 0x83, 0xaf, 0x9a, 0x13, 0x17, 0xb0, 0xbd, 0x89, 0x17, 0xe3, 0x72, 0xcb, 0x0e, 0x76, 0x7e, 0x41, 0x63, 0x04, 0x88, 0x71}} ,
{{0x75, 0x78, 0x38, 0x86, 0x57, 0xdd, 0x9f, 0xee, 0x54, 0x70, 0x65, 0xbf, 0xf1, 0x2c, 0xe0, 0x39, 0x0d, 0xe3, 0x89, 0xfd, 0x8e, 0x93, 0x4f, 0x43, 0xdc, 0xd5, 0x5b, 0xde, 0xf9, 0x98, 0xe5, 0x7b}}},
{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
{{{0xe7, 0x3b, 0x65, 0x11, 0xdf, 0xb2, 0xf2, 0x63, 0x94, 0x12, 0x6f, 0x5c, 0x9e, 0x77, 0xc1, 0xb6, 0xd8, 0xab, 0x58, 0x7a, 0x1d, 0x95, 0x73, 0xdd, 0xe7, 0xe3, 0x6f, 0xf2, 0x03, 0x1d, 0xdb, 0x76}} ,
{{0xae, 0x06, 0x4e, 0x2c, 0x52, 0x1b, 0xbc, 0x5a, 0x5a, 0xa5, 0xbe, 0x27, 0xbd, 0xeb, 0xe1, 0x14, 0x17, 0x68, 0x26, 0x07, 0x03, 0xd1, 0x18, 0x0b, 0xdf, 0xf1, 0x06, 0x5c, 0xa6, 0x1b, 0xb9, 0x24}}},
{{{0xc5, 0x66, 0x80, 0x13, 0x0e, 0x48, 0x8c, 0x87, 0x31, 0x84, 0xb4, 0x60, 0xed, 0xc5, 0xec, 0xb6, 0xc5, 0x05, 0x33, 0x5f, 0x2f, 0x7d, 0x40, 0xb6, 0x32, 0x1d, 0x38, 0x74, 0x1b, 0xf1, 0x09, 0x3d}} ,
{{0xd4, 0x69, 0x82, 0xbc, 0x8d, 0xf8, 0x34, 0x36, 0x75, 0x55, 0x18, 0x55, 0x58, 0x3c, 0x79, 0xaf, 0x26, 0x80, 0xab, 0x9b, 0x95, 0x00, 0xf1, 0xcb, 0xda, 0xc1, 0x9f, 0xf6, 0x2f, 0xa2, 0xf4, 0x45}}},
{{{0x17, 0xbe, 0xeb, 0x85, 0xed, 0x9e, 0xcd, 0x56, 0xf5, 0x17, 0x45, 0x42, 0xb4, 0x1f, 0x44, 0x4c, 0x05, 0x74, 0x15, 0x47, 0x00, 0xc6, 0x6a, 0x3d, 0x24, 0x09, 0x0d, 0x58, 0xb1, 0x42, 0xd7, 0x04}} ,
{{0x8d, 0xbd, 0xa3, 0xc4, 0x06, 0x9b, 0x1f, 0x90, 0x58, 0x60, 0x74, 0xb2, 0x00, 0x3b, 0x3c, 0xd2, 0xda, 0x82, 0xbb, 0x10, 0x90, 0x69, 0x92, 0xa9, 0xb4, 0x30, 0x81, 0xe3, 0x7c, 0xa8, 0x89, 0x45}}},
{{{0x3f, 0xdc, 0x05, 0xcb, 0x41, 0x3c, 0xc8, 0x23, 0x04, 0x2c, 0x38, 0x99, 0xe3, 0x68, 0x55, 0xf9, 0xd3, 0x32, 0xc7, 0xbf, 0xfa, 0xd4, 0x1b, 0x5d, 0xde, 0xdc, 0x10, 0x42, 0xc0, 0x42, 0xd9, 0x75}} ,
{{0x2d, 0xab, 0x35, 0x4e, 0x87, 0xc4, 0x65, 0x97, 0x67, 0x24, 0xa4, 0x47, 0xad, 0x3f, 0x8e, 0xf3, 0xcb, 0x31, 0x17, 0x77, 0xc5, 0xe2, 0xd7, 0x8f, 0x3c, 0xc1, 0xcd, 0x56, 0x48, 0xc1, 0x6c, 0x69}}},
{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
{{{0x14, 0xae, 0x5f, 0x88, 0x7b, 0xa5, 0x90, 0xdf, 0x10, 0xb2, 0x8b, 0x5e, 0x24, 0x17, 0xc3, 0xa3, 0xd4, 0x0f, 0x92, 0x61, 0x1a, 0x19, 0x5a, 0xad, 0x76, 0xbd, 0xd8, 0x1c, 0xdd, 0xe0, 0x12, 0x6d}} ,
{{0x8e, 0xbd, 0x70, 0x8f, 0x02, 0xa3, 0x24, 0x4d, 0x5a, 0x67, 0xc4, 0xda, 0xf7, 0x20, 0x0f, 0x81, 0x5b, 0x7a, 0x05, 0x24, 0x67, 0x83, 0x0b, 0x2a, 0x80, 0xe7, 0xfd, 0x74, 0x4b, 0x9e, 0x5c, 0x0d}}},
{{{0x94, 0xd5, 0x5f, 0x1f, 0xa2, 0xfb, 0xeb, 0xe1, 0x07, 0x34, 0xf8, 0x20, 0xad, 0x81, 0x30, 0x06, 0x2d, 0xa1, 0x81, 0x95, 0x36, 0xcf, 0x11, 0x0b, 0xaf, 0xc1, 0x2b, 0x9a, 0x6c, 0x55, 0xc1, 0x16}} ,
{{0x36, 0x4f, 0xf1, 0x5e, 0x74, 0x35, 0x13, 0x28, 0xd7, 0x11, 0xcf, 0xb8, 0xde, 0x93, 0xb3, 0x05, 0xb8, 0xb5, 0x73, 0xe9, 0xeb, 0xad, 0x19, 0x1e, 0x89, 0x0f, 0x8b, 0x15, 0xd5, 0x8c, 0xe3, 0x23}}},
{{{0x33, 0x79, 0xe7, 0x18, 0xe6, 0x0f, 0x57, 0x93, 0x15, 0xa0, 0xa7, 0xaa, 0xc4, 0xbf, 0x4f, 0x30, 0x74, 0x95, 0x5e, 0x69, 0x4a, 0x5b, 0x45, 0xe4, 0x00, 0xeb, 0x23, 0x74, 0x4c, 0xdf, 0x6b, 0x45}} ,
{{0x97, 0x29, 0x6c, 0xc4, 0x42, 0x0b, 0xdd, 0xc0, 0x29, 0x5c, 0x9b, 0x34, 0x97, 0xd0, 0xc7, 0x79, 0x80, 0x63, 0x74, 0xe4, 0x8e, 0x37, 0xb0, 0x2b, 0x7c, 0xe8, 0x68, 0x6c, 0xc3, 0x82, 0x97, 0x57}}},
{{{0x22, 0xbe, 0x83, 0xb6, 0x4b, 0x80, 0x6b, 0x43, 0x24, 0x5e, 0xef, 0x99, 0x9b, 0xa8, 0xfc, 0x25, 0x8d, 0x3b, 0x03, 0x94, 0x2b, 0x3e, 0xe7, 0x95, 0x76, 0x9b, 0xcc, 0x15, 0xdb, 0x32, 0xe6, 0x66}} ,
{{0x84, 0xf0, 0x4a, 0x13, 0xa6, 0xd6, 0xfa, 0x93, 0x46, 0x07, 0xf6, 0x7e, 0x5c, 0x6d, 0x5e, 0xf6, 0xa6, 0xe7, 0x48, 0xf0, 0x06, 0xea, 0xff, 0x90, 0xc1, 0xcc, 0x4c, 0x19, 0x9c, 0x3c, 0x4e, 0x53}}},
{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
{{{0x2a, 0x50, 0xe3, 0x07, 0x15, 0x59, 0xf2, 0x8b, 0x81, 0xf2, 0xf3, 0xd3, 0x6c, 0x99, 0x8c, 0x70, 0x67, 0xec, 0xcc, 0xee, 0x9e, 0x59, 0x45, 0x59, 0x7d, 0x47, 0x75, 0x69, 0xf5, 0x24, 0x93, 0x5d}} ,
{{0x6a, 0x4f, 0x1b, 0xbe, 0x6b, 0x30, 0xcf, 0x75, 0x46, 0xe3, 0x7b, 0x9d, 0xfc, 0xcd, 0xd8, 0x5c, 0x1f, 0xb4, 0xc8, 0xe2, 0x24, 0xec, 0x1a, 0x28, 0x05, 0x32, 0x57, 0xfd, 0x3c, 0x5a, 0x98, 0x10}}},
{{{0xa3, 0xdb, 0xf7, 0x30, 0xd8, 0xc2, 0x9a, 0xe1, 0xd3, 0xce, 0x22, 0xe5, 0x80, 0x1e, 0xd9, 0xe4, 0x1f, 0xab, 0xc0, 0x71, 0x1a, 0x86, 0x0e, 0x27, 0x99, 0x5b, 0xfa, 0x76, 0x99, 0xb0, 0x08, 0x3c}} ,
{{0x2a, 0x93, 0xd2, 0x85, 0x1b, 0x6a, 0x5d, 0xa6, 0xee, 0xd1, 0xd1, 0x33, 0xbd, 0x6a, 0x36, 0x73, 0x37, 0x3a, 0x44, 0xb4, 0xec, 0xa9, 0x7a, 0xde, 0x83, 0x40, 0xd7, 0xdf, 0x28, 0xba, 0xa2, 0x30}}},
{{{0xd3, 0xb5, 0x6d, 0x05, 0x3f, 0x9f, 0xf3, 0x15, 0x8d, 0x7c, 0xca, 0xc9, 0xfc, 0x8a, 0x7c, 0x94, 0xb0, 0x63, 0x36, 0x9b, 0x78, 0xd1, 0x91, 0x1f, 0x93, 0xd8, 0x57, 0x43, 0xde, 0x76, 0xa3, 0x43}} ,
{{0x9b, 0x35, 0xe2, 0xa9, 0x3d, 0x32, 0x1e, 0xbb, 0x16, 0x28, 0x70, 0xe9, 0x45, 0x2f, 0x8f, 0x70, 0x7f, 0x08, 0x7e, 0x53, 0xc4, 0x7a, 0xbf, 0xf7, 0xe1, 0xa4, 0x6a, 0xd8, 0xac, 0x64, 0x1b, 0x11}}},
{{{0xb2, 0xeb, 0x47, 0x46, 0x18, 0x3e, 0x1f, 0x99, 0x0c, 0xcc, 0xf1, 0x2c, 0xe0, 0xe7, 0x8f, 0xe0, 0x01, 0x7e, 0x65, 0xb8, 0x0c, 0xd0, 0xfb, 0xc8, 0xb9, 0x90, 0x98, 0x33, 0x61, 0x3b, 0xd8, 0x27}} ,
{{0xa0, 0xbe, 0x72, 0x3a, 0x50, 0x4b, 0x74, 0xab, 0x01, 0xc8, 0x93, 0xc5, 0xe4, 0xc7, 0x08, 0x6c, 0xb4, 0xca, 0xee, 0xeb, 0x8e, 0xd7, 0x4e, 0x26, 0xc6, 0x1d, 0xe2, 0x71, 0xaf, 0x89, 0xa0, 0x2a}}},
{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
{{{0x98, 0x0b, 0xe4, 0xde, 0xdb, 0xa8, 0xfa, 0x82, 0x74, 0x06, 0x52, 0x6d, 0x08, 0x52, 0x8a, 0xff, 0x62, 0xc5, 0x6a, 0x44, 0x0f, 0x51, 0x8c, 0x1f, 0x6e, 0xb6, 0xc6, 0x2c, 0x81, 0xd3, 0x76, 0x46}} ,
{{0xf4, 0x29, 0x74, 0x2e, 0x80, 0xa7, 0x1a, 0x8f, 0xf6, 0xbd, 0xd6, 0x8e, 0xbf, 0xc1, 0x95, 0x2a, 0xeb, 0xa0, 0x7f, 0x45, 0xa0, 0x50, 0x14, 0x05, 0xb1, 0x57, 0x4c, 0x74, 0xb7, 0xe2, 0x89, 0x7d}}},
{{{0x07, 0xee, 0xa7, 0xad, 0xb7, 0x09, 0x0b, 0x49, 0x4e, 0xbf, 0xca, 0xe5, 0x21, 0xe6, 0xe6, 0xaf, 0xd5, 0x67, 0xf3, 0xce, 0x7e, 0x7c, 0x93, 0x7b, 0x5a, 0x10, 0x12, 0x0e, 0x6c, 0x06, 0x11, 0x75}} ,
{{0xd5, 0xfc, 0x86, 0xa3, 0x3b, 0xa3, 0x3e, 0x0a, 0xfb, 0x0b, 0xf7, 0x36, 0xb1, 0x5b, 0xda, 0x70, 0xb7, 0x00, 0xa7, 0xda, 0x88, 0x8f, 0x84, 0xa8, 0xbc, 0x1c, 0x39, 0xb8, 0x65, 0xf3, 0x4d, 0x60}}},
{{{0x96, 0x9d, 0x31, 0xf4, 0xa2, 0xbe, 0x81, 0xb9, 0xa5, 0x59, 0x9e, 0xba, 0x07, 0xbe, 0x74, 0x58, 0xd8, 0xeb, 0xc5, 0x9f, 0x3d, 0xd1, 0xf4, 0xae, 0xce, 0x53, 0xdf, 0x4f, 0xc7, 0x2a, 0x89, 0x4d}} ,
{{0x29, 0xd8, 0xf2, 0xaa, 0xe9, 0x0e, 0xf7, 0x2e, 0x5f, 0x9d, 0x8a, 0x5b, 0x09, 0xed, 0xc9, 0x24, 0x22, 0xf4, 0x0f, 0x25, 0x8f, 0x1c, 0x84, 0x6e, 0x34, 0x14, 0x6c, 0xea, 0xb3, 0x86, 0x5d, 0x04}}},
{{{0x07, 0x98, 0x61, 0xe8, 0x6a, 0xd2, 0x81, 0x49, 0x25, 0xd5, 0x5b, 0x18, 0xc7, 0x35, 0x52, 0x51, 0xa4, 0x46, 0xad, 0x18, 0x0d, 0xc9, 0x5f, 0x18, 0x91, 0x3b, 0xb4, 0xc0, 0x60, 0x59, 0x8d, 0x66}} ,
{{0x03, 0x1b, 0x79, 0x53, 0x6e, 0x24, 0xae, 0x57, 0xd9, 0x58, 0x09, 0x85, 0x48, 0xa2, 0xd3, 0xb5, 0xe2, 0x4d, 0x11, 0x82, 0xe6, 0x86, 0x3c, 0xe9, 0xb1, 0x00, 0x19, 0xc2, 0x57, 0xf7, 0x66, 0x7a}}},
{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
{{{0x0f, 0xe3, 0x89, 0x03, 0xd7, 0x22, 0x95, 0x9f, 0xca, 0xb4, 0x8d, 0x9e, 0x6d, 0x97, 0xff, 0x8d, 0x21, 0x59, 0x07, 0xef, 0x03, 0x2d, 0x5e, 0xf8, 0x44, 0x46, 0xe7, 0x85, 0x80, 0xc5, 0x89, 0x50}} ,
{{0x8b, 0xd8, 0x53, 0x86, 0x24, 0x86, 0x29, 0x52, 0x01, 0xfa, 0x20, 0xc3, 0x4e, 0x95, 0xcb, 0xad, 0x7b, 0x34, 0x94, 0x30, 0xb7, 0x7a, 0xfa, 0x96, 0x41, 0x60, 0x2b, 0xcb, 0x59, 0xb9, 0xca, 0x50}}},
{{{0xc2, 0x5b, 0x9b, 0x78, 0x23, 0x1b, 0x3a, 0x88, 0x94, 0x5f, 0x0a, 0x9b, 0x98, 0x2b, 0x6e, 0x53, 0x11, 0xf6, 0xff, 0xc6, 0x7d, 0x42, 0xcc, 0x02, 0x80, 0x40, 0x0d, 0x1e, 0xfb, 0xaf, 0x61, 0x07}} ,
{{0xb0, 0xe6, 0x2f, 0x81, 0x70, 0xa1, 0x2e, 0x39, 0x04, 0x7c, 0xc4, 0x2c, 0x87, 0x45, 0x4a, 0x5b, 0x69, 0x97, 0xac, 0x6d, 0x2c, 0x10, 0x42, 0x7c, 0x3b, 0x15, 0x70, 0x60, 0x0e, 0x11, 0x6d, 0x3a}}},
{{{0x9b, 0x18, 0x80, 0x5e, 0xdb, 0x05, 0xbd, 0xc6, 0xb7, 0x3c, 0xc2, 0x40, 0x4d, 0x5d, 0xce, 0x97, 0x8a, 0x34, 0x15, 0xab, 0x28, 0x5d, 0x10, 0xf0, 0x37, 0x0c, 0xcc, 0x16, 0xfa, 0x1f, 0x33, 0x0d}} ,
{{0x19, 0xf9, 0x35, 0xaa, 0x59, 0x1a, 0x0c, 0x5c, 0x06, 0xfc, 0x6a, 0x0b, 0x97, 0x53, 0x36, 0xfc, 0x2a, 0xa5, 0x5a, 0x9b, 0x30, 0xef, 0x23, 0xaf, 0x39, 0x5d, 0x9a, 0x6b, 0x75, 0x57, 0x48, 0x0b}}},
{{{0x26, 0xdc, 0x76, 0x3b, 0xfc, 0xf9, 0x9c, 0x3f, 0x89, 0x0b, 0x62, 0x53, 0xaf, 0x83, 0x01, 0x2e, 0xbc, 0x6a, 0xc6, 0x03, 0x0d, 0x75, 0x2a, 0x0d, 0xe6, 0x94, 0x54, 0xcf, 0xb3, 0xe5, 0x96, 0x25}} ,
{{0xfe, 0x82, 0xb1, 0x74, 0x31, 0x8a, 0xa7, 0x6f, 0x56, 0xbd, 0x8d, 0xf4, 0xe0, 0x94, 0x51, 0x59, 0xde, 0x2c, 0x5a, 0xf4, 0x84, 0x6b, 0x4a, 0x88, 0x93, 0xc0, 0x0c, 0x9a, 0xac, 0xa7, 0xa0, 0x68}}},
{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
{{{0x25, 0x0d, 0xd6, 0xc7, 0x23, 0x47, 0x10, 0xad, 0xc7, 0x08, 0x5c, 0x87, 0x87, 0x93, 0x98, 0x18, 0xb8, 0xd3, 0x9c, 0xac, 0x5a, 0x3d, 0xc5, 0x75, 0xf8, 0x49, 0x32, 0x14, 0xcc, 0x51, 0x96, 0x24}} ,
{{0x65, 0x9c, 0x5d, 0xf0, 0x37, 0x04, 0xf0, 0x34, 0x69, 0x2a, 0xf0, 0xa5, 0x64, 0xca, 0xde, 0x2b, 0x5b, 0x15, 0x10, 0xd2, 0xab, 0x06, 0xdd, 0xc4, 0xb0, 0xb6, 0x5b, 0xc1, 0x17, 0xdf, 0x8f, 0x02}}},
{{{0xbd, 0x59, 0x3d, 0xbf, 0x5c, 0x31, 0x44, 0x2c, 0x32, 0x94, 0x04, 0x60, 0x84, 0x0f, 0xad, 0x00, 0xb6, 0x8f, 0xc9, 0x1d, 0xcc, 0x5c, 0xa2, 0x49, 0x0e, 0x50, 0x91, 0x08, 0x9a, 0x43, 0x55, 0x05}} ,
{{0x5d, 0x93, 0x55, 0xdf, 0x9b, 0x12, 0x19, 0xec, 0x93, 0x85, 0x42, 0x9e, 0x66, 0x0f, 0x9d, 0xaf, 0x99, 0xaf, 0x26, 0x89, 0xbc, 0x61, 0xfd, 0xff, 0xce, 0x4b, 0xf4, 0x33, 0x95, 0xc9, 0x35, 0x58}}},
{{{0x12, 0x55, 0xf9, 0xda, 0xcb, 0x44, 0xa7, 0xdc, 0x57, 0xe2, 0xf9, 0x9a, 0xe6, 0x07, 0x23, 0x60, 0x54, 0xa7, 0x39, 0xa5, 0x9b, 0x84, 0x56, 0x6e, 0xaa, 0x8b, 0x8f, 0xb0, 0x2c, 0x87, 0xaf, 0x67}} ,
{{0x00, 0xa9, 0x4c, 0xb2, 0x12, 0xf8, 0x32, 0xa8, 0x7a, 0x00, 0x4b, 0x49, 0x32, 0xba, 0x1f, 0x5d, 0x44, 0x8e, 0x44, 0x7a, 0xdc, 0x11, 0xfb, 0x39, 0x08, 0x57, 0x87, 0xa5, 0x12, 0x42, 0x93, 0x0e}}},
{{{0x17, 0xb4, 0xae, 0x72, 0x59, 0xd0, 0xaa, 0xa8, 0x16, 0x8b, 0x63, 0x11, 0xb3, 0x43, 0x04, 0xda, 0x0c, 0xa8, 0xb7, 0x68, 0xdd, 0x4e, 0x54, 0xe7, 0xaf, 0x5d, 0x5d, 0x05, 0x76, 0x36, 0xec, 0x0d}} ,
{{0x6d, 0x7c, 0x82, 0x32, 0x38, 0x55, 0x57, 0x74, 0x5b, 0x7d, 0xc3, 0xc4, 0xfb, 0x06, 0x29, 0xf0, 0x13, 0x55, 0x54, 0xc6, 0xa7, 0xdc, 0x4c, 0x9f, 0x98, 0x49, 0x20, 0xa8, 0xc3, 0x8d, 0xfa, 0x48}}},
{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
{{{0x87, 0x47, 0x9d, 0xe9, 0x25, 0xd5, 0xe3, 0x47, 0x78, 0xdf, 0x85, 0xa7, 0x85, 0x5e, 0x7a, 0x4c, 0x5f, 0x79, 0x1a, 0xf3, 0xa2, 0xb2, 0x28, 0xa0, 0x9c, 0xdd, 0x30, 0x40, 0xd4, 0x38, 0xbd, 0x28}} ,
{{0xfc, 0xbb, 0xd5, 0x78, 0x6d, 0x1d, 0xd4, 0x99, 0xb4, 0xaa, 0x44, 0x44, 0x7a, 0x1b, 0xd8, 0xfe, 0xb4, 0x99, 0xb9, 0xcc, 0xe7, 0xc4, 0xd3, 0x3a, 0x73, 0x83, 0x41, 0x5c, 0x40, 0xd7, 0x2d, 0x55}}},
{{{0x26, 0xe1, 0x7b, 0x5f, 0xe5, 0xdc, 0x3f, 0x7d, 0xa1, 0xa7, 0x26, 0x44, 0x22, 0x23, 0xc0, 0x8f, 0x7d, 0xf1, 0xb5, 0x11, 0x47, 0x7b, 0x19, 0xd4, 0x75, 0x6f, 0x1e, 0xa5, 0x27, 0xfe, 0xc8, 0x0e}} ,
{{0xd3, 0x11, 0x3d, 0xab, 0xef, 0x2c, 0xed, 0xb1, 0x3d, 0x7c, 0x32, 0x81, 0x6b, 0xfe, 0xf8, 0x1c, 0x3c, 0x7b, 0xc0, 0x61, 0xdf, 0xb8, 0x75, 0x76, 0x7f, 0xaa, 0xd8, 0x93, 0xaf, 0x3d, 0xe8, 0x3d}}},
{{{0xfd, 0x5b, 0x4e, 0x8d, 0xb6, 0x7e, 0x82, 0x9b, 0xef, 0xce, 0x04, 0x69, 0x51, 0x52, 0xff, 0xef, 0xa0, 0x52, 0xb5, 0x79, 0x17, 0x5e, 0x2f, 0xde, 0xd6, 0x3c, 0x2d, 0xa0, 0x43, 0xb4, 0x0b, 0x19}} ,
{{0xc0, 0x61, 0x48, 0x48, 0x17, 0xf4, 0x9e, 0x18, 0x51, 0x2d, 0xea, 0x2f, 0xf2, 0xf2, 0xe0, 0xa3, 0x14, 0xb7, 0x8b, 0x3a, 0x30, 0xf5, 0x81, 0xc1, 0x5d, 0x71, 0x39, 0x62, 0x55, 0x1f, 0x60, 0x5a}}},
{{{0xe5, 0x89, 0x8a, 0x76, 0x6c, 0xdb, 0x4d, 0x0a, 0x5b, 0x72, 0x9d, 0x59, 0x6e, 0x63, 0x63, 0x18, 0x7c, 0xe3, 0xfa, 0xe2, 0xdb, 0xa1, 0x8d, 0xf4, 0xa5, 0xd7, 0x16, 0xb2, 0xd0, 0xb3, 0x3f, 0x39}} ,
{{0xce, 0x60, 0x09, 0x6c, 0xf5, 0x76, 0x17, 0x24, 0x80, 0x3a, 0x96, 0xc7, 0x94, 0x2e, 0xf7, 0x6b, 0xef, 0xb5, 0x05, 0x96, 0xef, 0xd3, 0x7b, 0x51, 0xda, 0x05, 0x44, 0x67, 0xbc, 0x07, 0x21, 0x4e}}},
{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
{{{0xe9, 0x73, 0x6f, 0x21, 0xb9, 0xde, 0x22, 0x7d, 0xeb, 0x97, 0x31, 0x10, 0xa3, 0xea, 0xe1, 0xc6, 0x37, 0xeb, 0x8f, 0x43, 0x58, 0xde, 0x41, 0x64, 0x0e, 0x3e, 0x07, 0x99, 0x3d, 0xf1, 0xdf, 0x1e}} ,
{{0xf8, 0xad, 0x43, 0xc2, 0x17, 0x06, 0xe2, 0xe4, 0xa9, 0x86, 0xcd, 0x18, 0xd7, 0x78, 0xc8, 0x74, 0x66, 0xd2, 0x09, 0x18, 0xa5, 0xf1, 0xca, 0xa6, 0x62, 0x92, 0xc1, 0xcb, 0x00, 0xeb, 0x42, 0x2e}}},
{{{0x7b, 0x34, 0x24, 0x4c, 0xcf, 0x38, 0xe5, 0x6c, 0x0a, 0x01, 0x2c, 0x22, 0x0b, 0x24, 0x38, 0xad, 0x24, 0x7e, 0x19, 0xf0, 0x6c, 0xf9, 0x31, 0xf4, 0x35, 0x11, 0xf6, 0x46, 0x33, 0x3a, 0x23, 0x59}} ,
{{0x20, 0x0b, 0xa1, 0x08, 0x19, 0xad, 0x39, 0x54, 0xea, 0x3e, 0x23, 0x09, 0xb6, 0xe2, 0xd2, 0xbc, 0x4d, 0xfc, 0x9c, 0xf0, 0x13, 0x16, 0x22, 0x3f, 0xb9, 0xd2, 0x11, 0x86, 0x90, 0x55, 0xce, 0x3c}}},
{{{0xc4, 0x0b, 0x4b, 0x62, 0x99, 0x37, 0x84, 0x3f, 0x74, 0xa2, 0xf9, 0xce, 0xe2, 0x0b, 0x0f, 0x2a, 0x3d, 0xa3, 0xe3, 0xdb, 0x5a, 0x9d, 0x93, 0xcc, 0xa5, 0xef, 0x82, 0x91, 0x1d, 0xe6, 0x6c, 0x68}} ,
{{0xa3, 0x64, 0x17, 0x9b, 0x8b, 0xc8, 0x3a, 0x61, 0xe6, 0x9d, 0xc6, 0xed, 0x7b, 0x03, 0x52, 0x26, 0x9d, 0x3a, 0xb3, 0x13, 0xcc, 0x8a, 0xfd, 0x2c, 0x1a, 0x1d, 0xed, 0x13, 0xd0, 0x55, 0x57, 0x0e}}},
{{{0x1a, 0xea, 0xbf, 0xfd, 0x4a, 0x3c, 0x8e, 0xec, 0x29, 0x7e, 0x77, 0x77, 0x12, 0x99, 0xd7, 0x84, 0xf9, 0x55, 0x7f, 0xf1, 0x8b, 0xb4, 0xd2, 0x95, 0xa3, 0x8d, 0xf0, 0x8a, 0xa7, 0xeb, 0x82, 0x4b}} ,
{{0x2c, 0x28, 0xf4, 0x3a, 0xf6, 0xde, 0x0a, 0xe0, 0x41, 0x44, 0x23, 0xf8, 0x3f, 0x03, 0x64, 0x9f, 0xc3, 0x55, 0x4c, 0xc6, 0xc1, 0x94, 0x1c, 0x24, 0x5d, 0x5f, 0x92, 0x45, 0x96, 0x57, 0x37, 0x14}}},
{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
{{{0xc1, 0xcd, 0x90, 0x66, 0xb9, 0x76, 0xa0, 0x5b, 0xa5, 0x85, 0x75, 0x23, 0xf9, 0x89, 0xa5, 0x82, 0xb2, 0x6f, 0xb1, 0xeb, 0xc4, 0x69, 0x6f, 0x18, 0x5a, 0xed, 0x94, 0x3d, 0x9d, 0xd9, 0x2c, 0x1a}} ,
{{0x35, 0xb0, 0xe6, 0x73, 0x06, 0xb7, 0x37, 0xe0, 0xf8, 0xb0, 0x22, 0xe8, 0xd2, 0xed, 0x0b, 0xef, 0xe6, 0xc6, 0x5a, 0x99, 0x9e, 0x1a, 0x9f, 0x04, 0x97, 0xe4, 0x4d, 0x0b, 0xbe, 0xba, 0x44, 0x40}}},
{{{0xc1, 0x56, 0x96, 0x91, 0x5f, 0x1f, 0xbb, 0x54, 0x6f, 0x88, 0x89, 0x0a, 0xb2, 0xd6, 0x41, 0x42, 0x6a, 0x82, 0xee, 0x14, 0xaa, 0x76, 0x30, 0x65, 0x0f, 0x67, 0x39, 0xa6, 0x51, 0x7c, 0x49, 0x24}} ,
{{0x35, 0xa3, 0x78, 0xd1, 0x11, 0x0f, 0x75, 0xd3, 0x70, 0x46, 0xdb, 0x20, 0x51, 0xcb, 0x92, 0x80, 0x54, 0x10, 0x74, 0x36, 0x86, 0xa9, 0xd7, 0xa3, 0x08, 0x78, 0xf1, 0x01, 0x29, 0xf8, 0x80, 0x3b}}},
{{{0xdb, 0xa7, 0x9d, 0x9d, 0xbf, 0xa0, 0xcc, 0xed, 0x53, 0xa2, 0xa2, 0x19, 0x39, 0x48, 0x83, 0x19, 0x37, 0x58, 0xd1, 0x04, 0x28, 0x40, 0xf7, 0x8a, 0xc2, 0x08, 0xb7, 0xa5, 0x42, 0xcf, 0x53, 0x4c}} ,
{{0xa7, 0xbb, 0xf6, 0x8e, 0xad, 0xdd, 0xf7, 0x90, 0xdd, 0x5f, 0x93, 0x89, 0xae, 0x04, 0x37, 0xe6, 0x9a, 0xb7, 0xe8, 0xc0, 0xdf, 0x16, 0x2a, 0xbf, 0xc4, 0x3a, 0x3c, 0x41, 0xd5, 0x89, 0x72, 0x5a}}},
{{{0x1f, 0x96, 0xff, 0x34, 0x2c, 0x13, 0x21, 0xcb, 0x0a, 0x89, 0x85, 0xbe, 0xb3, 0x70, 0x9e, 0x1e, 0xde, 0x97, 0xaf, 0x96, 0x30, 0xf7, 0x48, 0x89, 0x40, 0x8d, 0x07, 0xf1, 0x25, 0xf0, 0x30, 0x58}} ,
{{0x1e, 0xd4, 0x93, 0x57, 0xe2, 0x17, 0xe7, 0x9d, 0xab, 0x3c, 0x55, 0x03, 0x82, 0x2f, 0x2b, 0xdb, 0x56, 0x1e, 0x30, 0x2e, 0x24, 0x47, 0x6e, 0xe6, 0xff, 0x33, 0x24, 0x2c, 0x75, 0x51, 0xd4, 0x67}}},
{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
{{{0x2b, 0x06, 0xd9, 0xa1, 0x5d, 0xe1, 0xf4, 0xd1, 0x1e, 0x3c, 0x9a, 0xc6, 0x29, 0x2b, 0x13, 0x13, 0x78, 0xc0, 0xd8, 0x16, 0x17, 0x2d, 0x9e, 0xa9, 0xc9, 0x79, 0x57, 0xab, 0x24, 0x91, 0x92, 0x19}} ,
{{0x69, 0xfb, 0xa1, 0x9c, 0xa6, 0x75, 0x49, 0x7d, 0x60, 0x73, 0x40, 0x42, 0xc4, 0x13, 0x0a, 0x95, 0x79, 0x1e, 0x04, 0x83, 0x94, 0x99, 0x9b, 0x1e, 0x0c, 0xe8, 0x1f, 0x54, 0xef, 0xcb, 0xc0, 0x52}}},
{{{0x14, 0x89, 0x73, 0xa1, 0x37, 0x87, 0x6a, 0x7a, 0xcf, 0x1d, 0xd9, 0x2e, 0x1a, 0x67, 0xed, 0x74, 0xc0, 0xf0, 0x9c, 0x33, 0xdd, 0xdf, 0x08, 0xbf, 0x7b, 0xd1, 0x66, 0xda, 0xe6, 0xc9, 0x49, 0x08}} ,
{{0xe9, 0xdd, 0x5e, 0x55, 0xb0, 0x0a, 0xde, 0x21, 0x4c, 0x5a, 0x2e, 0xd4, 0x80, 0x3a, 0x57, 0x92, 0x7a, 0xf1, 0xc4, 0x2c, 0x40, 0xaf, 0x2f, 0xc9, 0x92, 0x03, 0xe5, 0x5a, 0xbc, 0xdc, 0xf4, 0x09}}},
{{{0xf3, 0xe1, 0x2b, 0x7c, 0x05, 0x86, 0x80, 0x93, 0x4a, 0xad, 0xb4, 0x8f, 0x7e, 0x99, 0x0c, 0xfd, 0xcd, 0xef, 0xd1, 0xff, 0x2c, 0x69, 0x34, 0x13, 0x41, 0x64, 0xcf, 0x3b, 0xd0, 0x90, 0x09, 0x1e}} ,
{{0x9d, 0x45, 0xd6, 0x80, 0xe6, 0x45, 0xaa, 0xf4, 0x15, 0xaa, 0x5c, 0x34, 0x87, 0x99, 0xa2, 0x8c, 0x26, 0x84, 0x62, 0x7d, 0xb6, 0x29, 0xc0, 0x52, 0xea, 0xf5, 0x81, 0x18, 0x0f, 0x35, 0xa9, 0x0e}}},
{{{0xe7, 0x20, 0x72, 0x7c, 0x6d, 0x94, 0x5f, 0x52, 0x44, 0x54, 0xe3, 0xf1, 0xb2, 0xb0, 0x36, 0x46, 0x0f, 0xae, 0x92, 0xe8, 0x70, 0x9d, 0x6e, 0x79, 0xb1, 0xad, 0x37, 0xa9, 0x5f, 0xc0, 0xde, 0x03}} ,
{{0x15, 0x55, 0x37, 0xc6, 0x1c, 0x27, 0x1c, 0x6d, 0x14, 0x4f, 0xca, 0xa4, 0xc4, 0x88, 0x25, 0x46, 0x39, 0xfc, 0x5a, 0xe5, 0xfe, 0x29, 0x11, 0x69, 0xf5, 0x72, 0x84, 0x4d, 0x78, 0x9f, 0x94, 0x15}}},
{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
{{{0xec, 0xd3, 0xff, 0x57, 0x0b, 0xb0, 0xb2, 0xdc, 0xf8, 0x4f, 0xe2, 0x12, 0xd5, 0x36, 0xbe, 0x6b, 0x09, 0x43, 0x6d, 0xa3, 0x4d, 0x90, 0x2d, 0xb8, 0x74, 0xe8, 0x71, 0x45, 0x19, 0x8b, 0x0c, 0x6a}} ,
{{0xb8, 0x42, 0x1c, 0x03, 0xad, 0x2c, 0x03, 0x8e, 0xac, 0xd7, 0x98, 0x29, 0x13, 0xc6, 0x02, 0x29, 0xb5, 0xd4, 0xe7, 0xcf, 0xcc, 0x8b, 0x83, 0xec, 0x35, 0xc7, 0x9c, 0x74, 0xb7, 0xad, 0x85, 0x5f}}},
{{{0x78, 0x84, 0xe1, 0x56, 0x45, 0x69, 0x68, 0x5a, 0x4f, 0xb8, 0xb1, 0x29, 0xff, 0x33, 0x03, 0x31, 0xb7, 0xcb, 0x96, 0x25, 0xe6, 0xe6, 0x41, 0x98, 0x1a, 0xbb, 0x03, 0x56, 0xf2, 0xb2, 0x91, 0x34}} ,
{{0x2c, 0x6c, 0xf7, 0x66, 0xa4, 0x62, 0x6b, 0x39, 0xb3, 0xba, 0x65, 0xd3, 0x1c, 0xf8, 0x11, 0xaa, 0xbe, 0xdc, 0x80, 0x59, 0x87, 0xf5, 0x7b, 0xe5, 0xe3, 0xb3, 0x3e, 0x39, 0xda, 0xbe, 0x88, 0x09}}},
{{{0x8b, 0xf1, 0xa0, 0xf5, 0xdc, 0x29, 0xb4, 0xe2, 0x07, 0xc6, 0x7a, 0x00, 0xd0, 0x89, 0x17, 0x51, 0xd4, 0xbb, 0xd4, 0x22, 0xea, 0x7e, 0x7d, 0x7c, 0x24, 0xea, 0xf2, 0xe8, 0x22, 0x12, 0x95, 0x06}} ,
{{0xda, 0x7c, 0xa4, 0x0c, 0xf4, 0xba, 0x6e, 0xe1, 0x89, 0xb5, 0x59, 0xca, 0xf1, 0xc0, 0x29, 0x36, 0x09, 0x44, 0xe2, 0x7f, 0xd1, 0x63, 0x15, 0x99, 0xea, 0x25, 0xcf, 0x0c, 0x9d, 0xc0, 0x44, 0x6f}}},
{{{0x1d, 0x86, 0x4e, 0xcf, 0xf7, 0x37, 0x10, 0x25, 0x8f, 0x12, 0xfb, 0x19, 0xfb, 0xe0, 0xed, 0x10, 0xc8, 0xe2, 0xf5, 0x75, 0xb1, 0x33, 0xc0, 0x96, 0x0d, 0xfb, 0x15, 0x6c, 0x0d, 0x07, 0x5f, 0x05}} ,
{{0x69, 0x3e, 0x47, 0x97, 0x2c, 0xaf, 0x52, 0x7c, 0x78, 0x83, 0xad, 0x1b, 0x39, 0x82, 0x2f, 0x02, 0x6f, 0x47, 0xdb, 0x2a, 0xb0, 0xe1, 0x91, 0x99, 0x55, 0xb8, 0x99, 0x3a, 0xa0, 0x44, 0x11, 0x51}}}

373
src/external/sc25519.c vendored
View File

@@ -1,373 +0,0 @@
/*
* Public Domain, Authors: Daniel J. Bernstein, Niels Duif, Tanja Lange,
* Peter Schwabe, Bo-Yin Yang.
* Copied from supercop-20130419/crypto_sign/ed25519/ref/sc25519.c
*/
#include "libssh/priv.h"
#include "libssh/sc25519.h"
/*Arithmetic modulo the group order m = 2^252 + 27742317777372353535851937790883648493 = 7237005577332262213973186563042994240857116359379907606001950938285454250989 */
static const uint32_t m[32] = {
0xED, 0xD3, 0xF5, 0x5C, 0x1A, 0x63, 0x12, 0x58,
0xD6, 0x9C, 0xF7, 0xA2, 0xDE, 0xF9, 0xDE, 0x14,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10
};
static const uint32_t mu[33] = {
0x1B, 0x13, 0x2C, 0x0A, 0xA3, 0xE5, 0x9C, 0xED,
0xA7, 0x29, 0x63, 0x08, 0x5D, 0x21, 0x06, 0x21,
0xEB, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F
};
static uint32_t lt(uint32_t a,uint32_t b) /* 16-bit inputs */
{
unsigned int x = a;
x -= (unsigned int) b; /* 0..65535: no; 4294901761..4294967295: yes */
x >>= 31; /* 0: no; 1: yes */
return x;
}
/* Reduce coefficients of r before calling reduce_add_sub */
static void reduce_add_sub(sc25519 *r)
{
uint32_t pb = 0;
uint32_t b;
uint32_t mask;
int i;
unsigned char t[32];
for (i = 0; i < 32; i++) {
pb += m[i];
b = lt(r->v[i],pb);
t[i] = r->v[i]-pb+(b<<8);
pb = b;
}
mask = b - 1;
for (i = 0; i < 32; i++) {
r->v[i] ^= mask & (r->v[i] ^ t[i]);
}
}
/* Reduce coefficients of x before calling barrett_reduce */
static void barrett_reduce(sc25519 *r, const uint32_t x[64])
{
/* See HAC, Alg. 14.42 */
int i,j;
uint32_t q2[66];
uint32_t *q3 = q2 + 33;
uint32_t r1[33];
uint32_t r2[33];
uint32_t carry;
uint32_t pb = 0;
uint32_t b;
for (i = 0; i < 66; i++) {
q2[i] = 0;
}
for (i = 0; i < 33; i++) {
r2[i] = 0;
}
for (i = 0; i < 33; i++) {
for (j = 0; j < 33; j++) {
if (i + j >= 31) {
q2[i+j] += mu[i]*x[j+31];
}
}
}
carry = q2[31] >> 8;
q2[32] += carry;
carry = q2[32] >> 8;
q2[33] += carry;
for (i = 0; i < 33; i++) {
r1[i] = x[i];
}
for (i = 0; i < 32; i++) {
for (j = 0; j < 33; j++) {
if (i + j < 33) {
r2[i+j] += m[i]*q3[j];
}
}
}
for (i = 0; i < 32; i++) {
carry = r2[i] >> 8;
r2[i+1] += carry;
r2[i] &= 0xff;
}
for (i = 0; i < 32; i++) {
pb += r2[i];
b = lt(r1[i],pb);
r->v[i] = r1[i]-pb+(b<<8);
pb = b;
}
/* XXX: Can it really happen that r<0?, See HAC, Alg 14.42, Step 3
* If so: Handle it here!
*/
reduce_add_sub(r);
reduce_add_sub(r);
}
void sc25519_from32bytes(sc25519 *r, const unsigned char x[32])
{
int i;
uint32_t t[64];
for (i = 0; i < 32; i++) {
t[i] = x[i];
}
for (i = 32; i < 64; i++) {
t[i] = 0;
}
barrett_reduce(r, t);
}
void shortsc25519_from16bytes(shortsc25519 *r, const unsigned char x[16])
{
int i;
for (i = 0; i < 16; i++) {
r->v[i] = x[i];
}
}
void sc25519_from64bytes(sc25519 *r, const unsigned char x[64])
{
int i;
uint32_t t[64];
for (i = 0; i < 64; i++) {
t[i] = x[i];
}
barrett_reduce(r, t);
}
void sc25519_from_shortsc(sc25519 *r, const shortsc25519 *x)
{
int i;
for (i = 0; i < 16; i++) {
r->v[i] = x->v[i];
}
for (i = 0; i < 16; i++) {
r->v[16+i] = 0;
}
}
void sc25519_to32bytes(unsigned char r[32], const sc25519 *x)
{
int i;
for (i = 0; i < 32; i++) {
r[i] = x->v[i];
}
}
int sc25519_iszero_vartime(const sc25519 *x)
{
int i;
for (i = 0; i < 32; i++) {
if(x->v[i] != 0) {
return 0;
}
}
return 1;
}
int sc25519_isshort_vartime(const sc25519 *x)
{
int i;
for (i = 31; i > 15; i--) {
if (x->v[i] != 0) {
return 0;
}
}
return 1;
}
int sc25519_lt_vartime(const sc25519 *x, const sc25519 *y)
{
int i;
for (i = 31; i >= 0; i--) {
if (x->v[i] < y->v[i]) {
return 1;
}
if (x->v[i] > y->v[i]) {
return 0;
}
}
return 0;
}
void sc25519_add(sc25519 *r, const sc25519 *x, const sc25519 *y)
{
int i, carry;
for (i = 0; i < 32; i++) {
r->v[i] = x->v[i] + y->v[i];
}
for (i = 0;i < 31; i++) {
carry = r->v[i] >> 8;
r->v[i+1] += carry;
r->v[i] &= 0xff;
}
reduce_add_sub(r);
}
void sc25519_sub_nored(sc25519 *r, const sc25519 *x, const sc25519 *y)
{
uint32_t b = 0;
uint32_t t;
int i;
for (i = 0; i < 32; i++) {
t = x->v[i] - y->v[i] - b;
r->v[i] = t & 255;
b = (t >> 8) & 1;
}
}
void sc25519_mul(sc25519 *r, const sc25519 *x, const sc25519 *y)
{
int i,j,carry;
uint32_t t[64];
for (i = 0; i < 64; i++) {
t[i] = 0;
}
for (i = 0; i < 32; i++) {
for (j = 0; j < 32; j++) {
t[i+j] += x->v[i] * y->v[j];
}
}
/* Reduce coefficients */
for (i = 0; i < 63; i++) {
carry = t[i] >> 8;
t[i+1] += carry;
t[i] &= 0xff;
}
barrett_reduce(r, t);
}
void sc25519_mul_shortsc(sc25519 *r, const sc25519 *x, const shortsc25519 *y)
{
sc25519 t;
sc25519_from_shortsc(&t, y);
sc25519_mul(r, x, &t);
}
void sc25519_window3(signed char r[85], const sc25519 *s)
{
char carry;
int i;
for (i = 0; i < 10; i++) {
r[8*i+0] = s->v[3*i+0] & 7;
r[8*i+1] = (s->v[3*i+0] >> 3) & 7;
r[8*i+2] = (s->v[3*i+0] >> 6) & 7;
r[8*i+2] ^= (s->v[3*i+1] << 2) & 7;
r[8*i+3] = (s->v[3*i+1] >> 1) & 7;
r[8*i+4] = (s->v[3*i+1] >> 4) & 7;
r[8*i+5] = (s->v[3*i+1] >> 7) & 7;
r[8*i+5] ^= (s->v[3*i+2] << 1) & 7;
r[8*i+6] = (s->v[3*i+2] >> 2) & 7;
r[8*i+7] = (s->v[3*i+2] >> 5) & 7;
}
r[8*i+0] = s->v[3*i+0] & 7;
r[8*i+1] = (s->v[3*i+0] >> 3) & 7;
r[8*i+2] = (s->v[3*i+0] >> 6) & 7;
r[8*i+2] ^= (s->v[3*i+1] << 2) & 7;
r[8*i+3] = (s->v[3*i+1] >> 1) & 7;
r[8*i+4] = (s->v[3*i+1] >> 4) & 7;
/* Making it signed */
carry = 0;
for (i = 0; i < 84; i++) {
r[i] += carry;
r[i+1] += r[i] >> 3;
r[i] &= 7;
carry = r[i] >> 2;
r[i] -= carry<<3;
}
r[84] += carry;
}
void sc25519_window5(signed char r[51], const sc25519 *s)
{
char carry;
int i;
for (i = 0; i < 6; i++) {
r[8*i+0] = s->v[5*i+0] & 31;
r[8*i+1] = (s->v[5*i+0] >> 5) & 31;
r[8*i+1] ^= (s->v[5*i+1] << 3) & 31;
r[8*i+2] = (s->v[5*i+1] >> 2) & 31;
r[8*i+3] = (s->v[5*i+1] >> 7) & 31;
r[8*i+3] ^= (s->v[5*i+2] << 1) & 31;
r[8*i+4] = (s->v[5*i+2] >> 4) & 31;
r[8*i+4] ^= (s->v[5*i+3] << 4) & 31;
r[8*i+5] = (s->v[5*i+3] >> 1) & 31;
r[8*i+6] = (s->v[5*i+3] >> 6) & 31;
r[8*i+6] ^= (s->v[5*i+4] << 2) & 31;
r[8*i+7] = (s->v[5*i+4] >> 3) & 31;
}
r[8*i+0] = s->v[5*i+0] & 31;
r[8*i+1] = (s->v[5*i+0] >> 5) & 31;
r[8*i+1] ^= (s->v[5*i+1] << 3) & 31;
r[8*i+2] = (s->v[5*i+1] >> 2) & 31;
/* Making it signed */
carry = 0;
for (i = 0; i < 50; i++) {
r[i] += carry;
r[i+1] += r[i] >> 5;
r[i] &= 31;
carry = r[i] >> 4;
r[i] -= carry<<5;
}
r[50] += carry;
}
void sc25519_2interleave2(unsigned char r[127],
const sc25519 *s1,
const sc25519 *s2)
{
int i;
for (i = 0; i < 31; i++) {
r[4*i] = ( s1->v[i] & 3) ^ (( s2->v[i] & 3) << 2);
r[4*i+1] = ((s1->v[i] >> 2) & 3) ^ (((s2->v[i] >> 2) & 3) << 2);
r[4*i+2] = ((s1->v[i] >> 4) & 3) ^ (((s2->v[i] >> 4) & 3) << 2);
r[4*i+3] = ((s1->v[i] >> 6) & 3) ^ (((s2->v[i] >> 6) & 3) << 2);
}
r[124] = ( s1->v[31] & 3) ^ (( s2->v[31] & 3) << 2);
r[125] = ((s1->v[31] >> 2) & 3) ^ (((s2->v[31] >> 2) & 3) << 2);
r[126] = ((s1->v[31] >> 4) & 3) ^ (((s2->v[31] >> 4) & 3) << 2);
}

View File

@@ -120,7 +120,6 @@ static int ssh_gssapi_send_response(ssh_session session, ssh_string oid){
ssh_set_error_oom(session);
return SSH_ERROR;
}
session->auth_state = SSH_AUTH_STATE_GSSAPI_TOKEN;
packet_send(session);
SSH_LOG(SSH_LOG_PACKET,
@@ -130,53 +129,11 @@ static int ssh_gssapi_send_response(ssh_session session, ssh_string oid){
#endif /* WITH_SERVER */
static void ssh_gssapi_log_error(int verb,
const char *msg,
int maj_stat,
int min_stat)
{
gss_buffer_desc msg_maj = {
.length = 0,
};
gss_buffer_desc msg_min = {
.length = 0,
};
OM_uint32 dummy_maj, dummy_min;
OM_uint32 message_context = 0;
dummy_maj = gss_display_status(&dummy_min,
maj_stat,
GSS_C_GSS_CODE,
GSS_C_NO_OID,
&message_context,
&msg_maj);
if (dummy_maj != 0) {
goto out;
}
dummy_maj = gss_display_status(&dummy_min,
min_stat,
GSS_C_MECH_CODE,
GSS_C_NO_OID,
&message_context,
&msg_min);
if (dummy_maj != 0) {
goto out;
}
SSH_LOG(verb,
"GSSAPI(%s): %s - %s",
msg,
(const char *)msg_maj.value,
(const char *)msg_min.value);
out:
if (msg_maj.value) {
dummy_maj = gss_release_buffer(&dummy_min, &msg_maj);
}
if (msg_min.value) {
dummy_maj = gss_release_buffer(&dummy_min, &msg_min);
}
static void ssh_gssapi_log_error(int verb, const char *msg, int maj_stat){
gss_buffer_desc buffer;
OM_uint32 dummy, message_context;
gss_display_status(&dummy,maj_stat,GSS_C_GSS_CODE, GSS_C_NO_OID, &message_context, &buffer);
SSH_LOG(verb, "GSSAPI(%s): %s", msg, (const char *)buffer.value);
}
#ifdef WITH_SERVER
@@ -255,10 +212,7 @@ int ssh_gssapi_handle_userauth(ssh_session session, const char *user, uint32_t n
(gss_OID) GSS_C_NT_HOSTBASED_SERVICE, &server_name);
if (maj_stat != GSS_S_COMPLETE) {
SSH_LOG(SSH_LOG_WARNING, "importing name %d, %d", maj_stat, min_stat);
ssh_gssapi_log_error(SSH_LOG_WARNING,
"importing name",
maj_stat,
min_stat);
ssh_gssapi_log_error(SSH_LOG_WARNING, "importing name", maj_stat);
return -1;
}
@@ -270,10 +224,7 @@ int ssh_gssapi_handle_userauth(ssh_session session, const char *user, uint32_t n
if (maj_stat != GSS_S_COMPLETE) {
SSH_LOG(SSH_LOG_WARNING, "error acquiring credentials %d, %d", maj_stat, min_stat);
ssh_gssapi_log_error(SSH_LOG_WARNING,
"acquiring creds",
maj_stat,
min_stat);
ssh_gssapi_log_error(SSH_LOG_WARNING, "acquiring creds", maj_stat);
ssh_auth_reply_default(session,0);
return SSH_ERROR;
}
@@ -315,10 +266,7 @@ static char *ssh_gssapi_name_to_char(gss_name_t name){
OM_uint32 maj_stat, min_stat;
char *ptr;
maj_stat = gss_display_name(&min_stat, name, &buffer, NULL);
ssh_gssapi_log_error(SSH_LOG_WARNING,
"converting name",
maj_stat,
min_stat);
ssh_gssapi_log_error(SSH_LOG_WARNING, "converting name", maj_stat);
ptr=malloc(buffer.length + 1);
memcpy(ptr, buffer.value, buffer.length);
ptr[buffer.length] = '\0';
@@ -363,11 +311,14 @@ SSH_PACKET_CALLBACK(ssh_packet_userauth_gssapi_token_server){
return SSH_PACKET_USED;
}
if (ssh_string_len(out_token) != 0){
rc = ssh_buffer_pack(session->out_buffer,
"bS",
SSH2_MSG_USERAUTH_GSSAPI_TOKEN,
out_token);
if (rc != SSH_OK) {
rc = buffer_add_u8(session->out_buffer,
SSH2_MSG_USERAUTH_GSSAPI_TOKEN);
if (rc < 0) {
ssh_set_error_oom(session);
return SSH_PACKET_USED;
}
rc = buffer_add_ssh_string(session->out_buffer, out_token);
if (rc < 0) {
ssh_set_error_oom(session);
return SSH_PACKET_USED;
}
@@ -387,20 +338,14 @@ SSH_PACKET_CALLBACK(ssh_packet_userauth_gssapi_token_server){
maj_stat = gss_accept_sec_context(&min_stat, &session->gssapi->ctx, session->gssapi->server_creds,
&input_token, input_bindings, &client_name, NULL /*mech_oid*/, &output_token, &ret_flags,
NULL /*time*/, &session->gssapi->client_creds);
ssh_gssapi_log_error(SSH_LOG_PROTOCOL,
"accepting token",
maj_stat,
min_stat);
ssh_gssapi_log_error(SSH_LOG_PROTOCOL, "accepting token", maj_stat);
ssh_string_free(token);
if (client_name != GSS_C_NO_NAME){
session->gssapi->client_name = client_name;
session->gssapi->canonic_user = ssh_gssapi_name_to_char(client_name);
}
if (GSS_ERROR(maj_stat)){
ssh_gssapi_log_error(SSH_LOG_WARNING,
"Gssapi error",
maj_stat,
min_stat);
ssh_gssapi_log_error(SSH_LOG_WARNING, "Gssapi error", maj_stat);
ssh_auth_reply_default(session,0);
ssh_gssapi_free(session);
session->gssapi=NULL;
@@ -411,12 +356,12 @@ SSH_PACKET_CALLBACK(ssh_packet_userauth_gssapi_token_server){
hexa = ssh_get_hexa(output_token.value, output_token.length);
SSH_LOG(SSH_LOG_PACKET, "GSSAPI: sending token %s",hexa);
SAFE_FREE(hexa);
ssh_buffer_pack(session->out_buffer,
"bdP",
SSH2_MSG_USERAUTH_GSSAPI_TOKEN,
output_token.length,
(size_t)output_token.length, output_token.value);
token = ssh_string_new(output_token.length);
ssh_string_fill(token, output_token.value, output_token.length);
buffer_add_u8(session->out_buffer, SSH2_MSG_USERAUTH_GSSAPI_TOKEN);
buffer_add_ssh_string(session->out_buffer,token);
packet_send(session);
ssh_string_free(token);
}
if(maj_stat == GSS_S_COMPLETE){
session->gssapi->state = SSH_GSSAPI_STATE_RCV_MIC;
@@ -428,24 +373,69 @@ SSH_PACKET_CALLBACK(ssh_packet_userauth_gssapi_token_server){
static ssh_buffer ssh_gssapi_build_mic(ssh_session session){
ssh_buffer mic_buffer;
ssh_string str;
int rc;
str = ssh_string_new(session->current_crypto->digest_len);
if (str == NULL) {
return NULL;
}
ssh_string_fill(str, session->current_crypto->session_id,
session->current_crypto->digest_len);
mic_buffer = ssh_buffer_new();
if (mic_buffer == NULL) {
ssh_set_error_oom(session);
ssh_string_free(str);
return NULL;
}
rc = ssh_buffer_pack(mic_buffer,
"dPbsss",
session->current_crypto->digest_len,
(size_t)session->current_crypto->digest_len, session->current_crypto->session_id,
SSH2_MSG_USERAUTH_REQUEST,
session->gssapi->user,
"ssh-connection",
"gssapi-with-mic");
if (rc != SSH_OK) {
ssh_set_error_oom(session);
rc = buffer_add_ssh_string(mic_buffer, str);
ssh_string_free(str);
if (rc < 0) {
ssh_buffer_free(mic_buffer);
return NULL;
}
rc = buffer_add_u8(mic_buffer, SSH2_MSG_USERAUTH_REQUEST);
if (rc < 0) {
ssh_buffer_free(mic_buffer);
return NULL;
}
str = ssh_string_from_char(session->gssapi->user);
if (str == NULL) {
ssh_buffer_free(mic_buffer);
return NULL;
}
rc = buffer_add_ssh_string(mic_buffer, str);
ssh_string_free(str);
if (rc < 0) {
ssh_buffer_free(mic_buffer);
return NULL;
}
str = ssh_string_from_char("ssh-connection");
if (str == NULL) {
ssh_buffer_free(mic_buffer);
return NULL;
}
rc = buffer_add_ssh_string(mic_buffer, str);
ssh_string_free(str);
if (rc < 0) {
ssh_buffer_free(mic_buffer);
return NULL;
}
str = ssh_string_from_char("gssapi-with-mic");
if (str == NULL) {
ssh_buffer_free(mic_buffer);
return NULL;
}
rc = buffer_add_ssh_string(mic_buffer, str);
ssh_string_free(str);
if (rc < 0) {
ssh_buffer_free(mic_buffer);
return NULL;
}
@@ -497,10 +487,8 @@ SSH_PACKET_CALLBACK(ssh_packet_userauth_gssapi_mic)
mic_token_buf.value = ssh_string_data(mic_token);
maj_stat = gss_verify_mic(&min_stat, session->gssapi->ctx, &mic_buf, &mic_token_buf, NULL);
ssh_gssapi_log_error(SSH_LOG_PROTOCOL,
"verifying MIC",
maj_stat,
min_stat);
ssh_gssapi_log_error(SSH_LOG_PROTOCOL, "verifying MIC", maj_stat);
ssh_gssapi_log_error(SSH_LOG_PROTOCOL, "verifying MIC (min stat)", min_stat);
if (maj_stat == GSS_S_DEFECTIVE_TOKEN || GSS_ERROR(maj_stat)) {
goto error;
}
@@ -576,19 +564,46 @@ void ssh_gssapi_set_creds(ssh_session session, const ssh_gssapi_creds creds)
}
static int ssh_gssapi_send_auth_mic(ssh_session session, ssh_string *oid_set, int n_oid){
ssh_string str;
int rc;
int i;
rc = buffer_add_u8(session->out_buffer, SSH2_MSG_USERAUTH_REQUEST);
if (rc < 0) {
goto fail;
}
/* username */
str = ssh_string_from_char(session->opts.username);
if (str == NULL) {
goto fail;
}
rc = buffer_add_ssh_string(session->out_buffer, str);
ssh_string_free(str);
if (rc < 0) {
goto fail;
}
/* service */
str = ssh_string_from_char("ssh-connection");
if (str == NULL) {
goto fail;
}
rc = buffer_add_ssh_string(session->out_buffer, str);
ssh_string_free(str);
if (rc < 0) {
goto fail;
}
/* method */
str = ssh_string_from_char("gssapi-with-mic");
if (str == NULL) {
goto fail;
}
rc = buffer_add_ssh_string(session->out_buffer, str);
ssh_string_free(str);
if (rc < 0) {
goto fail;
}
rc = ssh_buffer_pack(session->out_buffer,
"bsssd",
SSH2_MSG_USERAUTH_REQUEST,
session->opts.username,
"ssh-connection",
"gssapi-with-mic",
n_oid);
if (rc != SSH_OK) {
ssh_set_error_oom(session);
rc = buffer_add_u32(session->out_buffer, htonl(n_oid));
if (rc < 0) {
goto fail;
}
@@ -602,7 +617,7 @@ static int ssh_gssapi_send_auth_mic(ssh_session session, ssh_string *oid_set, in
session->auth_state = SSH_AUTH_STATE_GSSAPI_REQUEST_SENT;
return packet_send(session);
fail:
ssh_buffer_reinit(session->out_buffer);
buffer_reinit(session->out_buffer);
return SSH_ERROR;
}
@@ -713,11 +728,8 @@ int ssh_gssapi_auth_mic(ssh_session session){
&session->gssapi->client.server_name);
if (maj_stat != GSS_S_COMPLETE) {
SSH_LOG(SSH_LOG_WARNING, "importing name %d, %d", maj_stat, min_stat);
ssh_gssapi_log_error(SSH_LOG_WARNING,
"importing name",
maj_stat,
min_stat);
return SSH_AUTH_DENIED;
ssh_gssapi_log_error(SSH_LOG_WARNING, "importing name", maj_stat);
return SSH_PACKET_USED;
}
/* copy username */
@@ -787,6 +799,7 @@ SSH_PACKET_CALLBACK(ssh_packet_userauth_gssapi_response){
gss_buffer_desc input_token = GSS_C_EMPTY_BUFFER;
gss_buffer_desc output_token = GSS_C_EMPTY_BUFFER;
char *hexa;
ssh_string token;
(void)type;
(void)user;
@@ -822,22 +835,19 @@ SSH_PACKET_CALLBACK(ssh_packet_userauth_gssapi_response){
0, NULL, &input_token, NULL,
&output_token, NULL, NULL);
if(GSS_ERROR(maj_stat)){
ssh_gssapi_log_error(SSH_LOG_WARNING,
"Initializing gssapi context",
maj_stat,
min_stat);
ssh_gssapi_log_error(SSH_LOG_WARNING, "Initializing gssapi context", maj_stat);
return SSH_PACKET_USED;
}
if (output_token.length != 0){
hexa = ssh_get_hexa(output_token.value, output_token.length);
SSH_LOG(SSH_LOG_PACKET, "GSSAPI: sending token %s",hexa);
SAFE_FREE(hexa);
ssh_buffer_pack(session->out_buffer,
"bdP",
SSH2_MSG_USERAUTH_GSSAPI_TOKEN,
output_token.length,
(size_t)output_token.length, output_token.value);
token = ssh_string_new(output_token.length);
ssh_string_fill(token, output_token.value, output_token.length);
buffer_add_u8(session->out_buffer, SSH2_MSG_USERAUTH_GSSAPI_TOKEN);
buffer_add_ssh_string(session->out_buffer,token);
packet_send(session);
ssh_string_free(token);
session->auth_state = SSH_AUTH_STATE_GSSAPI_TOKEN;
}
return SSH_PACKET_USED;
@@ -863,24 +873,31 @@ static int ssh_gssapi_send_mic(ssh_session session){
maj_stat = gss_get_mic(&min_stat,session->gssapi->ctx, GSS_C_QOP_DEFAULT, &mic_buf, &mic_token_buf);
if (GSS_ERROR(maj_stat)){
ssh_buffer_free(mic_buffer);
ssh_gssapi_log_error(SSH_LOG_PROTOCOL,
"generating MIC",
maj_stat,
min_stat);
ssh_gssapi_log_error(SSH_LOG_PROTOCOL, "generating MIC", maj_stat);
return SSH_ERROR;
}
rc = ssh_buffer_pack(session->out_buffer,
"bdP",
SSH2_MSG_USERAUTH_GSSAPI_MIC,
mic_token_buf.length,
(size_t)mic_token_buf.length, mic_token_buf.value);
if (rc != SSH_OK) {
rc = buffer_add_u8(session->out_buffer, SSH2_MSG_USERAUTH_GSSAPI_MIC);
if (rc < 0) {
ssh_buffer_free(mic_buffer);
ssh_set_error_oom(session);
return SSH_ERROR;
}
rc = buffer_add_u32(session->out_buffer, htonl(mic_token_buf.length));
if (rc < 0) {
ssh_buffer_free(mic_buffer);
ssh_set_error_oom(session);
return SSH_ERROR;
}
rc = buffer_add_data(session->out_buffer, mic_token_buf.value, mic_token_buf.length);
ssh_buffer_free(mic_buffer);
if (rc < 0) {
ssh_set_error_oom(session);
return SSH_ERROR;
}
return packet_send(session);
}
@@ -917,16 +934,10 @@ SSH_PACKET_CALLBACK(ssh_packet_userauth_gssapi_token_client){
0, NULL, &input_token, NULL,
&output_token, NULL, NULL);
ssh_gssapi_log_error(SSH_LOG_PROTOCOL,
"accepting token",
maj_stat,
min_stat);
ssh_gssapi_log_error(SSH_LOG_PROTOCOL, "accepting token", maj_stat);
ssh_string_free(token);
if (GSS_ERROR(maj_stat)){
ssh_gssapi_log_error(SSH_LOG_PROTOCOL,
"Gssapi error",
maj_stat,
min_stat);
ssh_gssapi_log_error(SSH_LOG_PROTOCOL, "Gssapi error", maj_stat);
ssh_gssapi_free(session);
session->gssapi=NULL;
return SSH_PACKET_USED;
@@ -936,16 +947,16 @@ SSH_PACKET_CALLBACK(ssh_packet_userauth_gssapi_token_client){
hexa = ssh_get_hexa(output_token.value, output_token.length);
SSH_LOG(SSH_LOG_PACKET, "GSSAPI: sending token %s",hexa);
SAFE_FREE(hexa);
ssh_buffer_pack(session->out_buffer,
"bdP",
SSH2_MSG_USERAUTH_GSSAPI_TOKEN,
output_token.length,
(size_t)output_token.length, output_token.value);
token = ssh_string_new(output_token.length);
ssh_string_fill(token, output_token.value, output_token.length);
buffer_add_u8(session->out_buffer, SSH2_MSG_USERAUTH_GSSAPI_TOKEN);
buffer_add_ssh_string(session->out_buffer,token);
packet_send(session);
ssh_string_free(token);
}
if(maj_stat == GSS_S_COMPLETE){
session->auth_state = SSH_AUTH_STATE_NONE;
ssh_gssapi_send_mic(session);
session->auth_state = SSH_AUTH_STATE_GSSAPI_MIC_SENT;
}
return SSH_PACKET_USED;
}

View File

@@ -90,7 +90,7 @@ static ssh_buffer gzip_compress(ssh_session session,ssh_buffer source,int level)
return NULL;
}
len = BLOCKSIZE - zout->avail_out;
if (ssh_buffer_add_data(dest, out_buf, len) < 0) {
if (buffer_add_data(dest, out_buf, len) < 0) {
ssh_buffer_free(dest);
return NULL;
}
@@ -108,12 +108,12 @@ int compress_buffer(ssh_session session, ssh_buffer buf) {
return -1;
}
if (ssh_buffer_reinit(buf) < 0) {
if (buffer_reinit(buf) < 0) {
ssh_buffer_free(dest);
return -1;
}
if (ssh_buffer_add_data(buf, buffer_get_rest(dest), buffer_get_rest_len(dest)) < 0) {
if (buffer_add_data(buf, buffer_get_rest(dest), buffer_get_rest_len(dest)) < 0) {
ssh_buffer_free(dest);
return -1;
}
@@ -181,7 +181,7 @@ static ssh_buffer gzip_decompress(ssh_session session, ssh_buffer source, size_t
}
len = BLOCKSIZE - zin->avail_out;
if (ssh_buffer_add_data(dest,out_buf,len) < 0) {
if (buffer_add_data(dest,out_buf,len) < 0) {
ssh_buffer_free(dest);
return NULL;
}
@@ -204,12 +204,12 @@ int decompress_buffer(ssh_session session,ssh_buffer buf, size_t maxlen){
return -1;
}
if (ssh_buffer_reinit(buf) < 0) {
if (buffer_reinit(buf) < 0) {
ssh_buffer_free(dest);
return -1;
}
if (ssh_buffer_add_data(buf, buffer_get_rest(dest), buffer_get_rest_len(dest)) < 0) {
if (buffer_add_data(buf, buffer_get_rest(dest), buffer_get_rest_len(dest)) < 0) {
ssh_buffer_free(dest);
return -1;
}

317
src/kex.c
View File

@@ -40,30 +40,24 @@
#ifdef HAVE_LIBGCRYPT
# define BLOWFISH "blowfish-cbc,"
# define AES "aes256-ctr,aes192-ctr,aes128-ctr,aes256-cbc,aes192-cbc,aes128-cbc,"
# define DES "3des-cbc"
# define DES_SUPPORTED "3des-cbc,des-cbc-ssh1"
# define DES "3des-cbc,des-cbc-ssh1"
#elif defined(HAVE_LIBCRYPTO)
# ifdef HAVE_OPENSSL_BLOWFISH_H
# define BLOWFISH "blowfish-cbc,"
# else /* HAVE_OPENSSL_BLOWFISH_H */
# else
# define BLOWFISH ""
# endif /* HAVE_OPENSSL_BLOWFISH_H */
# endif
# ifdef HAVE_OPENSSL_AES_H
# ifdef BROKEN_AES_CTR
# define AES "aes256-cbc,aes192-cbc,aes128-cbc,"
# else /* BROKEN_AES_CTR */
# else
# define AES "aes256-ctr,aes192-ctr,aes128-ctr,aes256-cbc,aes192-cbc,aes128-cbc,"
# endif /* BROKEN_AES_CTR */
# else /* HAVE_OPENSSL_AES_H */
# else
# define AES ""
# endif /* HAVE_OPENSSL_AES_H */
# define DES "3des-cbc"
# define DES_SUPPORTED "3des-cbc,des-cbc-ssh1"
#endif /* HAVE_LIBCRYPTO */
# endif
# define DES "3des-cbc,des-cbc-ssh1"
#endif
#ifdef WITH_ZLIB
#define ZLIB "none,zlib,zlib@openssh.com"
@@ -79,9 +73,9 @@
#ifdef HAVE_ECDH
#define ECDH "ecdh-sha2-nistp256,"
#define HOSTKEYS "ssh-ed25519,ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,ssh-rsa,ssh-dss"
#define HOSTKEYS "ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,ssh-rsa,ssh-dss"
#else
#define HOSTKEYS "ssh-ed25519,ssh-rsa,ssh-dss"
#define HOSTKEYS "ssh-rsa,ssh-dss"
#define ECDH ""
#endif
@@ -94,8 +88,8 @@ static const char *default_methods[] = {
HOSTKEYS,
AES BLOWFISH DES,
AES BLOWFISH DES,
"hmac-sha2-256,hmac-sha2-512,hmac-sha1",
"hmac-sha2-256,hmac-sha2-512,hmac-sha1",
"hmac-sha1",
"hmac-sha1",
"none",
"none",
"",
@@ -107,10 +101,10 @@ static const char *default_methods[] = {
static const char *supported_methods[] = {
KEY_EXCHANGE,
HOSTKEYS,
AES BLOWFISH DES_SUPPORTED,
AES BLOWFISH DES_SUPPORTED,
"hmac-sha2-256,hmac-sha2-512,hmac-sha1",
"hmac-sha2-256,hmac-sha2-512,hmac-sha1",
AES BLOWFISH DES,
AES BLOWFISH DES,
"hmac-sha1",
"hmac-sha1",
ZLIB,
ZLIB,
"",
@@ -281,187 +275,92 @@ char *ssh_find_matching(const char *available_d, const char *preferred_d){
return NULL;
}
/**
* @internal
* @brief returns whether the first client key exchange algorithm or
* hostkey type matches its server counterpart
* @returns whether the first client key exchange algorithm or hostkey type
* matches its server counterpart
*/
static int cmp_first_kex_algo(const char *client_str,
const char *server_str) {
int is_wrong = 1;
char **server_str_tokens = NULL;
char **client_str_tokens = NULL;
if ((client_str == NULL) || (server_str == NULL)) {
goto out;
}
client_str_tokens = tokenize(client_str);
if (client_str_tokens == NULL) {
goto out;
}
if (client_str_tokens[0] == NULL) {
goto freeout;
}
server_str_tokens = tokenize(server_str);
if (server_str_tokens == NULL) {
goto freeout;
}
is_wrong = (strcmp(client_str_tokens[0], server_str_tokens[0]) != 0);
SAFE_FREE(server_str_tokens[0]);
SAFE_FREE(server_str_tokens);
freeout:
SAFE_FREE(client_str_tokens[0]);
SAFE_FREE(client_str_tokens);
out:
return is_wrong;
}
SSH_PACKET_CALLBACK(ssh_packet_kexinit){
int i;
int server_kex=session->server;
ssh_string str = NULL;
char *strings[KEX_METHODS_SIZE];
int rc = SSH_ERROR;
int server_kex=session->server;
ssh_string str = NULL;
char *strings[KEX_METHODS_SIZE];
int i;
uint8_t first_kex_packet_follows = 0;
uint32_t kexinit_reserved = 0;
(void)type;
(void)user;
memset(strings, 0, sizeof(strings));
if (session->session_state == SSH_SESSION_STATE_AUTHENTICATED){
SSH_LOG(SSH_LOG_WARNING, "Other side initiating key re-exchange");
} else if(session->session_state != SSH_SESSION_STATE_INITIAL_KEX){
ssh_set_error(session,SSH_FATAL,"SSH_KEXINIT received in wrong state");
(void)type;
(void)user;
memset(strings, 0, sizeof(strings));
if (session->session_state == SSH_SESSION_STATE_AUTHENTICATED){
SSH_LOG(SSH_LOG_WARNING, "Other side initiating key re-exchange");
} else if(session->session_state != SSH_SESSION_STATE_INITIAL_KEX){
ssh_set_error(session,SSH_FATAL,"SSH_KEXINIT received in wrong state");
goto error;
}
if (server_kex) {
if (buffer_get_data(packet,session->next_crypto->client_kex.cookie,16) != 16) {
ssh_set_error(session, SSH_FATAL, "ssh_packet_kexinit: no cookie in packet");
goto error;
}
if (hashbufin_add_cookie(session, session->next_crypto->client_kex.cookie) < 0) {
ssh_set_error(session, SSH_FATAL, "ssh_packet_kexinit: adding cookie failed");
goto error;
}
} else {
if (buffer_get_data(packet,session->next_crypto->server_kex.cookie,16) != 16) {
ssh_set_error(session, SSH_FATAL, "ssh_packet_kexinit: no cookie in packet");
goto error;
}
if (hashbufin_add_cookie(session, session->next_crypto->server_kex.cookie) < 0) {
ssh_set_error(session, SSH_FATAL, "ssh_packet_kexinit: adding cookie failed");
goto error;
}
}
for (i = 0; i < KEX_METHODS_SIZE; i++) {
str = buffer_get_ssh_string(packet);
if (str == NULL) {
goto error;
}
if (server_kex) {
rc = buffer_get_data(packet,session->next_crypto->client_kex.cookie, 16);
if (rc != 16) {
ssh_set_error(session, SSH_FATAL, "ssh_packet_kexinit: no cookie in packet");
goto error;
}
rc = hashbufin_add_cookie(session, session->next_crypto->client_kex.cookie);
if (rc < 0) {
ssh_set_error(session, SSH_FATAL, "ssh_packet_kexinit: adding cookie failed");
goto error;
}
} else {
rc = buffer_get_data(packet,session->next_crypto->server_kex.cookie, 16);
if (rc != 16) {
ssh_set_error(session, SSH_FATAL, "ssh_packet_kexinit: no cookie in packet");
goto error;
}
rc = hashbufin_add_cookie(session, session->next_crypto->server_kex.cookie);
if (rc < 0) {
ssh_set_error(session, SSH_FATAL, "ssh_packet_kexinit: adding cookie failed");
goto error;
}
if (buffer_add_ssh_string(session->in_hashbuf, str) < 0) {
ssh_set_error(session, SSH_FATAL, "Error adding string in hash buffer");
goto error;
}
for (i = 0; i < KEX_METHODS_SIZE; i++) {
str = buffer_get_ssh_string(packet);
if (str == NULL) {
goto error;
}
rc = buffer_add_ssh_string(session->in_hashbuf, str);
if (rc < 0) {
ssh_set_error(session, SSH_FATAL, "Error adding string in hash buffer");
goto error;
}
strings[i] = ssh_string_to_char(str);
if (strings[i] == NULL) {
ssh_set_error_oom(session);
goto error;
}
ssh_string_free(str);
str = NULL;
strings[i] = ssh_string_to_char(str);
if (strings[i] == NULL) {
ssh_set_error_oom(session);
goto error;
}
/* copy the server kex info into an array of strings */
if (server_kex) {
for (i = 0; i < SSH_KEX_METHODS; i++) {
session->next_crypto->client_kex.methods[i] = strings[i];
}
} else { /* client */
for (i = 0; i < SSH_KEX_METHODS; i++) {
session->next_crypto->server_kex.methods[i] = strings[i];
}
}
/*
* Handle the two final fields for the KEXINIT message (RFC 4253 7.1):
*
* boolean first_kex_packet_follows
* uint32 0 (reserved for future extension)
*
* Notably if clients set 'first_kex_packet_follows', it is expected
* that its value is included when computing the session ID (see
* 'make_sessionid').
*/
if (server_kex) {
rc = buffer_get_u8(packet, &first_kex_packet_follows);
if (rc != 1) {
goto error;
}
rc = buffer_add_u8(session->in_hashbuf, first_kex_packet_follows);
if (rc < 0) {
goto error;
}
rc = buffer_add_u32(session->in_hashbuf, kexinit_reserved);
if (rc < 0) {
goto error;
}
/*
* Remember whether 'first_kex_packet_follows' was set and the client
* guess was wrong: in this case the next SSH_MSG_KEXDH_INIT message
* must be ignored.
*/
if (first_kex_packet_follows) {
session->first_kex_follows_guess_wrong =
cmp_first_kex_algo(session->next_crypto->client_kex.methods[SSH_KEX],
session->next_crypto->server_kex.methods[SSH_KEX]) ||
cmp_first_kex_algo(session->next_crypto->client_kex.methods[SSH_HOSTKEYS],
session->next_crypto->server_kex.methods[SSH_HOSTKEYS]);
}
}
session->session_state = SSH_SESSION_STATE_KEXINIT_RECEIVED;
session->dh_handshake_state = DH_STATE_INIT;
session->ssh_connection_callback(session);
return SSH_PACKET_USED;
error:
ssh_string_free(str);
str = NULL;
}
/* copy the server kex info into an array of strings */
if (server_kex) {
for (i = 0; i < SSH_KEX_METHODS; i++) {
if (server_kex) {
session->next_crypto->client_kex.methods[i] = NULL;
} else { /* client */
session->next_crypto->server_kex.methods[i] = NULL;
}
SAFE_FREE(strings[i]);
session->next_crypto->client_kex.methods[i] = strings[i];
}
} else { /* client */
for (i = 0; i < SSH_KEX_METHODS; i++) {
session->next_crypto->server_kex.methods[i] = strings[i];
}
}
session->session_state = SSH_SESSION_STATE_ERROR;
session->session_state=SSH_SESSION_STATE_KEXINIT_RECEIVED;
session->dh_handshake_state=DH_STATE_INIT;
session->ssh_connection_callback(session);
return SSH_PACKET_USED;
error:
ssh_string_free(str);
for (i = 0; i < SSH_KEX_METHODS; i++) {
if (server_kex) {
session->next_crypto->client_kex.methods[i] = NULL;
} else { /* client */
session->next_crypto->server_kex.methods[i] = NULL;
}
SAFE_FREE(strings[i]);
}
return SSH_PACKET_USED;
session->session_state = SSH_SESSION_STATE_ERROR;
return SSH_PACKET_USED;
}
void ssh_list_kex(struct ssh_kex_struct *kex) {
@@ -489,16 +388,8 @@ void ssh_list_kex(struct ssh_kex_struct *kex) {
*/
static char *ssh_client_select_hostkeys(ssh_session session){
char methods_buffer[128]={0};
static const char *preferred_hostkeys[] = {
"ssh-ed25519",
"ecdsa-sha2-nistp521",
"ecdsa-sha2-nistp384",
"ecdsa-sha2-nistp256",
"ssh-rsa",
"ssh-dss",
"ssh-rsa1",
NULL
};
static const char *preferred_hostkeys[]={"ecdsa-sha2-nistp521","ecdsa-sha2-nistp384",
"ecdsa-sha2-nistp256", "ssh-rsa", "ssh-dss", "ssh-rsa1", NULL};
char **methods;
int i,j;
int needcoma=0;
@@ -603,15 +494,14 @@ int ssh_send_kex(ssh_session session, int server_kex) {
&session->next_crypto->client_kex);
ssh_string str = NULL;
int i;
int rc;
rc = ssh_buffer_pack(session->out_buffer,
"bP",
SSH2_MSG_KEXINIT,
16,
kex->cookie); /* cookie */
if (rc != SSH_OK)
if (buffer_add_u8(session->out_buffer, SSH2_MSG_KEXINIT) < 0) {
goto error;
}
if (buffer_add_data(session->out_buffer, kex->cookie, 16) < 0) {
goto error;
}
if (hashbufout_add_cookie(session) < 0) {
goto error;
}
@@ -634,11 +524,10 @@ int ssh_send_kex(ssh_session session, int server_kex) {
str = NULL;
}
rc = ssh_buffer_pack(session->out_buffer,
"bd",
0,
0);
if (rc != SSH_OK) {
if (buffer_add_u8(session->out_buffer, 0) < 0) {
goto error;
}
if (buffer_add_u32(session->out_buffer, 0) < 0) {
goto error;
}
@@ -648,8 +537,8 @@ int ssh_send_kex(ssh_session session, int server_kex) {
return 0;
error:
ssh_buffer_reinit(session->out_buffer);
ssh_buffer_reinit(session->out_hashbuf);
buffer_reinit(session->out_buffer);
buffer_reinit(session->out_hashbuf);
ssh_string_free(str);
return -1;

View File

@@ -36,10 +36,6 @@
#include "libssh/ssh1.h"
#include "libssh/wrapper.h"
#if defined(HAVE_LIBCRYPTO)
#include "libcrypto-compat.h"
#endif
/* SSHv1 functions */
/* makes a STRING contating 3 strings : ssh-rsa1,e and n */
@@ -50,10 +46,6 @@ static ssh_string make_rsa1_string(ssh_string e, ssh_string n){
ssh_string ret = NULL;
buffer = ssh_buffer_new();
if (buffer == NULL) {
goto error;
}
rsa = ssh_string_from_char("ssh-rsa1");
if (rsa == NULL) {
goto error;
@@ -127,8 +119,8 @@ static int modulus_smaller(ssh_public_key k1, ssh_public_key k2){
n2=gcry_sexp_nth_mpi(sexp,1,GCRYMPI_FMT_USG);
gcry_sexp_release(sexp);
#elif defined HAVE_LIBCRYPTO
RSA_get0_key(k1->rsa_pub, (const BIGNUM **)&n1, NULL, NULL);
RSA_get0_key(k2->rsa_pub, (const BIGNUM **)&n2, NULL, NULL);
n1=k1->rsa_pub->n;
n2=k2->rsa_pub->n;
#endif
if(bignum_cmp(n1,n2)<0)
res=1;
@@ -425,7 +417,7 @@ SSH_PACKET_CALLBACK(ssh_packet_publickey1){
if (buffer_add_u8(session->out_buffer, support_3DES ? SSH_CIPHER_3DES : SSH_CIPHER_DES) < 0) {
goto error;
}
if (ssh_buffer_add_data(session->out_buffer, session->next_crypto->server_kex.cookie, 8) < 0) {
if (buffer_add_data(session->out_buffer, session->next_crypto->server_kex.cookie, 8) < 0) {
goto error;
}
@@ -439,10 +431,10 @@ SSH_PACKET_CALLBACK(ssh_packet_publickey1){
bits, ssh_string_len(enc_session));
bits = htons(bits);
/* the encrypted mpint */
if (ssh_buffer_add_data(session->out_buffer, &bits, sizeof(uint16_t)) < 0) {
if (buffer_add_data(session->out_buffer, &bits, sizeof(uint16_t)) < 0) {
goto error;
}
if (ssh_buffer_add_data(session->out_buffer, ssh_string_data(enc_session),
if (buffer_add_data(session->out_buffer, ssh_string_data(enc_session),
ssh_string_len(enc_session)) < 0) {
goto error;
}

View File

@@ -239,9 +239,9 @@ static int check_public_key(ssh_session session, char **tokens) {
/* TODO: fix the hardcoding */
tmpstring->size = htonl(len);
#ifdef HAVE_LIBGCRYPT
bignum_bn2bin(tmpbn, len, ssh_string_data(tmpstring));
bignum_bn2bin(tmpbn, len, string_data(tmpstring));
#elif defined HAVE_LIBCRYPTO
bignum_bn2bin(tmpbn, ssh_string_data(tmpstring));
bignum_bn2bin(tmpbn, string_data(tmpstring));
#endif
bignum_free(tmpbn);
if (buffer_add_ssh_string(pubkey_buffer, tmpstring) < 0) {
@@ -435,7 +435,7 @@ int ssh_is_server_known(ssh_session session) {
return SSH_SERVER_ERROR;
}
host = ssh_lowercase(session->opts.host);
hostport = ssh_hostport(host, session->opts.port > 0 ? session->opts.port : 22);
hostport = ssh_hostport(host, session->opts.port);
if (host == NULL || hostport == NULL) {
ssh_set_error_oom(session);
SAFE_FREE(host);
@@ -542,7 +542,7 @@ int ssh_write_knownhost(ssh_session session) {
host = ssh_lowercase(session->opts.host);
/* If using a nonstandard port, save the host in the [host]:port format */
if (session->opts.port > 0 && session->opts.port != 22) {
if(session->opts.port != 22) {
hostport = ssh_hostport(host, session->opts.port);
SAFE_FREE(host);
if (hostport == NULL) {
@@ -682,7 +682,7 @@ char **ssh_knownhosts_algorithms(ssh_session session) {
}
host = ssh_lowercase(session->opts.host);
hostport = ssh_hostport(host, session->opts.port > 0 ? session->opts.port : 22);
hostport = ssh_hostport(host, session->opts.port);
array = malloc(sizeof(char *) * KNOWNHOSTS_MAXTYPES);
if (host == NULL || hostport == NULL || array == NULL) {

View File

@@ -163,7 +163,7 @@ int channel_change_pty_size(ssh_channel channel,int cols,int rows){
}
ssh_channel channel_forward_accept(ssh_session session, int timeout_ms){
return ssh_channel_accept_forward(session, timeout_ms, NULL);
return ssh_forward_accept(session,timeout_ms);
}
int channel_close(ssh_channel channel){
@@ -171,12 +171,12 @@ int channel_close(ssh_channel channel){
}
int channel_forward_cancel(ssh_session session, const char *address, int port){
return ssh_channel_cancel_forward(session, address, port);
return ssh_forward_cancel(session, address, port);
}
int channel_forward_listen(ssh_session session, const char *address,
int port, int *bound_port){
return ssh_channel_listen_forward(session, address, port, bound_port);
return ssh_forward_listen(session, address, port, bound_port);
}
void channel_free(ssh_channel channel){
@@ -580,7 +580,7 @@ int ssh_publickey_to_file(ssh_session session,
ssh_set_error(session, SSH_FATAL, "Invalid parameters");
return SSH_ERROR;
}
pubkey_64 = bin_to_base64(ssh_string_data(pubkey), ssh_string_len(pubkey));
pubkey_64 = bin_to_base64(string_data(pubkey), ssh_string_len(pubkey));
if (pubkey_64 == NULL) {
return SSH_ERROR;
}

View File

@@ -1,318 +0,0 @@
/*
* Copyright 2016 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the OpenSSL license (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
* in the file LICENSE in the source distribution or at
* https://www.openssl.org/source/license.html
*/
#include <string.h>
#include <openssl/engine.h>
#include "libcrypto-compat.h"
static void *OPENSSL_zalloc(size_t num)
{
void *ret = OPENSSL_malloc(num);
if (ret != NULL)
memset(ret, 0, num);
return ret;
}
int RSA_set0_key(RSA *r, BIGNUM *n, BIGNUM *e, BIGNUM *d)
{
/* If the fields n and e in r are NULL, the corresponding input
* parameters MUST be non-NULL for n and e. d may be
* left NULL (in case only the public key is used).
*/
if ((r->n == NULL && n == NULL)
|| (r->e == NULL && e == NULL))
return 0;
if (n != NULL) {
BN_free(r->n);
r->n = n;
}
if (e != NULL) {
BN_free(r->e);
r->e = e;
}
if (d != NULL) {
BN_free(r->d);
r->d = d;
}
return 1;
}
int RSA_set0_factors(RSA *r, BIGNUM *p, BIGNUM *q)
{
/* If the fields p and q in r are NULL, the corresponding input
* parameters MUST be non-NULL.
*/
if ((r->p == NULL && p == NULL)
|| (r->q == NULL && q == NULL))
return 0;
if (p != NULL) {
BN_free(r->p);
r->p = p;
}
if (q != NULL) {
BN_free(r->q);
r->q = q;
}
return 1;
}
int RSA_set0_crt_params(RSA *r, BIGNUM *dmp1, BIGNUM *dmq1, BIGNUM *iqmp)
{
/* If the fields dmp1, dmq1 and iqmp in r are NULL, the corresponding input
* parameters MUST be non-NULL.
*/
if ((r->dmp1 == NULL && dmp1 == NULL)
|| (r->dmq1 == NULL && dmq1 == NULL)
|| (r->iqmp == NULL && iqmp == NULL))
return 0;
if (dmp1 != NULL) {
BN_free(r->dmp1);
r->dmp1 = dmp1;
}
if (dmq1 != NULL) {
BN_free(r->dmq1);
r->dmq1 = dmq1;
}
if (iqmp != NULL) {
BN_free(r->iqmp);
r->iqmp = iqmp;
}
return 1;
}
void RSA_get0_key(const RSA *r,
const BIGNUM **n, const BIGNUM **e, const BIGNUM **d)
{
if (n != NULL)
*n = r->n;
if (e != NULL)
*e = r->e;
if (d != NULL)
*d = r->d;
}
void RSA_get0_factors(const RSA *r, const BIGNUM **p, const BIGNUM **q)
{
if (p != NULL)
*p = r->p;
if (q != NULL)
*q = r->q;
}
void RSA_get0_crt_params(const RSA *r,
const BIGNUM **dmp1, const BIGNUM **dmq1,
const BIGNUM **iqmp)
{
if (dmp1 != NULL)
*dmp1 = r->dmp1;
if (dmq1 != NULL)
*dmq1 = r->dmq1;
if (iqmp != NULL)
*iqmp = r->iqmp;
}
void DSA_get0_pqg(const DSA *d,
const BIGNUM **p, const BIGNUM **q, const BIGNUM **g)
{
if (p != NULL)
*p = d->p;
if (q != NULL)
*q = d->q;
if (g != NULL)
*g = d->g;
}
int DSA_set0_pqg(DSA *d, BIGNUM *p, BIGNUM *q, BIGNUM *g)
{
/* If the fields p, q and g in d are NULL, the corresponding input
* parameters MUST be non-NULL.
*/
if ((d->p == NULL && p == NULL)
|| (d->q == NULL && q == NULL)
|| (d->g == NULL && g == NULL))
return 0;
if (p != NULL) {
BN_free(d->p);
d->p = p;
}
if (q != NULL) {
BN_free(d->q);
d->q = q;
}
if (g != NULL) {
BN_free(d->g);
d->g = g;
}
return 1;
}
void DSA_get0_key(const DSA *d,
const BIGNUM **pub_key, const BIGNUM **priv_key)
{
if (pub_key != NULL)
*pub_key = d->pub_key;
if (priv_key != NULL)
*priv_key = d->priv_key;
}
int DSA_set0_key(DSA *d, BIGNUM *pub_key, BIGNUM *priv_key)
{
/* If the field pub_key in d is NULL, the corresponding input
* parameters MUST be non-NULL. The priv_key field may
* be left NULL.
*/
if (d->pub_key == NULL && pub_key == NULL)
return 0;
if (pub_key != NULL) {
BN_free(d->pub_key);
d->pub_key = pub_key;
}
if (priv_key != NULL) {
BN_free(d->priv_key);
d->priv_key = priv_key;
}
return 1;
}
void DSA_SIG_get0(const DSA_SIG *sig, const BIGNUM **pr, const BIGNUM **ps)
{
if (pr != NULL)
*pr = sig->r;
if (ps != NULL)
*ps = sig->s;
}
int DSA_SIG_set0(DSA_SIG *sig, BIGNUM *r, BIGNUM *s)
{
if (r == NULL || s == NULL)
return 0;
BN_clear_free(sig->r);
BN_clear_free(sig->s);
sig->r = r;
sig->s = s;
return 1;
}
void ECDSA_SIG_get0(const ECDSA_SIG *sig, const BIGNUM **pr, const BIGNUM **ps)
{
if (pr != NULL)
*pr = sig->r;
if (ps != NULL)
*ps = sig->s;
}
int ECDSA_SIG_set0(ECDSA_SIG *sig, BIGNUM *r, BIGNUM *s)
{
if (r == NULL || s == NULL)
return 0;
BN_clear_free(sig->r);
BN_clear_free(sig->s);
sig->r = r;
sig->s = s;
return 1;
}
EVP_MD_CTX *EVP_MD_CTX_new(void)
{
return OPENSSL_zalloc(sizeof(EVP_MD_CTX));
}
static void OPENSSL_clear_free(void *str, size_t num)
{
if (str == NULL)
return;
if (num)
OPENSSL_cleanse(str, num);
OPENSSL_free(str);
}
/* This call frees resources associated with the context */
int EVP_MD_CTX_reset(EVP_MD_CTX *ctx)
{
if (ctx == NULL)
return 1;
/*
* Don't assume ctx->md_data was cleaned in EVP_Digest_Final, because
* sometimes only copies of the context are ever finalised.
*/
if (ctx->digest && ctx->digest->cleanup
&& !EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_CLEANED))
ctx->digest->cleanup(ctx);
if (ctx->digest && ctx->digest->ctx_size && ctx->md_data
&& !EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_REUSE)) {
OPENSSL_clear_free(ctx->md_data, ctx->digest->ctx_size);
}
EVP_PKEY_CTX_free(ctx->pctx);
#ifndef OPENSSL_NO_ENGINE
ENGINE_finish(ctx->engine);
#endif
OPENSSL_cleanse(ctx, sizeof(*ctx));
return 1;
}
void EVP_MD_CTX_free(EVP_MD_CTX *ctx)
{
EVP_MD_CTX_reset(ctx);
OPENSSL_free(ctx);
}
HMAC_CTX *HMAC_CTX_new(void)
{
HMAC_CTX *ctx = OPENSSL_zalloc(sizeof(HMAC_CTX));
if (ctx != NULL) {
if (!HMAC_CTX_reset(ctx)) {
HMAC_CTX_free(ctx);
return NULL;
}
}
return ctx;
}
static void hmac_ctx_cleanup(HMAC_CTX *ctx)
{
EVP_MD_CTX_reset(&ctx->i_ctx);
EVP_MD_CTX_reset(&ctx->o_ctx);
EVP_MD_CTX_reset(&ctx->md_ctx);
ctx->md = NULL;
ctx->key_length = 0;
OPENSSL_cleanse(ctx->key, sizeof(ctx->key));
}
void HMAC_CTX_free(HMAC_CTX *ctx)
{
if (ctx != NULL) {
hmac_ctx_cleanup(ctx);
#if OPENSSL_VERSION_NUMBER > 0x10100000L
EVP_MD_CTX_free(&ctx->i_ctx);
EVP_MD_CTX_free(&ctx->o_ctx);
EVP_MD_CTX_free(&ctx->md_ctx);
#endif
OPENSSL_free(ctx);
}
}
int HMAC_CTX_reset(HMAC_CTX *ctx)
{
HMAC_CTX_init(ctx);
return 1;
}

View File

@@ -1,42 +0,0 @@
#ifndef LIBCRYPTO_COMPAT_H
#define LIBCRYPTO_COMPAT_H
#include <openssl/opensslv.h>
#if OPENSSL_VERSION_NUMBER < 0x10100000L
#include <openssl/rsa.h>
#include <openssl/dsa.h>
#include <openssl/ecdsa.h>
#include <openssl/dh.h>
#include <openssl/evp.h>
#include <openssl/hmac.h>
int RSA_set0_key(RSA *r, BIGNUM *n, BIGNUM *e, BIGNUM *d);
int RSA_set0_factors(RSA *r, BIGNUM *p, BIGNUM *q);
int RSA_set0_crt_params(RSA *r, BIGNUM *dmp1, BIGNUM *dmq1, BIGNUM *iqmp);
void RSA_get0_key(const RSA *r, const BIGNUM **n, const BIGNUM **e, const BIGNUM **d);
void RSA_get0_factors(const RSA *r, const BIGNUM **p, const BIGNUM **q);
void RSA_get0_crt_params(const RSA *r, const BIGNUM **dmp1, const BIGNUM **dmq1, const BIGNUM **iqmp);
void DSA_get0_pqg(const DSA *d, const BIGNUM **p, const BIGNUM **q, const BIGNUM **g);
int DSA_set0_pqg(DSA *d, BIGNUM *p, BIGNUM *q, BIGNUM *g);
void DSA_get0_key(const DSA *d, const BIGNUM **pub_key, const BIGNUM **priv_key);
int DSA_set0_key(DSA *d, BIGNUM *pub_key, BIGNUM *priv_key);
void DSA_SIG_get0(const DSA_SIG *sig, const BIGNUM **pr, const BIGNUM **ps);
int DSA_SIG_set0(DSA_SIG *sig, BIGNUM *r, BIGNUM *s);
void ECDSA_SIG_get0(const ECDSA_SIG *sig, const BIGNUM **pr, const BIGNUM **ps);
int ECDSA_SIG_set0(ECDSA_SIG *sig, BIGNUM *r, BIGNUM *s);
int EVP_MD_CTX_reset(EVP_MD_CTX *ctx);
EVP_MD_CTX *EVP_MD_CTX_new(void);
void EVP_MD_CTX_free(EVP_MD_CTX *ctx);
HMAC_CTX *HMAC_CTX_new(void);
int HMAC_CTX_reset(HMAC_CTX *ctx);
void HMAC_CTX_free(HMAC_CTX *ctx);
#endif /* OPENSSL_VERSION_NUMBER */
#endif /* LIBCRYPTO_COMPAT_H */

View File

@@ -43,8 +43,6 @@
#include <openssl/hmac.h>
#include <openssl/opensslv.h>
#include <openssl/rand.h>
#include <openssl/modes.h>
#include "libcrypto-compat.h"
#ifdef HAVE_OPENSSL_AES_H
#define HAS_AES
@@ -70,8 +68,6 @@ struct ssh_mac_ctx_struct {
union {
SHACTX sha1_ctx;
SHA256CTX sha256_ctx;
SHA384CTX sha384_ctx;
SHA512CTX sha512_ctx;
} ctx;
};
@@ -135,19 +131,18 @@ static const EVP_MD *nid_to_evpmd(int nid)
void evp(int nid, unsigned char *digest, int len, unsigned char *hash, unsigned int *hlen)
{
const EVP_MD *evp_md = nid_to_evpmd(nid);
EVP_MD_CTX *md = EVP_MD_CTX_new();
EVP_MD_CTX md;
EVP_DigestInit(md, evp_md);
EVP_DigestUpdate(md, digest, len);
EVP_DigestFinal(md, hash, hlen);
EVP_MD_CTX_free(md);
EVP_DigestInit(&md, evp_md);
EVP_DigestUpdate(&md, digest, len);
EVP_DigestFinal(&md, hash, hlen);
}
EVPCTX evp_init(int nid)
{
const EVP_MD *evp_md = nid_to_evpmd(nid);
EVPCTX ctx = EVP_MD_CTX_new();
EVPCTX ctx = malloc(sizeof(EVP_MD_CTX));
if (ctx == NULL) {
return NULL;
}
@@ -165,7 +160,6 @@ void evp_update(EVPCTX ctx, const void *data, unsigned long len)
void evp_final(EVPCTX ctx, unsigned char *md, unsigned int *mdlen)
{
EVP_DigestFinal(ctx, md, mdlen);
EVP_MD_CTX_free(ctx);
}
#endif
@@ -192,52 +186,6 @@ void sha256(unsigned char *digest, int len, unsigned char *hash) {
SHA256(digest, len, hash);
}
SHA384CTX sha384_init(void){
SHA384CTX c = malloc(sizeof(*c));
if (c == NULL) {
return NULL;
}
SHA384_Init(c);
return c;
}
void sha384_update(SHA384CTX c, const void *data, unsigned long len){
SHA384_Update(c,data,len);
}
void sha384_final(unsigned char *md, SHA384CTX c) {
SHA384_Final(md, c);
SAFE_FREE(c);
}
void sha384(unsigned char *digest, int len, unsigned char *hash) {
SHA384(digest, len, hash);
}
SHA512CTX sha512_init(void){
SHA512CTX c = malloc(sizeof(*c));
if (c == NULL) {
return NULL;
}
SHA512_Init(c);
return c;
}
void sha512_update(SHA512CTX c, const void *data, unsigned long len){
SHA512_Update(c,data,len);
}
void sha512_final(unsigned char *md, SHA512CTX c) {
SHA512_Final(md, c);
SAFE_FREE(c);
}
void sha512(unsigned char *digest, int len, unsigned char *hash) {
SHA512(digest, len, hash);
}
MD5CTX md5_init(void) {
MD5CTX c = malloc(sizeof(*c));
if (c == NULL) {
@@ -273,11 +221,7 @@ ssh_mac_ctx ssh_mac_ctx_init(enum ssh_mac_e type){
ctx->ctx.sha256_ctx = sha256_init();
return ctx;
case SSH_MAC_SHA384:
ctx->ctx.sha384_ctx = sha384_init();
return ctx;
case SSH_MAC_SHA512:
ctx->ctx.sha512_ctx = sha512_init();
return ctx;
default:
SAFE_FREE(ctx);
return NULL;
@@ -293,11 +237,7 @@ void ssh_mac_update(ssh_mac_ctx ctx, const void *data, unsigned long len) {
sha256_update(ctx->ctx.sha256_ctx, data, len);
break;
case SSH_MAC_SHA384:
sha384_update(ctx->ctx.sha384_ctx, data, len);
break;
case SSH_MAC_SHA512:
sha512_update(ctx->ctx.sha512_ctx, data, len);
break;
default:
break;
}
@@ -312,11 +252,7 @@ void ssh_mac_final(unsigned char *md, ssh_mac_ctx ctx) {
sha256_final(md,ctx->ctx.sha256_ctx);
break;
case SSH_MAC_SHA384:
sha384_final(md,ctx->ctx.sha384_ctx);
break;
case SSH_MAC_SHA512:
sha512_final(md,ctx->ctx.sha512_ctx);
break;
default:
break;
}
@@ -326,33 +262,23 @@ void ssh_mac_final(unsigned char *md, ssh_mac_ctx ctx) {
HMACCTX hmac_init(const void *key, int len, enum ssh_hmac_e type) {
HMACCTX ctx = NULL;
ctx = HMAC_CTX_new();
ctx = malloc(sizeof(*ctx));
if (ctx == NULL) {
return NULL;
}
#ifndef OLD_CRYPTO
HMAC_CTX_reset(ctx); // openssl 0.9.7 requires it.
HMAC_CTX_init(ctx); // openssl 0.9.7 requires it.
#endif
switch(type) {
case SSH_HMAC_SHA1:
HMAC_Init_ex(ctx, key, len, EVP_sha1(), NULL);
break;
case SSH_HMAC_SHA256:
HMAC_Init_ex(ctx, key, len, EVP_sha256(), NULL);
break;
case SSH_HMAC_SHA384:
HMAC_Init_ex(ctx, key, len, EVP_sha384(), NULL);
break;
case SSH_HMAC_SHA512:
HMAC_Init_ex(ctx, key, len, EVP_sha512(), NULL);
HMAC_Init(ctx, key, len, EVP_sha1());
break;
case SSH_HMAC_MD5:
HMAC_Init_ex(ctx, key, len, EVP_md5(), NULL);
HMAC_Init(ctx, key, len, EVP_md5());
break;
default:
HMAC_CTX_free(ctx);
SAFE_FREE(ctx);
ctx = NULL;
}
@@ -368,8 +294,7 @@ void hmac_final(HMACCTX ctx, unsigned char *hashmacbuf, unsigned int *len) {
HMAC_Final(ctx,hashmacbuf,len);
#ifndef OLD_CRYPTO
HMAC_CTX_free(ctx);
ctx = NULL;
HMAC_CTX_cleanup(ctx);
#else
HMAC_cleanup(ctx);
#endif
@@ -461,12 +386,7 @@ static void aes_ctr128_encrypt(struct ssh_cipher_struct *cipher, void *in, void
* Same for num, which is being used to store the current offset in blocksize in CTR
* function.
*/
#ifdef HAVE_OPENSSL_CRYPTO_CTR128_ENCRYPT
CRYPTO_ctr128_encrypt(in, out, len, cipher->key, cipher->IV, tmp_buffer,
&num, (block128_f)AES_encrypt);
# else
AES_ctr128_encrypt(in, out, len, cipher->key, cipher->IV, tmp_buffer, &num);
#endif /* HAVE_OPENSSL_CRYPTO_CTR128_ENCRYPT */
}
#endif /* BROKEN_AES_CTR */
#endif /* HAS_AES */

View File

@@ -69,69 +69,10 @@ void sha1(unsigned char *digest, int len, unsigned char *hash) {
gcry_md_hash_buffer(GCRY_MD_SHA1, hash, digest, len);
}
SHA256CTX sha256_init(void) {
SHA256CTX ctx = NULL;
gcry_md_open(&ctx, GCRY_MD_SHA256, 0);
return ctx;
}
void sha256_update(SHACTX c, const void *data, unsigned long len) {
gcry_md_write(c, data, len);
}
void sha256_final(unsigned char *md, SHACTX c) {
gcry_md_final(c);
memcpy(md, gcry_md_read(c, 0), SHA256_DIGEST_LEN);
gcry_md_close(c);
}
void sha256(unsigned char *digest, int len, unsigned char *hash){
gcry_md_hash_buffer(GCRY_MD_SHA256, hash, digest, len);
}
SHA384CTX sha384_init(void) {
SHA384CTX ctx = NULL;
gcry_md_open(&ctx, GCRY_MD_SHA384, 0);
return ctx;
}
void sha384_update(SHACTX c, const void *data, unsigned long len) {
gcry_md_write(c, data, len);
}
void sha384_final(unsigned char *md, SHACTX c) {
gcry_md_final(c);
memcpy(md, gcry_md_read(c, 0), SHA384_DIGEST_LEN);
gcry_md_close(c);
}
void sha384(unsigned char *digest, int len, unsigned char *hash) {
gcry_md_hash_buffer(GCRY_MD_SHA384, hash, digest, len);
}
SHA512CTX sha512_init(void) {
SHA512CTX ctx = NULL;
gcry_md_open(&ctx, GCRY_MD_SHA512, 0);
return ctx;
}
void sha512_update(SHACTX c, const void *data, unsigned long len) {
gcry_md_write(c, data, len);
}
void sha512_final(unsigned char *md, SHACTX c) {
gcry_md_final(c);
memcpy(md, gcry_md_read(c, 0), SHA512_DIGEST_LEN);
gcry_md_close(c);
}
void sha512(unsigned char *digest, int len, unsigned char *hash) {
gcry_md_hash_buffer(GCRY_MD_SHA512, hash, digest, len);
}
MD5CTX md5_init(void) {
MD5CTX c = NULL;
gcry_md_open(&c, GCRY_MD_MD5, 0);
@@ -181,19 +122,19 @@ void ssh_mac_update(ssh_mac_ctx ctx, const void *data, unsigned long len) {
}
void ssh_mac_final(unsigned char *md, ssh_mac_ctx ctx) {
size_t len = 0;
size_t len;
switch(ctx->mac_type){
case SSH_MAC_SHA1:
len=SHA_DIGEST_LEN;
break;
case SSH_MAC_SHA256:
len=SHA256_DIGEST_LEN;
len=SHA256_DIGEST_LENGTH;
break;
case SSH_MAC_SHA384:
len=SHA384_DIGEST_LEN;
len=SHA384_DIGEST_LENGTH;
break;
case SSH_MAC_SHA512:
len=SHA512_DIGEST_LEN;
len=SHA512_DIGEST_LENGTH;
break;
}
gcry_md_final(ctx->ctx);
@@ -209,15 +150,6 @@ HMACCTX hmac_init(const void *key, int len, enum ssh_hmac_e type) {
case SSH_HMAC_SHA1:
gcry_md_open(&c, GCRY_MD_SHA1, GCRY_MD_FLAG_HMAC);
break;
case SSH_HMAC_SHA256:
gcry_md_open(&c, GCRY_MD_SHA256, GCRY_MD_FLAG_HMAC);
break;
case SSH_HMAC_SHA384:
gcry_md_open(&c, GCRY_MD_SHA384, GCRY_MD_FLAG_HMAC);
break;
case SSH_HMAC_SHA512:
gcry_md_open(&c, GCRY_MD_SHA512, GCRY_MD_FLAG_HMAC);
break;
case SSH_HMAC_MD5:
gcry_md_open(&c, GCRY_MD_MD5, GCRY_MD_FLAG_HMAC);
break;
@@ -478,8 +410,8 @@ static struct ssh_cipher_struct ssh_ciphertab[] = {
.keysize = 128,
.set_encrypt_key = blowfish_set_key,
.set_decrypt_key = blowfish_set_key,
.encrypt = blowfish_encrypt,
.decrypt = blowfish_decrypt
.cbc_encrypt = blowfish_encrypt,
.cbc_decrypt = blowfish_decrypt
},
{
.name = "aes128-ctr",
@@ -489,8 +421,8 @@ static struct ssh_cipher_struct ssh_ciphertab[] = {
.keysize = 128,
.set_encrypt_key = aes_set_key,
.set_decrypt_key = aes_set_key,
.encrypt = aes_encrypt,
.decrypt = aes_encrypt
.cbc_encrypt = aes_encrypt,
.cbc_decrypt = aes_encrypt
},
{
.name = "aes192-ctr",
@@ -500,8 +432,8 @@ static struct ssh_cipher_struct ssh_ciphertab[] = {
.keysize = 192,
.set_encrypt_key = aes_set_key,
.set_decrypt_key = aes_set_key,
.encrypt = aes_encrypt,
.decrypt = aes_encrypt
.cbc_encrypt = aes_encrypt,
.cbc_decrypt = aes_encrypt
},
{
.name = "aes256-ctr",
@@ -511,8 +443,8 @@ static struct ssh_cipher_struct ssh_ciphertab[] = {
.keysize = 256,
.set_encrypt_key = aes_set_key,
.set_decrypt_key = aes_set_key,
.encrypt = aes_encrypt,
.decrypt = aes_encrypt
.cbc_encrypt = aes_encrypt,
.cbc_decrypt = aes_encrypt
},
{
.name = "aes128-cbc",
@@ -522,8 +454,8 @@ static struct ssh_cipher_struct ssh_ciphertab[] = {
.keysize = 128,
.set_encrypt_key = aes_set_key,
.set_decrypt_key = aes_set_key,
.encrypt = aes_encrypt,
.decrypt = aes_decrypt
.cbc_encrypt = aes_encrypt,
.cbc_decrypt = aes_decrypt
},
{
.name = "aes192-cbc",
@@ -533,8 +465,8 @@ static struct ssh_cipher_struct ssh_ciphertab[] = {
.keysize = 192,
.set_encrypt_key = aes_set_key,
.set_decrypt_key = aes_set_key,
.encrypt = aes_encrypt,
.decrypt = aes_decrypt
.cbc_encrypt = aes_encrypt,
.cbc_decrypt = aes_decrypt
},
{
.name = "aes256-cbc",
@@ -544,8 +476,8 @@ static struct ssh_cipher_struct ssh_ciphertab[] = {
.keysize = 256,
.set_encrypt_key = aes_set_key,
.set_decrypt_key = aes_set_key,
.encrypt = aes_encrypt,
.decrypt = aes_decrypt
.cbc_encrypt = aes_encrypt,
.cbc_decrypt = aes_decrypt
},
{
.name = "3des-cbc",
@@ -555,8 +487,8 @@ static struct ssh_cipher_struct ssh_ciphertab[] = {
.keysize = 192,
.set_encrypt_key = des3_set_key,
.set_decrypt_key = des3_set_key,
.encrypt = des3_encrypt,
.decrypt = des3_decrypt
.cbc_encrypt = des3_encrypt,
.cbc_decrypt = des3_decrypt
},
{
.name = "3des-cbc-ssh1",
@@ -566,8 +498,8 @@ static struct ssh_cipher_struct ssh_ciphertab[] = {
.keysize = 192,
.set_encrypt_key = des3_1_set_key,
.set_decrypt_key = des3_1_set_key,
.encrypt = des3_1_encrypt,
.decrypt = des3_1_decrypt
.cbc_encrypt = des3_1_encrypt,
.cbc_decrypt = des3_1_decrypt
},
{
.name = "des-cbc-ssh1",
@@ -577,8 +509,8 @@ static struct ssh_cipher_struct ssh_ciphertab[] = {
.keysize = 64,
.set_encrypt_key = des1_set_key,
.set_decrypt_key = des1_set_key,
.encrypt = des1_1_encrypt,
.decrypt = des1_1_decrypt
.cbc_encrypt = des1_1_encrypt,
.cbc_decrypt = des1_1_decrypt
},
{
.name = NULL,
@@ -588,8 +520,8 @@ static struct ssh_cipher_struct ssh_ciphertab[] = {
.keysize = 0,
.set_encrypt_key = NULL,
.set_decrypt_key = NULL,
.encrypt = NULL,
.decrypt = NULL
.cbc_encrypt = NULL,
.cbc_decrypt = NULL
}
};

View File

@@ -215,10 +215,6 @@ ssh_logging_callback ssh_get_log_callback(void) {
*/
void *ssh_get_log_userdata(void)
{
if (ssh_log_userdata == NULL) {
return NULL;
}
return ssh_log_userdata;
}

View File

@@ -524,25 +524,6 @@ void ssh_message_free(ssh_message msg){
SAFE_FREE(msg->channel_request.var_value);
SAFE_FREE(msg->channel_request.command);
SAFE_FREE(msg->channel_request.subsystem);
switch (msg->channel_request.type) {
case SSH_CHANNEL_REQUEST_EXEC:
SAFE_FREE(msg->channel_request.command);
break;
case SSH_CHANNEL_REQUEST_ENV:
SAFE_FREE(msg->channel_request.var_name);
SAFE_FREE(msg->channel_request.var_value);
break;
case SSH_CHANNEL_REQUEST_PTY:
SAFE_FREE(msg->channel_request.TERM);
break;
case SSH_CHANNEL_REQUEST_SUBSYSTEM:
SAFE_FREE(msg->channel_request.subsystem);
break;
case SSH_CHANNEL_REQUEST_X11:
SAFE_FREE(msg->channel_request.x11_auth_protocol);
SAFE_FREE(msg->channel_request.x11_auth_cookie);
break;
}
break;
case SSH_REQUEST_SERVICE:
SAFE_FREE(msg->service_request.service);
@@ -604,34 +585,104 @@ static ssh_buffer ssh_msg_userauth_build_digest(ssh_session session,
session->current_crypto ? session->current_crypto :
session->next_crypto;
ssh_buffer buffer;
ssh_string str=NULL;
ssh_string str;
int rc;
buffer = ssh_buffer_new();
if (buffer == NULL) {
return NULL;
}
rc = ssh_pki_export_pubkey_blob(msg->auth_request.pubkey, &str);
/* Add session id */
str = ssh_string_new(crypto->digest_len);
if (str == NULL) {
ssh_buffer_free(buffer);
return NULL;
}
ssh_string_fill(str, crypto->session_id, crypto->digest_len);
rc = buffer_add_ssh_string(buffer, str);
string_free(str);
if (rc < 0) {
ssh_buffer_free(buffer);
return NULL;
}
rc = ssh_buffer_pack(buffer,
"dPbsssbsS",
crypto->digest_len, /* session ID string */
(size_t)crypto->digest_len, crypto->session_id,
SSH2_MSG_USERAUTH_REQUEST, /* type */
msg->auth_request.username,
service,
"publickey", /* method */
1, /* has to be signed (true) */
msg->auth_request.pubkey->type_c, /* pubkey algorithm */
str); /* public key as a blob */
/* Add the type */
rc = buffer_add_u8(buffer, SSH2_MSG_USERAUTH_REQUEST);
if (rc < 0) {
ssh_buffer_free(buffer);
return NULL;
}
ssh_string_free(str);
if (rc != SSH_OK) {
ssh_set_error_oom(session);
/* Add the username */
str = ssh_string_from_char(msg->auth_request.username);
if (str == NULL) {
ssh_buffer_free(buffer);
return NULL;
}
rc = buffer_add_ssh_string(buffer, str);
string_free(str);
if (rc < 0) {
ssh_buffer_free(buffer);
return NULL;
}
/* Add the service name */
str = ssh_string_from_char(service);
if (str == NULL) {
ssh_buffer_free(buffer);
return NULL;
}
rc = buffer_add_ssh_string(buffer, str);
string_free(str);
if (rc < 0) {
ssh_buffer_free(buffer);
return NULL;
}
/* Add the method (publickey) */
str = ssh_string_from_char("publickey");
if (str == NULL) {
ssh_buffer_free(buffer);
return NULL;
}
rc = buffer_add_ssh_string(buffer, str);
string_free(str);
if (rc < 0) {
ssh_buffer_free(buffer);
return NULL;
}
/* Has been signed (TRUE) */
rc = buffer_add_u8(buffer, 1);
if (rc < 0) {
ssh_buffer_free(buffer);
return NULL;
}
/* Add the public key algorithm */
str = ssh_string_from_char(msg->auth_request.pubkey->type_c);
if (str == NULL) {
ssh_buffer_free(buffer);
return NULL;
}
rc = buffer_add_ssh_string(buffer, str);
string_free(str);
if (rc < 0) {
ssh_buffer_free(buffer);
return NULL;
}
/* Add the publickey as blob */
rc = ssh_pki_export_pubkey_blob(msg->auth_request.pubkey, &str);
if (rc < 0) {
ssh_buffer_free(buffer);
return NULL;
}
rc = buffer_add_ssh_string(buffer, str);
string_free(str);
if (rc < 0) {
ssh_buffer_free(buffer);
return NULL;
}
@@ -646,11 +697,11 @@ static ssh_buffer ssh_msg_userauth_build_digest(ssh_session session,
* SSH Message
*/
SSH_PACKET_CALLBACK(ssh_packet_userauth_request){
ssh_string str;
ssh_message msg = NULL;
char *service = NULL;
char *method = NULL;
int cmp;
int rc;
uint32_t method_size = 0;
(void)user;
(void)type;
@@ -661,13 +712,35 @@ SSH_PACKET_CALLBACK(ssh_packet_userauth_request){
goto error;
}
msg->type = SSH_REQUEST_AUTH;
rc = ssh_buffer_unpack(packet,
"sss",
&msg->auth_request.username,
&service,
&method);
if (rc != SSH_OK) {
str = buffer_get_ssh_string(packet);
if (str == NULL) {
goto error;
}
msg->auth_request.username = ssh_string_to_char(str);
ssh_string_free(str);
if (msg->auth_request.username == NULL) {
goto error;
}
str = buffer_get_ssh_string(packet);
if (str == NULL) {
goto error;
}
service = ssh_string_to_char(str);
ssh_string_free(str);
if (service == NULL) {
goto error;
}
str = buffer_get_ssh_string(packet);
if (str == NULL) {
goto error;
}
method = ssh_string_to_char(str);
method_size = ssh_string_len(str);
ssh_string_free(str);
if (method == NULL) {
goto error;
}
@@ -676,31 +749,33 @@ SSH_PACKET_CALLBACK(ssh_packet_userauth_request){
service, method,
msg->auth_request.username);
cmp = strcmp(service, "ssh-connection");
if (cmp != 0) {
SSH_LOG(SSH_LOG_WARNING,
"Invalid service request: %s",
service);
goto end;
}
if (strcmp(method, "none") == 0) {
if (strncmp(method, "none", method_size) == 0) {
msg->auth_request.method = SSH_AUTH_METHOD_NONE;
goto end;
}
if (strcmp(method, "password") == 0) {
if (strncmp(method, "password", method_size) == 0) {
ssh_string pass = NULL;
uint8_t tmp;
msg->auth_request.method = SSH_AUTH_METHOD_PASSWORD;
rc = ssh_buffer_unpack(packet, "bs", &tmp, &msg->auth_request.password);
if (rc != SSH_OK) {
buffer_get_u8(packet, &tmp);
pass = buffer_get_ssh_string(packet);
if (pass == NULL) {
goto error;
}
msg->auth_request.password = ssh_string_to_char(pass);
ssh_string_burn(pass);
ssh_string_free(pass);
pass = NULL;
if (msg->auth_request.password == NULL) {
goto error;
}
goto end;
}
if (strcmp(method, "keyboard-interactive") == 0) {
if (strncmp(method, "keyboard-interactive", method_size) == 0) {
ssh_string lang = NULL;
ssh_string submethods = NULL;
@@ -730,20 +805,23 @@ SSH_PACKET_CALLBACK(ssh_packet_userauth_request){
goto end;
}
if (strcmp(method, "publickey") == 0) {
if (strncmp(method, "publickey", method_size) == 0) {
ssh_string algo = NULL;
ssh_string pubkey_blob = NULL;
uint8_t has_sign;
int rc;
msg->auth_request.method = SSH_AUTH_METHOD_PUBLICKEY;
SAFE_FREE(method);
rc = ssh_buffer_unpack(packet, "bSS",
&has_sign,
&algo,
&pubkey_blob
);
if (rc != SSH_OK) {
buffer_get_u8(packet, &has_sign);
algo = buffer_get_ssh_string(packet);
if (algo == NULL) {
goto error;
}
pubkey_blob = buffer_get_ssh_string(packet);
if (pubkey_blob == NULL) {
ssh_string_free(algo);
algo = NULL;
goto error;
}
ssh_string_free(algo);
@@ -798,7 +876,7 @@ SSH_PACKET_CALLBACK(ssh_packet_userauth_request){
goto end;
}
#ifdef WITH_GSSAPI
if (strcmp(method, "gssapi-with-mic") == 0) {
if (strncmp(method, "gssapi-with-mic", method_size) == 0) {
uint32_t n_oid;
ssh_string *oids;
ssh_string oid;
@@ -887,7 +965,6 @@ SSH_PACKET_CALLBACK(ssh_packet_userauth_info_response){
uint32_t nanswers;
uint32_t i;
ssh_string tmp;
int rc;
ssh_message msg = NULL;
@@ -915,11 +992,7 @@ SSH_PACKET_CALLBACK(ssh_packet_userauth_info_response){
msg->auth_request.username = NULL;
#endif
rc = ssh_buffer_unpack(packet, "d", &nanswers);
if (rc != SSH_OK) {
ssh_set_error_invalid(session);
goto error;
}
buffer_get_u32(packet, &nanswers);
if (session->kbdint == NULL) {
SSH_LOG(SSH_LOG_PROTOCOL, "Warning: Got a keyboard-interactive "
@@ -931,17 +1004,9 @@ SSH_PACKET_CALLBACK(ssh_packet_userauth_info_response){
goto error;
}
} else if (session->kbdint->nanswers > 0) {
uint32_t n;
for (n = 0; n < session->kbdint->nanswers; n++) {
BURN_STRING(session->kbdint->answers[n]);
SAFE_FREE(session->kbdint->answers[n]);
}
SAFE_FREE(session->kbdint->answers);
session->kbdint->nanswers = 0;
}
nanswers = ntohl(nanswers);
SSH_LOG(SSH_LOG_PACKET,"kbdint: %d answers",nanswers);
if (nanswers > KBDINT_MAX_PROMPT) {
ssh_set_error(session, SSH_FATAL,
@@ -959,8 +1024,7 @@ SSH_PACKET_CALLBACK(ssh_packet_userauth_info_response){
" mismatch: p=%u a=%u", session->kbdint->nprompts, nanswers);
}
session->kbdint->nanswers = nanswers;
session->kbdint->answers = calloc(1, nanswers * sizeof(char *));
session->kbdint->answers = malloc(nanswers * sizeof(char *));
if (session->kbdint->answers == NULL) {
session->kbdint->nanswers = 0;
ssh_set_error_oom(session);
@@ -969,6 +1033,7 @@ SSH_PACKET_CALLBACK(ssh_packet_userauth_info_response){
goto error;
}
memset(session->kbdint->answers, 0, nanswers * sizeof(char *));
for (i = 0; i < nanswers; i++) {
tmp = buffer_get_ssh_string(packet);
@@ -1005,9 +1070,9 @@ error:
SSH_PACKET_CALLBACK(ssh_packet_channel_open){
ssh_message msg = NULL;
ssh_string type_s = NULL, originator = NULL, destination = NULL;
char *type_c = NULL;
uint32_t originator_port, destination_port;
int rc;
uint32_t sender, window, packet_size, originator_port, destination_port;
(void)type;
(void)user;
@@ -1018,18 +1083,30 @@ SSH_PACKET_CALLBACK(ssh_packet_channel_open){
}
msg->type = SSH_REQUEST_CHANNEL_OPEN;
rc = ssh_buffer_unpack(packet, "s", &type_c);
if (rc != SSH_OK){
goto error;
type_s = buffer_get_ssh_string(packet);
if (type_s == NULL) {
ssh_set_error_oom(session);
goto error;
}
type_c = ssh_string_to_char(type_s);
if (type_c == NULL) {
ssh_set_error_oom(session);
goto error;
}
SSH_LOG(SSH_LOG_PACKET,
"Clients wants to open a %s channel", type_c);
ssh_string_free(type_s);
type_s=NULL;
ssh_buffer_unpack(packet,"ddd",
&msg->channel_request_open.sender,
&msg->channel_request_open.window,
&msg->channel_request_open.packet_size);
buffer_get_u32(packet, &sender);
buffer_get_u32(packet, &window);
buffer_get_u32(packet, &packet_size);
msg->channel_request_open.sender = ntohl(sender);
msg->channel_request_open.window = ntohl(window);
msg->channel_request_open.packet_size = ntohl(packet_size);
if (session->session_state != SSH_SESSION_STATE_AUTHENTICATED){
ssh_set_error(session,SSH_FATAL, "Invalid state when receiving channel open request (must be authenticated)");
@@ -1043,46 +1120,96 @@ SSH_PACKET_CALLBACK(ssh_packet_channel_open){
}
if (strcmp(type_c,"direct-tcpip") == 0) {
rc = ssh_buffer_unpack(packet,
"sdsd",
&msg->channel_request_open.destination,
&destination_port,
&msg->channel_request_open.originator,
&originator_port);
if (rc != SSH_OK) {
destination = buffer_get_ssh_string(packet);
if (destination == NULL) {
ssh_set_error_oom(session);
goto error;
}
msg->channel_request_open.destination = ssh_string_to_char(destination);
if (msg->channel_request_open.destination == NULL) {
ssh_set_error_oom(session);
ssh_string_free(destination);
goto error;
}
ssh_string_free(destination);
buffer_get_u32(packet, &destination_port);
msg->channel_request_open.destination_port = (uint16_t) ntohl(destination_port);
originator = buffer_get_ssh_string(packet);
if (originator == NULL) {
ssh_set_error_oom(session);
goto error;
}
msg->channel_request_open.originator = ssh_string_to_char(originator);
if (msg->channel_request_open.originator == NULL) {
ssh_set_error_oom(session);
ssh_string_free(originator);
goto error;
}
ssh_string_free(originator);
buffer_get_u32(packet, &originator_port);
msg->channel_request_open.originator_port = (uint16_t) ntohl(originator_port);
msg->channel_request_open.destination_port = (uint16_t) destination_port;
msg->channel_request_open.originator_port = (uint16_t) originator_port;
msg->channel_request_open.type = SSH_CHANNEL_DIRECT_TCPIP;
goto end;
}
if (strcmp(type_c,"forwarded-tcpip") == 0) {
rc = ssh_buffer_unpack(packet, "sdsd",
&msg->channel_request_open.destination,
&destination_port,
&msg->channel_request_open.originator,
&originator_port
);
if (rc != SSH_OK){
goto error;
}
msg->channel_request_open.destination_port = (uint16_t) destination_port;
msg->channel_request_open.originator_port = (uint16_t) originator_port;
destination = buffer_get_ssh_string(packet);
if (destination == NULL) {
ssh_set_error_oom(session);
goto error;
}
msg->channel_request_open.destination = ssh_string_to_char(destination);
if (msg->channel_request_open.destination == NULL) {
ssh_set_error_oom(session);
ssh_string_free(destination);
goto error;
}
ssh_string_free(destination);
buffer_get_u32(packet, &destination_port);
msg->channel_request_open.destination_port = (uint16_t) ntohl(destination_port);
originator = buffer_get_ssh_string(packet);
if (originator == NULL) {
ssh_set_error_oom(session);
goto error;
}
msg->channel_request_open.originator = ssh_string_to_char(originator);
if (msg->channel_request_open.originator == NULL) {
ssh_set_error_oom(session);
ssh_string_free(originator);
goto error;
}
ssh_string_free(originator);
buffer_get_u32(packet, &originator_port);
msg->channel_request_open.originator_port = (uint16_t) ntohl(originator_port);
msg->channel_request_open.type = SSH_CHANNEL_FORWARDED_TCPIP;
goto end;
}
if (strcmp(type_c,"x11") == 0) {
rc = ssh_buffer_unpack(packet, "sd",
&msg->channel_request_open.originator,
&originator_port);
if (rc != SSH_OK){
goto error;
}
msg->channel_request_open.originator_port = (uint16_t) originator_port;
originator = buffer_get_ssh_string(packet);
if (originator == NULL) {
ssh_set_error_oom(session);
goto error;
}
msg->channel_request_open.originator = ssh_string_to_char(originator);
if (msg->channel_request_open.originator == NULL) {
ssh_set_error_oom(session);
ssh_string_free(originator);
goto error;
}
ssh_string_free(originator);
buffer_get_u32(packet, &originator_port);
msg->channel_request_open.originator_port = (uint16_t) ntohl(originator_port);
msg->channel_request_open.type = SSH_CHANNEL_X11;
goto end;
}
@@ -1094,6 +1221,8 @@ error:
ssh_message_free(msg);
msg=NULL;
end:
if(type_s != NULL)
ssh_string_free(type_s);
SAFE_FREE(type_c);
if(msg != NULL)
ssh_message_queue(session,msg);
@@ -1118,17 +1247,29 @@ int ssh_message_channel_request_open_reply_accept_channel(ssh_message msg, ssh_c
chan->remote_maxpacket = msg->channel_request_open.packet_size;
chan->remote_window = msg->channel_request_open.window;
chan->state = SSH_CHANNEL_STATE_OPEN;
chan->flags &= ~SSH_CHANNEL_FLAG_NOT_BOUND;
rc = ssh_buffer_pack(session->out_buffer,
"bdddd",
SSH2_MSG_CHANNEL_OPEN_CONFIRMATION,
chan->remote_channel,
chan->local_channel,
chan->local_window,
chan->local_maxpacket);
if (rc != SSH_OK) {
ssh_set_error_oom(session);
rc = buffer_add_u8(session->out_buffer, SSH2_MSG_CHANNEL_OPEN_CONFIRMATION);
if (rc < 0) {
return SSH_ERROR;
}
rc = buffer_add_u32(session->out_buffer, htonl(chan->remote_channel));
if (rc < 0) {
return SSH_ERROR;
}
rc =buffer_add_u32(session->out_buffer, htonl(chan->local_channel));
if (rc < 0) {
return SSH_ERROR;
}
rc = buffer_add_u32(session->out_buffer, htonl(chan->local_window));
if (rc < 0) {
return SSH_ERROR;
}
rc = buffer_add_u32(session->out_buffer, htonl(chan->local_maxpacket));
if (rc < 0) {
return SSH_ERROR;
}
@@ -1185,7 +1326,6 @@ ssh_channel ssh_message_channel_request_open_reply_accept(ssh_message msg) {
int ssh_message_handle_channel_request(ssh_session session, ssh_channel channel, ssh_buffer packet,
const char *request, uint8_t want_reply) {
ssh_message msg = NULL;
int rc;
msg = ssh_message_new(session);
if (msg == NULL) {
@@ -1202,18 +1342,37 @@ int ssh_message_handle_channel_request(ssh_session session, ssh_channel channel,
msg->channel_request.want_reply = want_reply;
if (strcmp(request, "pty-req") == 0) {
rc = ssh_buffer_unpack(packet, "sddddS",
&msg->channel_request.TERM,
&msg->channel_request.width,
&msg->channel_request.height,
&msg->channel_request.pxwidth,
&msg->channel_request.pxheight,
&msg->channel_request.modes
);
ssh_string term = NULL;
char *term_c = NULL;
term = buffer_get_ssh_string(packet);
if (term == NULL) {
ssh_set_error_oom(session);
goto error;
}
term_c = ssh_string_to_char(term);
if (term_c == NULL) {
ssh_set_error_oom(session);
ssh_string_free(term);
goto error;
}
ssh_string_free(term);
msg->channel_request.type = SSH_CHANNEL_REQUEST_PTY;
msg->channel_request.TERM = term_c;
if (rc != SSH_OK) {
buffer_get_u32(packet, &msg->channel_request.width);
buffer_get_u32(packet, &msg->channel_request.height);
buffer_get_u32(packet, &msg->channel_request.pxwidth);
buffer_get_u32(packet, &msg->channel_request.pxheight);
msg->channel_request.width = ntohl(msg->channel_request.width);
msg->channel_request.height = ntohl(msg->channel_request.height);
msg->channel_request.pxwidth = ntohl(msg->channel_request.pxwidth);
msg->channel_request.pxheight = ntohl(msg->channel_request.pxheight);
msg->channel_request.modes = buffer_get_ssh_string(packet);
if (msg->channel_request.modes == NULL) {
msg->channel_request.TERM = NULL;
SAFE_FREE(term_c);
goto error;
}
goto end;
@@ -1221,24 +1380,39 @@ int ssh_message_handle_channel_request(ssh_session session, ssh_channel channel,
if (strcmp(request, "window-change") == 0) {
msg->channel_request.type = SSH_CHANNEL_REQUEST_WINDOW_CHANGE;
rc = ssh_buffer_unpack(packet, "dddd",
&msg->channel_request.width,
&msg->channel_request.height,
&msg->channel_request.pxwidth,
&msg->channel_request.pxheight);
if (rc != SSH_OK){
goto error;
}
buffer_get_u32(packet, &msg->channel_request.width);
buffer_get_u32(packet, &msg->channel_request.height);
buffer_get_u32(packet, &msg->channel_request.pxwidth);
buffer_get_u32(packet, &msg->channel_request.pxheight);
msg->channel_request.width = ntohl(msg->channel_request.width);
msg->channel_request.height = ntohl(msg->channel_request.height);
msg->channel_request.pxwidth = ntohl(msg->channel_request.pxwidth);
msg->channel_request.pxheight = ntohl(msg->channel_request.pxheight);
goto end;
}
if (strcmp(request, "subsystem") == 0) {
rc = ssh_buffer_unpack(packet, "s",
&msg->channel_request.subsystem);
msg->channel_request.type = SSH_CHANNEL_REQUEST_SUBSYSTEM;
if (rc != SSH_OK){
goto error;
ssh_string subsys = NULL;
char *subsys_c = NULL;
subsys = buffer_get_ssh_string(packet);
if (subsys == NULL) {
ssh_set_error_oom(session);
goto error;
}
subsys_c = ssh_string_to_char(subsys);
if (subsys_c == NULL) {
ssh_set_error_oom(session);
ssh_string_free(subsys);
goto error;
}
ssh_string_free(subsys);
msg->channel_request.type = SSH_CHANNEL_REQUEST_SUBSYSTEM;
msg->channel_request.subsystem = subsys_c;
goto end;
}
@@ -1248,37 +1422,84 @@ int ssh_message_handle_channel_request(ssh_session session, ssh_channel channel,
}
if (strcmp(request, "exec") == 0) {
rc = ssh_buffer_unpack(packet, "s",
&msg->channel_request.command);
ssh_string cmd = NULL;
cmd = buffer_get_ssh_string(packet);
if (cmd == NULL) {
ssh_set_error_oom(session);
goto error;
}
msg->channel_request.type = SSH_CHANNEL_REQUEST_EXEC;
if (rc != SSH_OK) {
msg->channel_request.command = ssh_string_to_char(cmd);
ssh_string_free(cmd);
if (msg->channel_request.command == NULL) {
goto error;
}
goto end;
}
if (strcmp(request, "env") == 0) {
rc = ssh_buffer_unpack(packet, "ss",
&msg->channel_request.var_name,
&msg->channel_request.var_value);
msg->channel_request.type = SSH_CHANNEL_REQUEST_ENV;
if (rc != SSH_OK) {
ssh_string name = NULL;
ssh_string value = NULL;
name = buffer_get_ssh_string(packet);
if (name == NULL) {
ssh_set_error_oom(session);
goto error;
}
value = buffer_get_ssh_string(packet);
if (value == NULL) {
ssh_set_error_oom(session);
ssh_string_free(name);
goto error;
}
msg->channel_request.type = SSH_CHANNEL_REQUEST_ENV;
msg->channel_request.var_name = ssh_string_to_char(name);
msg->channel_request.var_value = ssh_string_to_char(value);
if (msg->channel_request.var_name == NULL ||
msg->channel_request.var_value == NULL) {
ssh_string_free(name);
ssh_string_free(value);
goto error;
}
ssh_string_free(name);
ssh_string_free(value);
goto end;
}
if (strcmp(request, "x11-req") == 0) {
rc = ssh_buffer_unpack(packet, "bssd",
&msg->channel_request.x11_single_connection,
&msg->channel_request.x11_auth_protocol,
&msg->channel_request.x11_auth_cookie,
&msg->channel_request.x11_screen_number);
ssh_string auth_protocol = NULL;
ssh_string auth_cookie = NULL;
uint32_t screen_number;
msg->channel_request.type = SSH_CHANNEL_REQUEST_X11;
if (rc != SSH_OK) {
buffer_get_u8(packet, &msg->channel_request.x11_single_connection);
auth_protocol = buffer_get_ssh_string(packet);
if (auth_protocol == NULL) {
ssh_set_error_oom(session);
goto error;
}
auth_cookie = buffer_get_ssh_string(packet);
if (auth_cookie == NULL) {
ssh_set_error_oom(session);
ssh_string_free(auth_protocol);
goto error;
}
msg->channel_request.type = SSH_CHANNEL_REQUEST_X11;
msg->channel_request.x11_auth_protocol = ssh_string_to_char(auth_protocol);
msg->channel_request.x11_auth_cookie = ssh_string_to_char(auth_cookie);
if (msg->channel_request.x11_auth_protocol == NULL ||
msg->channel_request.x11_auth_cookie == NULL) {
ssh_string_free(auth_protocol);
ssh_string_free(auth_cookie);
goto error;
}
ssh_string_free(auth_protocol);
ssh_string_free(auth_cookie);
buffer_get_u32(packet, &screen_number);
msg->channel_request.x11_screen_number = ntohl(screen_number);
goto end;
}
@@ -1296,7 +1517,6 @@ error:
int ssh_message_channel_request_reply_success(ssh_message msg) {
uint32_t channel;
int rc;
if (msg == NULL) {
return SSH_ERROR;
@@ -1308,12 +1528,10 @@ int ssh_message_channel_request_reply_success(ssh_message msg) {
SSH_LOG(SSH_LOG_PACKET,
"Sending a channel_request success to channel %d", channel);
rc = ssh_buffer_pack(msg->session->out_buffer,
"bd",
SSH2_MSG_CHANNEL_SUCCESS,
channel);
if (rc != SSH_OK){
ssh_set_error_oom(msg->session);
if (buffer_add_u8(msg->session->out_buffer, SSH2_MSG_CHANNEL_SUCCESS) < 0) {
return SSH_ERROR;
}
if (buffer_add_u32(msg->session->out_buffer, htonl(channel)) < 0) {
return SSH_ERROR;
}
@@ -1329,74 +1547,77 @@ int ssh_message_channel_request_reply_success(ssh_message msg) {
#ifdef WITH_SERVER
SSH_PACKET_CALLBACK(ssh_packet_global_request){
ssh_message msg = NULL;
ssh_string request_s=NULL;
char *request=NULL;
ssh_string bind_addr_s=NULL;
char *bind_addr=NULL;
uint32_t bind_port;
uint8_t want_reply;
int rc = SSH_PACKET_USED;
int r;
(void)user;
(void)type;
(void)packet;
SSH_LOG(SSH_LOG_PROTOCOL,"Received SSH_MSG_GLOBAL_REQUEST packet");
r = ssh_buffer_unpack(packet, "sb",
&request,
&want_reply);
if (r != SSH_OK){
goto error;
request_s = buffer_get_ssh_string(packet);
if (request_s != NULL) {
request = ssh_string_to_char(request_s);
ssh_string_free(request_s);
}
buffer_get_u8(packet, &want_reply);
SSH_LOG(SSH_LOG_PROTOCOL,"Received SSH_MSG_GLOBAL_REQUEST packet");
msg = ssh_message_new(session);
if (msg == NULL) {
ssh_set_error_oom(session);
goto error;
ssh_string_free_char(request);
return SSH_PACKET_NOT_USED;
}
msg->type = SSH_REQUEST_GLOBAL;
if (strcmp(request, "tcpip-forward") == 0) {
r = ssh_buffer_unpack(packet, "sd",
&msg->global_request.bind_address,
&msg->global_request.bind_port
);
if (r != SSH_OK){
goto error;
if (request && strcmp(request, "tcpip-forward") == 0) {
bind_addr_s = buffer_get_ssh_string(packet);
if (bind_addr_s != NULL) {
bind_addr = ssh_string_to_char(bind_addr_s);
ssh_string_free(bind_addr_s);
}
buffer_get_u32(packet, &bind_port);
bind_port = ntohl(bind_port);
msg->global_request.type = SSH_GLOBAL_REQUEST_TCPIP_FORWARD;
msg->global_request.want_reply = want_reply;
msg->global_request.bind_address = bind_addr;
msg->global_request.bind_port = bind_port;
SSH_LOG(SSH_LOG_PROTOCOL, "Received SSH_MSG_GLOBAL_REQUEST %s %d %s:%d", request, want_reply,
msg->global_request.bind_address,
msg->global_request.bind_port);
SSH_LOG(SSH_LOG_PROTOCOL, "Received SSH_MSG_GLOBAL_REQUEST %s %d %s:%d", request, want_reply, bind_addr, bind_port);
if(ssh_callbacks_exists(session->common.callbacks, global_request_function)) {
SSH_LOG(SSH_LOG_PROTOCOL, "Calling callback for SSH_MSG_GLOBAL_REQUEST %s %d %s:%d", request,
want_reply, msg->global_request.bind_address,
msg->global_request.bind_port);
SSH_LOG(SSH_LOG_PROTOCOL, "Calling callback for SSH_MSG_GLOBAL_REQUEST %s %d %s:%d", request, want_reply, bind_addr, bind_port);
session->common.callbacks->global_request_function(session, msg, session->common.callbacks->userdata);
} else {
SAFE_FREE(request);
ssh_message_queue(session, msg);
return rc;
ssh_message_reply_default(msg);
}
} else if (strcmp(request, "cancel-tcpip-forward") == 0) {
r = ssh_buffer_unpack(packet, "sd",
&msg->global_request.bind_address,
&msg->global_request.bind_port);
if (r != SSH_OK){
goto error;
} else if (request && strcmp(request, "cancel-tcpip-forward") == 0) {
bind_addr_s = buffer_get_ssh_string(packet);
if (bind_addr_s != NULL) {
bind_addr = ssh_string_to_char(bind_addr_s);
ssh_string_free(bind_addr_s);
}
buffer_get_u32(packet, &bind_port);
bind_port = ntohl(bind_port);
msg->global_request.type = SSH_GLOBAL_REQUEST_CANCEL_TCPIP_FORWARD;
msg->global_request.want_reply = want_reply;
msg->global_request.bind_address = bind_addr;
msg->global_request.bind_port = bind_port;
SSH_LOG(SSH_LOG_PROTOCOL, "Received SSH_MSG_GLOBAL_REQUEST %s %d %s:%d", request, want_reply,
msg->global_request.bind_address,
msg->global_request.bind_port);
SSH_LOG(SSH_LOG_PROTOCOL, "Received SSH_MSG_GLOBAL_REQUEST %s %d %s:%d", request, want_reply, bind_addr, bind_port);
if(ssh_callbacks_exists(session->common.callbacks, global_request_function)) {
session->common.callbacks->global_request_function(session, msg, session->common.callbacks->userdata);
} else {
SAFE_FREE(request);
ssh_message_queue(session, msg);
return rc;
ssh_message_reply_default(msg);
}
} else {
SSH_LOG(SSH_LOG_PROTOCOL, "UNKNOWN SSH_MSG_GLOBAL_REQUEST %s %d", request, want_reply);
@@ -1405,12 +1626,9 @@ SSH_PACKET_CALLBACK(ssh_packet_global_request){
SAFE_FREE(msg);
SAFE_FREE(request);
SAFE_FREE(bind_addr);
return rc;
error:
SAFE_FREE(msg);
SAFE_FREE(request);
SSH_LOG(SSH_LOG_WARNING, "Invalid SSH_MSG_GLOBAL_REQUEST packet");
return SSH_PACKET_NOT_USED;
}
#endif /* WITH_SERVER */

View File

@@ -33,10 +33,9 @@
#include <netinet/in.h>
#include <arpa/inet.h>
#ifdef HAVE_SYS_TIME_H
#ifndef HAVE_CLOCK_GETTIME
#include <sys/time.h>
#endif /* HAVE_SYS_TIME_H */
#endif /* HAVE_CLOCK_GETTIME */
#endif /* _WIN32 */
#include <limits.h>
@@ -290,6 +289,23 @@ int ssh_is_ipaddr(const char *str) {
#endif /* _WIN32 */
#ifndef HAVE_NTOHLL
uint64_t ntohll(uint64_t a) {
#ifdef WORDS_BIGENDIAN
return a;
#else /* WORDS_BIGENDIAN */
return (((uint64_t)(a) << 56) | \
(((uint64_t)(a) << 40) & 0xff000000000000ULL) | \
(((uint64_t)(a) << 24) & 0xff0000000000ULL) | \
(((uint64_t)(a) << 8) & 0xff00000000ULL) | \
(((uint64_t)(a) >> 8) & 0xff000000ULL) | \
(((uint64_t)(a) >> 24) & 0xff0000ULL) | \
(((uint64_t)(a) >> 40) & 0xff00ULL) | \
((uint64_t)(a) >> 56));
#endif /* WORDS_BIGENDIAN */
}
#endif /* HAVE_NTOHLL */
char *ssh_lowercase(const char* str) {
char *new, *p;
@@ -846,7 +862,7 @@ int ssh_analyze_banner(ssh_session session, int server, int *ssh1, int *ssh2) {
openssh = strstr(banner, "OpenSSH");
if (openssh != NULL) {
unsigned int major, minor;
int major, minor;
/*
* The banner is typical:
@@ -854,22 +870,8 @@ int ssh_analyze_banner(ssh_session session, int server, int *ssh1, int *ssh2) {
* 012345678901234567890
*/
if (strlen(openssh) > 9) {
major = strtoul(openssh + 8, (char **) NULL, 10);
if (major < 1 || major > 100) {
ssh_set_error(session,
SSH_FATAL,
"Invalid major version number: %s",
banner);
return -1;
}
major = strtol(openssh + 8, (char **) NULL, 10);
minor = strtol(openssh + 10, (char **) NULL, 10);
if (minor > 100) {
ssh_set_error(session,
SSH_FATAL,
"Invalid minor version number: %s",
banner);
return -1;
}
session->openssh = SSH_VERSION_INT(major, minor, 0);
SSH_LOG(SSH_LOG_RARE,
"We are talking to an OpenSSH client version: %d.%d (%x)",
@@ -1028,27 +1030,6 @@ int ssh_match_group(const char *group, const char *object)
return 0;
}
#if !defined(HAVE_STRNDUP)
char *strndup(const char *s, size_t n)
{
char *x = NULL;
if (n + 1 < n) {
return NULL;
}
x = malloc(n + 1);
if (x == NULL) {
return NULL;
}
memcpy(x, s, n);
x[n] = '\0';
return x;
}
#endif /* ! HAVE_STRNDUP */
/** @} */
/* vim: set ts=4 sw=4 et cindent: */

View File

@@ -93,6 +93,12 @@ int ssh_options_copy(ssh_session src, ssh_session *dest) {
if (src->opts.identity) {
struct ssh_iterator *it;
new->opts.identity = ssh_list_new();
if (new->opts.identity == NULL) {
ssh_free(new);
return -1;
}
it = ssh_list_get_iterator(src->opts.identity);
while (it) {
char *id;
@@ -130,7 +136,7 @@ int ssh_options_copy(ssh_session src, ssh_session *dest) {
}
}
for (i = 0; i < 10; i++) {
for (i = 0; i < 10; ++i) {
if (src->opts.wanted_methods[i]) {
new->opts.wanted_methods[i] = strdup(src->opts.wanted_methods[i]);
if (new->opts.wanted_methods[i] == NULL) {
@@ -332,7 +338,7 @@ int ssh_options_set_algo(ssh_session session, int algo,
* - SSH_OPTIONS_HOSTKEYS:
* Set the preferred server host key types (const char *,
* comma-separated list). ex:
* "ssh-rsa,ssh-dss,ecdh-sha2-nistp256"
* "ssh-rsa,ssh-dsa,ecdh-sha2-nistp256"
*
* - SSH_OPTIONS_COMPRESSION_C_S:
* Set the compression to use for client to server
@@ -710,26 +716,6 @@ int ssh_options_set(ssh_session session, enum ssh_options_e type,
return -1;
}
break;
case SSH_OPTIONS_HMAC_C_S:
v = value;
if (v == NULL || v[0] == '\0') {
ssh_set_error_invalid(session);
return -1;
} else {
if (ssh_options_set_algo(session, SSH_MAC_C_S, v) < 0)
return -1;
}
break;
case SSH_OPTIONS_HMAC_S_C:
v = value;
if (v == NULL || v[0] == '\0') {
ssh_set_error_invalid(session);
return -1;
} else {
if (ssh_options_set_algo(session, SSH_MAC_S_C, v) < 0)
return -1;
}
break;
case SSH_OPTIONS_COMPRESSION_C_S:
v = value;
if (v == NULL || v[0] == '\0') {
@@ -885,14 +871,11 @@ int ssh_options_get_port(ssh_session session, unsigned int* port_target) {
if (session == NULL) {
return -1;
}
if (session->opts.port == 0) {
*port_target = 22;
return 0;
if (!session->opts.port) {
ssh_set_error_invalid(session);
return -1;
}
*port_target = session->opts.port;
return 0;
}
@@ -1301,6 +1284,25 @@ int ssh_options_apply(ssh_session session) {
* @addtogroup libssh_server
* @{
*/
static int ssh_bind_options_set_algo(ssh_bind sshbind, int algo,
const char *list) {
if (!verify_existing_algo(algo, list)) {
ssh_set_error(sshbind, SSH_REQUEST_DENIED,
"Setting method: no algorithm for method \"%s\" (%s)\n",
ssh_kex_get_description(algo), list);
return -1;
}
SAFE_FREE(sshbind->wanted_methods[algo]);
sshbind->wanted_methods[algo] = strdup(list);
if (sshbind->wanted_methods[algo] == NULL) {
ssh_set_error_oom(sshbind);
return -1;
}
return 0;
}
static int ssh_bind_set_key(ssh_bind sshbind, char **key_loc,
const void *value) {
if (value == NULL) {
@@ -1326,12 +1328,8 @@ static int ssh_bind_set_key(ssh_bind sshbind, char **key_loc,
* following:
*
* - SSH_BIND_OPTIONS_HOSTKEY:
* Set the path to an ssh host key, regardless
* of type. Only one key from per key type
* (RSA, DSA, ECDSA) is allowed in an ssh_bind
* at a time, and later calls to this function
* with this option for the same key type will
* override prior calls (const char *).
* Set the server public key type: ssh-rsa or ssh-dss
* (const char *).
*
* - SSH_BIND_OPTIONS_BINDADDR:
* Set the IP address to bind (const char *).
@@ -1350,10 +1348,10 @@ static int ssh_bind_set_key(ssh_bind sshbind, char **key_loc,
* with verbosity less than or equal to the
* logging verbosity will be shown.
* - SSH_LOG_NOLOG: No logging
* - SSH_LOG_WARNING: Only warnings
* - SSH_LOG_PROTOCOL: High level protocol information
* - SSH_LOG_PACKET: Lower level protocol infomations, packet level
* - SSH_LOG_FUNCTIONS: Every function path
* - SSH_LOG_RARE: Rare conditions or warnings
* - SSH_LOG_ENTRY: API-accessible entrypoints
* - SSH_LOG_PACKET: Packet id and size
* - SSH_LOG_FUNCTIONS: Function entering and leaving
*
* - SSH_BIND_OPTIONS_LOG_VERBOSITY_STR:
* Set the session logging verbosity via a
@@ -1399,61 +1397,8 @@ int ssh_bind_options_set(ssh_bind sshbind, enum ssh_bind_options_e type,
ssh_set_error_invalid(sshbind);
return -1;
} else {
int key_type;
ssh_key key;
ssh_key *bind_key_loc = NULL;
char **bind_key_path_loc;
rc = ssh_pki_import_privkey_file(value, NULL, NULL, NULL, &key);
if (rc != SSH_OK) {
return -1;
}
key_type = ssh_key_type(key);
switch (key_type) {
case SSH_KEYTYPE_DSS:
bind_key_loc = &sshbind->dsa;
bind_key_path_loc = &sshbind->dsakey;
break;
case SSH_KEYTYPE_ECDSA:
#ifdef HAVE_ECC
bind_key_loc = &sshbind->ecdsa;
bind_key_path_loc = &sshbind->ecdsakey;
#else
ssh_set_error(sshbind,
SSH_FATAL,
"ECDSA key used and libssh compiled "
"without ECDSA support");
#endif
break;
case SSH_KEYTYPE_RSA:
case SSH_KEYTYPE_RSA1:
bind_key_loc = &sshbind->rsa;
bind_key_path_loc = &sshbind->rsakey;
break;
case SSH_KEYTYPE_ED25519:
bind_key_loc = &sshbind->ed25519;
bind_key_path_loc = &sshbind->ed25519key;
break;
default:
ssh_set_error(sshbind,
SSH_FATAL,
"Unsupported key type %d", key_type);
}
if (bind_key_loc == NULL) {
ssh_key_free(key);
return -1;
}
/* Set the location of the key on disk even though we don't
need it in case some other function wants it */
rc = ssh_bind_set_key(sshbind, bind_key_path_loc, value);
if (rc < 0) {
ssh_key_free(key);
return -1;
}
ssh_key_free(*bind_key_loc);
*bind_key_loc = key;
if (ssh_bind_options_set_algo(sshbind, SSH_HOSTKEYS, value) < 0)
return -1;
}
break;
case SSH_BIND_OPTIONS_BINDADDR:

View File

@@ -48,6 +48,8 @@
#include "libssh/auth.h"
#include "libssh/gssapi.h"
#define MACSIZE SHA_DIGEST_LEN
static ssh_packet_callback default_packet_handlers[]= {
ssh_packet_disconnect_callback, // SSH2_MSG_DISCONNECT 1
ssh_packet_ignore_callback, // SSH2_MSG_IGNORE 2
@@ -127,776 +129,6 @@ static ssh_packet_callback default_packet_handlers[]= {
ssh_packet_channel_failure, // SSH2_MSG_CHANNEL_FAILURE 100
};
/** @internal
* @brief check if the received packet is allowed for the current session state
* @param session current ssh_session
* @returns SSH_PACKET_ALLOWED if the packet is allowed; SSH_PACKET_DENIED
* if the packet arrived in wrong state; SSH_PACKET_UNKNOWN if the packet type
* is unknown
*/
static enum ssh_packet_filter_result_e ssh_packet_incoming_filter(ssh_session session)
{
enum ssh_packet_filter_result_e rc;
#ifdef DEBUG_PACKET
SSH_LOG(SSH_LOG_PACKET, "Filtering packet type %d",
session->in_packet.type);
#endif
switch(session->in_packet.type) {
case SSH2_MSG_DISCONNECT: // 1
/*
* States required:
* - None
*
* Transitions:
* - session->socket->state = SSH_SOCKET_CLOSED
* - session->session_state = SSH_SESSION_STATE_ERROR
* */
/* Always allowed */
rc = SSH_PACKET_ALLOWED;
break;
case SSH2_MSG_IGNORE: // 2
/*
* States required:
* - None
*
* Transitions:
* - None
* */
/* Always allowed */
rc = SSH_PACKET_ALLOWED;
break;
case SSH2_MSG_UNIMPLEMENTED: // 3
/*
* States required:
* - None
*
* Transitions:
* - None
* */
/* Always allowed */
rc = SSH_PACKET_ALLOWED;
break;
case SSH2_MSG_DEBUG: // 4
/*
* States required:
* - None
*
* Transitions:
* - None
* */
/* Always allowed */
rc = SSH_PACKET_ALLOWED;
break;
case SSH2_MSG_SERVICE_REQUEST: // 5
/* Server only */
/*
* States required:
* - session->session_state == SSH_SESSION_STATE_AUTHENTICATING
* or session->session_state == SSH_SESSION_STATE_AUTHENTICATED
* - session->dh_handshake_state == DH_STATE_FINISHED
*
* Transitions:
* - None
* */
/* If this is a client, reject the message */
if (session->client) {
rc = SSH_PACKET_DENIED;
break;
}
if ((session->session_state != SSH_SESSION_STATE_AUTHENTICATING) &&
(session->session_state != SSH_SESSION_STATE_AUTHENTICATED))
{
rc = SSH_PACKET_DENIED;
break;
}
if (session->dh_handshake_state != DH_STATE_FINISHED) {
rc = SSH_PACKET_DENIED;
break;
}
rc = SSH_PACKET_ALLOWED;
break;
case SSH2_MSG_SERVICE_ACCEPT: // 6
/*
* States required:
* - session->session_state == SSH_SESSION_STATE_AUTHENTICATING
* or session->session_state == SSH_SESSION_STATE_AUTHENTICATED
* - session->dh_handshake_state == DH_STATE_FINISHED
* - session->auth_service_state == SSH_AUTH_SERVICE_SENT
*
* Transitions:
* - auth_service_state = SSH_AUTH_SERVICE_ACCEPTED
* */
if ((session->session_state != SSH_SESSION_STATE_AUTHENTICATING) &&
(session->session_state != SSH_SESSION_STATE_AUTHENTICATED))
{
rc = SSH_PACKET_DENIED;
break;
}
if (session->dh_handshake_state != DH_STATE_FINISHED) {
rc = SSH_PACKET_DENIED;
break;
}
/* TODO check if only auth service can be requested */
if (session->auth_service_state != SSH_AUTH_SERVICE_SENT) {
rc = SSH_PACKET_DENIED;
break;
}
rc = SSH_PACKET_ALLOWED;
break;
case SSH2_MSG_KEXINIT: // 20
/*
* States required:
* - session_state == SSH_SESSION_STATE_AUTHENTICATED
* or session_state == SSH_SESSION_STATE_INITIAL_KEX
* - dh_handshake_state == DH_STATE_INIT
* or dh_handshake_state == DH_STATE_FINISHED (re-exchange)
*
* Transitions:
* - session->dh_handshake_state = DH_STATE_INIT
* - session->session_state = SSH_SESSION_STATE_KEXINIT_RECEIVED
*
* On server:
* - session->session_state = SSH_SESSION_STATE_DH
* */
if ((session->session_state != SSH_SESSION_STATE_AUTHENTICATED) &&
(session->session_state != SSH_SESSION_STATE_INITIAL_KEX))
{
rc = SSH_PACKET_DENIED;
break;
}
if ((session->dh_handshake_state != DH_STATE_INIT) &&
(session->dh_handshake_state != DH_STATE_FINISHED))
{
rc = SSH_PACKET_DENIED;
break;
}
rc = SSH_PACKET_ALLOWED;
break;
case SSH2_MSG_NEWKEYS: // 21
/*
* States required:
* - session_state == SSH_SESSION_STATE_DH
* - dh_handshake_state == DH_STATE_NEWKEYS_SENT
*
* Transitions:
* - session->dh_handshake_state = DH_STATE_FINISHED
* - session->session_state = SSH_SESSION_STATE_AUTHENTICATING
* if session->flags & SSH_SESSION_FLAG_AUTHENTICATED
* - session->session_state = SSH_SESSION_STATE_AUTHENTICATED
* */
/* If DH has not been started, reject message */
if (session->session_state != SSH_SESSION_STATE_DH) {
rc = SSH_PACKET_DENIED;
break;
}
/* Only allowed if dh_handshake_state is in NEWKEYS_SENT state */
if (session->dh_handshake_state != DH_STATE_NEWKEYS_SENT) {
rc = SSH_PACKET_DENIED;
break;
}
rc = SSH_PACKET_ALLOWED;
break;
case SSH2_MSG_KEXDH_INIT: // 30
// SSH2_MSG_KEX_ECDH_INIT: // 30
// SSH2_MSG_ECMQV_INIT: // 30
// SSH2_MSG_KEX_DH_GEX_REQUEST_OLD: // 30
/* Server only */
/*
* States required:
* - session_state == SSH_SESSION_STATE_DH
* - dh_handshake_state == DH_STATE_INIT
*
* Transitions:
* - session->dh_handshake_state = DH_STATE_INIT_SENT
* then calls dh_handshake_server which triggers:
* - session->dh_handhsake_state = DH_STATE_NEWKEYS_SENT
* */
if (session->session_state != SSH_SESSION_STATE_DH) {
rc = SSH_PACKET_DENIED;
break;
}
/* Only allowed if dh_handshake_state is in initial state */
if (session->dh_handshake_state != DH_STATE_INIT) {
rc = SSH_PACKET_DENIED;
break;
}
rc = SSH_PACKET_ALLOWED;
break;
case SSH2_MSG_KEXDH_REPLY: // 31
// SSH2_MSG_KEX_ECDH_REPLY: // 31
// SSH2_MSG_ECMQV_REPLY: // 31
// SSH2_MSG_KEX_DH_GEX_GROUP: // 31
/*
* States required:
* - session_state == SSH_SESSION_STATE_DH
* - dh_handshake_state == DH_STATE_INIT_SENT
*
* Transitions:
* - session->dh_handhsake_state = DH_STATE_NEWKEYS_SENT
* */
if (session->session_state != SSH_SESSION_STATE_DH) {
rc = SSH_PACKET_DENIED;
break;
}
if (session->dh_handshake_state != DH_STATE_INIT_SENT) {
rc = SSH_PACKET_DENIED;
break;
}
rc = SSH_PACKET_ALLOWED;
break;
case SSH2_MSG_KEX_DH_GEX_INIT: // 32
/* TODO Not filtered */
rc = SSH_PACKET_ALLOWED;
break;
case SSH2_MSG_KEX_DH_GEX_REPLY: // 33
/* TODO Not filtered */
rc = SSH_PACKET_ALLOWED;
break;
case SSH2_MSG_KEX_DH_GEX_REQUEST: // 34
/* TODO Not filtered */
rc = SSH_PACKET_ALLOWED;
break;
case SSH2_MSG_USERAUTH_REQUEST: // 50
/* Server only */
/*
* States required:
* - session_state == SSH_SESSION_STATE_AUTHENTICATING
* - dh_hanshake_state == DH_STATE_FINISHED
*
* Transitions:
* - if authentication was successful:
* - session_state = SSH_SESSION_STATE_AUTHENTICATED
* */
/* If this is a client, reject the message */
if (session->client) {
rc = SSH_PACKET_DENIED;
break;
}
if (session->dh_handshake_state != DH_STATE_FINISHED) {
rc = SSH_PACKET_DENIED;
break;
}
if (session->session_state != SSH_SESSION_STATE_AUTHENTICATING) {
rc = SSH_PACKET_DENIED;
break;
}
rc = SSH_PACKET_ALLOWED;
break;
case SSH2_MSG_USERAUTH_FAILURE: // 51
/*
* States required:
* - session_state == SSH_SESSION_STATE_AUTHENTICATING
* - dh_hanshake_state == DH_STATE_FINISHED
* - session->auth_state == SSH_AUTH_STATE_KBDINT_SENT
* or session->auth_state == SSH_AUTH_STATE_PUBKEY_OFFER_SENT
* or session->auth_state == SSH_AUTH_STATE_PUBKEY_AUTH_SENT
* or session->auth_state == SSH_AUTH_STATE_PASSWORD_AUTH_SENT
* or session->auth_state == SSH_AUTH_STATE_GSSAPI_MIC_SENT
*
* Transitions:
* - if unpacking failed:
* - session->auth_state = SSH_AUTH_ERROR
* - if failure was partial:
* - session->auth_state = SSH_AUTH_PARTIAL
* - else:
* - session->auth_state = SSH_AUTH_STATE_FAILED
* */
/* If this is a server, reject the message */
if (session->server) {
rc = SSH_PACKET_DENIED;
break;
}
if (session->dh_handshake_state != DH_STATE_FINISHED) {
rc = SSH_PACKET_DENIED;
break;
}
if (session->session_state != SSH_SESSION_STATE_AUTHENTICATING) {
rc = SSH_PACKET_DENIED;
break;
}
rc = SSH_PACKET_ALLOWED;
break;
case SSH2_MSG_USERAUTH_SUCCESS: // 52
/*
* States required:
* - session_state == SSH_SESSION_STATE_AUTHENTICATING
* - dh_hanshake_state == DH_STATE_FINISHED
* - session->auth_state == SSH_AUTH_STATE_KBDINT_SENT
* or session->auth_state == SSH_AUTH_STATE_PUBKEY_AUTH_SENT
* or session->auth_state == SSH_AUTH_STATE_PASSWORD_AUTH_SENT
* or session->auth_state == SSH_AUTH_STATE_GSSAPI_MIC_SENT
* or session->auth_state == SSH_AUTH_STATE_AUTH_NONE_SENT
*
* Transitions:
* - session->auth_state = SSH_AUTH_STATE_SUCCESS
* - session->session_state = SSH_SESSION_STATE_AUTHENTICATED
* - session->flags |= SSH_SESSION_FLAG_AUTHENTICATED
* - sessions->auth.current_method = SSH_AUTH_METHOD_UNKNOWN
* */
/* If this is a server, reject the message */
if (session->server) {
rc = SSH_PACKET_DENIED;
break;
}
if (session->dh_handshake_state != DH_STATE_FINISHED) {
rc = SSH_PACKET_DENIED;
break;
}
if (session->session_state != SSH_SESSION_STATE_AUTHENTICATING) {
rc = SSH_PACKET_DENIED;
break;
}
if ((session->auth_state != SSH_AUTH_STATE_KBDINT_SENT) &&
(session->auth_state != SSH_AUTH_STATE_PUBKEY_AUTH_SENT) &&
(session->auth_state != SSH_AUTH_STATE_PASSWORD_AUTH_SENT) &&
(session->auth_state != SSH_AUTH_STATE_GSSAPI_MIC_SENT) &&
(session->auth_state != SSH_AUTH_STATE_AUTH_NONE_SENT))
{
rc = SSH_PACKET_DENIED;
break;
}
rc = SSH_PACKET_ALLOWED;
break;
case SSH2_MSG_USERAUTH_BANNER: // 53
/*
* States required:
* - session_state == SSH_SESSION_STATE_AUTHENTICATING
*
* Transitions:
* - None
* */
if (session->session_state != SSH_SESSION_STATE_AUTHENTICATING) {
rc = SSH_PACKET_DENIED;
break;
}
rc = SSH_PACKET_ALLOWED;
break;
case SSH2_MSG_USERAUTH_PK_OK: // 60
// SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ: // 60
// SSH2_MSG_USERAUTH_INFO_REQUEST: // 60
// SSH2_MSG_USERAUTH_GSSAPI_RESPONSE: // 60
/*
* States required:
* - session_state == SSH_SESSION_STATE_AUTHENTICATING
* - session->auth_state == SSH_AUTH_STATE_KBDINT_SENT
* or
* session->auth_state == SSH_AUTH_STATE_GSSAPI_REQUEST_SENT
* or
* session->auth_state == SSH_AUTH_STATE_PUBKEY_OFFER_SENT
*
* Transitions:
* Depending on the current state, the message is treated
* differently:
* - session->auth_state == SSH_AUTH_STATE_KBDINT_SENT
* - session->auth_state = SSH_AUTH_STATE_INFO
* - session->auth_state == SSH_AUTH_STATE_GSSAPI_REQUEST_SENT
* - session->auth_state = SSH_AUTH_STATE_GSSAPI_TOKEN
* - session->auth_state == SSH_AUTH_STATE_PUBKEY_OFFER_SENT
* - session->auth_state = SSH_AUTH_STATE_PK_OK
* */
if (session->session_state != SSH_SESSION_STATE_AUTHENTICATING) {
rc = SSH_PACKET_DENIED;
break;
}
if ((session->auth_state != SSH_AUTH_STATE_KBDINT_SENT) &&
(session->auth_state != SSH_AUTH_STATE_PUBKEY_OFFER_SENT) &&
(session->auth_state != SSH_AUTH_STATE_GSSAPI_REQUEST_SENT))
{
rc = SSH_PACKET_DENIED;
break;
}
rc = SSH_PACKET_ALLOWED;
break;
case SSH2_MSG_USERAUTH_INFO_RESPONSE: // 61
// SSH2_MSG_USERAUTH_GSSAPI_TOKEN: // 61
/*
* States required:
* - session_state == SSH_SESSION_STATE_AUTHENTICATING
* - session_state->auth_state == SSH_SESSION_STATE_GSSAPI_TOKEN
* or
* session_state->auth_state == SSH_SESSION_STATE_INFO
*
* Transitions:
* - None
* */
if (session->session_state != SSH_SESSION_STATE_AUTHENTICATING) {
rc = SSH_PACKET_DENIED;
break;
}
if ((session->auth_state != SSH_AUTH_STATE_INFO) &&
(session->auth_state != SSH_AUTH_STATE_GSSAPI_TOKEN))
{
rc = SSH_PACKET_DENIED;
break;
}
rc = SSH_PACKET_ALLOWED;
break;
case SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE: // 63
/* TODO Not filtered */
rc = SSH_PACKET_ALLOWED;
break;
case SSH2_MSG_USERAUTH_GSSAPI_ERROR: // 64
/* TODO Not filtered */
rc = SSH_PACKET_ALLOWED;
break;
case SSH2_MSG_USERAUTH_GSSAPI_ERRTOK: // 65
/* TODO Not filtered */
rc = SSH_PACKET_ALLOWED;
break;
case SSH2_MSG_USERAUTH_GSSAPI_MIC: // 66
/* Server only */
/*
* States required:
* - session_state == SSH_SESSION_STATE_AUTHENTICATING
* - session->gssapi->state == SSH_GSSAPI_STATE_RCV_MIC
*
* Transitions:
* Depending on the result of the verification, the states are
* changed:
* - SSH_AUTH_SUCCESS:
* - session->session_state = SSH_SESSION_STATE_AUTHENTICATED
* - session->flags != SSH_SESSION_FLAG_AUTHENTICATED
* - SSH_AUTH_PARTIAL:
* - None
* - any other case:
* - None
* */
/* If this is a client, reject the message */
if (session->client) {
rc = SSH_PACKET_DENIED;
break;
}
if (session->dh_handshake_state != DH_STATE_FINISHED) {
rc = SSH_PACKET_DENIED;
break;
}
if (session->session_state != SSH_SESSION_STATE_AUTHENTICATING) {
rc = SSH_PACKET_DENIED;
break;
}
rc = SSH_PACKET_ALLOWED;
break;
case SSH2_MSG_GLOBAL_REQUEST: // 80
/*
* States required:
* - session_state == SSH_SESSION_STATE_AUTHENTICATED
*
* Transitions:
* - None
* */
if (session->session_state != SSH_SESSION_STATE_AUTHENTICATED) {
rc = SSH_PACKET_DENIED;
break;
}
rc = SSH_PACKET_ALLOWED;
break;
case SSH2_MSG_REQUEST_SUCCESS: // 81
/*
* States required:
* - session_state == SSH_SESSION_STATE_AUTHENTICATED
* - session->global_req_state == SSH_CHANNEL_REQ_STATE_PENDING
*
* Transitions:
* - session->global_req_state == SSH_CHANNEL_REQ_STATE_ACCEPTED
* */
if (session->session_state != SSH_SESSION_STATE_AUTHENTICATED) {
rc = SSH_PACKET_DENIED;
break;
}
if (session->global_req_state != SSH_CHANNEL_REQ_STATE_PENDING) {
rc = SSH_PACKET_DENIED;
break;
}
rc = SSH_PACKET_ALLOWED;
break;
case SSH2_MSG_REQUEST_FAILURE: // 82
/*
* States required:
* - session_state == SSH_SESSION_STATE_AUTHENTICATED
* - session->global_req_state == SSH_CHANNEL_REQ_STATE_PENDING
*
* Transitions:
* - session->global_req_state == SSH_CHANNEL_REQ_STATE_DENIED
* */
if (session->session_state != SSH_SESSION_STATE_AUTHENTICATED) {
rc = SSH_PACKET_DENIED;
break;
}
if (session->global_req_state != SSH_CHANNEL_REQ_STATE_PENDING) {
rc = SSH_PACKET_DENIED;
break;
}
rc = SSH_PACKET_ALLOWED;
break;
case SSH2_MSG_CHANNEL_OPEN: // 90
/*
* States required:
* - session_state == SSH_SESSION_STATE_AUTHENTICATED
*
* Transitions:
* - None
* */
if (session->session_state != SSH_SESSION_STATE_AUTHENTICATED) {
rc = SSH_PACKET_DENIED;
break;
}
rc = SSH_PACKET_ALLOWED;
break;
case SSH2_MSG_CHANNEL_OPEN_CONFIRMATION: // 91
/*
* States required:
* - session_state == SSH_SESSION_STATE_AUTHENTICATED
*
* Transitions:
* - channel->state = SSH_CHANNEL_STATE_OPEN
* - channel->flags &= ~SSH_CHANNEL_FLAG_NOT_BOUND
* */
if (session->session_state != SSH_SESSION_STATE_AUTHENTICATED) {
rc = SSH_PACKET_DENIED;
break;
}
rc = SSH_PACKET_ALLOWED;
break;
case SSH2_MSG_CHANNEL_OPEN_FAILURE: // 92
/*
* States required:
* - session_state == SSH_SESSION_STATE_AUTHENTICATED
*
* Transitions:
* - channel->state = SSH_CHANNEL_STATE_OPEN_DENIED
* */
if (session->session_state != SSH_SESSION_STATE_AUTHENTICATED) {
rc = SSH_PACKET_DENIED;
break;
}
rc = SSH_PACKET_ALLOWED;
break;
case SSH2_MSG_CHANNEL_WINDOW_ADJUST: // 93
/*
* States required:
* - session_state == SSH_SESSION_STATE_AUTHENTICATED
*
* Transitions:
* - None
* */
if (session->session_state != SSH_SESSION_STATE_AUTHENTICATED) {
rc = SSH_PACKET_DENIED;
break;
}
rc = SSH_PACKET_ALLOWED;
break;
case SSH2_MSG_CHANNEL_DATA: // 94
/*
* States required:
* - session_state == SSH_SESSION_STATE_AUTHENTICATED
*
* Transitions:
* - None
* */
if (session->session_state != SSH_SESSION_STATE_AUTHENTICATED) {
rc = SSH_PACKET_DENIED;
break;
}
rc = SSH_PACKET_ALLOWED;
break;
case SSH2_MSG_CHANNEL_EXTENDED_DATA: // 95
/*
* States required:
* - session_state == SSH_SESSION_STATE_AUTHENTICATED
*
* Transitions:
* - None
* */
if (session->session_state != SSH_SESSION_STATE_AUTHENTICATED) {
rc = SSH_PACKET_DENIED;
break;
}
rc = SSH_PACKET_ALLOWED;
break;
case SSH2_MSG_CHANNEL_EOF: // 96
/*
* States required:
* - session_state == SSH_SESSION_STATE_AUTHENTICATED
*
* Transitions:
* - None
* */
if (session->session_state != SSH_SESSION_STATE_AUTHENTICATED) {
rc = SSH_PACKET_DENIED;
break;
}
rc = SSH_PACKET_ALLOWED;
break;
case SSH2_MSG_CHANNEL_CLOSE: // 97
/*
* States required:
* - session_state == SSH_SESSION_STATE_AUTHENTICATED
*
* Transitions:
* - channel->state = SSH_CHANNEL_STATE_CLOSED
* - channel->flags |= SSH_CHANNEL_FLAG_CLOSED_REMOTE
* */
if (session->session_state != SSH_SESSION_STATE_AUTHENTICATED) {
rc = SSH_PACKET_DENIED;
break;
}
rc = SSH_PACKET_ALLOWED;
break;
case SSH2_MSG_CHANNEL_REQUEST: // 98
/*
* States required:
* - session_state == SSH_SESSION_STATE_AUTHENTICATED
*
* Transitions:
* - Depends on the request
* */
if (session->session_state != SSH_SESSION_STATE_AUTHENTICATED) {
rc = SSH_PACKET_DENIED;
break;
}
rc = SSH_PACKET_ALLOWED;
break;
case SSH2_MSG_CHANNEL_SUCCESS: // 99
/*
* States required:
* - session_state == SSH_SESSION_STATE_AUTHENTICATED
* - channel->request_state == SSH_CHANNEL_REQ_STATE_PENDING
*
* Transitions:
* - channel->request_state = SSH_CHANNEL_REQ_STATE_ACCEPTED
* */
if (session->session_state != SSH_SESSION_STATE_AUTHENTICATED) {
rc = SSH_PACKET_DENIED;
break;
}
rc = SSH_PACKET_ALLOWED;
break;
case SSH2_MSG_CHANNEL_FAILURE: // 100
/*
* States required:
* - session_state == SSH_SESSION_STATE_AUTHENTICATED
* - channel->request_state == SSH_CHANNEL_REQ_STATE_PENDING
*
* Transitions:
* - channel->request_state = SSH_CHANNEL_REQ_STATE_DENIED
* */
if (session->session_state != SSH_SESSION_STATE_AUTHENTICATED) {
rc = SSH_PACKET_DENIED;
break;
}
rc = SSH_PACKET_ALLOWED;
break;
default:
/* Unknown message, do not filter */
rc = SSH_PACKET_UNKNOWN;
goto end;
}
end:
#ifdef DEBUG_PACKET
if (rc == SSH_PACKET_DENIED) {
SSH_LOG(SSH_LOG_PACKET, "REJECTED packet type %d: ",
session->in_packet.type);
}
if (rc == SSH_PACKET_UNKNOWN) {
SSH_LOG(SSH_LOG_PACKET, "UNKNOWN packet type %d",
session->in_packet.type);
}
#endif
return rc;
}
/* in nonblocking mode, socket_read will read as much as it can, and return */
/* SSH_OK if it has read at least len bytes, otherwise, SSH_AGAIN. */
/* in blocking mode, it will read at least len bytes and will block until it's ok. */
@@ -914,20 +146,15 @@ int ssh_packet_socket_callback(const void *data, size_t receivedlen, void *user)
ssh_session session= (ssh_session) user;
unsigned int blocksize = (session->current_crypto ?
session->current_crypto->in_cipher->blocksize : 8);
unsigned char mac[DIGEST_MAX_LEN] = {0};
int current_macsize = session->current_crypto ? MACSIZE : 0;
unsigned char mac[30] = {0};
char buffer[16] = {0};
size_t current_macsize = 0;
const uint8_t *packet;
int to_be_read;
int rc;
uint32_t len, compsize, payloadsize;
uint8_t padding;
size_t processed = 0; /* number of byte processed from the callback */
enum ssh_packet_filter_result_e filter_result;
if(session->current_crypto != NULL) {
current_macsize = hmac_digest_len(session->current_crypto->in_hmac);
}
if (data == NULL) {
goto error;
@@ -950,7 +177,7 @@ int ssh_packet_socket_callback(const void *data, size_t receivedlen, void *user)
memset(&session->in_packet, 0, sizeof(PACKET));
if (session->in_buffer) {
rc = ssh_buffer_reinit(session->in_buffer);
rc = buffer_reinit(session->in_buffer);
if (rc < 0) {
goto error;
}
@@ -965,7 +192,7 @@ int ssh_packet_socket_callback(const void *data, size_t receivedlen, void *user)
processed += blocksize;
len = packet_decrypt_len(session, buffer);
rc = ssh_buffer_add_data(session->in_buffer, buffer, blocksize);
rc = buffer_add_data(session->in_buffer, buffer, blocksize);
if (rc < 0) {
goto error;
}
@@ -1010,7 +237,7 @@ int ssh_packet_socket_callback(const void *data, size_t receivedlen, void *user)
to_be_read - current_macsize);
#endif
rc = ssh_buffer_add_data(session->in_buffer,
rc = buffer_add_data(session->in_buffer,
packet,
to_be_read - current_macsize);
if (rc < 0) {
@@ -1040,9 +267,9 @@ int ssh_packet_socket_callback(const void *data, size_t receivedlen, void *user)
/* copy the last part from the incoming buffer */
packet = ((uint8_t *)data) + processed;
memcpy(mac, packet, current_macsize);
memcpy(mac, packet, MACSIZE);
rc = packet_hmac_verify(session, session->in_buffer, mac, session->current_crypto->in_hmac);
rc = packet_hmac_verify(session, session->in_buffer, mac);
if (rc < 0) {
ssh_set_error(session, SSH_FATAL, "HMAC error");
goto error;
@@ -1084,10 +311,6 @@ int ssh_packet_socket_callback(const void *data, size_t receivedlen, void *user)
#endif /* WITH_ZLIB */
payloadsize = buffer_get_rest_len(session->in_buffer);
session->recv_seq++;
if (session->raw_counter != NULL) {
session->raw_counter->in_bytes += payloadsize;
session->raw_counter->in_packets++;
}
/*
* We don't want to rewrite a new packet while still executing the
@@ -1099,21 +322,8 @@ int ssh_packet_socket_callback(const void *data, size_t receivedlen, void *user)
"packet: read type %hhd [len=%d,padding=%hhd,comp=%d,payload=%d]",
session->in_packet.type, len, padding, compsize, payloadsize);
/* Check if the packet is expected */
filter_result = ssh_packet_incoming_filter(session);
switch(filter_result) {
case SSH_PACKET_ALLOWED:
/* Execute callbacks */
ssh_packet_process(session, session->in_packet.type);
break;
case SSH_PACKET_DENIED:
goto error;
case SSH_PACKET_UNKNOWN:
ssh_packet_send_unimplemented(session, session->recv_seq - 1);
break;
}
/* Execute callbacks */
ssh_packet_process(session, session->in_packet.type);
session->packet_state = PACKET_STATE_INIT;
if (processed < receivedlen) {
/* Handle a potential packet left in socket buffer */
@@ -1129,7 +339,7 @@ int ssh_packet_socket_callback(const void *data, size_t receivedlen, void *user)
return processed;
case PACKET_STATE_PROCESSING:
SSH_LOG(SSH_LOG_PACKET, "Nested packet processing. Delaying.");
SSH_LOG(SSH_LOG_RARE, "Nested packet processing. Delaying.");
return 0;
}
@@ -1226,42 +436,34 @@ void ssh_packet_process(ssh_session session, uint8_t type){
* @return SSH_ERROR on error, else SSH_OK
*/
int ssh_packet_send_unimplemented(ssh_session session, uint32_t seqnum){
int rc;
int r;
rc = ssh_buffer_pack(session->out_buffer,
"bd",
SSH2_MSG_UNIMPLEMENTED,
seqnum);
if (rc != SSH_OK) {
ssh_set_error_oom(session);
return SSH_ERROR;
}
rc = packet_send(session);
r = buffer_add_u8(session->out_buffer, SSH2_MSG_UNIMPLEMENTED);
if (r < 0) {
return SSH_ERROR;
}
r = buffer_add_u32(session->out_buffer, htonl(seqnum));
if (r < 0) {
return SSH_ERROR;
}
r = packet_send(session);
return rc;
return r;
}
/** @internal
* @brief handles a SSH_MSG_UNIMPLEMENTED packet
*/
SSH_PACKET_CALLBACK(ssh_packet_unimplemented){
uint32_t seq;
int rc;
uint32_t seq;
(void)session; /* unused */
(void)type;
(void)user;
rc = ssh_buffer_unpack(packet, "d", &seq);
if (rc != SSH_OK) {
SSH_LOG(SSH_LOG_WARNING,
"Could not unpack SSH_MSG_UNIMPLEMENTED packet");
}
SSH_LOG(SSH_LOG_RARE,
"Received SSH_MSG_UNIMPLEMENTED (sequence number %d)",seq);
return SSH_PACKET_USED;
(void)type;
(void)user;
buffer_get_u32(packet,&seq);
seq=ntohl(seq);
SSH_LOG(SSH_LOG_RARE,
"Received SSH_MSG_UNIMPLEMENTED (sequence number %d)",seq);
return SSH_PACKET_USED;
}
/** @internal
@@ -1300,8 +502,6 @@ static int ssh_packet_write(ssh_session session) {
static int packet_send2(ssh_session session) {
unsigned int blocksize = (session->current_crypto ?
session->current_crypto->out_cipher->blocksize : 8);
enum ssh_hmac_e hmac_type = (session->current_crypto ?
session->current_crypto->out_hmac : session->next_crypto->out_hmac);
uint32_t currentlen = buffer_get_rest_len(session->out_buffer);
unsigned char *hmac = NULL;
char padstring[32] = { 0 };
@@ -1340,7 +540,7 @@ static int packet_send2(ssh_session session) {
if (rc < 0) {
goto error;
}
rc = ssh_buffer_add_data(session->out_buffer, padstring, padding);
rc = buffer_add_data(session->out_buffer, padstring, padding);
if (rc < 0) {
goto error;
}
@@ -1354,23 +554,18 @@ static int packet_send2(ssh_session session) {
hmac = packet_encrypt(session, buffer_get_rest(session->out_buffer),
buffer_get_rest_len(session->out_buffer));
if (hmac) {
rc = ssh_buffer_add_data(session->out_buffer, hmac, hmac_digest_len(hmac_type));
if (rc < 0) {
if (buffer_add_data(session->out_buffer, hmac, 20) < 0) {
goto error;
}
}
rc = ssh_packet_write(session);
session->send_seq++;
if (session->raw_counter != NULL) {
session->raw_counter->out_bytes += payloadsize;
session->raw_counter->out_packets++;
}
SSH_LOG(SSH_LOG_PACKET,
"packet: wrote [len=%d,padding=%hhd,comp=%d,payload=%d]",
ntohl(finallen), padding, compsize, payloadsize);
if (ssh_buffer_reinit(session->out_buffer) < 0) {
if (buffer_reinit(session->out_buffer) < 0) {
rc = SSH_ERROR;
}
error:

View File

@@ -114,7 +114,7 @@ int ssh_packet_socket_callback1(const void *data, size_t receivedlen, void *user
memset(&session->in_packet, 0, sizeof(PACKET));
if (session->in_buffer) {
if (ssh_buffer_reinit(session->in_buffer) < 0) {
if (buffer_reinit(session->in_buffer) < 0) {
goto error;
}
} else {
@@ -155,7 +155,7 @@ int ssh_packet_socket_callback1(const void *data, size_t receivedlen, void *user
/* it is _not_ possible that to_be_read be < 8. */
packet = (char *)data + processed;
if (ssh_buffer_add_data(session->in_buffer,packet,to_be_read) < 0) {
if (buffer_add_data(session->in_buffer,packet,to_be_read) < 0) {
goto error;
}
processed += to_be_read;
@@ -241,7 +241,7 @@ int ssh_packet_socket_callback1(const void *data, size_t receivedlen, void *user
return processed;
case PACKET_STATE_PROCESSING:
SSH_LOG(SSH_LOG_PACKET, "Nested packet processing. Delaying.");
SSH_LOG(SSH_LOG_RARE, "Nested packet processing. Delaying.");
return 0;
}
@@ -322,7 +322,7 @@ int packet_send1(ssh_session session) {
session->send_seq++;
if (ssh_buffer_reinit(session->out_buffer) < 0) {
if (buffer_reinit(session->out_buffer) < 0) {
rc = SSH_ERROR;
}
error:

Some files were not shown because too many files have changed in this diff Show More