Compare commits

..

626 Commits

Author SHA1 Message Date
Andreas Schneider
e5352e3021 include: Add stddef.h for size_t
Fixes T119

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-10-30 09:20:29 +01:00
Andreas Schneider
64a2d37c30 Bump version to 0.7.7
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-10-29 10:52:49 +01:00
Andreas Schneider
9d5cf209df libcrypto: Fix memory leak in evp_final()
Fixes T116

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit a280747462)
2018-10-28 14:31:33 +01:00
Meng Tan
1039732154 gssapi: Set correct state after sending GSSAPI_RESPONSE (select mechanism OID)
Signed-off-by: Meng Tan <mtan@wallix.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit bce8d56705)
2018-10-26 09:04:56 +02:00
Andreas Schneider
7ad80ba1cc server: Fix compile error
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-10-24 19:57:17 +02:00
Andreas Schneider
acb0e4f401 examples: Explicitly track auth state in samplesshd-kbdint
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 0ff566b6dd)
2018-10-19 14:10:02 +02:00
Andreas Schneider
3fe7510b26 messages: Check that the requested service is 'ssh-connection'
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 9c200d3ef4)
2018-10-19 14:09:58 +02:00
Meng Tan
734e3ce674 server: Set correct state after sending INFO_REQUEST (Kbd Interactive)
Signed-off-by: Meng Tan <mtan@wallix.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 4ea46eecce)
2018-10-19 14:09:53 +02:00
Andreas Schneider
e4c6d591df packet: Add missing break in ssh_packet_incoming_filter()
CID 1396239

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit fe618a35dc)
2018-10-19 14:09:47 +02:00
Andreas Schneider
f81ca61612 misc: Add strndup implementation if not provides by the OS
Fixes T112

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 247983e982)
2018-10-17 08:23:15 +02:00
Andreas Schneider
c20b360c96 Bump version to 0.7.6
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-10-16 12:45:32 +02:00
Andreas Schneider
5e061962c5 cpack: Fix ignore files
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-10-16 12:45:32 +02:00
Anderson Toshiyuki Sasaki
f1d57223db CVE-2018-10933: Add tests for packet filtering
Created the test torture_packet_filter.c which tests if packets are
being correctly filtered.

Fixes T101

Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
2018-10-09 11:45:59 +02:00
Anderson Toshiyuki Sasaki
b9033ad56a CVE-2018-10933: Introduced packet filtering
The packet filter checks required states for the incoming packets and
reject them if they arrived in the wrong state.

Fixes T101

Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
2018-10-09 11:45:59 +02:00
Anderson Toshiyuki Sasaki
e5ff7aa410 CVE-2018-10933: Check channel state when OPEN_FAILURE arrives
When a SSH2_MSG_OPEN_FAILURE arrives, the channel state is checked
to be in SSH_CHANNEL_STATE_OPENING.

Fixes T101

Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
2018-10-09 11:45:59 +02:00
Anderson Toshiyuki Sasaki
3837a0547f CVE-2018-10933: Check channel state when OPEN_CONFIRMATION arrives
When a SSH2_MSG_OPEN_CONFIRMATION arrives, the channel state is checked
to be in SSH_CHANNEL_STATE_OPENING.

Fixes T101

Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
2018-10-09 11:45:58 +02:00
Anderson Toshiyuki Sasaki
7985acb768 CVE-2018-10933: Set correct state after sending MIC
After sending the client token, the auth state is set as
SSH_AUTH_STATE_GSSAPI_MIC_SENT.  Then this can be expected to be the
state when a USERAUTH_FAILURE or USERAUTH_SUCCESS arrives.

Fixes T101

Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
2018-10-09 11:45:58 +02:00
Anderson Toshiyuki Sasaki
acd6a1ca8a CVE-2018-10933: Introduce SSH_AUTH_STATE_AUTH_NONE_SENT
The introduced auth state allows to identify when a request without
authentication information was sent.

Fixes T101

Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
2018-10-09 11:45:58 +02:00
Anderson Toshiyuki Sasaki
ddea46f890 CVE-2018-10933: Introduce SSH_AUTH_STATE_PASSWORD_AUTH_SENT
The introduced auth state allows to identify when authentication using
password was tried.

Fixes T101

Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
2018-10-09 11:45:58 +02:00
Anderson Toshiyuki Sasaki
e5f0e711b0 CVE-2018-10933: Introduced new auth states
Introduced the states SSH_AUTH_STATE_PUBKEY_OFFER_SENT and
SSH_AUTH_STATE_PUBKEY_AUTH_SENT to know when SSH2_MSG_USERAUTH_PK_OK and
SSH2_MSG_USERAUTH_SUCCESS should be expected.

Fixes T101

Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
2018-10-09 11:45:58 +02:00
Andreas Schneider
e765c1400a dh: Use ssh_get_fingerprint_hash() in ssh_print_hash()
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 92aa2cf496)
2018-10-09 10:16:30 +02:00
Andreas Schneider
7a7c0a54bc dh: Add ssh_get_fingerprint_hash()
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit bbed139eca)
2018-10-09 10:16:27 +02:00
Jan-Niklas Burfeind
9c62d6dfcd dh: Add ssh_print_hash() function which can deal with sha256
Signed-off-by: Jan-Niklas Burfeind <libssh@aiyionpri.me>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit f32cb70675)
2018-10-09 10:16:20 +02:00
Jan-Niklas Burfeind
f3f140e65f dh: Add SSH_PUBLICKEY_HASH_SHA256 to ssh_get_publickey_hash()
Signed-off-by: Jan-Niklas Burfeind <libssh@aiyionpri.me>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 1499b38aef)
2018-10-09 10:16:14 +02:00
Jakub Jelen
c977a97093 Assorted changes to make the proxycommand test pass
Cherry-picked from the following commit:
e4653b82bd
2018-10-05 12:09:45 +02:00
Jakub Jelen
743a34ad9f Assorted changes to make the sftp_read test working
CHerry-picked from the following commit:
571f547556
2018-10-05 12:09:45 +02:00
Jakub Jelen
0f9e6598ef Assorted changes to make the sftp_dir test working
Cherry-picked from the following commit:
af3de262b6
2018-10-05 12:09:45 +02:00
Jakub Jelen
f8007d7147 Assorted changes to make the torture_forward test pass
Cherry-picked from the following commit:
be25b58380
2018-10-05 12:09:45 +02:00
Jakub Jelen
3d70d4f08d Assorted changes to make torture_request_env pass
Cherry-picked from the following commit:
4bc6af6c17
2018-10-05 12:09:45 +02:00
Andreas Schneider
bade29d3d5 torture: Fix torture_ssh_session() for cwrap testing
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>

(cherry-picked from commit 66f51df9)
2018-10-05 12:09:45 +02:00
Andreas Schneider
399ff6bbde tests: Add public keys for bob
This also allows bob to auth as alice.

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
(cherry-picked from commit ee866441)
2018-10-05 12:09:45 +02:00
Jakub Jelen
c0d9aeda18 Assorted changes to make knownhosts test work
Cherry-picked from the following commit:
b65dcb3a35
2018-10-05 12:09:45 +02:00
Andreas Schneider
82b2d31c29 tortrue: Add ed25519 hostkey to sshd
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>

(cherry-picked from commit 250bf37a)
2018-10-05 12:09:45 +02:00
Jakub Jelen
74102dfd7a Assorted changes from master to make torture_algorithms test working
Cherry-picked from the following commits:
cbd75c3e35
3014e3c458
2018-10-05 12:09:45 +02:00
Andreas Schneider
d678f6a9ea torture: Fix building on Windows
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>

(cherry-picked from commit b74a1841)
2018-10-05 12:09:45 +02:00
Jakub Jelen
00b8e6d1f0 tests: UsePrivilegeSeparation has no effect since OpenSSH 7.5
Additionally, we can already work around the privilege separation.

http://www.openssh.com/txt/release-7.5

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>

(cherry-picked from commit 56317caa)
2018-10-05 12:09:45 +02:00
Jakub Jelen
aeb859e130 tests: Do not trace sshd
OpenSSH's sshd does not work well under valgrind so lets avoid tracing it.

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>

(cherry-picked from commit ca4fb9c6)
2018-10-05 12:09:45 +02:00
Jakub Jelen
b393f7e5e9 tests: Temporarily build chroot_wrapper
(cherry-picked from commit 094aa5eb)
2018-10-05 12:09:45 +02:00
Andreas Schneider
2004617fd0 tests: Always start tests as root so we can switch to a user
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>

(cherry-picked from commit 1729d4a1)
2018-10-05 12:09:45 +02:00
Jakub Jelen
c5fe7c5a72 tests: Do not generate pcap file by default
pcap file is generated by the processes writing to the sockets,
which is not allowed for privilege-separated process in new
OpenSSH servers (confined by seccomp filter).

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>

(cherry-picked from commit 5d3ab421)
2018-10-05 12:09:45 +02:00
Jakub Jelen
fec4dc4eff tests: Give server more time to start
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>

(cherry-picked from commit f8f7989c)
2018-10-05 12:09:45 +02:00
Jakub Jelen
3d0c9cc6b5 tests: Do not test blowfish ciphers with OpenSSH 7.6 and newer
(cherry-picked from commit b92c4996)
2018-10-05 12:09:45 +02:00
Andreas Schneider
4d6048ef88 torture: Add support to specify verbosity level via env variable
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>

(cherry-picked from commit 2a9c3966)
2018-10-05 12:09:45 +02:00
Andreas Schneider
3d2d777e26 torture: Fix a warning
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>

(cherry-picked from commit 2bd65015)
2018-10-05 12:09:45 +02:00
Aris Adamantiadis
8520adf609 osx: fix compilation
(cherry-picked from commit 886fdc8b)
2018-10-05 12:09:45 +02:00
Justus Winter
c0be59f876 tests: Make test suite work out of the box on Debian
* tests/torture.c (torture_setup_create_sshd_config): Rework how the
location of the sftp server is discovered, and add the Debian-specific
location.

Signed-off-by: Justus Winter <justus@g10code.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>

(cherry-picked from commit e37fd832)
2018-10-05 12:09:45 +02:00
Andreas Schneider
2983b21996 torture: Fix ssh version detection
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>

(cherry-picked from commit de309c51)
2018-10-05 12:09:45 +02:00
Andreas Schneider
88ae595583 torture: Set sshd debug level to DEBUG3
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>

(cherry-picked from commit 06343074)
2018-10-05 12:09:45 +02:00
Andreas Schneider
a228c3f728 torture: Also write stderr to a file
This allows to capture debug information of the wrappers.

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>

(cherry-picked from commit c365ff3d)
2018-10-05 12:09:45 +02:00
Andreas Schneider
53ed121a9c torture: Add additional sftp-server path for BSD
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>

(cherry-picked from commit 1bbfe058)
2018-10-05 12:09:45 +02:00
Andreas Schneider
5a1ebdec9d tests: Wait for sshd to start before connecting
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>

(cherry-picked from commit a3557b81)
2018-10-05 12:09:45 +02:00
Andreas Schneider
bf2a33b21e tests: Turn on PAM support in sshd with pam_wrapper
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>

(cherry-picked from commit 7aa84318)
2018-10-05 12:09:45 +02:00
Andreas Schneider
130194aa0e torture: Improve process termination function
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>

(cherry-picked from commit 0e98f121)
2018-10-05 12:09:45 +02:00
Andreas Schneider
1ebfd3834a tests: Support other openssh versions ...
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>

(cherry-picked from commit 6e7eae96)
2018-10-05 12:09:45 +02:00
Andreas Schneider
1eeeace975 cmake: Configure nss_wrapper and uid_wrapper
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>

(cherry-picked from commit 21b0d29e)
2018-10-02 16:35:28 +02:00
Andreas Schneider
73ebcb3ab8 torture: Start sshd as root
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>

(cherry-picked from commit a30d16c4)
2018-10-02 16:35:08 +02:00
Andreas Schneider
bd7b509278 torture: Enable old host key algos for testing
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>

(cherry-picked from commit c1fb9483)
2018-10-02 16:34:49 +02:00
Andreas Schneider
652acbeb21 torture: Enable old cipher and kex algos in sshd
We need to test them, so enable them in the sshd.

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>

(cherry-picked from commit dd0d04ae)
2018-10-02 16:34:23 +02:00
Andreas Schneider
96e04d4691 torture: Create a torture_terminate_process() function
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>

(cherry-picked from commit ae89b6c0)
2018-10-02 16:34:02 +02:00
Andreas Schneider
7113074ae4 torture: Add torture_teardown_sshd_server().
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>

(cherry-picked from commit 14f1ce2e)
2018-10-02 16:33:40 +02:00
Andreas Schneider
2db325eb74 torture: Restrict files to we write to our user.
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>

(cherry-picked from commit 62b0f58d)
2018-10-02 16:33:18 +02:00
Andreas Schneider
9937d0b552 torture: Add function to setup sshd server
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>

(cherry-picked from commit c3f963e7)
2018-10-02 16:32:45 +02:00
Andreas Schneider
ae3e2a19c8 torture: Add torture_teardown_socket_dir().
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>

(cherry-picked from commit fd09c4cb)
2018-10-02 16:32:04 +02:00
Andreas Schneider
3567524fb2 torture: Add torture_setup_socket_dir().
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>

(cherry-picked from commit 13f68fc2)
2018-10-02 16:31:32 +02:00
Andreas Schneider
4814c188eb tests: Add ssh host keys for test environment.
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>

(cherry-picked from commit c2d63627)
2018-10-02 16:31:16 +02:00
Andreas Schneider
a317188cb7 cmake: Search for cwrap and sshd.
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>

(cherry-picked from commit 6596d27e)
2018-10-02 16:29:17 +02:00
Andreas Schneider
1d4151e51f libcrypt: Add missing header for compat
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-06-30 14:10:32 +02:00
Andreas Schneider
c228fa7631 pki: Fix duplicating ed25519 public keys
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 816234350d)
2018-06-29 17:18:12 +02:00
Andreas Schneider
9658d36087 kex1: Add missing NULL check in make_rsa1_string()
CID 1388445

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit c705fb6e3b)
2018-06-29 17:17:27 +02:00
Nikos Mavrogiannopoulos
bbaa3dc869 kex1: Use libcrypto-compat.h for RSA_get0_key with OpenSSL
Signed-off-by: Nikos Mavrogiannopoulos <nmav@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit a95bc8a016)
2018-06-29 17:17:03 +02:00
Andreas Schneider
4f10d6cd57 kex1: Fix building with OpenSSL 1.1+
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 8d65edb41f)
2018-06-29 17:16:49 +02:00
Meng Tan
2209fcace3 Set channel as bound when accepting channel open request
Signed-off-by: Meng Tan <mtan@wallix.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit f19158cadf)
2018-06-29 17:16:06 +02:00
Andreas Schneider
a1847660a3 pki: Fix random memory corruption
Fixes T78

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 1444ae5add)
2018-06-29 17:12:46 +02:00
Jon Simons
e2b48dc662 libcrypto: fix resource leak in hmac_final
Fix a resource leak in `hmac_final`: say `HMAC_CTX_free` instead
of `HMAC_CTX_reset`.  This matches the error handling as done in
`hmac_init`.  Introduced with cf1e808e2f.

The problem is reproducible running the `pkd_hello` test with:

    valgrind --leak-check=full ./pkd_hello -i1 -t torture_pkd_openssh_dsa_rsa_default

Resolves https://red.libssh.org/issues/252.

Cherry-picked from a64ddff3fe

Signed-off-by: Jon Simons <jon@jonsimons.org>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-06-29 17:08:54 +02:00
Jon Simons
1a5b6ac472 libcrypto-compat: fix HMAC_CTX_free for OpenSSL < 1.1.0
On older OpenSSL versions, the EVP_MD_CTX fields within an HMAC_CTX
structure are contained inlined (change here [1]): be sure to not
try to free those fields on those builds.

Found running the `pkd_hello` test with:

    valgrind ./pkd_hello -i1 -t torture_pkd_openssh_dsa_rsa_default

^ valgrind will cite "Invalid free() ..." errors which are present
before this fix and absent after, when building with OpenSSL 1.0.1.

[1] 6e59a892db

Cherry-picked from 25384e9558

Signed-off-by: Jon Simons <jon@jonsimons.org>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-06-29 17:08:54 +02:00
Andreas Schneider
0dd7a963a9 cmake: Only build libcrypto and libcrypto-compat when needed
This also fixes the gcrypt build.

Cherry-picked from 2f6a866373

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-06-29 17:08:54 +02:00
Andreas Schneider
1642cec280 cmake: Use configure check for CRYPTO_ctr128_encrypt
Cherry-picked from 3daf1760a1

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-06-29 17:08:54 +02:00
Jakub Jelen
2f1c6668e7 pki_crypto: Use getters and setters for opaque keys and signatures
This is for OpenSSL 1.1.0 support.

Cherry-picked from 3341f49a49

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-06-29 17:08:54 +02:00
Jakub Jelen
fbeecf388c libcrypto: Use a pointer for EVP_MD_CTX
This is for OpenSSL 1.1.0 support.

Cherry-picked from 607c671f67

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-06-29 17:08:54 +02:00
Jakub Jelen
7933756b5a libcrypto: Use newer API for HMAC
This is for OpenSSL 1.1.0 support.

Cherry-picked from cf1e808e2f

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-06-29 17:08:54 +02:00
Jakub Jelen
837e367d2d libcrypto: Introduce a libcrypto compat file
This is for OpenSSL 1.1.0 support.

Cherry-picked from b6cfde8987

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-06-29 17:08:54 +02:00
Jakub Jelen
f81c3ada9c libcrypto: Remove AES_ctr128_encrypt()
This is for OpenSSL 1.1.0.

Cherry-picked from d73f665edd

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-06-29 17:08:54 +02:00
Artyom V. Poptsov
83663895f4 config: Bugfix: Don't skip unseen opcodes
libssh fails to read the configuration from a config file due to a
wrong check in 'ssh_config_parse_line' procedure in 'config.c'; it's
effectively skipping every opcode (and therefore every option) from
the file.  The change fixes that behaviour.

Signed-off-by: Artyom V. Poptsov <poptsov.artyom@gmail.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 5333be5988)
2018-06-29 17:08:54 +02:00
Andreas Schneider
239d0f75b5 messages: Do not leak memory of previously allocated answers
Found by ozz-fuzz

BUG: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=1222

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 7c79b5c154)
2017-04-25 16:21:11 +02:00
Andreas Schneider
d88cc720fb messages: Do not leak memory if answeres had been allocated previously
Found by ozz-fuzz

BUG: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=1222

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 5eb41492c4)
2017-04-24 13:28:17 +02:00
Andreas Schneider
ee13becf9c messages: Do not leak memory if answered had been allocated previously
BUG: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=1184

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit c78c6c6542)
2017-04-21 11:14:51 +02:00
Andreas Schneider
95b2dbbeca misc: Validate integers converted from the SSH banner
BUG: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=1181

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit d5d8349224)
2017-04-21 11:14:46 +02:00
Andreas Schneider
02c0a3b99b messages: Fix memory leaks in the ssh_packet_global_request callback
BUG: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=1208

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 67a2ba6f99)
2017-04-21 11:14:42 +02:00
Andreas Schneider
419731a189 auth: Use calloc in ssh_userauth_agent_pubkey()
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 79437fa0c9)
2017-04-21 11:14:39 +02:00
Peter Volpe
2ac987bce9 session: Free session->kbdint in ssh_free()
Makes sure we free pending keyboard auth prompts
so prompts that have not be replied to do not leak.

Signed-off-by: Peter Volpe <pvolpe@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 76ba2b0055)
2017-04-20 17:04:54 +02:00
Andreas Schneider
0588cbf9d4 Bump version to 0.7.5
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2017-04-13 16:33:04 +02:00
Andreas Schneider
a7cce77550 buffer: Validate the length before before memory allocation
Check if the size the other party sent is a valid size in the
transmitted buffer.

Thanks to Alex Gaynor for finding and reporting the issue.

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 68b7ca6e92)
2017-04-13 16:28:18 +02:00
Andreas Schneider
5e63b40cde buffer: Create ssh_buffer_validate_length()
This functions allows if a given length can be obtained from the buffer.

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit c165c396de)
2017-04-13 16:27:33 +02:00
Alex Hermann
7b8b5eb4ea config: Only use first occurence of each parameter
ssh_config's manpage says:
"For each parameter, the first obtained value will be used."

Make libssh adhere to this rule.

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

Signed-off-by: Alex Hermann <alex@hexla.nl>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 5f202d7ffa)
2017-04-13 16:10:10 +02:00
Alex Hermann
8dc3d883b8 config: Don't expand Host variable
Tokens are not allowed (according to the manpage).
Expansion was introduced by a wrong fix for #127.

This commit reverts part of 6eea08a9ef

Signed-off-by: Alex Hermann <alex@hexla.nl>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit c3a8b5009f)
2017-04-13 16:10:09 +02:00
Alex Hermann
24a3f7020c config: Support expansion in the HostName variable
BUG: https://red.libssh.org/issues/127

The original "fix" for 127 was expanding the wrong variable: Host instead
of HostName.

Signed-off-by: Alex Hermann <alex@hexla.nl>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 9ef7e90821)
2017-04-13 16:10:07 +02:00
Yanis Kurganov
f74d5d5df4 session: Add SSH1 support in ssh_send_debug()
Signed-off-by: Yanis Kurganov <ykurganov@ptsecurity.com>
Reviewed-by: Andreas Schneider <asn@samba.org>
(cherry picked from commit 38cb19268a)
2017-04-11 17:40:58 +02:00
Yanis Kurganov
7a21187fb9 session: Add SSH1 support in ssh_send_ignore()
Signed-off-by: Yanis Kurganov <ykurganov@ptsecurity.com>
Reviewed-by: Andreas Schneider <asn@samba.org>
(cherry picked from commit 72fdb4867e)
2017-04-11 17:40:57 +02:00
Max Bachmann
439d3039e3 messages: Utilize the message queue for SSH_REQUEST_GLOBAL.
Signed-off-by: Max Bachmann <mabahltm@gmail.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 3ec8babfaf)
2017-04-11 09:55:46 +02:00
Andreas Schneider
61cbf160a0 cmake: Fix GCRYPT_ROOT_DIR and check correct paths
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 462c7726c3)
2017-04-11 09:55:05 +02:00
Andreas Schneider
ce029c0735 pki: Use byte mode for fopen()
BUG: https://red.libssh.org/issues/251

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit de369b46b1)
2017-02-03 13:19:24 +01:00
Andreas Schneider
8a2deeb3cc Bump version to 0.7.4 2017-02-03 09:47:18 +01:00
Andreas Schneider
40164c348e Update ChangeLog 2017-02-03 09:47:09 +01:00
Tilo Eckert
9d7f873fd3 session: Add missing ifdef that prevented Windows builds
Signed-off-by: Tilo Eckert <tilo.eckert@flam.de>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 4f392ebc7e)
2016-11-25 13:11:37 +01:00
Andreas Schneider
c5d320811b sftpserver: Fix SSH_FXP_FSTAT arguments
Thanks to Игорь Коваленко <igor.a.kovalenko@gmail.com>

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 47d21b6420)
2016-11-07 19:56:10 +01:00
Andreas Schneider
410f722ae5 misc: Use simpler macros for htonll and ntohll
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 52efbc3a23)
2016-11-07 09:43:09 +01:00
Andreas Schneider
8155b3c0a0 cmake: Always check for strtoull
This fixes building with different compilers on Windows

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

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit fab85b495e)
2016-11-06 11:42:04 +01:00
Andreas Schneider
6836ffa103 options: Fix log level documentation
BUG: https://red.libssh.org/issues/210

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 801bc29494)
2016-11-05 17:16:14 +01:00
Andreas Schneider
b62b822100 cmake: Correctly check for *snprintf functions on Windows
BUG: https://red.libssh.org/issues/205

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 1bf6c965e4)
2016-11-05 16:41:50 +01:00
Andreas Schneider
849f5db5d1 config: Fix build warning
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2016-11-05 16:33:29 +01:00
Pino Toscano
a6493efcae sftp: Fix memory leak in sftp_fstat
When parsing the result of a successful fstat call, make sure to free
the resulting reply message.

Signed-off-by: Pino Toscano <ptoscano@redhat.com>
Reviewed-by: Andreas Schneider <asn@samba.org>
(cherry picked from commit bc78383fac)
2016-10-22 16:04:00 +02:00
Andreas Schneider
1b0bf852be sftp: Correctly check for EOF else keep spinning if there is no data
This fixes an issue introduced with
dbf72ffba2

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit f561e6bcb3)
2016-10-07 13:37:48 +02:00
Andreas Schneider
2b3185ec29 gssapi: Use correct return code in ssh_gssapi_auth_mic()
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 83421c0e8c)
2016-10-06 19:39:06 +02:00
Andreas Schneider
d63547b18a gssapi: Print minor stat in error logging function
This also releases the memory allocated for the messages.

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 095733ed9c)
2016-10-06 19:39:01 +02:00
Jeremy Cross
6697f85b50 sftp: ensure sftp_packet_read recognizes channel EOF to avoid infinite loop
Signed-off-by: Jeremy Cross <jcross@bomgar.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit dbf72ffba2)
2016-09-09 11:40:07 +02:00
Travers Carter
67fe6f56ea Make "Host" pattern list handling consistent with OpenSSH
https://red.libssh.org/issues/187

Signed-off-by: Travers Carter <tcarter@noggin.com.au>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit bc2db86d1c)
2016-05-03 17:57:45 +02:00
Andreas Schneider
b5ce15eefa priv: Fix client banner specification for libssh
BUG: https://red.libssh.org/issues/231

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 4f7be0dbb2)
2016-05-03 10:58:47 +02:00
Andreas Schneider
a3688ada1a client: If SSHv1 is disabled send the banner immediately
This saves a round-trip with SSHv2 connecting to the server. See RFC
4253 section 5.2 (New Client, Old Server).

Thanks to Yang Yubo <yang@yangyubo.com> for the suggestion.

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 1da5c94b44)
2016-05-03 10:58:36 +02:00
Andreas Schneider
219d0bba42 client: Fix ssh_send_banner() to confirm with RFC 4253
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 3d1edffe77)
2016-05-03 10:58:27 +02:00
Andreas Schneider
bf3d8f3ad4 client: Fix maximum banner length
According to RFC 4253 the max banner length is 255.

Thanks to Saju Panikulam <spanikulam@ipswitch.com> for the report.

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit cb52ed7b12)
2016-05-03 10:58:18 +02:00
Andreas Schneider
04a5d5bd74 client: Reformat callback_receive_banner()
The function is hard to read as the indentation is not correctly
applied.

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 22799b107d)
2016-05-03 10:58:06 +02:00
Ken Reister
2957aaf9f0 client: Receive the banner correctly
Comply with RFC 4253 compliance section 4.2.

Allow data other than "SSH-" to be sent across prior to the actual
version striong.

Signed-off-by: Ken Reister <reister.kenneth@CIMCOR.COM>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit c3ce3d5cc3)
2016-05-03 10:57:50 +02:00
Kohei Suzuki
8360139506 Add id_ed25519 to the default identity list
Signed-off-by: Kohei Suzuki <eagletmt@gmail.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit c092101e01)
2016-05-02 15:34:32 +02:00
David Kedves
0bf78b0b8b channels: Bugfix for a possible invalid pointer usage (channel->session) in various places
BUG: https://red.libssh.org/issues/230

Signed-off-by: David Kedves <kedazo@severalnines.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit d7df4429eb)
2016-05-02 15:32:16 +02:00
Stef Walter
faca78f547 auth: Cleanup memory leak when using SSH agent
In Cockpit we've seen this memory leak:

at 0x4C2A9C7: calloc (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
by 0x5B76B03: ssh_userauth_agent (auth.c:778)
by 0x40DD5A: cockpit_ssh_authenticate (cockpitsshtransport.c:327)

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

Signed-off-by: Stef Walter <stefw@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit ffe8b98cc2)
2016-05-02 15:29:01 +02:00
Andreas Schneider
7da587ba6c auth1: Fix non-blocking SSHv1 auth
BUG: https://red.libssh.org/issues/232

Thanks to Fengyu Gao.

TODO: Add SSHv1 tests to our testsuite.

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 33ecaaac01)
2016-05-02 12:31:53 +02:00
Andreas Schneider
c7aa51240d Update the README
(cherry picked from commit e8b28f978e)
2016-05-02 12:11:02 +02:00
Andreas Schneider
cdf7690e03 Bump version to 0.7.3
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2016-02-23 08:23:31 +01:00
Andreas Schneider
7b19719022 Update ChangeLog 2016-02-23 08:22:09 +01:00
Aris Adamantiadis
f8d0026c65 dh: Fix CVE-2016-0739
Due to a byte/bit confusion, the DH secret was too short. This file was
completely reworked and will be commited in a future version.

Signed-off-by: Aris Adamantiadis <aris@0xbadc0de.be>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2016-02-23 08:17:43 +01:00
Hani Benhabiles
6b608e70ee options: Fix documentation typo
Signed-off-by: Hani Benhabiles <hani@linux.com>
Reviewed-by: Andreas Schneider <asn@samba.org>
(cherry picked from commit f8bde7156f)
2016-02-23 08:15:26 +01:00
Younes Serraj
a69a1af568 pki: Fixed documentation about return value.
Documentation now is congruent with the code:
- SSH_OK is returned on success,
- SSH_ERROR is returned on error.

Signed-off-by: Younes Serraj <younes.serraj@gmail.com>
Reviewed-by: Andreas Schneider <asn@samba.org>
(cherry picked from commit 66c6ae1a55)
2016-02-23 08:15:24 +01:00
pouete
32b72555ee cmake: use check_symbol for (v)snprintf
Updated how snprintf and vsnprintf are discovered by cmake. Visual studio
2015 now include it in the file stdio.h.
More information here :
https://msdn.microsoft.com/en-us/library/bb531344.aspx

Reviewed-By: Aris Adamantiadis <aris@0xbadc0de.be>
2015-12-30 19:51:26 +01:00
Sebastián Peyrott
32af6a2390 CMake: include CheckIncludeFiles for calls to check_include_files. 2015-12-24 13:01:56 +01:00
Fabiano Fidêncio
b470dd943f Fix a bunch of -Wmaybe-uninitialized
Reviewed-By: Aris Adamantiadis <aris@0xbadc0de.be>
2015-12-17 15:02:01 +01:00
Dirk Neukirchen
69ca977aed headers: fix missing mode_t (2nd)
Reviewed-By: Aris Adamantiadis <aris@0xbadc0de.be>
2015-11-10 18:39:59 +01:00
Aris Adamantiadis
728a6349b7 Revert "headers: fix missing mode_t"
I commited a patch file *headdesk*
This reverts commit 378fcccc0a.
2015-11-10 18:39:52 +01:00
Dirk Neukirchen
ec32174abc headers: fix missing mode_t
Signed-off-by: Dirk Neukirchen <dirkneukirchen@web.de>
Reviewed-by: Aris Adamantiadis <aris@0xbadc0de.be>
2015-11-10 18:28:45 +01:00
Andreas Schneider
2172cd234a Ignore all build and obj* directories
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2015-10-28 09:28:42 +01:00
Andreas Schneider
0425ac9ad0 agent: Fix agent auth on big endian machines
BUG: https://red.libssh.org/issues/204

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2015-10-20 17:17:17 +02:00
Aris Adamantiadis
367558bb21 crypto: fix potential memory leak in ECDH 2015-09-21 15:03:08 +02:00
Andreas Schneider
186e7b5ca4 kex: Fix zlib compression
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 747e7d05db)
2015-09-16 08:34:58 +02:00
Andreas Schneider
2197704693 Bump version to 0.7.2 2015-09-15 15:17:35 +02:00
Andreas Schneider
229eb8715d cmake: Use tar.xz source package generator
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 1f3a9105ff)
2015-09-15 15:17:35 +02:00
Andreas Schneider
1b18a06f8c kex: Prefer sha2 over sha1
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit b0f22fde62)
2015-09-15 15:09:21 +02:00
Andreas Schneider
91b513798e cmake: Handle libssh threas library correctly
This should fix the build on Windows and would not install pkg files.

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 5b586fdfec)
2015-09-08 17:32:57 +02:00
Michael Wilder
25234e510a bignum: Fix OpenSSL crash in SAFE_FREE
Signed-off-by: Michael Wilder <wilder.michael@cimcor.com>
Reviewed-by: Andreas Schneider <asn@samba.org>
(cherry picked from commit 2f193b5cbb)
2015-09-08 17:32:40 +02:00
Andreas Schneider
d16eac5704 server: Fix return code check of ssh_buffer_pack()
Thanks to Andreas Gutschick <andreas.gutschick@mitel.com>

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 36d9b62f1f)
2015-08-18 09:12:47 +02:00
Andreas Schneider
46bff47975 doc: Fix typos in sftp tutorial
Thanks to Anthony Baker <AnthonyBaker@fico.com>

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit da4bebbe1e)
2015-08-18 09:05:45 +02:00
Andreas Schneider
f718b50b3f tests: Add checks for ssh_key_is_private()
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit d54a1ab798)
2015-08-10 13:58:51 +02:00
Andreas Schneider
58b7d0f5d2 pki: Fix return values of ssh_key_is_(public|private)
Thanks to Kevin Haake <khaake@red-cocoa.com>

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit e1081796af)
2015-08-10 13:58:50 +02:00
Tilo Eckert
30d4581be5 sftp: Fix incorrect handling of received length fields
Signed-off-by: Tilo Eckert <tilo.eckert@flam.de>
2015-08-01 10:52:48 +03:00
Peter Volpe
83387f957f auth: Fix return status for ssh_userauth_agent()
BUG: https://red.libssh.org/issues/201

Return SSH_AUTH_DENIED instead of SSH_AUTH_ERROR when the provided agent
offers no public keys.

Signed-off-by: Peter Volpe <pvolpe@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit dc9c4d22ab)
2015-07-30 10:52:11 +02:00
Andreas Schneider
f3620bbbad cmake: Fix zlib include directory
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 728c2fbd01)
2015-07-03 12:36:53 +02:00
Andreas Schneider
b45933d30d cmake: Fix OpenSSL detection in non-standard path
This should fix the detection on Windows.

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 613b71b385)
2015-07-03 11:40:04 +02:00
Andreas Schneider
1613ed556d cmake: Fail if can't find OpenSSL aes and des headers
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 70cc11618a)
2015-07-03 10:52:56 +02:00
Andreas Schneider
8f5b7b65eb include: Add stdarg.h so we can check for va_copy macro
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2015-06-30 09:59:21 +02:00
Andreas Schneider
053f72c671 Bump version to 0.7.1
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2015-06-30 09:34:28 +02:00
Tilo Eckert
63a8f333b8 SSH_AUTH_PARTIAL is now correctly passed to the caller of ssh_userauth_publickey_auto().
Implicitly fixed unsafe return code handling that could result in use-after-free.

Signed-off-by: Tilo Eckert <tilo.eckert@flam.de>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 0423057424)
2015-06-29 11:11:26 +02:00
Tilo Eckert
57fd8e3187 available auth_methods must be reset on partial authentication
Signed-off-by: Tilo Eckert <tilo.eckert@flam.de>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit cc25d747d4)
2015-06-29 11:11:25 +02:00
Peter Volpe
03972b16c9 channels: Fix exit-signal data unpacking
Signed-off-by: Peter Volpe <pvolpe@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 7637351065)
2015-06-29 09:50:28 +02:00
Peter Volpe
ac7ed82585 agent: Add ssh_set_agent_socket
Allow callers to specify their own socket
for an ssh agent.

Signed-off-by: Peter Volpe <pvolpe@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 7aeba71a92)
2015-06-29 09:47:35 +02:00
Seb Boving
196c2e9c1f Don't allocate a new identity list in the new session's options.
The previous list is not freed. Since the new session just got
created, an identity list is already allocated and empty.

Signed-off-by: Sebastien Boving <seb@google.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit e020dd8d59)
2015-06-24 18:36:10 +02:00
Douglas Heriot
1accbcb98b cmake: Do not use CMAKE_(SOURCE|BINARY)_DIR
(cherry picked from commit a65af1b3b8)
2015-06-24 18:36:08 +02:00
Tiamo Laitakari
342ae10f08 pki: Fix allocation of ed25519 public keys
Signed-off-by: Tiamo Laitakari <tiamo.laitakari@cs.helsinki.fi>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 5478de1a64)
2015-06-24 18:36:08 +02:00
Jordy Moos
eb98a780ed Documentation fix where unsigned is used where signed is expected
Signed-off-by: Jordy Moos <jordymoos@gmail.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit fa9fbb1d67)
2015-06-24 18:36:08 +02:00
Andreas Schneider
64233fa3bb misc: Correctly guard the sys/time.h include
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit ef751a26d0)
2015-06-24 18:36:08 +02:00
Andreas Schneider
cbf5cf4ac3 include: Add support for older MSVC versions
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 30a7229fc5)
2015-06-24 16:24:12 +02:00
Andreas Schneider
a3f3f9cb76 kex: Add comments to #if clauses
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 1d69e073af)
2015-06-24 16:24:08 +02:00
Aris Adamantiadis
5aeae08be0 channels: fix exit-status not correctly set 2015-06-03 16:41:19 +02:00
Mike DePaulo
64a658acaa Comment that ssh_forward_cancel() is deprecated.
Signed-off-by: Aris Adamantiadis <aris@badcode.be>
2015-05-29 11:30:32 +02:00
Mike DePaulo
361940a5d7 Reintroduce ssh_forward_listen() (Fixes: #194)
Signed-off-by: Aris Adamantiadis <aris@badcode.be>
2015-05-29 11:24:27 +02:00
Andreas Schneider
2721cbc8ee ChangeLog: Set release date for 0.7.0 2015-05-11 10:42:08 +02:00
Andreas Schneider
5eb7a6ca38 cpack: Use application version.
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2015-05-08 13:54:56 +02:00
Andreas Schneider
3f4b5436e5 Bump version to 0.7.0
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2015-05-06 11:01:33 +02:00
Andreas Schneider
82cf5ea24c Update ChangeLog
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2015-05-06 11:00:43 +02:00
Andreas Schneider
90e4786523 valgrind: Add suppression for openssl FIPS dlopen leak
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2015-05-06 10:27:09 +02:00
Andreas Schneider
f65f41acc2 valgrind: Ignore valgrind free bug on exit
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2015-05-06 10:23:27 +02:00
Andreas Schneider
8979150745 tests: Migrate torture_keyfiles to testkey functions
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2015-05-06 09:47:37 +02:00
Andreas Schneider
f81d296e54 torture: Move TORTURE_TESTKEY_PASSWORD to header
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2015-05-06 09:47:17 +02:00
Andreas Schneider
57afe78167 tests: Fix memory leak in torture_server_x11 test
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2015-05-06 09:33:51 +02:00
Jon Simons
ee460dc04b kex: also compare host keys for 'first_kex_packet_follows'
Also consider the host key type at hand when computing whether a
'first_kex_packet_follows' packet matches the current server settings.
Without this change libssh may incorrectly believe that guessed
settings which match by kex algorithm alone fully match: the host
key types must also match.  Observed when testing with dropbear
clients.

Signed-off-by: Jon Simons <jon@jonsimons.org>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2015-05-05 22:03:47 +02:00
Jon Simons
f134cb3d57 server: return SSH_OK for ignored SSH_MSG_KEXDH_INIT case
Return SSH_OK for the case that an incoming SSH_MSG_KEXDH_INIT should be
ignored.  That is, for the case that the initial 'first_kex_packet_follows'
guess is incorrect.  Before this change sessions served with libssh can be
observed to error out unexpectedly early when testing with dropbear clients
that send an incompatible guess.

Signed-off-by: Jon Simons <jon@jonsimons.org>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2015-05-05 22:03:32 +02:00
Andreas Schneider
3eaad77de2 tests: Only link against threading library if available
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2015-05-05 19:09:51 +02:00
Andreas Schneider
9244750a63 cmake: Add missing OpenSSL include directory
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2015-05-05 19:04:49 +02:00
Andreas Schneider
e8720a30e2 cmake: Add --enable-stdcall-fixup for MinGW builds
This fixes warnings for getaddrinfo() and freeaddrinfo().

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2015-05-05 18:59:30 +02:00
Andreas Schneider
ad09009201 include: Fix variadic macro issues with MSVC
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2015-05-05 18:45:47 +02:00
Andreas Schneider
e4e3b3052f tests: Apply umask before calling mkstemp()
CID: #978660

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2015-05-05 11:27:09 +02:00
Andreas Schneider
96882cc58c example: Fix a use after free in the scp example
CID: #1032343

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2015-05-05 11:27:09 +02:00
Andreas Schneider
7c79959e94 example: Check return value of ssh_get_fd()
CID: #1199454

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2015-05-05 11:27:09 +02:00
Andreas Schneider
ca501df8c8 sftp: Fix size check
CID: #1296588

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2015-05-05 11:26:40 +02:00
Andreas Schneider
a4cecf59d5 external: Fix resetting the state
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2015-05-04 18:10:30 +02:00
Andreas Schneider
244881b87d external: Make sure we burn buffers in bcrypt
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2015-05-04 17:54:01 +02:00
Andreas Schneider
cf05e653de external: Fix a possible buffer overrun in bcrypt_pbkdf
CID: #1250106

This fixes a 1 byte output overflow for large key length (not reachable
in libssh). Pulled from OpenBSD BCrypt PBKDF implementation.

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2015-05-04 17:54:01 +02:00
Andreas Schneider
4b9916136d sftp: Add bound check for size
CID: #1238630

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2015-05-04 17:54:01 +02:00
Andreas Schneider
33ecff11dd buffer: Cleanup vaargs in ssh_buffer_unpack_va()
CID: #1267977

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2015-05-04 17:54:01 +02:00
Andreas Schneider
83d3ee7fdb string: Improve ssh_string_len() to avoid tainted variables
CID: #1278978

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2015-05-04 17:54:01 +02:00
Andreas Schneider
b1a3f4ee33 pki_container: Fix a memory leak
CID: #1267980

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2015-05-04 17:54:01 +02:00
Andreas Schneider
05498e0e33 pki_container: Add check for return value
CID: #1267982

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2015-05-04 17:54:01 +02:00
Andreas Schneider
4948fe21cd tests: Fix ctest default script
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2015-05-04 15:52:17 +02:00
Andreas Schneider
fe8fcb805c cmake: Add support for Address Sanitizer
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2015-05-04 15:25:17 +02:00
Andreas Schneider
c4af6fbce3 config: Add missing HAVE_ARPA_INET_H define
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2015-05-04 10:04:26 +02:00
Aris Adamantiadis
3091025472 buffers: Fix a possible null pointer dereference
This is an addition to CVE-2015-3146 to fix the null pointer
dereference. The patch is not required to fix the CVE but prevents
issues in future.

Signed-off-by: Aris Adamantiadis <aris@0xbadc0de.be>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2015-04-23 10:33:52 +02:00
Aris Adamantiadis
bf0c7ae0ae CVE-2015-3146: Fix state validation in packet handlers
The state validation in the packet handlers for SSH_MSG_NEWKEYS and
SSH_MSG_KEXDH_REPLY had a bug which did not raise an error.

The issue has been found and reported by Mariusz Ziule.

Signed-off-by: Aris Adamantiadis <aris@0xbadc0de.be>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2015-04-23 10:15:47 +02:00
Kevin Fan
b5dc8197f7 Fix leak of sftp->ext when sftp_new() fails
Signed-off-by: Kevin Fan <kevinfan@google.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2015-04-14 20:56:56 +02:00
Andreas Schneider
19e23e6128 cmake: Require cmake 2.8.5
I've improved FindOpenSSL and FindZLIB in that version to work well with
Windows and Linux. This was 2011 it should be old enough that most
distributions have at least this version available.

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2015-04-10 14:35:29 +02:00
Andreas Schneider
195f25cfbd cmake: Detect network function correctly on Windows
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2015-04-10 13:32:09 +02:00
Andreas Schneider
1cb940c44a socket: Cleanup ssh_socket_close() code.
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2015-04-10 13:32:09 +02:00
Andreas Schneider
3f04367fb8 bind: Correctly close sockets and invalidate them.
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2015-04-10 13:32:09 +02:00
Andreas Schneider
6c7e552509 cmake: Require cmake version 2.8.0 2015-04-10 13:32:09 +02:00
Andreas Schneider
b1cb8de385 cmake: Check for sys/param.h header file
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2015-04-10 13:07:12 +02:00
Andreas Schneider
69c9cd029f cmake: Check for arpa/inet.h header file
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2015-04-10 13:02:56 +02:00
Andreas Schneider
c699b9ca94 external: Use standard int types
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2015-04-10 13:02:56 +02:00
Andreas Schneider
53586ed4ba include: Do not make x11 variables const
We allocate them and also free them after the callback has been
executed.

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2015-04-02 16:19:45 +02:00
Andreas Schneider
5236358a48 messages: Don't leak memory after callback execution
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2015-04-02 16:13:20 +02:00
Andreas Schneider
d6fe9dc220 unittests: Fix memory leak in torture_pki_ed25519
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2015-04-02 15:05:19 +02:00
Andreas Schneider
e0a73d3dbe poll: Fix compilation with struct ssh_timestamp
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2015-04-02 15:02:29 +02:00
Andreas Schneider
dbe7df7571 cmake: Detect __func__ and __FUNCTION__ during configure step
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2015-04-02 13:41:02 +02:00
Andreas Schneider
a3357b8920 include: We should use __func__ which is C99
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2015-04-02 10:58:36 +02:00
Seb Boving
7ec798d3e7 Locally restart ssh_poll() upon EINTR.
BUG: https://red.libssh.org/issues/186

Reviewed-by: Aris Adamantiadis <aris@0xbadc0de.be>
Signed-off-by: Sebastien Boving <seb@google.com>
2015-02-23 22:05:54 +01:00
xjoaalm
f32e5f2191 Sending EOF on Socket that received a Broken Pipe makes call to poll to hang
Reviewed-by: Aris Adamantiadis <aris@0xbadc0de.be>
Signed-off-by: Joao Pedro Almeida Pereira <joao.almeida@blue-tc.com>
2015-02-23 22:01:15 +01:00
Andreas Schneider
cd078c7085 cmake: Drop reports via https only.
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2015-02-20 15:47:22 +01:00
Aris Adamantiadis
2e445d5871 torture: fix includes for freebsd10 2015-02-14 22:09:02 +01:00
Aris Adamantiadis
5c46fbc680 tests: torture-misc: check for NULL return codes
Use the LOGNAME environment variable if USER is not set, as it sometimes
happens in cron jobs.
2015-02-12 11:38:21 +01:00
Aris Adamantiadis
2a780afc57 tests: workaround for compiling with older cmocka 2015-02-12 11:19:04 +01:00
Aris Adamantiadis
940cb233ce buffer: buffer_pack & unpack on non-gnu compilers 2015-02-08 18:49:32 +01:00
Aris Adamantiadis
a653e27a2e buffer: detect compilers not supporting __VA_ARGS__ 2015-02-08 18:49:02 +01:00
Aris Adamantiadis
d3f30da158 buffer: fix use-before-nullcheck (coverity #1267979)
Additionally, the function call was already existing after
the NULL check
2015-02-03 22:21:22 +01:00
Aris Adamantiadis
760d93e87b Revert "pki_gcrypt: fix warnings for SSH_KEYTYPE_ED25519"
This reverts commit 10f71c6769.
Commit was redundant with ed25519 branch
2015-02-03 09:58:28 +01:00
Aris Adamantiadis
d42a1a35b0 tests: allow conditionnal execution on pattern
Option can be used to filter out irrelevant tests
usage: ./torture_pki '*ed25519'

Signed-off-by: Aris Adamantiadis <aris@0xbadc0de.be>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2015-02-02 17:34:15 +01:00
Aris Adamantiadis
8af829a42a base64: Use secure buffers
Signed-off-by: Aris Adamantiadis <aris@0xbadc0de.be>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2015-02-02 17:33:58 +01:00
Andreas Schneider
ad8fa427dd buffer: Abort if the canary is not intact in ssh_buffer_unpack()
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Aris Adamantiadis <aris@0xbadc0de.be>
2015-02-02 17:32:34 +01:00
Andreas Schneider
de10a7754b buffer: buffer: Improve argument checking of in ssh_buffer_pack()
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Aris Adamantiadis <aris@0xbadc0de.be>
2015-02-02 17:32:31 +01:00
Andreas Schneider
6789170799 buffer: Abort if the canary is not intact in ssh_buffer_unpack()
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Aris Adamantiadis <aris@0xbadc0de.be>
2015-02-02 17:32:28 +01:00
Andreas Schneider
afc9988c93 buffer: Improve argument checking in ssh_buffer_pack()
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Aris Adamantiadis <aris@0xbadc0de.be>
2015-02-02 17:32:18 +01:00
Aris Adamantiadis
2490404d45 Move all 3rd-party C files to src/external/
Signed-off-by: Aris Adamantiadis <aris@0xbadc0de.be>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2015-02-02 14:45:53 +01:00
Aris Adamantiadis
fbdb940c46 ed25519: Add test for signatures and verification
Signed-off-by: Aris Adamantiadis <aris@0xbadc0de.be>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2015-02-02 14:45:52 +01:00
Aris Adamantiadis
c8d0b724b3 tests: Add ed25519 encrypted keys export
Signed-off-by: Aris Adamantiadis <aris@0xbadc0de.be>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2015-02-02 14:45:52 +01:00
Aris Adamantiadis
9e4700cdc0 ed25519: Add support for OpenSSH encrypted container export
Signed-off-by: Aris Adamantiadis <aris@0xbadc0de.be>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2015-02-02 14:45:52 +01:00
Aris Adamantiadis
b76d37b341 tests: Add ed25519 encrypted keys import
Signed-off-by: Aris Adamantiadis <aris@0xbadc0de.be>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2015-02-02 14:45:52 +01:00
Aris Adamantiadis
423fa6818b ed25519: ADd OpenSSH encrypted container import
Signed-off-by: Aris Adamantiadis <aris@0xbadc0de.be>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2015-02-02 14:45:52 +01:00
Aris Adamantiadis
61e2c8f0f7 external: Add OpenSSH bcrypt and blowfish implementation
Signed-off-by: Aris Adamantiadis <aris@0xbadc0de.be>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2015-02-02 14:45:52 +01:00
Aris Adamantiadis
c02b260e7e server: Add support for ed25519 keys in the server.
Signed-off-by: Aris Adamantiadis <aris@0xbadc0de.be>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2015-02-02 14:45:52 +01:00
Aris Adamantiadis
01a6004171 kex: Add support for ed25519 on client connections.
Signed-off-by: Aris Adamantiadis <aris@0xbadc0de.be>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2015-02-02 14:45:52 +01:00
Aris Adamantiadis
4f5660e081 tests: Add ed25519 OpenSSH key saving
Signed-off-by: Aris Adamantiadis <aris@0xbadc0de.be>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2015-02-02 14:45:52 +01:00
Aris Adamantiadis
46bc11f977 ed25519: Add support to export OpenSSH container keys
Signed-off-by: Aris Adamantiadis <aris@0xbadc0de.be>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2015-02-02 14:45:52 +01:00
Aris Adamantiadis
119840b0a9 tests: Add ed25519 OpenSSH key loading and operations
Signed-off-by: Aris Adamantiadis <aris@0xbadc0de.be>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2015-02-02 14:45:52 +01:00
Aris Adamantiadis
4343ac5b08 libgcrypt: Make the PEM parser ed25519 aware
Signed-off-by: Aris Adamantiadis <aris@0xbadc0de.be>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2015-02-02 14:45:52 +01:00
Aris Adamantiadis
6b9183a20b libcrypto: Make the PEM parser ed25519 aware
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2015-02-02 14:45:52 +01:00
Aris Adamantiadis
3ec3a926e5 ed25519: Add support o import OpenSSH container keys
Signed-off-by: Aris Adamantiadis <aris@0xbadc0de.be>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2015-02-02 14:45:52 +01:00
Aris Adamantiadis
2f7886837f pki.h: Replace tabs with spaces
Signed-off-by: Aris Adamantiadis <aris@0xbadc0de.be>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2015-02-02 14:45:52 +01:00
Aris Adamantiadis
7febad5821 kex: disable des-cbc-ssh1 by default
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2015-01-26 08:57:06 +01:00
Andreas Schneider
b235c380f2 packet_cb: Add misssing include for ntohl().
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2015-01-21 09:23:43 +01:00
Andreas Schneider
f6a50aff4c tests: Fix torture_server_x11(). 2015-01-21 09:19:30 +01:00
Alan Dunn
6b7f275c32 tests: Add torture_server_x11 test.
torture_server_x11 tests whether a libssh server can correctly parse an
X11 request.

Signed-off-by: Alan Dunn <amdunn@gmail.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2015-01-20 20:23:19 +01:00
Alan Dunn
4bde48bb2e tests: Add ssh server setup functionality
Add the ability to generate a keypair (RSA, but tests that focus on
what occurs over a connection may well not care) and an ssh_bind
easily.

Signed-off-by: Alan Dunn <amdunn@gmail.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2015-01-20 19:50:52 +01:00
Alan Dunn
f4154c503b tests: Add port option to torture_ssh_session
Signed-off-by: Alan Dunn <amdunn@gmail.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2015-01-20 19:41:53 +01:00
Léo Peltier
8db4520d89 cmake: Add libsshpp.hpp to the distributed headers list.
BUG: https://red.libssh.org/issues/163

Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2015-01-20 19:32:48 +01:00
Andreas Schneider
9a7d450098 pki: Make sure sig is not used unintialized.
BUG: https://red.libssh.org/issues/167

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2015-01-20 19:31:12 +01:00
William Orr
7070117dc3 examples: Use safer names for stdin, stdout, stderr
BUG: https://red.libssh.org/issues/168

On some platforms, like OpenBSD, stdin and friends are macros which break
compilation of this struct. I've fixed these names such that it compiles and
runs cleanly on OpenBSD

Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2015-01-20 19:27:14 +01:00
Andreas Schneider
433f8fd550 threads: Fix building with POSIX threads in MinGW.
BUG: https://red.libssh.org/issues/181

Originally written by Patrick von Reth <vonreth () kde ! org>.

This patch is part of the larger patch:
https://projects.kde.org/projects/kdesupport/emerge/repository/revisions/master/changes/portage/win32libs/libssh/0002-add-a-way-to-test-ssh-connections-on-windows.patch

MinGW (in particular, the MinGW-w64 fork) can use either posix threads
or win32 threads. This patch fixes the MinGW build when using posix
threads.

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2015-01-20 19:01:15 +01:00
Yanis Kurganov
c6590bd189 channels1: Fix pty request state
Signed-off-by: Yanis Kurganov <YKurganov@ptsecurity.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2015-01-20 18:58:13 +01:00
Andreas Schneider
929868c691 Update README.CodingStyle 2015-01-20 12:08:51 +01:00
Andreas Schneider
06a0d8ff1c connect: Fix a memory leak.
CID: #1238618

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Aris Adamantiadis <aris@0xbadc0de.be>
2015-01-14 15:20:52 +01:00
Andreas Schneider
af0dd3fb02 sftp: Fix a possible integer overflow.
CID: #1238630

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Aris Adamantiadis <aris@0xbadc0de.be>
2015-01-14 15:20:49 +01:00
Andreas Schneider
ce02f6576a sftp: Use a declared variable for data len.
CID: #1238632

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Aris Adamantiadis <aris@0xbadc0de.be>
2015-01-14 15:20:46 +01:00
Andreas Schneider
68e720a3da pkd: Make sure we do not pass -1 to close.
CID: #1245696

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Aris Adamantiadis <aris@0xbadc0de.be>
2015-01-14 15:20:43 +01:00
Andreas Schneider
c224508bf8 pkd: Check return value of pkd_run_tests().
CID: #1245697

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Aris Adamantiadis <aris@0xbadc0de.be>
2015-01-14 15:20:34 +01:00
Tobias Klauser
15d71a8c51 sftp: Fix memory leak on realloc failure
If realloc of sftp->ext->name or sftp->ext->data fails, the memory
previously allocated for the respective member is leaked. Fix this by
storing the return value of realloc() in a temporary variable which only
gets assigned to the respective sftp->ext member on success.

Signed-off-by: Tobias Klauser <tklauser@distanz.ch>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2015-01-14 10:22:55 +01:00
Andreas Schneider
8536cd9808 cmake: Fix ntohll and htonll macro detection.
BUG: https://red.libssh.org/issues/164

Thanks to Ryan Schmidt!

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2015-01-13 08:53:42 +01:00
Tobias Klauser
353751e3e3 doc: Fix a typo in curve25519-sha256@libssh.org.txt
Fix the typo 'stengths' -> 'strengths' and remove the trailing white
space on the same line.

Signed-off-by: Tobias Klauser <tklauser@distanz.ch>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2015-01-13 08:45:51 +01:00
Andreas Schneider
159ef828dd doc: Fix link to curve25519-sha256@libssh.org spec. 2015-01-06 15:24:30 +01:00
Andreas Schneider
3dd069c0c8 doc: Fix a typo, blank lines and trailing spaces. 2015-01-06 15:22:16 +01:00
Andreas Schneider
a198193723 connect: Fix mingw build.
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2015-01-06 15:12:17 +01:00
Andreas Schneider
e051135a05 connect: Check that errno is 0 to fix Windows build.
Thanks to Viktor Butskih.

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2014-12-25 12:34:59 +01:00
Andreas Schneider
bb18442fe8 options: Fix setting the port.
Make sure we correctly read the port from the config file.

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2014-12-25 12:32:16 +01:00
Jon Simons
c2aed4ca78 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>
2014-12-17 19:45:09 +01:00
Andreas Schneider
b7b535816d 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>
2014-12-17 19:39:18 +01:00
Andreas Schneider
d8e691b58a cmake: Fix config variable names.
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2014-12-17 10:38:56 +01:00
William Orr
52968b1a11 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>
2014-12-17 10:34:27 +01:00
Jon Simons
b35f1f488c pki_gcrypt: fix DSA signature extraction
Fix DSA signature extraction for the LIBGCRYPT build.  Here, the same fix
that was applied to the LIBCRYPTO build for https://red.libssh.org/issues/144
is now adapted for pki_gcrypt.  Additionally, ensure to set the resulting
output sig_blob buffer before returning.

Before this fix, one can observe the failure with the pkd test on a LIBGCRYPT
build as so:

  # ./pkd_hello -i 1 -t torture_pkd_openssh_dsa_dsa_default

After, runs of 10000 back-to-back iterations of the same test are passing.

Signed-off-by: Jon Simons <jon@jonsimons.org>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2014-12-09 19:21:47 +01:00
Jon Simons
10f71c6769 pki_gcrypt: fix warnings for SSH_KEYTYPE_ED25519
Signed-off-by: Jon Simons <jon@jonsimons.org>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2014-12-09 19:21:34 +01:00
Jon Simons
014fde0542 torture: fix warning for SSH_KEYTYPE_ED25519
Signed-off-by: Jon Simons <jon@jonsimons.org>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2014-12-09 19:21:18 +01:00
Jon Simons
ca2acec34a bignum: no-op make_string_bn_inplace for LIBGCRYPT
Disable the 'make_string_bn_inplace' helper function for the LIBGCRYPT
build, rather than using '#error' to fail the build completely.

Signed-off-by: Jon Simons <jon@jonsimons.org>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2014-12-09 19:20:46 +01:00
Davide \"FunkyAss\" Del Zompo
bb197de75d doc: clarify tutorial error section
Signed-off-by: Davide "FunkyAss" Del Zompo <davide.delzompo@gmail.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2014-12-05 11:09:00 +01:00
Hani Benhabiles
03095f1516 Set the correct error in ssh_options_set().
Signed-off-by: Hani Benhabiles <hani@linux.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2014-12-05 11:03:55 +01:00
Jon Simons
6895d0b727 session: add getter for kexalgo
Signed-off-by: Jon Simons <jon@jonsimons.org>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2014-12-05 10:48:07 +01:00
Jon Simons
4745d652b5 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>
2014-12-05 10:42:32 +01:00
Andreas Schneider
a48711ae7e connect: Do not fail if the connect is in progress.
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2014-10-15 10:27:55 +02:00
Jon Simons
a25790d343 tests: fix pkd build breakages
Fix a build breakage when '-DWITH_SERVER=OFF' is set: skip building the
pkd test for that case.  Add some missing includes for the OpenIndiana
and FreeBSD builds.

Signed-off-by: Jon Simons <jon@jonsimons.org>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2014-10-15 10:26:24 +02:00
Stef Walter
cd2dc3770a 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>
2014-10-12 15:41:15 +02:00
William Orr
250f506487 Check return code of connect(2).
Signed-off-by: William Orr <will@worrbase.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2014-10-12 15:39:58 +02:00
Jon Simons
9dc932c02b tests: introduce pkd_hello
Introduce a sample public-key testing daemon to the 'pkd' test directory,
and add support code for cycling through various combinations of different
key exchange, cipher, and MAC algorithms.

The goal of the 'pkd_hello' test is to make it easy to test interactions
between non-libssh clients and a libssh-server, and to provide a starting
point for testing new implementations for key types, ciphers, MACs, and
so on.  The thinking is that testing a new algorithm should be as simple
as adding a new line for it in the PKDTESTS_* lists.

Macros are used to generate the tests and helper functions for a couple of
clients -- here, OpenSSH and dropbear are included for the first cut.  If
binaries are found for these clients, their test lists will be enabled;
when binaries are not found for a given client, those tests are skipped.

Tests are run in one large batch by default, but can also be run individually
to help with tracking down things like signature bugs that may take many
iterations to reproduce.

Each test logs its stdout and stderr to its own file, which is cleaned up
when a test succeeds.  For failures, those logs can be combined with verbose
libssh output from pkd itself to start debugging things.

Some example usages:

  pkd_hello
    Run all tests with default number of iterations.

  pkd_hello --list
    List available individual test names.

  pkd_hello -i 1000 -t torture_pkd_openssh_ecdsa_256_ecdh_sha2_nistp256
    Run only the torture_pkd_openssh_ecdsa_256_ecdh_sha2_nistp256
    testcase 1000 times.

  pkd_hello -v -v -v -v -e -o
    Run all tests with maximum libssh and pkd logging.

Included in the tests are passes for all existing kex, cipher, and MAC
algorithms.

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

Signed-off-by: Jon Simons <jon@jonsimons.org>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2014-10-12 15:01:02 +02:00
Artyom V. Poptsov
aaae6cd97d 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>
2014-10-02 08:30:17 +02:00
Jon Simons
509676e3a4 server: fix auth_interactive_request reply
Fix a missing 'buffer_pack' formatter in 'ssh_message_auth_interactive_request'.
With this fix the 'examples/samplesshd-kbdint' program is working again for me.

Signed-off-by: Jon Simons <jon@jonsimons.org>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2014-10-02 08:29:22 +02:00
Jon Simons
a6d412f0d7 ed25519: fix leak in pki_ed25519_sign
Signed-off-by: Jon Simons <jon@jonsimons.org>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2014-10-02 08:28:51 +02:00
Jon Simons
59da8dab50 pki: check ssh_buffer_pack return in ssh_pki_do_sign
Check the 'ssh_buffer_pack' return in ssh_pki_do_sign for the ED25519 case.

Signed-off-by: Jon Simons <jon@jonsimons.org>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2014-10-02 08:28:05 +02:00
Jon Simons
7edbedf0dd pki: fail when pubkey buffer length is not ED25519_PK_LEN
Fail fast in 'pki_import_pubkey_buffer' for the ED25519 case if a buffer
sized ED25519_PK_LEN can not be retrieved.  Before, the 'memcpy' could
have read beyond the bounds of 'ssh_string_data(pubkey)'.

Signed-off-by: Jon Simons <jon@jonsimons.org>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2014-10-02 08:27:05 +02:00
Jon Simons
af25c5e668 crypto: check malloc return in ssh_mac_ctx_init
Signed-off-by: Jon Simons <jon@jonsimons.org>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2014-10-02 08:25:53 +02:00
Jon Simons
092fe0b727 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>
2014-10-02 08:25:10 +02:00
Andreas Schneider
1ddb99c46f string: Correctly burn the string buffer.
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Aris Adamantiadis <aris@0xbadc0de.be>
2014-09-15 20:45:47 +02:00
Aris
93c7b81b4e ed25519: Generate, sign and verify keys.
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2014-09-07 22:07:34 +02:00
Aris Adamantiadis
93e82fa0c0 crypto: Add ed25519 implementation from OpenSSH.
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2014-09-07 21:35:20 +02:00
Aris Adamantiadis
e9b2d164e0 base64: Use a secure buffer.
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2014-09-07 10:38:23 +02:00
Aris Adamantiadis
86ae6b2251 buffer: Add a secure buffer mechanism to avoid memory spills
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2014-09-07 10:36:32 +02:00
Aris Adamantiadis
2cb2587b55 buffer: Implement "t" for text in ssh_buffer_pack().
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2014-09-07 10:27:35 +02:00
Andreas Schneider
86294ad3ea dh: Fix packing a pointer into the buffer.
Thanks to Giovanni Panozzo <giovanni@panozzo.it>.

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2014-08-25 12:23:17 +02:00
Andreas Schneider
173994786b tests: Fix writing the '\0'.
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2014-08-18 21:41:36 +02:00
Andreas Schneider
81123d6a91 ec: Fix build on CentOS.
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2014-08-18 10:08:00 +02:00
Andreas Schneider
25eb9c4914 tests: Use public testkey passphrase function in pki test.
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Aris Adamantiadis <aris@0xbadc0de.be>
2014-08-15 12:32:57 +02:00
Andreas Schneider
c6210f5aef torture: Add public testkey passphrase function.
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Aris Adamantiadis <aris@0xbadc0de.be>
2014-08-15 12:32:54 +02:00
Andreas Schneider
c673543e54 tests: Use public testkeys in pki test.
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Aris Adamantiadis <aris@0xbadc0de.be>
2014-08-15 12:32:51 +02:00
Andreas Schneider
edca9d6e96 torture: Add public testkey functions.
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Aris Adamantiadis <aris@0xbadc0de.be>
2014-08-15 12:32:47 +02:00
Andreas Schneider
83aed7610c tests: Make write file a public torture function.
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Aris Adamantiadis <aris@0xbadc0de.be>
2014-08-15 12:32:37 +02:00
Andreas Schneider
5fa4721c6e auth: Fix a memory leak in agent publickey auth.
CID: 1230358

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Aris Adamantiadis <aris@0xbadc0de.be>
2014-08-15 12:29:26 +02:00
Andreas Schneider
8b7627efd5 tests: Make sure we null terminate the buffer.
CID: 1230359

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Aris Adamantiadis <aris@0xbadc0de.be>
2014-08-15 12:29:23 +02:00
Andreas Schneider
662217f409 packet: Check return value of ssh_buffer_unpack().
CID: 1230357

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Aris Adamantiadis <aris@0xbadc0de.be>
2014-08-15 12:29:20 +02:00
Andreas Schneider
19433dca00 messages: Check return value of ssh_buffer_unpack().
CID: 1230356

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Aris Adamantiadis <aris@0xbadc0de.be>
2014-08-15 12:29:16 +02:00
Andreas Schneider
6961dd79ad tests: Fix memory leak in buffer test.
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Aris Adamantiadis <aris@0xbadc0de.be>
2014-08-15 12:29:13 +02:00
Andreas Schneider
1b6375ce89 buffer: Make sure rc is initialized.
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Aris Adamantiadis <aris@0xbadc0de.be>
2014-08-15 12:29:11 +02:00
Andreas Schneider
64f6abead7 libgcrypt: Fix initializer name.
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Aris Adamantiadis <aris@0xbadc0de.be>
2014-08-15 12:29:07 +02:00
Andreas Schneider
f20a6d0a82 bignum: Add missing include.
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Aris Adamantiadis <aris@0xbadc0de.be>
2014-08-15 12:29:00 +02:00
Andreas Schneider
97c6b76863 messages: Fix two ssh_buffer_unpack().
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Aris Adamantiadis <aris@0xbadc0de.be>
2014-08-07 17:28:42 +02:00
Aris Adamantiadis
6019cf1bed Fix sftp endianess bugs
Reviewed-by: Andreas Schneider <asn@samba.org>
2014-08-06 10:08:25 +02:00
Aris Adamantiadis
228dc08038 bignums: detach bignum-related functions from dh.c.
Reviewed-by: Andreas Schneider <asn@samba.org>
2014-08-06 10:07:36 +02:00
Aris Adamantiadis
33cd594f1f crypto: fix secure burning, structure members naming
Reviewed-by: Andreas Schneider <asn@samba.org>
2014-08-06 10:05:19 +02:00
Aris Adamantiadis
0cd0f685c9 torture_pki: avoid generating keys with ssh-keygen
ssh-keygen makes the tests very slow because new keys are generated
at the start of every test.
ssh-keygen on OSX doesn't support ecdsa keys, even if libcrypto does.

Reviewed-by: Andreas Schneider <asn@samba.org>
2014-08-06 10:04:57 +02:00
Aris Adamantiadis
664b94d1c5 tests: test the canary feature in buffer_(un)pack()
Reviewed-by: Andreas Schneider <asn@samba.org>
2014-08-06 10:00:07 +02:00
Aris Adamantiadis
3b4b0f01ec buffer: add a hidden canary to detect format errors
Reviewed-by: Andreas Schneider <asn@samba.org>
2014-08-06 09:58:52 +02:00
Aris Adamantiadis
7bd62dd652 buffers: adapt sftpserver.c to ssh_buffer_(un)pack()
Reviewed-by: Andreas Schneider <asn@samba.org>
2014-08-06 09:52:29 +02:00
Aris Adamantiadis
c341da03d3 buffers: adapt sftp.c to ssh_buffer_(un)pack()
Reviewed-by: Andreas Schneider <asn@samba.org>
2014-08-06 09:51:00 +02:00
Aris Adamantiadis
c238136010 buffers: adapt session.c to ssh_buffer_(un)pack()
Reviewed-by: Andreas Schneider <asn@samba.org>
2014-08-06 09:47:35 +02:00
Aris Adamantiadis
5a08ddcff2 buffers: adapt server.c to ssh_buffer_(un)pack()
Signed-off-by: Andreas Schneider <asn@samba.org>
2014-08-06 09:46:14 +02:00
Aris Adamantiadis
a182926024 buffers: adapt pcap.c to ssh_buffer_(un)pack()
Reviewed-by: Andreas Schneider <asn@samba.org>
2014-08-06 09:46:14 +02:00
Aris Adamantiadis
9457685320 buffers: adapt ecdh.c to ssh_buffer_(un)pack()
Reviewed-by: Andreas Schneider <asn@samba.org>
2014-08-06 09:46:14 +02:00
Aris Adamantiadis
e9fd14c7f0 buffers: adapt packet.c to ssh_buffer_(un)pack()
Reviewed-by: Andreas Schneider <asn@samba.org>
2014-08-06 09:46:14 +02:00
Aris Adamantiadis
cfd2e4894e buffers: adapt messages.c to ssh_buffer_(un)pack()
Reviewed-by: Andreas Schneider <asn@samba.org>
2014-08-06 09:46:14 +02:00
Aris Adamantiadis
3703389feb buffers: adapt gssapi.c to ssh_buffer_(un)pack() 2014-08-06 09:46:14 +02:00
Aris Adamantiadis
673990f568 buffers: adapt curve25519.c to ssh_buffer_(un)pack()
Reviewed-by: Andreas Schneider <asn@samba.org>
2014-08-06 09:33:32 +02:00
Aris Adamantiadis
97638a1465 buffers: adapt client.c to ssh_buffer_(un)pack()
Reviewed-by: Andreas Schneider <asn@samba.org>
2014-08-06 09:33:07 +02:00
Aris Adamantiadis
506e11fa8b buffers: adapt channels.c to ssh_buffer_(un)pack()
Reviewed-by: Andreas Schneider <asn@samba.org>
2014-08-06 09:33:03 +02:00
Aris Adamantiadis
1dd95675df buffer: adapt dh.c to new ssh_buffer_(un)pack()
Reviewed-by: Andreas Schneider <asn@samba.org>
2014-08-06 09:20:49 +02:00
Aris Adamantiadis
cb10ad0c84 buffer: adapt kex.c to new ssh_buffer_(un)pack()
Reviewed-by: Andreas Schneider <asn@samba.org>
2014-08-06 09:20:49 +02:00
Aris Adamantiadis
1f2c61d6ad buffer: adapt auth.c to ssh_buffer_(un)pack()
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2014-08-06 09:20:49 +02:00
Aris Adamantiadis
1d97f75b0a tests: test for ssh_buffer_(un)pack
Reviewed-by: Andreas Schneider <asn@samba.org>
2014-08-06 09:20:45 +02:00
Aris Adamantiadis
835e34d1eb Buffer: add ssh_buffer_(un)pack()
That function permits chaining of buffer values to minimize buffer handling
in packet sending code.

Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2014-08-06 09:04:34 +02:00
Aris Adamantiadis
13c42bff3f examples: cast arguments of connect(2)
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2014-07-06 20:36:49 +02:00
Andreas Schneider
59a1799501 log: Add check for return value.
For some reason I got a segfault in gdb here. Make sure it works
correctly.
2014-06-10 13:52:38 +02:00
Andreas Schneider
d9c47a8cfa tests: Add test for the logging function. 2014-06-10 13:52:20 +02:00
Jon Simons
987991a3f2 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:23:46 +02:00
Andreas Schneider
a738507ad2 cmake: Fix the build on Windows. 2014-05-27 15:42:53 +02:00
Andreas Schneider
142b2e4ede cmake: Fix libssh cmake-config files. 2014-05-22 14:52:52 +02:00
Hani Benhabiles
517a01b7ad Set the correct version in CMakeLists.txt
Signed-off-by: Hani Benhabiles <hani@linux.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2014-05-20 09:41:20 +02:00
Andreas Schneider
83633d539e pki: Fix build without ECC support.
Signed-off-by: Andreas Schneider <asn@samba.org>
2014-05-09 08:55:49 +02:00
Andreas Schneider
c2ee63431b pki: Add missing semi-colon. 2014-05-07 09:30:29 +02:00
Jon Simons
9e4bc10525 kex: NULL checks for 'first_kex_packet_follows'
Add NULL checks to 'is_first_kex_packet_follows_guess_wrong'
to ensure that a 'strdup(NULL)' path can not be taken.

Signed-off-by: Jon Simons <jon@jonsimons.org>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2014-05-06 09:04:07 +02:00
Alan Dunn
f37c844bf7 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:44 +02:00
Hani Benhabiles
2c7dfb02a8 Small documentation fix.
Signed-off-by: Hani Benhabiles <hani@linux.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2014-05-06 08:52:55 +02:00
Andreas Schneider
2884bbf5b1 pki: Correctly update the ECDSA keytype. 2014-04-23 11:16:28 +02:00
Andreas Schneider
f48a99b97c pki: Move ssh_pki_key_ecdsa_name() to the correct file. 2014-04-23 11:15:05 +02:00
Andreas Schneider
11cfb2903e pki: Make pki_key_ecdsa_nid_to_name() a shared function. 2014-04-23 11:12:08 +02:00
Dirkjan Bussink
c520d97dd9 Add tests for SHA2 HMAC algorithms
BUG: https://red.libssh.org/issues/91

Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2014-04-22 10:57:35 +02:00
Dirkjan Bussink
6c74d6f891 Add options support for setting and getting HMAC algorithms
BUG: https://red.libssh.org/issues/91

Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2014-04-22 10:57:18 +02:00
Dirkjan Bussink
262c82ac06 Add negotiation for SHA2 HMAC algorithms
BUG: https://red.libssh.org/issues/91

Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2014-04-22 10:57:00 +02:00
Dirkjan Bussink
164b8e99cc Add logic to support SHA2 HMAC algorithms
BUG: https://red.libssh.org/issues/91

Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2014-04-22 10:56:46 +02:00
Dirkjan Bussink
4a08902664 Add SHA2 algorithms for HMAC
BUG: https://red.libssh.org/issues/91

Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2014-04-22 10:55:59 +02:00
Gangadhar Sandrani
d6e6a453fc log: Fix log levels.
Signed-off-by: Gangadhar Sandrani <gangadhar.sandrani@gmail.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2014-04-22 09:35:33 +02:00
Jon Simons
eb86fd8cdf kex: server fix for first_kex_packet_follows
Ensure to honor the 'first_kex_packet_follow' field when processing
KEXINIT messages in the 'ssh_packet_kexinit' callback.  Until now
libssh would assume that this field is always unset (zero).  But
some clients may set this (dropbear at or beyond version 2013.57),
and it needs to be included when computing the session ID.

Also include logic for handling wrongly-guessed key exchange algorithms.
Save whether a client's guess is wrong in a new field in the session
struct: when set, the next KEX_DHINIT message to be processed will be
ignored per RFC 4253, 7.1.

While here, update both 'ssh_packet_kexinit' and 'make_sessionid' to
use softabs with a 4 space indent level throughout, and also convert
various error-checking to store intermediate values into an explicit
'rc'.

Patch adjusted from original to ensure that client tests remain passing
(ie 'torture_connect'): restrict the changes in 'ssh_packet_kexinit'
only for the 'server_kex' case.

Signed-off-by: Jon Simons <jon@jonsimons.org>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2014-04-22 09:26:59 +02:00
Alan Dunn
099e2e8438 build: Do not link against libssl, only libcrypto
Signed-off-by: Alan Dunn <amdunn@gmail.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2014-04-22 09:24:54 +02:00
Andreas Schneider
291312c5e4 cmake: Install cmake config files to the correct directory. 2014-04-16 15:45:33 +02:00
Andreas Schneider
e2805abbf7 Revert "kex: server fix for first_kex_packet_follows"
The patch breaks the client with ECDSA.

This reverts commit 5865b9436f.
2014-04-15 09:49:25 +02:00
Andreas Schneider
79d51099ac examples: Fix a bad shift if ssh_get_fd() returns -1.
Found by Coverity.

CID: #1199454
2014-04-14 21:24:28 +02:00
Andreas Schneider
adf23533e0 doc: Improve docs for ssh_channel_get_exit_status().
BUG: https://red.libssh.org/issues/154
2014-04-10 08:54:11 +02:00
Andreas Schneider
927cd90dc1 channels: Fix exit-signal request.
BUG: https://red.libssh.org/issues/153
2014-04-10 08:54:11 +02:00
Andreas Schneider
b5efbe75cd session: Fix a memory leak with custom banner.
BUG: https://red.libssh.org/issues/152
2014-04-10 08:54:10 +02:00
Andreas Schneider
01311dd419 cmake: Fix doxygen. 2014-04-10 08:54:10 +02:00
Jon Simons
5865b9436f kex: server fix for first_kex_packet_follows
Ensure to honor the 'first_kex_packet_follow' field when processing
KEXINIT messages in the 'ssh_packet_kexinit' callback.  Until now
libssh would assume that this field is always unset (zero).  But
some clients may set this (dropbear at or beyond version 2013.57),
and it needs to be included when computing the session ID.

Also include logic for handling wrongly-guessed key exchange algorithms.
Save whether a client's guess is wrong in a new field in the session
struct: when set, the next KEX_DHINIT message to be processed will be
ignored per RFC 4253, 7.1.

While here, update both 'ssh_packet_kexinit' and 'make_sessionid' to
use softabs with a 4 space indent level throughout, and also convert
various error-checking to store intermediate values into an explicit
'rc'.

Signed-off-by: Jon Simons <jon@jonsimons.org>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2014-04-10 08:54:10 +02:00
Andreas Schneider
ad1313c2e5 Revert "direct-tcpip and forwarded-tcpip callbacks"
This reverts commit efe785e711.

We need a Signed-off version. I didn't have the Certificate of Origin
yet.
2014-04-09 12:49:06 +02:00
Andreas Schneider
0cb9f792b8 cmake: Update doxygen module. 2014-04-09 11:21:29 +02:00
Loïc Michaux
efe785e711 direct-tcpip and forwarded-tcpip callbacks 2014-04-09 11:13:57 +02:00
Jon Simons
48aca98cd5 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-04-09 11:01:11 +02:00
Petar Koretic
89e154f78c libsshpp: include required <string> header for std::string
Signed-off-by: Petar Koretic <petar.koretic@sartura.hr>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2014-04-09 10:59:59 +02:00
Alan Dunn
491b407d17 examples: Update ssh_server_fork for new SSH_BIND_OPTIONS_HOSTKEY
Tested by

ssh_server_fork -k <an ecdsa key> -k <an rsa key> ...

and connection succeeded with OpenSSH clients both for ECDSA and RSA
(the latter forced via -o HostKeyAlgorithms=ssh-rsa and some known
hosts clearing was necessary).  Also

ssh_server_fork -k <an ecdsa key> -k <another ecdsa key> ...

caused the second key to be used, as expected.

Signed-off-by: Alan Dunn <amdunn@gmail.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2014-04-09 10:59:21 +02:00
Alan Dunn
2f4589b765 doc: Document new meaning of SSH_BIND_OPTIONS_HOSTKEY
Signed-off-by: Alan Dunn <amdunn@gmail.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2014-04-09 10:59:10 +02:00
Alan Dunn
acb7161c81 options: Repurpose SSH_BIND_OPTIONS_HOSTKEY to load host keys
SSH_BIND_OPTIONS_HOSTKEY will now load host keys of any supported type
rather than set the algorithms that the server permits (which seems
like an unhelpful option anyway; it seems you can always control this
by just loading the right keys).

This option has slightly different semantics than the
SSH_BIND_OPTIONS_<x>KEY options because it requires the key file to
exist immediately rather than on ssh_bind_listen or
ssh_bind_accept_fd.  The semantics of this option makes more sense to
me.

We also eliminate ssh_bind_options_set_algo, since it is no longer
used.

Signed-off-by: Alan Dunn <amdunn@gmail.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2014-04-09 10:57:16 +02:00
Andreas Schneider
437a39c798 cmake: Enable creation of the compile command database by default. 2014-04-04 10:03:43 +02:00
Andreas Schneider
b3e6d5df53 packet: Fix function name. 2014-03-27 11:26:27 +01:00
Luka Perkov
53644a14ac style: be consistent when iterating over wanted_methods
Signed-off-by: Luka Perkov <luka.perkov@sartura.hr>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2014-03-27 11:23:34 +01:00
Jon Simons
aa05248ca8 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>
2014-03-27 11:19:50 +01:00
Andreas Schneider
04543c9dbc doc: Fix ssh_userauth_none() function signature.
Thanks to David Tibbe!

BUG: https://red.libssh.org/issues/151
2014-03-27 11:06:01 +01:00
Alan Dunn
d5aeebe323 socket: Fix style of ssh_socket_pollcallback
Signed-off-by: Alan Dunn <amdunn@gmail.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2014-03-27 10:54:55 +01:00
Alan Dunn
47bd0b6d1f doc: Improve and consolidate ssh_bind_options_set docs
Signed-off-by: Alan Dunn <amdunn@gmail.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2014-03-27 10:49:08 +01:00
Petar Koretic
8e2590b535 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>
2014-03-27 10:48:13 +01:00
Petar Koretic
c51f42a566 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>
2014-03-27 10:46:21 +01:00
Petar Koretic
00d4fbe753 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>
2014-03-27 10:45:54 +01:00
Jon Simons
dee8e5688b channel: check for closed state in waitwindow loops
Signed-off-by: Jon Simons <jon@jonsimons.org>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2014-03-27 10:34:22 +01:00
Jon Simons
40d81bb7ca kex: enable more ECDSA hostkey algos
Signed-off-by: Jon Simons <jon@jonsimons.org>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2014-03-27 10:28:06 +01:00
Jon Simons
10bc5ac203 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>
2014-03-27 10:27:23 +01:00
Luka Perkov
8ba9402282 session: fix comment typo
Signed-off-by: Luka Perkov <luka.perkov@sartura.hr>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2014-03-27 10:16:24 +01:00
Luka Perkov
a2fe341da5 messages: use predefined macro for clearing sensitive data
Signed-off-by: Luka Perkov <luka.perkov@sartura.hr>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2014-03-27 10:16:14 +01:00
Luka Perkov
dbb2de272b 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>
2014-03-27 10:15:54 +01:00
Luka Perkov
9423a3a065 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>
2014-03-27 10:14:35 +01:00
Luka Perkov
0c5d4954a7 tests: torture_connect: fix coding style
Signed-off-by: Luka Perkov <luka.perkov@sartura.hr>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2014-03-27 10:13:57 +01:00
Petar Koretic
0b8d24f800 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>
2014-03-27 10:11:24 +01:00
Luka Perkov
48354f56ec 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>
2014-03-27 10:10:48 +01:00
Alan Dunn
5c0c95bd34 examples: Add ECDSA key option to ssh_server_fork
Signed-off-by: Alan Dunn <amdunn@gmail.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2014-03-27 10:06:36 +01:00
Alan Dunn
c82dd2eb81 examples: Add no default keys options to ssh_server_fork
It seems useful to be able to run ssh_server_fork without being
required to load some key of RSA and DSA keytypes.  However, with the
current ssh_server_fork, you need to have some keys as some default
value is set by default and you can't unset the value for a keytype
(e.g. by using NULL as an argument).  So the "no default keys"
argument turns off the default key assignments.

Signed-off-by: Alan Dunn <amdunn@gmail.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2014-03-27 10:06:11 +01:00
Alan Dunn
f6276fe739 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>
2014-03-27 10:05:58 +01:00
Alan Dunn
2a1089d607 options: Allow use of host ECDSA key
Signed-off-by: Alan Dunn <amdunn@gmail.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2014-03-27 10:05:23 +01:00
Andreas Schneider
fbf73ede1e tests: Check the the ecdsa_nid is the same. 2014-03-27 10:01:12 +01:00
Alan Dunn
577840d7f7 tests: Add test case for bug #147
Signed-off-by: Alan Dunn <amdunn@gmail.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2014-03-27 10:01:01 +01:00
Alan Dunn
3d9b1693eb 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:14:03 +01:00
Alan Dunn
15f3988bc8 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:13:29 +01:00
Luka Perkov
9c2127b798 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:12:18 +01:00
Jon Simons
0bb779904d packet: log disconnect code in host byte order
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2014-03-12 14:11:09 +01:00
Jon Simons
5eeac3566e 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:09:35 +01:00
Aris Adamantiadis
e99246246b 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:28 +01:00
Andreas Schneider
c96e862c08 examples: Add missing include for stderr.
This should fix the build on FreeBSD.
2014-02-17 09:20:46 +01:00
Andreas Schneider
7021a46617 cmake: Merge server examples. 2014-02-16 17:59:46 +01:00
Andreas Schneider
c7cb2d0657 examples: Remove old samplesshd-tty. 2014-02-16 17:58:55 +01:00
Andreas Schneider
fd50a4dd9f examples: Remove old samplesshd. 2014-02-16 17:57:09 +01:00
Audrius Butkevicius
afe97d6cab examples: Add ssh_server_fork example
Signed-off-by: Audrius Butkevicius <audrius.butkevicius@gmail.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2014-02-16 17:52:50 +01:00
Audrius Butkevicius
00949383f4 config: Add missing HAVE_LIBUTIL_H define in config.h
Signed-off-by: Audrius Butkevicius <audrius.butkevicius@gmail.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2014-02-16 17:45:47 +01:00
Andreas Schneider
2a1cb323f7 examples: Add missing include on FreeBSD. 2014-02-14 10:33:07 +01:00
Andreas Schneider
4463d89a4a cmake: Check for libutil.h on FreeBSD. 2014-02-14 10:33:07 +01:00
Andreas Schneider
9e0fb9f29b pki: Fix build warning about unused variables. 2014-02-14 10:33:07 +01:00
Audrius Butkevicius
a277dd9277 Add session/channel byte/packet counters
Signed-off-by: Audrius Butkevicius <audrius.butkevicius@elastichosts.com>
2014-02-12 18:21:16 +01:00
Andreas Schneider
370d4b014d pki: Fix the build on OpenSolaris. 2014-02-12 09:39:49 +01:00
Andreas Schneider
7bd5e4101c pki: Fix memory leak with ecdsa signatures. 2014-02-11 10:32:50 +01:00
Andreas Schneider
352c7381a8 cpack: Ignore obj directory. 2014-02-10 10:16:38 +01:00
Andreas Schneider
3e57b54688 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:30:29 +01:00
Alan Dunn
2a183440c7 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:41:01 +01:00
Alan Dunn
bb0023b7c7 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:41:00 +01:00
Raphael Kubo da Costa
398e8d50b5 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:12:50 +01:00
Jon Simons
fa34d11749 session: skip timestamp init for non-blocking case
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2014-02-06 10:21:57 +01:00
Jon Simons
93370d61ba session: add getters for session cipher names
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2014-02-06 10:21:07 +01:00
Aris Adamantiadis
22d6c36800 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:29:22 +01:00
Aris Adamantiadis
c28ad814d0 knownhosts: resolve leaks found by coverity 2014-02-05 08:07:45 +01:00
Aris Adamantiadis
fdc660f313 knownhosts: detect variations of ecdsa 2014-02-04 22:28:30 +01:00
Audrius Butkevicius
57418dd2cc server: use custom server banners
Value of session->serverbanner never gets used

Signed-off-by: Audrius Butkevicius <audrius.butkevicius@gmail.com>
2014-02-04 15:54:20 +01:00
Raphael Kubo da Costa
4e04ec8bf5 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:38:39 +01:00
Raphael Kubo da Costa
79a80cdc77 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:36:56 +01:00
Jon Simons
95782ada1f 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:19:46 +01:00
Jon Simons
f7b61bf557 doc: correct ssh_channel_read_timeout units
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2014-02-02 22:19:46 +01:00
Audrius Butkevicius
adf4d4f147 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:19:46 +01:00
Audrius Butkevicius
dc93edc932 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:19:46 +01:00
Joseph Southwell
6bbdaceaca src: Define MAX_BUF_SIZE globally and use it.
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2014-02-02 22:19:46 +01:00
Joseph Southwell
eedecd0269 client: Fix EOF session error reporting.
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2014-02-02 22:19:46 +01:00
Oleksandr Shneyder
d904784489 Make function ssh_channel_accept() nonblocking if timeout is 0.
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2014-02-02 22:19:45 +01:00
Aris Adamantiadis
31fb4e1e69 build: remove OSX deprecated warnings for openssl 2014-02-02 21:41:32 +01:00
Aris Adamantiadis
3bdc2b1d4f build: fix cmake bug introduced yesterday
Compilation failed on OSX because of the missing OR OSX
2014-02-02 20:56:21 +01:00
Aris Adamantiadis
1e37430dbe Kex: fix coverity warning + edge case 2014-02-02 20:50:36 +01:00
Aris Adamantiadis
671f1979a6 server: allow custom server banners (bug #83) 2014-02-01 18:00:01 +01:00
Aris Adamantiadis
fdaa42da1a Knownhosts: implement hostkey with knownhosts heuristic 2014-02-01 17:34:16 +01:00
Aris Adamantiadis
8d450ef81a knownhosts: add test case for bug #138 2014-02-01 16:48:36 +01:00
Aris Adamantiadis
c433ac02bd 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
2014-02-01 16:42:29 +01:00
Aris Adamantiadis
1c24a0508f Added known host test cases 2014-02-01 15:33:15 +01:00
Aris Adamantiadis
f0d6ce8958 tests: fix compilation on OSX (libargp detection) 2014-02-01 14:49:57 +01:00
Andreas Schneider
75be42df75 pki_crypto: Fix memory leak with EC_KEY_set_public_key().
BUG: https://red.libssh.org/issues/146
2014-01-28 11:56:59 +01:00
Andreas Schneider
3224506fe0 doc: Document the unit for ssh_select() timeout.
BUG: https://red.libssh.org/issues/143
2014-01-23 11:29:39 +01:00
Rod Vagg
d4d30d0375 dh: Fix NULL check for p_group14.
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2014-01-23 11:21:51 +01:00
Jon Simons
7ff6b3537f 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:13 +01:00
Andreas Schneider
368509f5d1 pki: Use ssh_buffer_add_data() in pki_gcrypt.. 2014-01-22 16:12:31 +01:00
Alan Dunn
7eff889384 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:45:45 +01:00
Jon Simons
465816f4a0 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:11:12 +01:00
Alan Dunn
9fff70fa41 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:07:09 +01:00
Alan Dunn
d3e081ba44 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:07:04 +01:00
Alan Dunn
086847f997 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:06:53 +01:00
Andreas Schneider
cb9786b3ae src: Rename buffer_add_data() to ssh_buffer_add_data(). 2014-01-19 20:55:55 +01:00
Andreas Schneider
9c4144689d src: Rename buffer_init to ssh_buffer_init(). 2014-01-19 20:43:29 +01:00
Andreas Schneider
e745236ae5 doc: Fix channel documentation. 2014-01-17 11:08:49 +01:00
Andreas Schneider
13eef19000 pki: Do not use deprecated string functions. 2014-01-17 09:29:24 +01:00
Andreas Schneider
2fe59071b2 src: Do not use deprecated functions. 2014-01-16 15:27:46 +01:00
Andreas Schneider
a7157b7907 include: Mark functions as deprecated! 2014-01-16 15:27:23 +01:00
Jon Simons
6007c3c43f 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:41 +01:00
Andreas Schneider
9d1ddd0547 doc: Add changes to the forwarding tutorial. 2014-01-16 09:13:06 +01:00
Andreas Schneider
5229253f86 channel: Fix the name scheme of the forward functions. 2014-01-16 09:13:06 +01:00
Oleksandr Shneyder
a1c4fc07d4 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:12:03 +01:00
Andreas Schneider
6d09104ad3 Rename build directory to obj.
Some buildsystem use build in the pathname and so we will filter out
e.g. docs generation.
2014-01-16 08:53:32 +01:00
Aris Adamantiadis
57ef959aa3 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 18:57:31 +01:00
Andreas Schneider
b617d7fa29 include: Remove warning cause VSC doesn't know about it. 2014-01-08 10:55:20 +01:00
Andreas Schneider
4b3363ecf2 include: Fix building if we do not have asm volatile. 2014-01-08 10:52:29 +01:00
Andreas Schneider
6fe51b13fb src: Update my mail address. 2014-01-07 16:08:23 +01:00
Andreas Schneider
8bcbfb1642 cmake: Remove unused macro modules. 2014-01-07 16:07:00 +01:00
Aris Adamantiadis
aecd952d18 update copyright information 2014-01-07 15:18:15 +01:00
Aris Adamantiadis
fedb1b3def tests: avoid reading uninitialized bytes 2014-01-07 14:43:46 +01:00
Aris Adamantiadis
8fdfa13227 pki: fix gcrypt signature process 2014-01-07 14:20:49 +01:00
Andreas Schneider
9d90d15e91 examples: Make sure buffer is initialized. 2014-01-07 09:19:02 +01:00
Andreas Schneider
09a715b147 example: Add missing include for forkpty(). 2014-01-07 09:03:53 +01:00
Aris Adamantiadis
42ad55377f test: fixed torture_auth_none condition 2014-01-06 22:09:43 +01:00
Aris Adamantiadis
d771dafe04 test: test case for async auth_none
This test currently fails
2014-01-06 16:52:44 +01:00
Aris Adamantiadis
09af855b6f tests: auth_agent_nonblocking should run in nonblocking 2014-01-06 16:52:44 +01:00
Aris Adamantiadis
0571360f37 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:16 +01:00
Andreas Schneider
f3e3700063 session: Fix a possible memory leak. 2014-01-05 23:05:13 +01:00
Aris Adamantiadis
41fe03e0d6 poll: fix poll_handles ownerships 2014-01-05 22:33:45 +01:00
Aris Adamantiadis
b514957af7 socket: don't attempt reading a non-connected socket 2014-01-05 21:54:08 +01:00
Andreas Schneider
d9c5d0767c examples: Fix building samplesshd-tty on FreeBSD. 2013-12-26 09:42:32 +01:00
Andreas Schneider
8f162e3b13 poll: Correctly free ssh_event_fd_wrapper.
This is allocated by ssh_event_add_fd.
2013-12-22 22:08:45 +01:00
Andreas Schneider
32ba84dac7 config: Support expansion in the Host variable too.
BUG: https://red.libssh.org/issues/127
2013-12-21 12:30:32 +01:00
Andreas Schneider
7f806b7c68 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:03:00 +01:00
Andreas Schneider
a6107f7432 tests: Fix blocking mode in password auth test. 2013-12-15 20:42:18 +01:00
Andreas Schneider
9829aa2236 tests: Use new auth API in the torture_session test. 2013-12-15 20:29:30 +01:00
Andreas Schneider
f8debe9a19 tests: Use new auth API in the torture_auth test. 2013-12-15 20:26:17 +01:00
Andreas Schneider
8b407f1ca2 tests: Fix pki test with gcrypt. 2013-12-11 21:11:49 +01:00
Jon Simons
20b5734649 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:02:47 +01:00
Jon Simons
0557f57c63 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:02:05 +01:00
Andreas Schneider
4f4e917187 bind: Correctly free all memory in ssh_bind_free().
Thanks to Jacob Baines.
2013-12-09 19:49:54 +01:00
Jon Simons
a1f0b2acfc session: Add ssh_get_clientbanner(). 2013-12-07 16:24:33 +01:00
Andreas Schneider
d65777b570 channels: Add a ssh_channel_read_timeout function. 2013-12-04 20:34:13 +01:00
Andreas Schneider
2df00fd84c tests: Try to fix torture_forward. 2013-12-04 14:21:52 +01:00
Andreas Schneider
d1d3beac33 tests: Fix memory leaks. 2013-11-28 14:40:11 +01:00
Andreas Schneider
ad0abff8b3 tests: Add missing line breaks. 2013-11-28 11:49:11 +01:00
Andreas Schneider
cdd7a6cb8d pki: Fix a memory leak.
CID #1132819
2013-11-28 09:09:45 +01:00
Andreas Schneider
004240af48 tests: Add torture_pki_write_privkey_ecdsa test. 2013-11-27 22:54:13 +01:00
Andreas Schneider
4e3d16e291 tests: Add torture_pki_write_privkey_dsa test. 2013-11-27 22:54:13 +01:00
Andreas Schneider
7933aef747 tests: Add torture_pki_write_privkey_rsa test. 2013-11-27 22:54:13 +01:00
Andreas Schneider
136efd6ed5 pki: Add ssh_pki_import_privkey_file(). 2013-11-27 22:54:13 +01:00
Andreas Schneider
94969cf263 pki_crypto: Add pki_private_key_to_pem(). 2013-11-27 22:54:13 +01:00
Andreas Schneider
68c3c26029 pki_gcrypt: Add pki_private_key_to_pem() stub. 2013-11-27 22:54:13 +01:00
Andreas Schneider
fd185acbea curve25519: Fix memory leaks in ssh_server_curve25519_init().
CID #1125255
2013-11-27 20:26:14 +01:00
Andreas Schneider
7a4e8e58f0 curve25519: Do not leak q_s_string.
CID #1125256
2013-11-27 20:20:07 +01:00
Andreas Schneider
cbeb2a9de7 curve25519: Fix a memory leak.
CID #1125257
2013-11-27 20:18:25 +01:00
Andreas Schneider
d61fcbf7b2 examples: Fix else branch.
CID #1127816
2013-11-27 20:16:09 +01:00
Andreas Schneider
75e61f498b packet: Remove logically dead code.
CID #1128796
2013-11-27 20:14:02 +01:00
Andreas Schneider
09edee123a tests: Try to fix valgrind warnings. 2013-11-27 18:04:44 +01:00
Andreas Schneider
060171028c tests: Fix a valgrind warning. 2013-11-27 17:55:48 +01:00
Andreas Schneider
7ecdc3e0d5 ecdh: Check if we have ECC support. 2013-11-27 17:38:21 +01:00
Andreas Schneider
67a080874b ecdh: Use bignum_bin2bn. 2013-11-27 17:35:36 +01:00
Nicolas Viennot
7b63fe2f22 server: Add a ssh_send_keepalive() function.
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2013-11-24 23:21:04 +01:00
Jon Simons
3d934f3ddc 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:23 +01:00
Rod Vagg
06cc94eecf flush channel after EOF and CLOSE 2013-11-18 17:22:30 +01:00
Aris Adamantiadis
f6443b725a logging: fix server-side logging 2013-11-18 15:29:27 +01:00
Aris Adamantiadis
d8ead516de gssapi: fix logging 2013-11-18 15:11:26 +01:00
Aris Adamantiadis
ccdc0f1805 sockets: null pointer check 2013-11-18 14:42:40 +01:00
Simo Sorce
66e7e7023b 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-15 23:32:20 -05:00
Simo Sorce
b4fc5d9524 gssapi: Add support for GSSAPIDelegateCredentials config option.
Signed-off-by: Simo Sorce <simo@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2013-11-15 16:53:59 -05:00
Simo Sorce
811c645f2a 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-15 16:10:29 -05:00
Andreas Schneider
c2312f9dda gssapi: Add error checks and cleanup the code in ssh_gssapi_auth_mic(). 2013-11-15 16:28:49 +01:00
Simo Sorce
440d2ec0ea 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:19:28 +01:00
Andreas Schneider
47e53deebd gssapi: Add support for GSSAPIClientIdentity config option. 2013-11-15 15:50:09 +01:00
Andreas Schneider
095a01b70c options: Add SSH_OPTIONS_GSSAPI_CLIENT_IDENTITY option. 2013-11-15 15:50:09 +01:00
Andreas Schneider
503c729bb0 gssapi: Add support for GSSAPIServerIdentity config option. 2013-11-15 15:50:09 +01:00
Andreas Schneider
41d99d32e8 gssapi: Add suppport to set GSSAPI server identity. 2013-11-15 15:50:09 +01:00
Simo Sorce
c481f9dafd 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 14:49:29 +01:00
Andreas Schneider
f240ecf328 socket: Fix connect if we pass in a fd.
BUG: https://red.libssh.org/issues/106

Thanks to Saju Panikulam.
2013-11-15 08:47:58 +01:00
Andreas Schneider
1972a27fe0 packet: Remove dead code. 2013-11-14 11:43:49 +01:00
Andreas Schneider
097760db17 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:42:21 +01:00
Andreas Schneider
b3a08ba8d3 dh: Fix wrong assignment.
Ups, sorry.
2013-11-14 08:08:49 +01:00
Andreas Schneider
fef7e1dffe poll: Fix realloc in ssh_poll_ctx_resize(). 2013-11-09 13:27:59 +01:00
Andreas Schneider
6d7bbe63fe dh: Avoid possible memory leaks with realloc. 2013-11-09 13:20:13 +01:00
Andreas Schneider
387e26c837 packet: Refactor ssh_packet_socket_callback().
Make error checking more readable and add additional NULL checks.
2013-11-09 13:10:41 +01:00
Andreas Schneider
e8e99ec6de server: Fix malloc call. 2013-11-09 12:47:02 +01:00
Colin Walters
13c4499449 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:07 +01:00
Colin Walters
4cc7f4ad03 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:26:19 +01:00
Colin Walters
a8dc67ded8 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:25:41 +01:00
Andreas Schneider
aa33d18930 example: Use ssh_get_publickey_hash(). 2013-11-06 17:10:41 +01:00
Andreas Schneider
8c5777554a 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:10:41 +01:00
Andreas Schneider
06cd9bc4dc dh: Add new ssh_get_publickey_hash() function. 2013-11-06 17:10:35 +01:00
Andreas Schneider
0c8984ba9f doc: Add curve25519 to features list. 2013-11-05 13:15:11 +01:00
Andreas Schneider
6f0f1ef292 doc: Fix doxygen warnings. 2013-11-04 21:55:29 +01:00
Aris Adamantiadis
b12f3f38c7 Fix cast warnings on 64bits 2013-11-04 10:49:32 +01:00
Aris Adamantiadis
cb165df64e remove warnings on OSX (workaround) 2013-11-04 10:47:22 +01:00
Aris Adamantiadis
e4c4f57f05 logging: fix wording 2013-11-04 10:31:10 +01:00
Aris Adamantiadis
c5ef5ed18f curve25519: include reference implementation 2013-11-03 14:58:10 +01:00
Aris Adamantiadis
ebf4a03908 examples: fix forktty() warning on OSX 2013-11-03 14:10:04 +01:00
Aris Adamantiadis
4f3ee2fc7e Fix examples compilation on OSX (libargp) 2013-11-03 13:49:27 +01:00
Aris Adamantiadis
f565aeebfa Compile libssh with nacl if possible
Conflicts:
	DefineOptions.cmake
2013-11-03 13:18:26 +01:00
Aris Adamantiadis
04cb94a2dd socket: Fix check for pending data.
BUG: https://red.libssh.org/issues/119

Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2013-11-03 12:46:27 +01:00
Nicolas Viennot
754152aa22 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:52:38 +01:00
Nicolas Viennot
1ef00045dd 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:48:59 +01:00
Andreas Schneider
a466a624e2 session: Make sure we correctly burn the buffer. 2013-11-03 10:45:02 +01:00
Andreas Schneider
643a3b7cc3 wrapper: Make sure we really burn the buffer. 2013-11-03 10:39:31 +01:00
Andreas Schneider
d2dea8dc2e priv: Fix brackets of burn macros. 2013-11-03 10:24:47 +01:00
Andreas Schneider
6edb6bcca1 doc: Add missing RFCs. 2013-11-03 09:35:35 +01:00
Jon Simons
d4f5a0e6ab 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:02:56 +01:00
William Orr
ce1d73e0f0 ssh_options_get can now return ProxyCommand
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2013-11-02 21:02:56 +01:00
Jon Simons
20caa68b84 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:45:21 +01:00
Andreas Schneider
b00a6e3885 tests: Add a test for ssh_channel(). 2013-10-31 12:44:48 +01:00
Jon Simons
ffc33ca28c 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:09 +01:00
Alan Dunn
ee95c05c08 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:18:55 +01:00
Andreas Schneider
cfea381307 cmake: Check for isblank(). 2013-10-30 17:30:07 +01:00
Jon Simons
099b914fd9 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:37 +02:00
Andreas Schneider
afd35fa98c tests: Add a sftp_read blocking test. 2013-10-23 15:49:07 +02:00
Colin Walters
f02bc4768e 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:09 +02:00
Andreas Schneider
bcb162816e doc: Improve sftp_read_sync() example. 2013-10-23 09:53:16 +02:00
Andreas Schneider
5baa6aed6b include: Fix build on platforms without ECC. 2013-10-21 07:15:59 +02:00
Andreas Schneider
6a6e85752e tests: Add a test for ssh_channel_request_env(). 2013-10-20 17:05:35 +02:00
Andreas Schneider
4421540b7b tests: We can't test the accept right now. 2013-10-20 13:28:53 +02:00
Andreas Schneider
d3c186b04c tests: Fix torture_forward. 2013-10-20 13:23:31 +02:00
Andreas Schneider
e30acdb58a channel: Reinit the buffer and reset the state on error.
BUG: https://red.libssh.org/issues/126
2013-10-20 12:46:57 +02:00
Andreas Schneider
b0cbe88b0b channel: Fix ssh_global_request_termination().
BUG: https://red.libssh.org/issues/126
2013-10-20 12:46:17 +02:00
Andreas Schneider
3afba83134 tests: Add torture forward test. 2013-10-20 12:46:17 +02:00
Andreas Schneider
b8d47a438c pki: Don't leak a buffer. 2013-10-19 10:41:57 +02:00
Andreas Schneider
5201c5850e wrapper: Fix compilation with gcrypt. 2013-10-19 10:39:00 +02:00
Andreas Schneider
bd8ab422d0 pki_crpypto: Fix ecdsa signature to blob.
BUG: https://red.libssh.org/issues/118
2013-10-18 23:48:21 +02:00
Andreas Schneider
33890daf41 pki: Add support for ECDSA private key signing. 2013-10-18 23:22:24 +02:00
Andreas Schneider
ac4c5699b1 pki: Add the type as a char pointer. 2013-10-18 23:22:24 +02:00
Andreas Schneider
15e31eb464 wrapper: Add more evp functions. 2013-10-18 23:22:24 +02:00
Andreas Schneider
2e81dd61dd client: Fix the build. 2013-10-18 21:18:36 +02:00
Oliver Stöneberg
f2c2687ca6 scp: Fixed result of ssh_scp_string_mode() to get SCP working.
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2013-10-18 14:58:47 +02:00
Oliver Stöneberg
4c300313c3 client: Added a missing NULL pointer check.
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2013-10-18 14:57:33 +02:00
Andreas Schneider
bec13a6ac0 doc: Make sure we have the defines to build all docs. 2013-10-14 15:39:33 +02:00
Andreas Schneider
423d8c9b6a channel: Fix packets termination timeout in global_request().
BUG: https://red.libssh.org/issues/126
2013-10-01 14:50:56 +02:00
Andreas Schneider
685fe1d0b6 session: Try the ecdsa default key first. 2013-10-01 14:45:01 +02:00
Tristan CACQUERAY
e588e2325d callbacks: add support for auth_none_function 2013-09-27 15:34:45 +02:00
Aris Adamantiadis
04fd756c49 doc: Documentation of curve25519-sha256@libssh.org 2013-09-27 15:32:52 +02:00
Aris Adamantiadis
4cb6afcbd4 kex: implement curve25519-sha256@libssh.org 2013-09-27 15:32:44 +02:00
Andreas Schneider
4eae4d592c channels: Correctly handle timeouts in channel functions. 2013-09-17 11:23:56 +02:00
Andreas Schneider
566d842405 channel: Use the correct timeout option in channel_open().
BUG: https://red.libssh.org/issues/124
2013-09-17 11:19:49 +02:00
Andreas Schneider
5e2fbbc202 callbacks: Improve the documentation of ssh_threads_set_callbacks().
BUG: https://red.libssh.org/issues/123
2013-09-16 10:54:30 +02:00
Andreas Schneider
8e703b9974 callbacks: Improve the documentation of ssh_threads_get_noop().
BUG: https://red.libssh.org/issues/123
2013-09-16 10:50:25 +02:00
Andreas Schneider
89853607c5 session: Document return value of ssh_get_serverbanner().
BUG: https://red.libssh.org/issues/122
2013-09-16 10:38:14 +02:00
Andreas Schneider
20658abc78 session: Remove obsolete status variables.
BUG: https://red.libssh.org/issues/121
2013-09-16 10:38:14 +02:00
Andreas Schneider
8823dee51a client: Add example code for ssh_get_openssh_version().
BUG: https://red.libssh.org/issues/120
2013-09-16 10:38:14 +02:00
Andreas Schneider
3e07359a35 channels: Correctly decrement timeout value in ssh_channel_accept().
BUG: https://red.libssh.org/issues/116
2013-09-16 10:38:14 +02:00
Andreas Schneider
e9242a7a31 channel: Document SSH_AGAIN in ssh_channel_read().
BUG: https://red.libssh.org/issues/115
2013-09-16 10:38:14 +02:00
Andreas Schneider
b9ada25296 cmake: Allow to build without examples.
BUG: https://red.libssh.org/issues/114
2013-09-16 10:38:14 +02:00
Andreas Schneider
33cb1bc08b doc: Improve the PKI documentation a bit. 2013-09-10 06:59:25 +02:00
Andreas Schneider
6da54688eb doc: Update documentation of ssh_set_blocking().
This should work correctly in libssh 0.6.0. If not then you hit a bug.
2013-09-09 16:43:46 +02:00
Andreas Schneider
ef6d19fbb1 clang_complete: Update definitons. 2013-08-13 12:09:59 +02:00
Andreas Schneider
acbca6a562 ecdh: Refactor ecdh_build_k to check errors codes. 2013-08-13 12:09:36 +02:00
Andreas Schneider
fc8081cd06 channel: Refactor channel_write_common() code.
This makes it easier to read and easier to debug.
2013-08-13 08:22:28 +02:00
Andreas Schneider
7a64dd1b9a channel: Make channel_write_common() static. 2013-08-13 08:17:15 +02:00
Andreas Schneider
5045133dc2 channel: Use MIN macro in channel_write_common(). 2013-08-13 08:15:37 +02:00
Andreas Schneider
7f2049b0d5 include: Add a MIN macro. 2013-08-13 08:15:16 +02:00
Andreas Schneider
aa3eeb38f9 scp: Document more scp functionts. 2013-08-12 11:24:38 +02:00
175 changed files with 15871 additions and 5269 deletions

View File

@@ -4,6 +4,8 @@
-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
/build
/obj*

View File

@@ -1,14 +1,14 @@
project(libssh C)
# Required cmake version
cmake_minimum_required(VERSION 2.6.0)
cmake_minimum_required(VERSION 2.8.5)
# global needed variables
set(APPLICATION_NAME ${PROJECT_NAME})
set(APPLICATION_VERSION_MAJOR "0")
set(APPLICATION_VERSION_MINOR "6")
set(APPLICATION_VERSION_PATCH "5")
set(APPLICATION_VERSION_MINOR "7")
set(APPLICATION_VERSION_PATCH "7")
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.5.1")
set(LIBRARY_VERSION "4.4.4")
set(LIBRARY_SOVERSION "4")
# where to look first for cmake modules, before ${CMAKE_ROOT}/Modules/ is checked
set(CMAKE_MODULE_PATH
${CMAKE_SOURCE_DIR}/cmake/Modules
${CMAKE_CURRENT_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,6 +96,20 @@ 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_SOURCE_DIR}/README")
set(CPACK_PACKAGE_DESCRIPTION_FILE "${CMAKE_CURRENT_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_SOURCE_DIR}/COPYING")
set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_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 "TGZ")
set(CPACK_SOURCE_IGNORE_FILES "~$;[.]swp$;/[.]svn/;/[.]git/;.gitignore;/build/;/obj/;tags;cscope.*")
set(CPACK_SOURCE_GENERATOR "TXZ")
set(CPACK_SOURCE_IGNORE_FILES "~$;[.]swp$;/[.]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 "http")
set(CTEST_DROP_METHOD "https")
set(CTEST_DROP_SITE "test.libssh.org")
set(CTEST_DROP_LOCATION "/submit.php?project=libssh")
set(CTEST_DROP_SITE_CDASH TRUE)

View File

@@ -1,6 +1,62 @@
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

View File

@@ -1,59 +0,0 @@
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,4 +1,5 @@
include(CheckIncludeFile)
include(CheckIncludeFiles)
include(CheckSymbolExists)
include(CheckFunctionExists)
include(CheckLibraryExists)
@@ -48,10 +49,15 @@ 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)
@@ -61,23 +67,35 @@ if (WIN32)
check_include_files("winsock2.h;ws2tcpip.h" HAVE_WS2TCPIP_H)
endif (WIN32)
set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIRS})
check_include_file(openssl/aes.h HAVE_OPENSSL_AES_H)
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/blowfish.h HAVE_OPENSSL_BLOWFISH_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/des.h HAVE_OPENSSL_DES_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/ecdh.h HAVE_OPENSSL_ECDH_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/ec.h HAVE_OPENSSL_EC_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/ecdsa.h HAVE_OPENSSL_ECDSA_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()
if (CMAKE_HAVE_PTHREAD_H)
set(HAVE_PTHREAD_H 1)
@@ -97,16 +115,22 @@ endif (NOT WITH_GCRYPT)
check_function_exists(isblank HAVE_ISBLANK)
check_function_exists(strncpy HAVE_STRNCPY)
check_function_exists(vsnprintf HAVE_VSNPRINTF)
check_function_exists(snprintf HAVE_SNPRINTF)
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)
if (WIN32)
check_function_exists(_strtoui64 HAVE__STRTOUI64)
check_symbol_exists(vsnprintf "stdio.h" HAVE_VSNPRINTF)
check_symbol_exists(snprintf "stdio.h" HAVE_SNPRINTF)
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)
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)
@@ -120,6 +144,8 @@ if (WIN32)
set(CMAKE_REQUIRED_LIBRARIES)
endif (HAVE_WSPIAPI_H OR HAVE_WS2TCPIP_H)
check_function_exists(_strtoui64 HAVE__STRTOUI64)
set(HAVE_SELECT TRUE)
else (WIN32)
check_function_exists(poll HAVE_POLL)
@@ -157,7 +183,6 @@ 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)
@@ -207,6 +232,18 @@ 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) {
@@ -221,6 +258,7 @@ int main(void) {
return 0;
}" HAVE_COMPILER__FUNCTION__)
if (WITH_DEBUG_CRYPTO)
set(DEBUG_CRYPTO 1)
endif (WITH_DEBUG_CRYPTO)

125
README
View File

@@ -33,130 +33,11 @@ If you ask yourself how to compile libssh, please read INSTALL before anything.
http://www.libssh.org
4* API Changes !
4* Contributing
-_-_-_-_-_-_-_-_-_
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.
Please read the file 'SubmittingPatches' next to this README file. It explains
our copyright policy and how you should send patches for upstream inclusion.
Have fun and happy libssh hacking!

354
README.CodingStyle Normal file
View File

@@ -0,0 +1,354 @@
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,10 +10,17 @@ 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,6 +35,8 @@ find_path(GCRYPT_INCLUDE_DIR
gcrypt.h
HINTS
${_GCRYPT_ROOT_HINTS_AND_PATHS}
PATH_SUFFIXES
include
)
find_library(GCRYPT_LIBRARY
@@ -44,6 +46,8 @@ find_library(GCRYPT_LIBRARY
libgcrypt-11
HINTS
${_GCRYPT_ROOT_HINTS_AND_PATHS}
PATH_SUFFIXES
lib
)
set(GCRYPT_LIBRARIES ${GCRYPT_LIBRARY})

View File

@@ -1,208 +0,0 @@
# - 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

@@ -1,120 +0,0 @@
# - 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,12 +17,21 @@
/* 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
@@ -67,6 +76,9 @@
/*************************** 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
@@ -91,6 +103,9 @@
/* 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
@@ -138,6 +153,7 @@
#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

View File

@@ -721,7 +721,7 @@ EXCLUDE_SYMLINKS = NO
EXCLUDE_PATTERNS = */.git/* \
*/.svn/* \
*/cmake/* \
*/build/*
*/obj/*
# 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];
unsigned int nbytes;
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 stengths are its speed, its
proposed in 2006 by DJB [Curve25519]. Its main strengths 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 attempts to provide alternatives to the ecdsa-sha1-*
authentication keys.
This document does not attempt 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_forward_listen(),
To do reverse port forwarding, call ssh_channel_listen_forward(),
then ssh_channel_accept_forward().
When you call ssh_forward_listen(), you can let the remote server
When you call ssh_channel_listen_forward(), 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;
int port = 0;
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_forward_listen(session, NULL, 8080, NULL);
rc = ssh_channel_listen_forward(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];
unsigned int nbytes;
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) != nbytes)
if (write(1, buffer, nbytes) != (unsigned int) 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>ecdh-sha2-nistp256</i>, diffie-hellman-group1-sha1, diffie-hellman-group14-sha1
- <strong>Key Exchange Methods</strong>: <i>curve25519-sha256@libssh.org, 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,6 +184,8 @@ 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
@@ -203,6 +205,12 @@ 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, buf, nbytes);
nwritten = write(fd, buffer, 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 are not ready yet, a counter is incrementer.
time the data is not ready yet, a counter is incremented.
@code
// Good chunk size

View File

@@ -25,13 +25,6 @@ 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})
@@ -41,8 +34,10 @@ if (UNIX AND NOT WIN32)
target_link_libraries(samplessh ${LIBSSH_SHARED_LIBRARY})
if (WITH_SERVER)
add_executable(samplesshd samplesshd.c)
target_link_libraries(samplesshd ${LIBSSH_SHARED_LIBRARY} ${ARGP_LIBRARIES})
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)
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_auth_list(session);
method = ssh_userauth_list(session, NULL);
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_autopubkey(session, NULL);
rc = ssh_userauth_publickey_auto(session, NULL, NULL);
if (rc == SSH_AUTH_ERROR) {
error(session);
return rc;
error(session);
return rc;
} else if (rc == SSH_AUTH_SUCCESS) {
break;
}

View File

@@ -229,6 +229,7 @@ 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,13 +298,22 @@ 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_SET(ssh_get_fd(session),&fds);
maxfd=ssh_get_fd(session)+1;
fd = ssh_get_fd(session);
if (fd < 0) {
fprintf(stderr, "Error getting fd\n");
return;
}
FD_SET(fd, &fds);
maxfd = fd + 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,6 +23,7 @@ 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"
@@ -36,6 +37,7 @@ 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";
@@ -61,11 +63,20 @@ static void cleanup_pcap(void) {
#endif
static int auth_password(const char *user, const char *password){
if(strcmp(user, SSHD_USER))
static int auth_password(const char *user, const char *password)
{
int cmp;
cmp = strcmp(user, SSHD_USER);
if (cmp != 0) {
return 0;
if(strcmp(password, SSHD_PASSWORD))
}
cmp = strcmp(password, SSHD_PASSWORD);
if (cmp != 0) {
return 0;
}
authenticated = true;
return 1; // authenticated
}
#ifdef HAVE_ARGP_H
@@ -200,6 +211,7 @@ static int kbdint_check_response(ssh_session session) {
return 0;
}
authenticated = true;
return 1;
}
@@ -328,7 +340,7 @@ int main(int argc, char **argv){
/* proceed to authentication */
auth = authenticate(session);
if(!auth){
if (!auth || !authenticated) {
printf("Authentication error: %s\n", ssh_get_error(session));
ssh_disconnect(session);
return 1;

View File

@@ -1,469 +0,0 @@
/* 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;
}

View File

@@ -1,314 +0,0 @@
/* 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;
}

697
examples/ssh_server_fork.c Normal file
View File

@@ -0,0 +1,697 @@
/* 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,13 +87,23 @@ 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_SET(ssh_get_fd(session),&fds);
maxfd=ssh_get_fd(session)+1;
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;
channels[0]=channel; // set the first channel we want to read from
channels[1]=NULL;
ret=ssh_select(channels,outchannels,maxfd,&fds,&timeout);
@@ -102,27 +112,27 @@ static void select_loop(ssh_session session,ssh_channel channel){
if(FD_ISSET(0,&fds)){
lus=read(0,buffer,sizeof(buffer));
if(lus)
channel_write(channel,buffer,lus);
ssh_channel_write(channel,buffer,lus);
else {
eof=1;
channel_send_eof(channel);
ssh_channel_send_eof(channel);
}
}
if(channel && channel_is_closed(channel)){
channel_free(channel);
if(channel && ssh_channel_is_closed(channel)){
ssh_channel_free(channel);
channel=NULL;
channels[0]=NULL;
}
if(outchannels[0]){
while(channel && channel_is_open(channel) && channel_poll(channel,0)){
lus=channel_read(channel,buffer,sizeof(buffer),0);
while(channel && ssh_channel_is_open(channel) && ssh_channel_poll(channel,0)){
lus = ssh_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){
channel_free(channel);
ssh_channel_free(channel);
channel=channels[0]=NULL;
} else {
ret = write(1, buffer, lus);
@@ -133,15 +143,15 @@ static void select_loop(ssh_session session,ssh_channel channel){
}
}
}
while(channel && channel_is_open(channel) && channel_poll(channel,1)){ /* stderr */
lus=channel_read(channel,buffer,sizeof(buffer),1);
while(channel && ssh_channel_is_open(channel) && ssh_channel_poll(channel,1)){ /* stderr */
lus = ssh_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){
channel_free(channel);
ssh_channel_free(channel);
channel=channels[0]=NULL;
} else {
ret = write(2, buffer, lus);
@@ -153,8 +163,8 @@ static void select_loop(ssh_session session,ssh_channel channel){
}
}
}
if(channel && channel_is_closed(channel)){
channel_free(channel);
if(channel && ssh_channel_is_closed(channel)){
ssh_channel_free(channel);
channel=NULL;
}
} while (ret==EINTR || ret==SSH_EINTR);
@@ -165,8 +175,8 @@ static void select_loop(ssh_session session,ssh_channel channel){
static void forwarding(ssh_session session){
ssh_channel channel;
int r;
channel=channel_new(session);
r=channel_open_forward(channel,desthost,atoi(port),"localhost",22);
channel = ssh_channel_new(session);
r = ssh_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(headers C)
project(libssh-headers-x C)
add_subdirectory(libssh)

View File

@@ -90,6 +90,14 @@ 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

33
include/libssh/bignum.h Normal file
View File

@@ -0,0 +1,33 @@
/*
* 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,9 +36,11 @@ 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;

87
include/libssh/blf.h Normal file
View File

@@ -0,0 +1,87 @@
/* $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,6 +21,8 @@
#ifndef BUFFER_H_
#define BUFFER_H_
#include <stdarg.h>
#include "libssh/libssh.h"
/*
* Describes a buffer state
@@ -34,21 +36,49 @@ 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 buffer_add_data(ssh_buffer buffer, const void *data, uint32_t len);
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_prepend_data(ssh_buffer buffer, const void *data, uint32_t len);
int buffer_add_buffer(ssh_buffer buffer, ssh_buffer source);
int buffer_reinit(ssh_buffer buffer);
int ssh_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,6 +75,8 @@ 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);
@@ -96,8 +98,6 @@ 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,6 +46,8 @@
#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,
@@ -79,8 +81,10 @@ struct ssh_crypto_struct {
unsigned char *encryptkey;
unsigned char *encryptMAC;
unsigned char *decryptMAC;
unsigned char hmacbuf[EVP_MAX_MD_SIZE];
unsigned char hmacbuf[DIGEST_MAX_LEN];
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 */
@@ -111,9 +115,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 (*cbc_encrypt)(struct ssh_cipher_struct *cipher, void *in, void *out,
void (*encrypt)(struct ssh_cipher_struct *cipher, void *in, void *out,
unsigned long len);
void (*cbc_decrypt)(struct ssh_cipher_struct *cipher, void *in, void *out,
void (*decrypt)(struct ssh_cipher_struct *cipher, void *in, void *out,
unsigned long len);
};

View File

@@ -25,7 +25,6 @@
#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);
@@ -48,10 +47,5 @@ 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);
#ifdef HAVE_LIBCRYPTO
void make_string_bn_inplace(ssh_string string, bignum bnout);
#endif /* HAVE_LIBCRYPTO */
ssh_string make_bignum_string(bignum num);
#endif /* DH_H_ */

79
include/libssh/ed25519.h Normal file
View File

@@ -0,0 +1,79 @@
/*
* 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_ */

68
include/libssh/fe25519.h Normal file
View File

@@ -0,0 +1,68 @@
/* $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

43
include/libssh/ge25519.h Normal file
View File

@@ -0,0 +1,43 @@
/* $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);
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 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 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,
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,
int remoteport, const char *sourcehost, int localport);
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_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_read_buffer(ssh_channel channel, ssh_buffer buffer, uint32_t count,
SSH_DEPRECATED LIBSSH_API int channel_read_buffer(ssh_channel channel, ssh_buffer buffer, uint32_t count,
int is_stderr);
LIBSSH_API int channel_read_nonblocking(ssh_channel channel, void *dest, uint32_t count,
SSH_DEPRECATED LIBSSH_API int channel_read_nonblocking(ssh_channel channel, void *dest, uint32_t count,
int is_stderr);
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,
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,
int cols, int rows);
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,
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,
const char *cookie, int screen_number);
LIBSSH_API int channel_send_eof(ssh_channel channel);
LIBSSH_API int channel_select(ssh_channel *readchans, ssh_channel *writechans, ssh_channel *exceptchans, struct
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
timeval * timeout);
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);
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 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);
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);
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);
#endif /* LEGACY_H_ */

View File

@@ -36,6 +36,8 @@
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
@@ -45,6 +47,9 @@ 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
@@ -84,6 +89,14 @@ 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,6 +27,9 @@
#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;
@@ -34,11 +37,14 @@ 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 36
#define EVP_MAX_MD_SIZE 64
#endif
#define EVP_DIGEST_LEN EVP_MAX_MD_SIZE

View File

@@ -58,6 +58,7 @@
#else /* _MSC_VER */
#include <unistd.h>
#include <inttypes.h>
#include <sys/types.h>
#endif /* _MSC_VER */
#ifdef _WIN32
@@ -77,8 +78,8 @@
/* libssh version */
#define LIBSSH_VERSION_MAJOR 0
#define LIBSSH_VERSION_MINOR 6
#define LIBSSH_VERSION_MICRO 5
#define LIBSSH_VERSION_MINOR 7
#define LIBSSH_VERSION_MICRO 7
#define LIBSSH_VERSION_INT SSH_VERSION_INT(LIBSSH_VERSION_MAJOR, \
LIBSSH_VERSION_MINOR, \
@@ -104,6 +105,13 @@
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;
@@ -245,7 +253,8 @@ enum ssh_keytypes_e{
SSH_KEYTYPE_DSS=1,
SSH_KEYTYPE_RSA,
SSH_KEYTYPE_RSA1,
SSH_KEYTYPE_ECDSA
SSH_KEYTYPE_ECDSA,
SSH_KEYTYPE_ED25519
};
enum ssh_keycmp_e {
@@ -335,6 +344,8 @@ 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 {
@@ -395,6 +406,8 @@ 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);
@@ -405,10 +418,19 @@ 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);
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);
/* 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 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);
@@ -422,14 +444,20 @@ 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_MD5,
SSH_PUBLICKEY_HASH_SHA256
};
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);
@@ -536,6 +564,10 @@ 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);
@@ -562,7 +594,10 @@ 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);
@@ -630,8 +665,11 @@ 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,6 +56,7 @@
#include <stdlib.h>
#include <stdarg.h>
#include <stdio.h>
#include <string>
namespace ssh {
@@ -365,14 +366,14 @@ public:
/* implemented outside the class due Channel references */
void_throwable cancelForward(const char *address, int port){
int err=ssh_forward_cancel(c_session, address, port);
int err=ssh_channel_cancel_forward(c_session, address, port);
ssh_throw(err);
return_throwable;
}
void_throwable listenForward(const char *address, int port,
int &boundport){
int err=ssh_forward_listen(c_session, address, port, &boundport);
int err=ssh_channel_listen_forward(c_session, address, port, &boundport);
ssh_throw(err);
return_throwable;
}
@@ -599,10 +600,9 @@ private:
};
/* 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);
inline Channel *Session::acceptForward(int timeout_ms){
ssh_channel forward =
ssh_channel_accept_forward(c_session, timeout_ms, NULL);
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;
const char *x11_auth_protocol;
const char *x11_auth_cookie;
char *x11_auth_protocol;
char *x11_auth_cookie;
uint32_t x11_screen_number;
};

View File

@@ -33,15 +33,6 @@ 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,6 +21,8 @@
#ifndef PACKET_H_
#define PACKET_H_
#include "libssh/wrapper.h"
struct ssh_socket_struct;
/* this structure should go someday */
@@ -41,6 +43,12 @@ 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
@@ -82,6 +90,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);
unsigned char *mac, enum ssh_hmac_e type);
#endif /* PACKET_H_ */

View File

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

View File

@@ -21,12 +21,27 @@
#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__)
@@ -41,6 +56,8 @@ 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);
@@ -91,4 +108,22 @@ 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,6 +31,8 @@
#include "config.h"
#include <stddef.h>
#if !defined(HAVE_STRTOULL)
# if defined(HAVE___STRTOULL)
# define strtoull __strtoull
@@ -43,6 +45,20 @@
# 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 */
@@ -60,11 +76,16 @@
# 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)
@@ -109,11 +130,15 @@
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"
@@ -127,10 +152,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 :) */
@@ -240,8 +265,9 @@ 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)
@@ -302,5 +328,64 @@ 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: */

74
include/libssh/sc25519.h Normal file
View File

@@ -0,0 +1,74 @@
/* $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,6 +127,15 @@ 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;
@@ -147,7 +156,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;
@@ -188,6 +197,9 @@ 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;
ssh_string lang;
uint32_t id;
uint32_t status;
ssh_string error_unused; /* not used anymore */
ssh_string lang_unused; /* not used anymore */
char *errormsg;
char *langmsg;
};

View File

@@ -22,6 +22,7 @@
#define WRAPPER_H_
#include "config.h"
#include "libssh/libssh.h"
#include "libssh/libcrypto.h"
#include "libssh/libgcrypt.h"
@@ -34,6 +35,9 @@ enum ssh_mac_e {
enum ssh_hmac_e {
SSH_HMAC_SHA1 = 1,
SSH_HMAC_SHA256,
SSH_HMAC_SHA384,
SSH_HMAC_SHA512,
SSH_HMAC_MD5
};
@@ -42,16 +46,36 @@ 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);
@@ -64,6 +88,7 @@ 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);
@@ -72,4 +97,8 @@ 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,13 +1,12 @@
project(libssh-library C)
set(LIBSSH_PUBLIC_INCLUDE_DIRS
${CMAKE_SOURCE_DIR}/include
${libssh_SOURCE_DIR}/include
CACHE INTERNAL "libssh public include directories"
)
set(LIBSSH_PRIVATE_INCLUDE_DIRS
${CMAKE_BINARY_DIR}
${OPENSSL_INCLUDE_DIRS}
${libssh_BINARY_DIR}
)
set(LIBSSH_LINK_LIBRARIES
@@ -28,17 +27,17 @@ if (HAVE_LIBSOCKET)
)
endif (HAVE_LIBSOCKET)
if (OPENSSL_LIBRARIES)
if (OPENSSL_CRYPTO_LIBRARY)
set(LIBSSH_PRIVATE_INCLUDE_DIRS
${LIBSSH_PRIVATE_INCLUDE_DIRS}
${OPENSSL_INCLUDE_DIRS}
${OPENSSL_INCLUDE_DIR}
)
set(LIBSSH_LINK_LIBRARIES
${LIBSSH_LINK_LIBRARIES}
${OPENSSL_LIBRARIES}
${OPENSSL_CRYPTO_LIBRARY}
)
endif (OPENSSL_LIBRARIES)
endif (OPENSSL_CRYPTO_LIBRARY)
if (GCRYPT_LIBRARY)
set(LIBSSH_PRIVATE_INCLUDE_DIRS
@@ -55,7 +54,7 @@ endif (GCRYPT_LIBRARY)
if (WITH_ZLIB)
set(LIBSSH_PRIVATE_INCLUDE_DIRS
${LIBSSH_PRIVATE_INCLUDE_DIRS}
${ZLIB_INCLUDE_DIRS}
${ZLIB_INCLUDE_DIR}
)
set(LIBSSH_LINK_LIBRARIES
@@ -109,6 +108,7 @@ set(libssh_SRCS
agent.c
auth.c
base64.c
bignum.c
buffer.c
callbacks.c
channels.c
@@ -124,7 +124,6 @@ set(libssh_SRCS
kex.c
known_hosts.c
legacy.c
libcrypto.c
log.c
match.c
messages.c
@@ -135,6 +134,8 @@ set(libssh_SRCS
packet_crypt.c
pcap.c
pki.c
pki_container_openssh.c
pki_ed25519.c
poll.c
session.c
scp.c
@@ -142,6 +143,12 @@ 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)
@@ -155,7 +162,11 @@ 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)
@@ -208,7 +219,7 @@ endif (WITH_GSSAPI AND GSSAPI_FOUND)
if (NOT WITH_NACL)
set(libssh_SRCS
${libssh_SRCS}
curve25519_ref.c
external/curve25519_ref.c
)
endif (NOT WITH_NACL)
@@ -238,6 +249,10 @@ 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
@@ -288,6 +303,7 @@ 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,15 +185,32 @@ 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;
}
if (getenv("SSH_AUTH_SOCK")) {
ssh_socket_close(agent->sock);
}
ssh_socket_close(agent->sock);
}
void agent_free(ssh_agent agent) {
@@ -300,7 +317,7 @@ static int agent_talk(struct ssh_session_struct *session,
"Error reading response from authentication socket.");
return -1;
}
if (buffer_add_data(reply, payload, n) < 0) {
if (ssh_buffer_add_data(reply, payload, n) < 0) {
SSH_LOG(SSH_LOG_WARN, "Not enough space");
return -1;
}
@@ -365,6 +382,9 @@ 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",
@@ -375,7 +395,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: %d", type);
"Bad authentication reply message type: %u", type);
ssh_buffer_free(reply);
return -1;
}
@@ -393,7 +413,7 @@ int ssh_agent_get_ident_count(struct ssh_session_struct *session) {
}
if (session->agent->ident) {
buffer_reinit(session->agent->ident);
ssh_buffer_reinit(session->agent->ident);
}
session->agent->ident = reply;
@@ -490,8 +510,8 @@ ssh_string ssh_agent_sign_data(ssh_session session,
ssh_buffer reply;
ssh_string key_blob;
ssh_string sig_blob;
int type = SSH2_AGENT_FAILURE;
int flags = 0;
unsigned int type = 0;
unsigned int flags = 0;
uint32_t dlen;
int rc;
@@ -526,7 +546,7 @@ ssh_string ssh_agent_sign_data(ssh_session session,
ssh_buffer_free(request);
return NULL;
}
if (buffer_add_data(request, buffer_get_rest(data), dlen) < 0) {
if (ssh_buffer_add_data(request, buffer_get_rest(data), dlen) < 0) {
ssh_buffer_free(request);
return NULL;
}
@@ -555,13 +575,19 @@ 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: %d", type);
ssh_set_error(session,
SSH_FATAL,
"Bad authentication response: %u",
type);
ssh_buffer_free(reply);
return NULL;
}

653
src/auth.c Normal file → Executable file
View File

@@ -85,6 +85,10 @@ static int ssh_auth_response_termination(void *user){
case SSH_AUTH_STATE_GSSAPI_REQUEST_SENT:
case SSH_AUTH_STATE_GSSAPI_TOKEN:
case SSH_AUTH_STATE_GSSAPI_MIC_SENT:
case SSH_AUTH_STATE_PUBKEY_AUTH_SENT:
case SSH_AUTH_STATE_PUBKEY_OFFER_SENT:
case SSH_AUTH_STATE_PASSWORD_AUTH_SENT:
case SSH_AUTH_STATE_AUTH_NONE_SENT:
return 0;
default:
return 1;
@@ -137,6 +141,10 @@ static int ssh_userauth_get_response(ssh_session session) {
case SSH_AUTH_STATE_GSSAPI_REQUEST_SENT:
case SSH_AUTH_STATE_GSSAPI_TOKEN:
case SSH_AUTH_STATE_GSSAPI_MIC_SENT:
case SSH_AUTH_STATE_PUBKEY_OFFER_SENT:
case SSH_AUTH_STATE_PUBKEY_AUTH_SENT:
case SSH_AUTH_STATE_PASSWORD_AUTH_SENT:
case SSH_AUTH_STATE_AUTH_NONE_SENT:
case SSH_AUTH_STATE_NONE:
/* not reached */
rc = SSH_AUTH_ERROR;
@@ -182,25 +190,19 @@ SSH_PACKET_CALLBACK(ssh_packet_userauth_banner){
*/
SSH_PACKET_CALLBACK(ssh_packet_userauth_failure){
char *auth_methods = NULL;
ssh_string auth;
uint8_t partial = 0;
int rc;
(void) type;
(void) user;
auth = buffer_get_ssh_string(packet);
if (auth == NULL || buffer_get_u8(packet, &partial) != 1) {
rc = ssh_buffer_unpack(packet, "sb", &auth_methods, &partial);
if (rc != SSH_OK) {
ssh_set_error(session, SSH_FATAL,
"Invalid SSH_MSG_USERAUTH_FAILURE message");
session->auth_state=SSH_AUTH_STATE_ERROR;
goto end;
}
auth_methods = ssh_string_to_char(auth);
if (auth_methods == NULL) {
ssh_set_error_oom(session);
goto end;
}
if (partial) {
session->auth_state=SSH_AUTH_STATE_PARTIAL;
SSH_LOG(SSH_LOG_INFO,
@@ -215,8 +217,8 @@ SSH_PACKET_CALLBACK(ssh_packet_userauth_failure){
"Access denied. Authentication that can continue: %s",
auth_methods);
session->auth_methods = 0;
}
session->auth_methods = 0;
if (strstr(auth_methods, "password") != NULL) {
session->auth_methods |= SSH_AUTH_METHOD_PASSWORD;
}
@@ -234,7 +236,6 @@ SSH_PACKET_CALLBACK(ssh_packet_userauth_failure){
}
end:
ssh_string_free(auth);
SAFE_FREE(auth_methods);
return SSH_PACKET_USED;
@@ -282,21 +283,27 @@ SSH_PACKET_CALLBACK(ssh_packet_userauth_success){
SSH_PACKET_CALLBACK(ssh_packet_userauth_pk_ok){
int rc;
SSH_LOG(SSH_LOG_TRACE, "Received SSH_USERAUTH_PK_OK/INFO_REQUEST/GSSAPI_RESPONSE");
SSH_LOG(SSH_LOG_TRACE,
"Received SSH_USERAUTH_PK_OK/INFO_REQUEST/GSSAPI_RESPONSE");
if(session->auth_state==SSH_AUTH_STATE_KBDINT_SENT){
if (session->auth_state == SSH_AUTH_STATE_KBDINT_SENT) {
/* Assuming we are in keyboard-interactive context */
SSH_LOG(SSH_LOG_TRACE,
"keyboard-interactive context, assuming SSH_USERAUTH_INFO_REQUEST");
rc=ssh_packet_userauth_info_request(session,type,packet,user);
"keyboard-interactive context, "
"assuming SSH_USERAUTH_INFO_REQUEST");
rc = ssh_packet_userauth_info_request(session, type, packet, user);
#ifdef WITH_GSSAPI
} else if (session->auth_state == SSH_AUTH_STATE_GSSAPI_REQUEST_SENT){
} else if (session->auth_state == SSH_AUTH_STATE_GSSAPI_REQUEST_SENT) {
rc = ssh_packet_userauth_gssapi_response(session, type, packet, user);
#endif
} else if (session->auth_state == SSH_AUTH_STATE_PUBKEY_OFFER_SENT) {
session->auth_state = SSH_AUTH_STATE_PK_OK;
SSH_LOG(SSH_LOG_TRACE, "Assuming SSH_USERAUTH_PK_OK");
rc = SSH_PACKET_USED;
} else {
session->auth_state=SSH_AUTH_STATE_PK_OK;
SSH_LOG(SSH_LOG_TRACE, "Assuming SSH_USERAUTH_PK_OK");
rc=SSH_PACKET_USED;
session->auth_state = SSH_AUTH_STATE_ERROR;
SSH_LOG(SSH_LOG_TRACE, "SSH_USERAUTH_PK_OK received in wrong state");
rc = SSH_PACKET_USED;
}
return rc;
@@ -359,7 +366,6 @@ int ssh_userauth_list(ssh_session session, const char *username)
* before you connect to the server.
*/
int ssh_userauth_none(ssh_session session, const char *username) {
ssh_string str;
int rc;
#ifdef WITH_SSH1
@@ -387,52 +393,17 @@ int ssh_userauth_none(ssh_session session, const char *username) {
}
/* request */
rc = buffer_add_u8(session->out_buffer, SSH2_MSG_USERAUTH_REQUEST);
rc = ssh_buffer_pack(session->out_buffer, "bsss",
SSH2_MSG_USERAUTH_REQUEST,
username ? username : session->opts.username,
"ssh-connection",
"none"
);
if (rc < 0) {
goto fail;
}
/* username */
if (username) {
str = ssh_string_from_char(username);
} else {
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("none");
if (str == NULL) {
goto fail;
}
rc = buffer_add_ssh_string(session->out_buffer, str);
ssh_string_free(str);
if (rc < 0) {
goto fail;
}
session->auth_state = SSH_AUTH_STATE_NONE;
session->auth_state = SSH_AUTH_STATE_AUTH_NONE_SENT;
session->pending_call_state = SSH_PENDING_CALL_AUTH_NONE;
rc = packet_send(session);
if (rc == SSH_ERROR) {
@@ -448,7 +419,7 @@ pending:
return rc;
fail:
ssh_set_error_oom(session);
buffer_reinit(session->out_buffer);
ssh_buffer_reinit(session->out_buffer);
return SSH_AUTH_ERROR;
}
@@ -485,7 +456,7 @@ int ssh_userauth_try_publickey(ssh_session session,
const char *username,
const ssh_key pubkey)
{
ssh_string str;
ssh_string pubkey_s = NULL;
int rc;
if (session == NULL) {
@@ -522,83 +493,29 @@ int ssh_userauth_try_publickey(ssh_session session,
return SSH_AUTH_ERROR;
}
/* request */
rc = buffer_add_u8(session->out_buffer, SSH2_MSG_USERAUTH_REQUEST);
if (rc < 0) {
goto fail;
}
/* username */
if (username) {
str = ssh_string_from_char(username);
} else {
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("publickey");
if (str == NULL) {
goto fail;
}
rc = buffer_add_ssh_string(session->out_buffer, str);
ssh_string_free(str);
if (rc < 0) {
goto fail;
}
/* private key? */
rc = buffer_add_u8(session->out_buffer, 0);
if (rc < 0) {
goto fail;
}
/* algo */
str = ssh_string_from_char(pubkey->type_c);
if (str == NULL) {
goto fail;
}
rc = buffer_add_ssh_string(session->out_buffer, str);
ssh_string_free(str);
if (rc < 0) {
goto fail;
}
/* public key */
rc = ssh_pki_export_pubkey_blob(pubkey, &str);
rc = ssh_pki_export_pubkey_blob(pubkey, &pubkey_s);
if (rc < 0) {
goto fail;
}
rc = buffer_add_ssh_string(session->out_buffer, str);
ssh_string_free(str);
/* request */
rc = ssh_buffer_pack(session->out_buffer, "bsssbsS",
SSH2_MSG_USERAUTH_REQUEST,
username ? username : session->opts.username,
"ssh-connection",
"publickey",
0, /* private key ? */
pubkey->type_c, /* algo */
pubkey_s /* public key */
);
if (rc < 0) {
goto fail;
}
session->auth_state = SSH_AUTH_STATE_NONE;
ssh_string_free(pubkey_s);
session->auth_state = SSH_AUTH_STATE_PUBKEY_OFFER_SENT;
session->pending_call_state = SSH_PENDING_CALL_AUTH_OFFER_PUBKEY;
rc = packet_send(session);
if (rc == SSH_ERROR) {
@@ -613,8 +530,9 @@ pending:
return rc;
fail:
ssh_string_free(pubkey_s);
ssh_set_error_oom(session);
buffer_reinit(session->out_buffer);
ssh_buffer_reinit(session->out_buffer);
return SSH_AUTH_ERROR;
}
@@ -647,7 +565,7 @@ int ssh_userauth_publickey(ssh_session session,
const char *username,
const ssh_key privkey)
{
ssh_string str;
ssh_string str = NULL;
int rc;
if (session == NULL) {
@@ -684,81 +602,26 @@ int ssh_userauth_publickey(ssh_session session,
return SSH_AUTH_ERROR;
}
/* request */
rc = buffer_add_u8(session->out_buffer, SSH2_MSG_USERAUTH_REQUEST);
if (rc < 0) {
goto fail;
}
/* username */
if (username) {
str = ssh_string_from_char(username);
} else {
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("publickey");
if (str == NULL) {
goto fail;
}
rc = buffer_add_ssh_string(session->out_buffer, str);
ssh_string_free(str);
if (rc < 0) {
goto fail;
}
/* private key? */
rc = buffer_add_u8(session->out_buffer, 1);
if (rc < 0) {
goto fail;
}
/* algo */
str = ssh_string_from_char(privkey->type_c);
if (str == NULL) {
goto fail;
}
rc = buffer_add_ssh_string(session->out_buffer, str);
ssh_string_free(str);
if (rc < 0) {
goto fail;
}
/* public key */
rc = ssh_pki_export_pubkey_blob(privkey, &str);
if (rc < 0) {
goto fail;
}
rc = buffer_add_ssh_string(session->out_buffer, str);
ssh_string_free(str);
/* request */
rc = ssh_buffer_pack(session->out_buffer, "bsssbsS",
SSH2_MSG_USERAUTH_REQUEST,
username ? username : session->opts.username,
"ssh-connection",
"publickey",
1, /* private key */
privkey->type_c, /* algo */
str /* public key */
);
if (rc < 0) {
goto fail;
}
ssh_string_free(str);
/* sign the buffer with the private key */
str = ssh_pki_do_sign(session, session->out_buffer, privkey);
@@ -768,11 +631,12 @@ int ssh_userauth_publickey(ssh_session session,
rc = buffer_add_ssh_string(session->out_buffer, str);
ssh_string_free(str);
str = NULL;
if (rc < 0) {
goto fail;
}
session->auth_state = SSH_AUTH_STATE_NONE;
session->auth_state = SSH_AUTH_STATE_PUBKEY_AUTH_SENT;
session->pending_call_state = SSH_PENDING_CALL_AUTH_PUBKEY;
rc = packet_send(session);
if (rc == SSH_ERROR) {
@@ -787,8 +651,9 @@ pending:
return rc;
fail:
ssh_string_free(str);
ssh_set_error_oom(session);
buffer_reinit(session->out_buffer);
ssh_buffer_reinit(session->out_buffer);
return SSH_AUTH_ERROR;
}
@@ -798,7 +663,7 @@ static int ssh_userauth_agent_publickey(ssh_session session,
const char *username,
ssh_key pubkey)
{
ssh_string str;
ssh_string str = NULL;
int rc;
switch(session->pending_call_state) {
@@ -820,69 +685,6 @@ static int ssh_userauth_agent_publickey(ssh_session session,
return SSH_AUTH_ERROR;
}
/* request */
rc = buffer_add_u8(session->out_buffer, SSH2_MSG_USERAUTH_REQUEST);
if (rc < 0) {
goto fail;
}
/* username */
if (username) {
str = ssh_string_from_char(username);
} else {
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("publickey");
if (str == NULL) {
goto fail;
}
rc = buffer_add_ssh_string(session->out_buffer, str);
ssh_string_free(str);
if (rc < 0) {
goto fail;
}
/* private key? */
rc = buffer_add_u8(session->out_buffer, 1);
if (rc < 0) {
goto fail;
}
/* algo */
str = ssh_string_from_char(pubkey->type_c);
if (str == NULL) {
goto fail;
}
rc = buffer_add_ssh_string(session->out_buffer, str);
ssh_string_free(str);
if (rc < 0) {
goto fail;
}
/* public key */
rc = ssh_pki_export_pubkey_blob(pubkey, &str);
@@ -890,12 +692,22 @@ static int ssh_userauth_agent_publickey(ssh_session session,
goto fail;
}
rc = buffer_add_ssh_string(session->out_buffer, str);
ssh_string_free(str);
/* request */
rc = ssh_buffer_pack(session->out_buffer, "bsssbsS",
SSH2_MSG_USERAUTH_REQUEST,
username ? username : session->opts.username,
"ssh-connection",
"publickey",
1, /* private key */
pubkey->type_c, /* algo */
str /* public key */
);
if (rc < 0) {
goto fail;
}
ssh_string_free(str);
/* sign the buffer with the private key */
str = ssh_pki_do_sign_agent(session, session->out_buffer, pubkey);
if (str == NULL) {
@@ -908,7 +720,7 @@ static int ssh_userauth_agent_publickey(ssh_session session,
goto fail;
}
session->auth_state = SSH_AUTH_STATE_NONE;
session->auth_state = SSH_AUTH_STATE_PUBKEY_AUTH_SENT;
session->pending_call_state = SSH_PENDING_CALL_AUTH_AGENT;
rc = packet_send(session);
if (rc == SSH_ERROR) {
@@ -924,7 +736,8 @@ pending:
return rc;
fail:
ssh_set_error_oom(session);
buffer_reinit(session->out_buffer);
ssh_buffer_reinit(session->out_buffer);
ssh_string_free(str);
return SSH_AUTH_ERROR;
}
@@ -941,6 +754,15 @@ struct ssh_agent_state_struct {
char *comment;
};
/* Internal function */
void ssh_agent_state_free(void *data) {
struct ssh_agent_state_struct *state = data;
if (state) {
ssh_string_free_char(state->comment);
ssh_key_free(state->pubkey);
free (state);
}
}
/**
* @brief Try to do public key authentication with ssh agent.
@@ -987,6 +809,11 @@ int ssh_userauth_agent(ssh_session session,
state = session->agent_state;
if (state->pubkey == NULL)
state->pubkey = ssh_agent_get_first_ident(session, &state->comment);
if (state->pubkey == NULL) {
return SSH_AUTH_DENIED;
}
while (state->pubkey != NULL) {
if(state->state == SSH_AGENT_STATE_NONE){
SSH_LOG(SSH_LOG_DEBUG,
@@ -996,9 +823,8 @@ int ssh_userauth_agent(ssh_session session,
state->state == SSH_AGENT_STATE_PUBKEY){
rc = ssh_userauth_try_publickey(session, username, state->pubkey);
if (rc == SSH_AUTH_ERROR) {
ssh_string_free_char(state->comment);
ssh_key_free(state->pubkey);
SAFE_FREE(session->agent_state);
ssh_agent_state_free (state);
session->agent_state = NULL;
return rc;
} else if (rc == SSH_AUTH_AGAIN) {
state->state = SSH_AGENT_STATE_PUBKEY;
@@ -1007,6 +833,7 @@ int ssh_userauth_agent(ssh_session session,
SSH_LOG(SSH_LOG_DEBUG,
"Public key of %s refused by server", state->comment);
ssh_string_free_char(state->comment);
state->comment = NULL;
ssh_key_free(state->pubkey);
state->pubkey = ssh_agent_get_next_ident(session, &state->comment);
state->state = SSH_AGENT_STATE_NONE;
@@ -1022,23 +849,27 @@ int ssh_userauth_agent(ssh_session session,
if (rc == SSH_AUTH_AGAIN)
return rc;
ssh_string_free_char(state->comment);
ssh_key_free(state->pubkey);
state->comment = NULL;
if (rc == SSH_AUTH_ERROR) {
SAFE_FREE(session->agent_state);
ssh_agent_state_free (session->agent_state);
session->agent_state = NULL;
return rc;
} else if (rc != SSH_AUTH_SUCCESS) {
SSH_LOG(SSH_LOG_INFO,
"Server accepted public key but refused the signature");
ssh_key_free(state->pubkey);
state->pubkey = ssh_agent_get_next_ident(session, &state->comment);
state->state = SSH_AGENT_STATE_NONE;
continue;
}
SAFE_FREE(session->agent_state);
ssh_agent_state_free (session->agent_state);
session->agent_state = NULL;
return SSH_AUTH_SUCCESS;
}
}
SAFE_FREE(session->agent_state);
ssh_agent_state_free (session->agent_state);
session->agent_state = NULL;
return rc;
}
#endif
@@ -1246,15 +1077,14 @@ int ssh_userauth_publickey_auto(ssh_session session,
ssh_key_free(state->privkey);
ssh_key_free(state->pubkey);
SAFE_FREE(session->auth_auto_state);
if (rc == SSH_AUTH_SUCCESS) {
SSH_LOG(SSH_LOG_INFO,
"Successfully authenticated using %s",
privkey_file);
}
return rc;
}
if (rc == SSH_AUTH_ERROR) {
return rc;
} else if (rc == SSH_AUTH_SUCCESS) {
SSH_LOG(SSH_LOG_INFO,
"Successfully authenticated using %s",
privkey_file);
return rc;
} else if (rc == SSH_AUTH_AGAIN){
if (rc == SSH_AUTH_AGAIN){
return rc;
}
@@ -1306,7 +1136,6 @@ int ssh_userauth_publickey_auto(ssh_session session,
int ssh_userauth_password(ssh_session session,
const char *username,
const char *password) {
ssh_string str;
int rc;
#ifdef WITH_SSH1
@@ -1336,70 +1165,19 @@ int ssh_userauth_password(ssh_session session,
}
/* request */
rc = buffer_add_u8(session->out_buffer, SSH2_MSG_USERAUTH_REQUEST);
rc = ssh_buffer_pack(session->out_buffer, "bsssbs",
SSH2_MSG_USERAUTH_REQUEST,
username ? username : session->opts.username,
"ssh-connection",
"password",
0, /* false */
password
);
if (rc < 0) {
goto fail;
}
/* username */
if (username) {
str = ssh_string_from_char(username);
} else {
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("password");
if (str == NULL) {
goto fail;
}
rc = buffer_add_ssh_string(session->out_buffer, str);
ssh_string_free(str);
if (rc < 0) {
goto fail;
}
/* FALSE */
rc = buffer_add_u8(session->out_buffer, 0);
if (rc < 0) {
goto fail;
}
/* password */
str = ssh_string_from_char(password);
if (str == NULL) {
goto fail;
}
rc = buffer_add_ssh_string(session->out_buffer, str);
ssh_string_free(str);
if (rc < 0) {
goto fail;
}
session->auth_state = SSH_AUTH_STATE_NONE;
session->auth_state = SSH_AUTH_STATE_PASSWORD_AUTH_SENT;
session->pending_call_state = SSH_PENDING_CALL_AUTH_OFFER_PUBKEY;
rc = packet_send(session);
if (rc == SSH_ERROR) {
@@ -1415,7 +1193,7 @@ pending:
return rc;
fail:
ssh_set_error_oom(session);
buffer_reinit(session->out_buffer);
ssh_buffer_reinit(session->out_buffer);
return SSH_AUTH_ERROR;
}
@@ -1453,11 +1231,10 @@ int ssh_userauth_agent_pubkey(ssh_session session,
ssh_kbdint ssh_kbdint_new(void) {
ssh_kbdint kbd;
kbd = malloc(sizeof(struct ssh_kbdint_struct));
kbd = calloc(1, sizeof(struct ssh_kbdint_struct));
if (kbd == NULL) {
return NULL;
}
ZERO_STRUCTP(kbd);
return kbd;
}
@@ -1536,7 +1313,6 @@ static int ssh_userauth_kbdint_init(ssh_session session,
const char *username,
const char *submethods)
{
ssh_string str;
int rc;
if (session->pending_call_state == SSH_PENDING_CALL_AUTH_KBDINT_INIT)
goto pending;
@@ -1552,78 +1328,18 @@ static int ssh_userauth_kbdint_init(ssh_session session,
}
/* request */
rc = buffer_add_u8(session->out_buffer, SSH2_MSG_USERAUTH_REQUEST);
rc = ssh_buffer_pack(session->out_buffer, "bsssss",
SSH2_MSG_USERAUTH_REQUEST,
username ? username : session->opts.username,
"ssh-connection",
"keyboard-interactive",
"", /* lang (ignore it) */
submethods ? submethods : ""
);
if (rc < 0) {
goto fail;
}
/* username */
if (username) {
str = ssh_string_from_char(username);
} else {
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("keyboard-interactive");
if (str == NULL) {
goto fail;
}
rc = buffer_add_ssh_string(session->out_buffer, str);
ssh_string_free(str);
if (rc < 0) {
goto fail;
}
/* lang string (ignore it) */
str = ssh_string_from_char("");
if (str == NULL) {
goto fail;
}
rc = buffer_add_ssh_string(session->out_buffer, str);
ssh_string_free(str);
if (rc < 0) {
goto fail;
}
/* submethods */
if (submethods == NULL) {
submethods = "";
}
str = ssh_string_from_char(submethods);
if (str == NULL) {
goto fail;
}
rc = buffer_add_ssh_string(session->out_buffer, str);
ssh_string_free(str);
if (rc < 0) {
goto fail;
}
session->auth_state = SSH_AUTH_STATE_KBDINT_SENT;
session->pending_call_state = SSH_PENDING_CALL_AUTH_KBDINT_INIT;
@@ -1642,7 +1358,7 @@ pending:
return rc;
fail:
ssh_set_error_oom(session);
buffer_reinit(session->out_buffer);
ssh_buffer_reinit(session->out_buffer);
return SSH_AUTH_ERROR;
}
@@ -1660,7 +1376,6 @@ fail:
*/
static int ssh_userauth_kbdint_send(ssh_session session)
{
ssh_string answer;
uint32_t i;
int rc;
if (session->pending_call_state == SSH_PENDING_CALL_AUTH_KBDINT_SEND)
@@ -1669,29 +1384,17 @@ static int ssh_userauth_kbdint_send(ssh_session session)
ssh_set_error_invalid(session);
return SSH_ERROR;
}
rc = buffer_add_u8(session->out_buffer, SSH2_MSG_USERAUTH_INFO_RESPONSE);
if (rc < 0) {
goto fail;
}
rc = buffer_add_u32(session->out_buffer, htonl(session->kbdint->nprompts));
rc = ssh_buffer_pack(session->out_buffer, "bd",
SSH2_MSG_USERAUTH_INFO_RESPONSE,
session->kbdint->nprompts);
if (rc < 0) {
goto fail;
}
for (i = 0; i < session->kbdint->nprompts; i++) {
if (session->kbdint->answers && session->kbdint->answers[i]) {
answer = ssh_string_from_char(session->kbdint->answers[i]);
} else {
answer = ssh_string_from_char("");
}
if (answer == NULL) {
goto fail;
}
rc = buffer_add_ssh_string(session->out_buffer, answer);
string_burn(answer);
string_free(answer);
rc = ssh_buffer_pack(session->out_buffer, "s",
session->kbdint->answers && session->kbdint->answers[i] ?
session->kbdint->answers[i]:"");
if (rc < 0) {
goto fail;
}
@@ -1716,7 +1419,7 @@ pending:
return rc;
fail:
ssh_set_error_oom(session);
buffer_reinit(session->out_buffer);
ssh_buffer_reinit(session->out_buffer);
return SSH_AUTH_ERROR;
}
@@ -1728,64 +1431,41 @@ fail:
* authentication state.
*/
SSH_PACKET_CALLBACK(ssh_packet_userauth_info_request) {
ssh_string name; /* name of the "asking" window showed to client */
ssh_string instruction;
ssh_string tmp;
ssh_string tmp = NULL;
uint32_t nprompts;
uint32_t i;
int rc;
(void)user;
(void)type;
name = buffer_get_ssh_string(packet);
instruction = buffer_get_ssh_string(packet);
tmp = buffer_get_ssh_string(packet);
buffer_get_u32(packet, &nprompts);
/* We don't care about tmp */
ssh_string_free(tmp);
if (name == NULL || instruction == NULL) {
ssh_string_free(name);
ssh_string_free(instruction);
ssh_set_error(session, SSH_FATAL, "Invalid USERAUTH_INFO_REQUEST msg");
return SSH_PACKET_USED;
}
if (session->kbdint == NULL) {
session->kbdint = ssh_kbdint_new();
if (session->kbdint == NULL) {
ssh_set_error_oom(session);
ssh_string_free(name);
ssh_string_free(instruction);
return SSH_PACKET_USED;
}
} else {
ssh_kbdint_clean(session->kbdint);
}
session->kbdint->name = ssh_string_to_char(name);
ssh_string_free(name);
if (session->kbdint->name == NULL) {
ssh_set_error_oom(session);
ssh_kbdint_free(session->kbdint);
ssh_string_free(instruction);
rc = ssh_buffer_unpack(packet, "ssSd",
&session->kbdint->name, /* name of the "asking" window shown to client */
&session->kbdint->instruction,
&tmp, /* to ignore */
&nprompts
);
return SSH_PACKET_USED;
/* We don't care about tmp */
ssh_string_free(tmp);
if (rc != SSH_OK) {
ssh_set_error(session, SSH_FATAL, "Invalid USERAUTH_INFO_REQUEST msg");
ssh_kbdint_free(session->kbdint);
session->kbdint = NULL;
return SSH_PACKET_USED;
}
session->kbdint->instruction = ssh_string_to_char(instruction);
ssh_string_free(instruction);
if (session->kbdint->instruction == NULL) {
ssh_set_error_oom(session);
ssh_kbdint_free(session->kbdint);
session->kbdint = NULL;
return SSH_PACKET_USED;
}
nprompts = ntohl(nprompts);
SSH_LOG(SSH_LOG_DEBUG,
"%d keyboard-interactive prompts", nprompts);
if (nprompts > KBDINT_MAX_PROMPT) {
@@ -1823,23 +1503,14 @@ SSH_PACKET_CALLBACK(ssh_packet_userauth_info_request) {
memset(session->kbdint->echo, 0, nprompts);
for (i = 0; i < nprompts; i++) {
tmp = buffer_get_ssh_string(packet);
buffer_get_u8(packet, &session->kbdint->echo[i]);
if (tmp == NULL) {
rc = ssh_buffer_unpack(packet, "sb",
&session->kbdint->prompts[i],
&session->kbdint->echo[i]);
if (rc == SSH_ERROR) {
ssh_set_error(session, SSH_FATAL, "Short INFO_REQUEST packet");
ssh_kbdint_free(session->kbdint);
session->kbdint = NULL;
return SSH_PACKET_USED;
}
session->kbdint->prompts[i] = ssh_string_to_char(tmp);
ssh_string_free(tmp);
if (session->kbdint->prompts[i] == NULL) {
ssh_set_error_oom(session);
session->kbdint->nprompts = i;
ssh_kbdint_free(session->kbdint);
session->kbdint = NULL;
return SSH_PACKET_USED;
}
}

View File

@@ -23,6 +23,7 @@
#include "config.h"
#include <errno.h>
#include <string.h>
#include <stdlib.h>
@@ -117,6 +118,7 @@ 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){
@@ -161,12 +163,14 @@ 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 ...
@@ -219,8 +223,11 @@ int ssh_userauth1_password(ssh_session session, const char *username,
}
pending:
rc = wait_auth1_status(session);
if (rc != SSH_AUTH_AGAIN)
session->pending_call_state = SSH_PENDING_CALL_NONE;
if (rc == SSH_AUTH_ERROR && errno == EAGAIN) {
/* Nothing to do */
} else if (rc != SSH_AUTH_AGAIN) {
session->pending_call_state = SSH_PENDING_CALL_NONE;
}
return rc;
}

View File

@@ -82,13 +82,18 @@ 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 (buffer_add_data(buffer, block, 3) < 0) {
if (ssh_buffer_add_data(buffer, block, 3) < 0) {
goto error;
}
len -= 4;
@@ -112,7 +117,7 @@ ssh_buffer base64_to_bin(const char *source) {
if (_base64_to_bin(block, ptr, 3) < 0) {
goto error;
}
if (buffer_add_data(buffer, block, 3) < 0) {
if (ssh_buffer_add_data(buffer, block, 3) < 0) {
goto error;
}
SAFE_FREE(base64);
@@ -131,7 +136,7 @@ ssh_buffer base64_to_bin(const char *source) {
if (_base64_to_bin(block, ptr, 1) < 0) {
goto error;
}
if (buffer_add_data(buffer, block, 1) < 0) {
if (ssh_buffer_add_data(buffer, block, 1) < 0) {
goto error;
}
SAFE_FREE(base64);
@@ -149,7 +154,7 @@ ssh_buffer base64_to_bin(const char *source) {
if (_base64_to_bin(block, ptr, 2) < 0) {
goto error;
}
if (buffer_add_data(buffer,block,2) < 0) {
if (ssh_buffer_add_data(buffer,block,2) < 0) {
goto error;
}
SAFE_FREE(base64);

111
src/bignum.c Normal file
View File

@@ -0,0 +1,111 @@
/*
* 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(s);
CLOSE_SOCKET(s);
return -1;
}
@@ -121,7 +121,7 @@ static socket_t bind_socket(ssh_bind sshbind, const char *hostname,
port,
strerror(errno));
freeaddrinfo (ai);
close(s);
CLOSE_SOCKET(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(fd);
CLOSE_SOCKET(fd);
ssh_key_free(sshbind->dsa);
sshbind->dsa = NULL;
ssh_key_free(sshbind->rsa);
@@ -350,11 +350,7 @@ void ssh_bind_free(ssh_bind sshbind){
}
if (sshbind->bindfd >= 0) {
#ifdef _WIN32
closesocket(sshbind->bindfd);
#else
close(sshbind->bindfd);
#endif
CLOSE_SOCKET(sshbind->bindfd);
}
sshbind->bindfd = SSH_INVALID_SOCKET;
@@ -365,6 +361,7 @@ 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;
@@ -372,6 +369,8 @@ 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]) {
@@ -394,7 +393,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) {
@@ -459,6 +458,14 @@ 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;
@@ -488,11 +495,7 @@ int ssh_bind_accept(ssh_bind sshbind, ssh_session session) {
rc = ssh_bind_accept_fd(sshbind, session, fd);
if(rc == SSH_ERROR){
#ifdef _WIN32
closesocket(fd);
#else
close(fd);
#endif
CLOSE_SOCKET(fd);
ssh_socket_free(session->socket);
}
return rc;

View File

@@ -24,6 +24,7 @@
#include <limits.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#ifndef _WIN32
#include <netinet/in.h>
@@ -32,6 +33,8 @@
#include "libssh/priv.h"
#include "libssh/buffer.h"
#include "libssh/misc.h"
#include "libssh/bignum.h"
/**
* @defgroup libssh_buffer The SSH buffer functions.
@@ -104,13 +107,25 @@ void ssh_buffer_free(struct ssh_buffer_struct *buffer) {
if (buffer->data) {
/* burn the data */
memset(buffer->data, 0, buffer->allocated);
BURN_BUFFER(buffer->data, buffer->allocated);
SAFE_FREE(buffer->data);
}
memset(buffer, 'X', sizeof(*buffer));
BURN_BUFFER(buffer, sizeof(struct ssh_buffer_struct));
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;
@@ -125,9 +140,20 @@ static int realloc_buffer(struct ssh_buffer_struct *buffer, size_t needed) {
smallest <<= 1;
}
needed = smallest;
new = realloc(buffer->data, needed);
if (new == NULL) {
return -1;
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;
}
}
buffer->data = new;
buffer->allocated = needed;
@@ -140,12 +166,20 @@ 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);
}
@@ -158,9 +192,10 @@ static void buffer_shift(ssh_buffer buffer){
*
* @return 0 on success, < 0 on error.
*/
int buffer_reinit(struct ssh_buffer_struct *buffer) {
int ssh_buffer_reinit(struct ssh_buffer_struct *buffer)
{
buffer_verify(buffer);
memset(buffer->data, 0, buffer->used);
BURN_BUFFER(buffer->data, buffer->used);
buffer->used = 0;
buffer->pos = 0;
if(buffer->allocated > 127) {
@@ -185,7 +220,8 @@ int buffer_reinit(struct ssh_buffer_struct *buffer) {
*
* @return 0 on success, < 0 on error.
*/
int buffer_add_data(struct ssh_buffer_struct *buffer, const void *data, uint32_t len) {
int ssh_buffer_add_data(struct ssh_buffer_struct *buffer, const void *data, uint32_t len)
{
buffer_verify(buffer);
if (data == NULL) {
@@ -230,7 +266,7 @@ int buffer_add_ssh_string(struct ssh_buffer_struct *buffer,
}
len = ssh_string_len(string);
if (buffer_add_data(buffer, string, len + sizeof(uint32_t)) < 0) {
if (ssh_buffer_add_data(buffer, string, len + sizeof(uint32_t)) < 0) {
return -1;
}
@@ -248,12 +284,16 @@ 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){
if (buffer_add_data(buffer, &data, sizeof(data)) < 0) {
return -1;
}
int buffer_add_u32(struct ssh_buffer_struct *buffer,uint32_t data)
{
int rc;
return 0;
rc = ssh_buffer_add_data(buffer, &data, sizeof(data));
if (rc < 0) {
return -1;
}
return 0;
}
/**
@@ -267,12 +307,16 @@ 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){
if (buffer_add_data(buffer, &data, sizeof(data)) < 0) {
return -1;
}
int buffer_add_u16(struct ssh_buffer_struct *buffer,uint16_t data)
{
int rc;
return 0;
rc = ssh_buffer_add_data(buffer, &data, sizeof(data));
if (rc < 0) {
return -1;
}
return 0;
}
/**
@@ -286,12 +330,16 @@ 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){
if (buffer_add_data(buffer, &data, sizeof(data)) < 0) {
return -1;
}
int buffer_add_u64(struct ssh_buffer_struct *buffer, uint64_t data)
{
int rc;
return 0;
rc = ssh_buffer_add_data(buffer, &data, sizeof(data));
if (rc < 0) {
return -1;
}
return 0;
}
/**
@@ -305,12 +353,16 @@ 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){
if (buffer_add_data(buffer, &data, sizeof(uint8_t)) < 0) {
return -1;
}
int buffer_add_u8(struct ssh_buffer_struct *buffer,uint8_t data)
{
int rc;
return 0;
rc = ssh_buffer_add_data(buffer, &data, sizeof(uint8_t));
if (rc < 0) {
return -1;
}
return 0;
}
/**
@@ -368,12 +420,18 @@ 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) {
if (buffer_add_data(buffer, buffer_get_rest(source), buffer_get_rest_len(source)) < 0) {
return -1;
}
struct ssh_buffer_struct *source)
{
int rc;
return 0;
rc = ssh_buffer_add_data(buffer,
buffer_get_rest(source),
buffer_get_rest_len(source));
if (rc < 0) {
return -1;
}
return 0;
}
/**
@@ -505,12 +563,15 @@ 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.
*/
if (buffer->pos + len < len || buffer->pos + len > buffer->used) {
return 0;
rc = ssh_buffer_validate_length(buffer, len);
if (rc != SSH_OK) {
return 0;
}
memcpy(data,buffer->data+buffer->pos,len);
buffer->pos+=len;
@@ -559,6 +620,24 @@ 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
*
@@ -572,13 +651,15 @@ 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 */
if (buffer->pos + hostlen < hostlen || buffer->pos + hostlen > buffer->used) {
rc = ssh_buffer_validate_length(buffer, hostlen);
if (rc != SSH_OK) {
return NULL; /* it is indeed */
}
str = ssh_string_new(hostlen);
@@ -629,6 +710,388 @@ 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

@@ -357,7 +357,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 ||
buffer_add_data(session->out_buffer, ptr, effectivelen) < 0) {
ssh_buffer_add_data(session->out_buffer, ptr, effectivelen) < 0) {
return -1;
}
@@ -368,6 +368,9 @@ 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,52 +90,74 @@ 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){
#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);
}
#endif
if(buffer[i]=='\r') {
buffer[i]='\0';
return SSH_ERROR;
}
if (buffer[i]=='\n') {
buffer[i] = '\0';
str = strdup(buffer);
if (str == NULL) {
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);
}
/* 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);
#endif
if (buffer[i] == '\r') {
buffer[i] = '\0';
}
if (buffer[i] == '\n') {
int cmp;
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");
buffer[i] = '\0';
return 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;
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;
}
}
return ret;
}
/** @internal
@@ -147,46 +169,75 @@ 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;
char buffer[128] = {0};
int err=SSH_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;
banner = session->version == 1 ? CLIENTBANNER1 : CLIENTBANNER2;
banner = session->version == 1 ? CLIENTBANNER1 : CLIENTBANNER2;
terminator = session->version == 1 ? "\n" : "\r\n";
if (server) {
if(session->opts.custombanner == NULL){
session->serverbanner = strdup(banner);
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);
} else {
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);
}
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);
}
session->clientbanner = strdup(banner);
if (session->clientbanner == NULL) {
goto end;
}
if (ssh_socket_write(session->socket, buffer, strlen(buffer)) == SSH_ERROR) {
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);
}
rc = ssh_socket_write(session->socket, buffer, strlen(buffer));
if (rc == SSH_ERROR) {
goto end;
}
#ifdef WITH_PCAP
if(session->pcap_ctx)
ssh_pcap_context_write(session->pcap_ctx,SSH_PCAP_DIR_OUT,buffer,strlen(buffer),strlen(buffer));
if (session->pcap_ctx != NULL) {
ssh_pcap_context_write(session->pcap_ctx,
SSH_PCAP_DIR_OUT,
buffer,
strlen(buffer),
strlen(buffer));
}
#endif
err=SSH_OK;
end:
return err;
rc = SSH_OK;
end:
return rc;
}
/** @internal
@@ -269,24 +320,19 @@ 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;
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);
rc = ssh_buffer_pack(session->out_buffer,
"bs",
SSH2_MSG_SERVICE_REQUEST,
service);
if (rc != SSH_OK){
ssh_set_error_oom(session);
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,
@@ -340,7 +386,13 @@ 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) {
@@ -386,7 +438,9 @@ static void ssh_client_connection_callback(ssh_session session){
#endif
ssh_packet_set_default_callbacks(session);
session->session_state=SSH_SESSION_STATE_INITIAL_KEX;
ssh_send_banner(session, 0);
if (session->opts.ssh1 == 1) {
ssh_send_banner(session, 0);
}
set_status(session, 0.5f);
break;
case SSH_SESSION_STATE_INITIAL_KEX:
@@ -506,7 +560,12 @@ int ssh_connect(ssh_session session) {
ssh_set_error(session, SSH_FATAL, "Couldn't apply options");
return SSH_ERROR;
}
SSH_LOG(SSH_LOG_RARE,"libssh %s, using threading %s", ssh_copyright(), ssh_threads_get_type());
SSH_LOG(SSH_LOG_PROTOCOL,
"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);
@@ -545,7 +604,7 @@ pending:
if (timeout == 0) {
timeout = 10 * 1000;
}
SSH_LOG(SSH_LOG_PACKET,"ssh_connect: Actual timeout : %d", timeout);
SSH_LOG(SSH_LOG_PACKET,"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))) {
@@ -563,7 +622,7 @@ pending:
session->session_state = SSH_SESSION_STATE_ERROR;
}
}
SSH_LOG(SSH_LOG_PACKET,"ssh_connect: Actual state : %d",session->session_state);
SSH_LOG(SSH_LOG_PACKET,"current state : %d",session->session_state);
if(!ssh_is_blocking(session) && !ssh_connect_termination(session)){
return SSH_AGAIN;
}
@@ -625,32 +684,23 @@ 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)) {
if (buffer_add_u8(session->out_buffer, SSH2_MSG_DISCONNECT) < 0) {
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);
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);
@@ -671,14 +721,18 @@ error:
crypto_free(session->current_crypto);
session->current_crypto=NULL;
}
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);
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);
}
session->auth_methods = 0;
SAFE_FREE(session->serverbanner);
SAFE_FREE(session->clientbanner);

View File

@@ -50,6 +50,8 @@ 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 {
@@ -185,7 +187,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) {
unsigned int count, int *parsing, int seen[]) {
enum ssh_config_opcode_e opcode;
const char *p;
char *s, *x;
@@ -216,32 +218,43 @@ 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:
case SOC_HOST: {
int ok = 0;
*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)) {
char *z = ssh_path_expand_escape(session, p);
int ok;
if (z == NULL) {
z = strdup(p);
if (ok >= 0) {
ok = match_hostname(lowerhost, p, strlen(p));
if (ok < 0) {
*parsing = 0;
} else if (ok > 0) {
*parsing = 1;
}
}
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) {
ssh_options_set(session, SSH_OPTIONS_HOST, p);
char *z = ssh_path_expand_escape(session, p);
if (z == NULL) {
z = strdup(p);
}
ssh_options_set(session, SSH_OPTIONS_HOST, z);
free(z);
}
break;
case SOC_PORT:
@@ -378,17 +391,18 @@ 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_RARE, "Reading configuration data from %s", filename);
SSH_LOG(SSH_LOG_PACKET, "Reading configuration data from %s", filename);
parsing = 1;
while (fgets(line, sizeof(line), f)) {
count++;
if (ssh_config_parse_line(session, line, count, &parsing) < 0) {
if (ssh_config_parse_line(session, line, count, &parsing, seen) < 0) {
fclose(f);
return -1;
}

View File

@@ -37,19 +37,14 @@
#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");
@@ -58,15 +53,14 @@ int ssh_client_curve25519_init(ssh_session session){
crypto_scalarmult_base(session->next_crypto->curve25519_client_pubkey,
session->next_crypto->curve25519_privkey);
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) {
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);
return SSH_ERROR;
}
@@ -283,7 +277,7 @@ int ssh_server_curve25519_init(ssh_session session, ssh_buffer packet){
return rc;
error:
buffer_reinit(session->out_buffer);
ssh_buffer_reinit(session->out_buffer);
return SSH_ERROR;
}

728
src/dh.c
View File

@@ -60,6 +60,7 @@
#include "libssh/dh.h"
#include "libssh/ssh2.h"
#include "libssh/pki.h"
#include "libssh/bignum.h"
/* todo: remove it */
#include "libssh/string.h"
@@ -225,30 +226,22 @@ 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, 128);
bignum_rand(session->next_crypto->x, keysize);
#elif defined HAVE_LIBCRYPTO
bignum_rand(session->next_crypto->x, 128, 0, -1);
bignum_rand(session->next_crypto->x, keysize, -1, 0);
#endif
/* not harder than this */
@@ -261,15 +254,21 @@ int dh_generate_x(ssh_session session) {
/* used by server */
int dh_generate_y(ssh_session session) {
session->next_crypto->y = bignum_new();
int keysize;
if (session->next_crypto->kex_type == SSH_KEX_DH_GROUP1_SHA1) {
keysize = 1023;
} else {
keysize = 2047;
}
session->next_crypto->y = bignum_new();
if (session->next_crypto->y == NULL) {
return -1;
}
#ifdef HAVE_LIBGCRYPT
bignum_rand(session->next_crypto->y, 128);
bignum_rand(session->next_crypto->y, keysize);
#elif defined HAVE_LIBCRYPTO
bignum_rand(session->next_crypto->y, 128, 0, -1);
bignum_rand(session->next_crypto->y, keysize, -1, 0);
#endif
/* not harder than this */
@@ -351,74 +350,6 @@ 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;
}
#ifdef HAVE_LIBCRYPTO
/** @internal
* @brief converts the content of a SSH string in an already allocated bignum
* @warning only available with OpenSSL builds
*/
void make_string_bn_inplace(ssh_string string, bignum bnout) {
unsigned int len = ssh_string_len(string);
bignum_bin2bn(string->data, len, bnout);
}
#endif /* HAVE_LIBCRYPTO */
ssh_string dh_get_e(ssh_session session) {
return make_bignum_string(session->next_crypto->e);
}
@@ -516,10 +447,6 @@ 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;
}
@@ -532,9 +459,11 @@ int ssh_client_dh_init(ssh_session session){
goto error;
}
if (buffer_add_ssh_string(session->out_buffer, e) < 0) {
rc = ssh_buffer_pack(session->out_buffer, "bS", SSH2_MSG_KEXDH_INIT, e);
if (rc != SSH_OK) {
goto error;
}
ssh_string_burn(e);
ssh_string_free(e);
e=NULL;
@@ -599,218 +528,180 @@ 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_string str = NULL;
ssh_buffer server_hash = NULL;
ssh_buffer client_hash = NULL;
ssh_buffer buf = NULL;
uint32_t len;
int rc = SSH_ERROR;
ssh_string num = NULL;
ssh_buffer server_hash = NULL;
ssh_buffer client_hash = NULL;
ssh_buffer buf = NULL;
int rc = SSH_ERROR;
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;
buf = ssh_buffer_new();
if (buf == NULL) {
return rc;
}
len = ssh_string_len(num) + 4;
if (buffer_add_data(buf, num, len) < 0) {
goto error;
rc = ssh_buffer_pack(buf,
"ss",
session->clientbanner,
session->serverbanner);
if (rc == SSH_ERROR) {
goto error;
}
ssh_string_free(num);
num = make_bignum_string(session->next_crypto->f);
if (num == NULL) {
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;
}
len = ssh_string_len(num) + 4;
if (buffer_add_data(buf, num, len) < 0) {
goto error;
/*
* 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;
}
ssh_string_free(num);
/* 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 = 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;
}
} 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 = 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;
}
} 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);
len = ssh_string_len(num) + 4;
if (buffer_add_data(buf, num, len) < 0) {
goto error;
}
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));
ssh_print_hexa("hash buffer", ssh_buffer_get_begin(buf), ssh_buffer_get_len(buf));
#endif
switch(session->next_crypto->kex_type){
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;
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);
}
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);
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;
rc = SSH_OK;
error:
ssh_buffer_free(buf);
ssh_buffer_free(client_hash);
ssh_buffer_free(server_hash);
ssh_buffer_free(buf);
ssh_buffer_free(client_hash);
ssh_buffer_free(server_hash);
session->in_hashbuf = NULL;
session->out_hashbuf = NULL;
session->in_hashbuf = NULL;
session->out_hashbuf = NULL;
ssh_string_free(str);
ssh_string_free(num);
ssh_string_free(num);
return rc;
return rc;
}
int hashbufout_add_cookie(ssh_session session) {
@@ -820,20 +711,20 @@ int hashbufout_add_cookie(ssh_session session) {
}
if (buffer_add_u8(session->out_hashbuf, 20) < 0) {
buffer_reinit(session->out_hashbuf);
ssh_buffer_reinit(session->out_hashbuf);
return -1;
}
if (session->server) {
if (buffer_add_data(session->out_hashbuf,
if (ssh_buffer_add_data(session->out_hashbuf,
session->next_crypto->server_kex.cookie, 16) < 0) {
buffer_reinit(session->out_hashbuf);
ssh_buffer_reinit(session->out_hashbuf);
return -1;
}
} else {
if (buffer_add_data(session->out_hashbuf,
if (ssh_buffer_add_data(session->out_hashbuf,
session->next_crypto->client_kex.cookie, 16) < 0) {
buffer_reinit(session->out_hashbuf);
ssh_buffer_reinit(session->out_hashbuf);
return -1;
}
}
@@ -848,11 +739,11 @@ int hashbufin_add_cookie(ssh_session session, unsigned char *cookie) {
}
if (buffer_add_u8(session->in_hashbuf, 20) < 0) {
buffer_reinit(session->in_hashbuf);
ssh_buffer_reinit(session->in_hashbuf);
return -1;
}
if (buffer_add_data(session->in_hashbuf,cookie, 16) < 0) {
buffer_reinit(session->in_hashbuf);
if (ssh_buffer_add_data(session->in_hashbuf,cookie, 16) < 0) {
ssh_buffer_reinit(session->in_hashbuf);
return -1;
}
@@ -860,8 +751,10 @@ 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) {
struct ssh_crypto_struct *crypto, unsigned char **output, char letter, size_t requested_size) {
ssh_mac_ctx ctx;
unsigned char *tmp;
size_t size = crypto->digest_len;
ctx=ssh_mac_ctx_init(crypto->mac_type);
if (ctx == NULL) {
@@ -872,16 +765,33 @@ 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);
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;
}
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);
@@ -905,96 +815,71 @@ int generate_session_keys(ssh_session session) {
/* IV */
if (session->client) {
if (generate_one_key(k_string, crypto, crypto->encryptIV, 'A') < 0) {
rc = generate_one_key(k_string, crypto, &crypto->encryptIV, 'A', crypto->digest_len);
if (rc < 0) {
goto error;
}
if (generate_one_key(k_string, crypto, crypto->decryptIV, 'B') < 0) {
rc = generate_one_key(k_string, crypto, &crypto->decryptIV, 'B', crypto->digest_len);
if (rc < 0) {
goto error;
}
} else {
if (generate_one_key(k_string, crypto, crypto->decryptIV, 'A') < 0) {
rc = generate_one_key(k_string, crypto, &crypto->decryptIV, 'A', crypto->digest_len);
if (rc < 0) {
goto error;
}
if (generate_one_key(k_string, crypto, crypto->encryptIV, 'B') < 0) {
rc = generate_one_key(k_string, crypto, &crypto->encryptIV, 'B', crypto->digest_len);
if (rc < 0) {
goto error;
}
}
if (session->client) {
if (generate_one_key(k_string, crypto, crypto->encryptkey, 'C') < 0) {
rc = generate_one_key(k_string, crypto, &crypto->encryptkey, 'C', crypto->out_cipher->keysize / 8);
if (rc < 0) {
goto error;
}
if (generate_one_key(k_string, crypto, crypto->decryptkey, 'D') < 0) {
rc = generate_one_key(k_string, crypto, &crypto->decryptkey, 'D', crypto->in_cipher->keysize / 8);
if (rc < 0) {
goto error;
}
} else {
if (generate_one_key(k_string, crypto, crypto->decryptkey, 'C') < 0) {
rc = generate_one_key(k_string, crypto, &crypto->decryptkey, 'C', crypto->in_cipher->keysize / 8);
if (rc < 0) {
goto error;
}
if (generate_one_key(k_string, crypto, crypto->encryptkey, 'D') < 0) {
rc = generate_one_key(k_string, crypto, &crypto->encryptkey, 'D', crypto->out_cipher->keysize / 8);
if (rc < 0) {
goto error;
}
}
/* 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;
}
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) {
rc = generate_one_key(k_string, crypto, &crypto->encryptMAC, 'E', hmac_digest_len(crypto->out_hmac));
if (rc < 0) {
goto error;
}
if (generate_one_key(k_string, crypto, crypto->decryptMAC, 'F') < 0) {
rc = generate_one_key(k_string, crypto, &crypto->decryptMAC, 'F', hmac_digest_len(crypto->in_hmac));
if (rc < 0) {
goto error;
}
} else {
if (generate_one_key(k_string, crypto, crypto->decryptMAC, 'E') < 0) {
rc = generate_one_key(k_string, crypto, &crypto->decryptMAC, 'E', hmac_digest_len(crypto->in_hmac));
if (rc < 0) {
goto error;
}
if (generate_one_key(k_string, crypto, crypto->encryptMAC, 'F') < 0) {
rc = generate_one_key(k_string, crypto, &crypto->encryptMAC, 'F', hmac_digest_len(crypto->out_hmac));
if (rc < 0) {
goto error;
}
}
#ifdef DEBUG_CRYPTO
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);
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));
#endif
rc = 0;
@@ -1154,6 +1039,29 @@ 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;
@@ -1189,6 +1097,38 @@ 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.
@@ -1226,6 +1166,110 @@ 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,6 +26,7 @@
#include "libssh/buffer.h"
#include "libssh/ssh2.h"
#include "libssh/pki.h"
#include "libssh/bignum.h"
#ifdef HAVE_ECDH
#include <openssl/ecdh.h>
@@ -99,8 +100,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 len = (EC_GROUP_get_degree(group) + 7) / 8;
int rc;
int len = (EC_GROUP_get_degree(group) + 7) / 8;
bignum_CTX ctx = bignum_ctx_new();
if (ctx == NULL) {
return -1;
@@ -118,12 +119,25 @@ static int ecdh_build_k(ssh_session session) {
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);
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;
}
buffer = malloc(len);
if (buffer == NULL) {
EC_POINT_clear_free(pubkey);
@@ -143,8 +157,10 @@ 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);
@@ -153,10 +169,6 @@ 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;
}
@@ -274,12 +286,6 @@ 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) {
@@ -299,30 +305,22 @@ 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 = buffer_add_ssh_string(session->out_buffer, sig_blob);
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 */
ssh_string_free(sig_blob);
if (rc < 0) {
if (rc != SSH_OK) {
ssh_set_error_oom(session);
return SSH_ERROR;
}

181
src/external/bcrypt_pbkdf.c vendored Normal file
View File

@@ -0,0 +1,181 @@
/* $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 */

694
src/external/blowfish.c vendored Normal file
View File

@@ -0,0 +1,694 @@
/* $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)) */

View File

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

222
src/external/ed25519.c vendored Normal file
View File

@@ -0,0 +1,222 @@
/* $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 Normal file
View File

@@ -0,0 +1,416 @@
/*
* 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 Normal file
View File

@@ -0,0 +1,367 @@
/* $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);
}
}

858
src/external/ge25519_base.data vendored Normal file
View File

@@ -0,0 +1,858 @@
/* $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 Normal file
View File

@@ -0,0 +1,373 @@
/*
* 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,6 +120,7 @@ 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,
@@ -129,11 +130,53 @@ 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){
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);
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);
}
}
#ifdef WITH_SERVER
@@ -212,7 +255,10 @@ 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);
ssh_gssapi_log_error(SSH_LOG_WARNING,
"importing name",
maj_stat,
min_stat);
return -1;
}
@@ -224,7 +270,10 @@ 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);
ssh_gssapi_log_error(SSH_LOG_WARNING,
"acquiring creds",
maj_stat,
min_stat);
ssh_auth_reply_default(session,0);
return SSH_ERROR;
}
@@ -266,7 +315,10 @@ 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);
ssh_gssapi_log_error(SSH_LOG_WARNING,
"converting name",
maj_stat,
min_stat);
ptr=malloc(buffer.length + 1);
memcpy(ptr, buffer.value, buffer.length);
ptr[buffer.length] = '\0';
@@ -311,14 +363,11 @@ SSH_PACKET_CALLBACK(ssh_packet_userauth_gssapi_token_server){
return SSH_PACKET_USED;
}
if (ssh_string_len(out_token) != 0){
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) {
rc = ssh_buffer_pack(session->out_buffer,
"bS",
SSH2_MSG_USERAUTH_GSSAPI_TOKEN,
out_token);
if (rc != SSH_OK) {
ssh_set_error_oom(session);
return SSH_PACKET_USED;
}
@@ -338,14 +387,20 @@ 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);
ssh_gssapi_log_error(SSH_LOG_PROTOCOL,
"accepting token",
maj_stat,
min_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);
ssh_gssapi_log_error(SSH_LOG_WARNING,
"Gssapi error",
maj_stat,
min_stat);
ssh_auth_reply_default(session,0);
ssh_gssapi_free(session);
session->gssapi=NULL;
@@ -356,12 +411,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);
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);
ssh_buffer_pack(session->out_buffer,
"bdP",
SSH2_MSG_USERAUTH_GSSAPI_TOKEN,
output_token.length,
(size_t)output_token.length, output_token.value);
packet_send(session);
ssh_string_free(token);
}
if(maj_stat == GSS_S_COMPLETE){
session->gssapi->state = SSH_GSSAPI_STATE_RCV_MIC;
@@ -373,69 +428,24 @@ 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_string_free(str);
ssh_set_error_oom(session);
return NULL;
}
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) {
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);
ssh_buffer_free(mic_buffer);
return NULL;
}
@@ -487,8 +497,10 @@ 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);
ssh_gssapi_log_error(SSH_LOG_PROTOCOL, "verifying MIC (min stat)", min_stat);
ssh_gssapi_log_error(SSH_LOG_PROTOCOL,
"verifying MIC",
maj_stat,
min_stat);
if (maj_stat == GSS_S_DEFECTIVE_TOKEN || GSS_ERROR(maj_stat)) {
goto error;
}
@@ -564,46 +576,19 @@ 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 = buffer_add_u32(session->out_buffer, htonl(n_oid));
if (rc < 0) {
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);
goto fail;
}
@@ -617,7 +602,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:
buffer_reinit(session->out_buffer);
ssh_buffer_reinit(session->out_buffer);
return SSH_ERROR;
}
@@ -728,8 +713,11 @@ 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);
return SSH_PACKET_USED;
ssh_gssapi_log_error(SSH_LOG_WARNING,
"importing name",
maj_stat,
min_stat);
return SSH_AUTH_DENIED;
}
/* copy username */
@@ -799,7 +787,6 @@ 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;
@@ -835,19 +822,22 @@ 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);
ssh_gssapi_log_error(SSH_LOG_WARNING,
"Initializing gssapi context",
maj_stat,
min_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);
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);
ssh_buffer_pack(session->out_buffer,
"bdP",
SSH2_MSG_USERAUTH_GSSAPI_TOKEN,
output_token.length,
(size_t)output_token.length, output_token.value);
packet_send(session);
ssh_string_free(token);
session->auth_state = SSH_AUTH_STATE_GSSAPI_TOKEN;
}
return SSH_PACKET_USED;
@@ -873,31 +863,24 @@ 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);
ssh_gssapi_log_error(SSH_LOG_PROTOCOL,
"generating MIC",
maj_stat,
min_stat);
return SSH_ERROR;
}
rc = buffer_add_u8(session->out_buffer, SSH2_MSG_USERAUTH_GSSAPI_MIC);
if (rc < 0) {
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) {
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);
}
@@ -934,10 +917,16 @@ 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);
ssh_gssapi_log_error(SSH_LOG_PROTOCOL,
"accepting token",
maj_stat,
min_stat);
ssh_string_free(token);
if (GSS_ERROR(maj_stat)){
ssh_gssapi_log_error(SSH_LOG_PROTOCOL, "Gssapi error", maj_stat);
ssh_gssapi_log_error(SSH_LOG_PROTOCOL,
"Gssapi error",
maj_stat,
min_stat);
ssh_gssapi_free(session);
session->gssapi=NULL;
return SSH_PACKET_USED;
@@ -947,16 +936,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);
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);
ssh_buffer_pack(session->out_buffer,
"bdP",
SSH2_MSG_USERAUTH_GSSAPI_TOKEN,
output_token.length,
(size_t)output_token.length, output_token.value);
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 (buffer_add_data(dest, out_buf, len) < 0) {
if (ssh_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 (buffer_reinit(buf) < 0) {
if (ssh_buffer_reinit(buf) < 0) {
ssh_buffer_free(dest);
return -1;
}
if (buffer_add_data(buf, buffer_get_rest(dest), buffer_get_rest_len(dest)) < 0) {
if (ssh_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 (buffer_add_data(dest,out_buf,len) < 0) {
if (ssh_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 (buffer_reinit(buf) < 0) {
if (ssh_buffer_reinit(buf) < 0) {
ssh_buffer_free(dest);
return -1;
}
if (buffer_add_data(buf, buffer_get_rest(dest), buffer_get_rest_len(dest)) < 0) {
if (ssh_buffer_add_data(buf, buffer_get_rest(dest), buffer_get_rest_len(dest)) < 0) {
ssh_buffer_free(dest);
return -1;
}

325
src/kex.c
View File

@@ -40,24 +40,30 @@
#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,des-cbc-ssh1"
# define DES "3des-cbc"
# define DES_SUPPORTED "3des-cbc,des-cbc-ssh1"
#elif defined(HAVE_LIBCRYPTO)
# ifdef HAVE_OPENSSL_BLOWFISH_H
# define BLOWFISH "blowfish-cbc,"
# else
# else /* HAVE_OPENSSL_BLOWFISH_H */
# define BLOWFISH ""
# endif
# endif /* HAVE_OPENSSL_BLOWFISH_H */
# ifdef HAVE_OPENSSL_AES_H
# ifdef BROKEN_AES_CTR
# define AES "aes256-cbc,aes192-cbc,aes128-cbc,"
# else
# else /* BROKEN_AES_CTR */
# define AES "aes256-ctr,aes192-ctr,aes128-ctr,aes256-cbc,aes192-cbc,aes128-cbc,"
# endif /* BROKEN_AES_CTR */
# else
# else /* HAVE_OPENSSL_AES_H */
# define AES ""
# endif
# define DES "3des-cbc,des-cbc-ssh1"
#endif
# endif /* HAVE_OPENSSL_AES_H */
# define DES "3des-cbc"
# define DES_SUPPORTED "3des-cbc,des-cbc-ssh1"
#endif /* HAVE_LIBCRYPTO */
#ifdef WITH_ZLIB
#define ZLIB "none,zlib,zlib@openssh.com"
@@ -73,9 +79,9 @@
#ifdef HAVE_ECDH
#define ECDH "ecdh-sha2-nistp256,"
#define HOSTKEYS "ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,ssh-rsa,ssh-dss"
#define HOSTKEYS "ssh-ed25519,ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,ssh-rsa,ssh-dss"
#else
#define HOSTKEYS "ssh-rsa,ssh-dss"
#define HOSTKEYS "ssh-ed25519,ssh-rsa,ssh-dss"
#define ECDH ""
#endif
@@ -88,8 +94,8 @@ static const char *default_methods[] = {
HOSTKEYS,
AES BLOWFISH DES,
AES BLOWFISH DES,
"hmac-sha1",
"hmac-sha1",
"hmac-sha2-256,hmac-sha2-512,hmac-sha1",
"hmac-sha2-256,hmac-sha2-512,hmac-sha1",
"none",
"none",
"",
@@ -101,10 +107,10 @@ static const char *default_methods[] = {
static const char *supported_methods[] = {
KEY_EXCHANGE,
HOSTKEYS,
AES BLOWFISH DES,
AES BLOWFISH DES,
"hmac-sha1",
"hmac-sha1",
AES BLOWFISH DES_SUPPORTED,
AES BLOWFISH DES_SUPPORTED,
"hmac-sha2-256,hmac-sha2-512,hmac-sha1",
"hmac-sha2-256,hmac-sha2-512,hmac-sha1",
ZLIB,
ZLIB,
"",
@@ -275,92 +281,187 @@ 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 server_kex=session->server;
ssh_string str = NULL;
char *strings[KEX_METHODS_SIZE];
int i;
int i;
int server_kex=session->server;
ssh_string str = NULL;
char *strings[KEX_METHODS_SIZE];
int rc = SSH_ERROR;
(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");
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");
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 (buffer_add_ssh_string(session->in_hashbuf, str) < 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;
}
/* 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];
}
}
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;
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;
}
}
SAFE_FREE(strings[i]);
}
session->session_state = SSH_SESSION_STATE_ERROR;
for (i = 0; i < KEX_METHODS_SIZE; i++) {
str = buffer_get_ssh_string(packet);
if (str == NULL) {
goto error;
}
return SSH_PACKET_USED;
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;
}
/* 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);
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->session_state = SSH_SESSION_STATE_ERROR;
return SSH_PACKET_USED;
}
void ssh_list_kex(struct ssh_kex_struct *kex) {
@@ -388,8 +489,16 @@ 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[]={"ecdsa-sha2-nistp521","ecdsa-sha2-nistp384",
"ecdsa-sha2-nistp256", "ssh-rsa", "ssh-dss", "ssh-rsa1", NULL};
static const char *preferred_hostkeys[] = {
"ssh-ed25519",
"ecdsa-sha2-nistp521",
"ecdsa-sha2-nistp384",
"ecdsa-sha2-nistp256",
"ssh-rsa",
"ssh-dss",
"ssh-rsa1",
NULL
};
char **methods;
int i,j;
int needcoma=0;
@@ -494,14 +603,15 @@ int ssh_send_kex(ssh_session session, int server_kex) {
&session->next_crypto->client_kex);
ssh_string str = NULL;
int i;
int rc;
if (buffer_add_u8(session->out_buffer, SSH2_MSG_KEXINIT) < 0) {
rc = ssh_buffer_pack(session->out_buffer,
"bP",
SSH2_MSG_KEXINIT,
16,
kex->cookie); /* cookie */
if (rc != SSH_OK)
goto error;
}
if (buffer_add_data(session->out_buffer, kex->cookie, 16) < 0) {
goto error;
}
if (hashbufout_add_cookie(session) < 0) {
goto error;
}
@@ -524,10 +634,11 @@ int ssh_send_kex(ssh_session session, int server_kex) {
str = NULL;
}
if (buffer_add_u8(session->out_buffer, 0) < 0) {
goto error;
}
if (buffer_add_u32(session->out_buffer, 0) < 0) {
rc = ssh_buffer_pack(session->out_buffer,
"bd",
0,
0);
if (rc != SSH_OK) {
goto error;
}
@@ -537,8 +648,8 @@ int ssh_send_kex(ssh_session session, int server_kex) {
return 0;
error:
buffer_reinit(session->out_buffer);
buffer_reinit(session->out_hashbuf);
ssh_buffer_reinit(session->out_buffer);
ssh_buffer_reinit(session->out_hashbuf);
ssh_string_free(str);
return -1;

View File

@@ -36,6 +36,10 @@
#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 */
@@ -46,6 +50,10 @@ 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;
@@ -119,8 +127,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
n1=k1->rsa_pub->n;
n2=k2->rsa_pub->n;
RSA_get0_key(k1->rsa_pub, (const BIGNUM **)&n1, NULL, NULL);
RSA_get0_key(k2->rsa_pub, (const BIGNUM **)&n2, NULL, NULL);
#endif
if(bignum_cmp(n1,n2)<0)
res=1;
@@ -417,7 +425,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 (buffer_add_data(session->out_buffer, session->next_crypto->server_kex.cookie, 8) < 0) {
if (ssh_buffer_add_data(session->out_buffer, session->next_crypto->server_kex.cookie, 8) < 0) {
goto error;
}
@@ -431,10 +439,10 @@ SSH_PACKET_CALLBACK(ssh_packet_publickey1){
bits, ssh_string_len(enc_session));
bits = htons(bits);
/* the encrypted mpint */
if (buffer_add_data(session->out_buffer, &bits, sizeof(uint16_t)) < 0) {
if (ssh_buffer_add_data(session->out_buffer, &bits, sizeof(uint16_t)) < 0) {
goto error;
}
if (buffer_add_data(session->out_buffer, ssh_string_data(enc_session),
if (ssh_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, string_data(tmpstring));
bignum_bn2bin(tmpbn, len, ssh_string_data(tmpstring));
#elif defined HAVE_LIBCRYPTO
bignum_bn2bin(tmpbn, string_data(tmpstring));
bignum_bn2bin(tmpbn, ssh_string_data(tmpstring));
#endif
bignum_free(tmpbn);
if (buffer_add_ssh_string(pubkey_buffer, tmpstring) < 0) {

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_forward_accept(session,timeout_ms);
return ssh_channel_accept_forward(session, timeout_ms, NULL);
}
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_forward_cancel(session, address, port);
return ssh_channel_cancel_forward(session, address, port);
}
int channel_forward_listen(ssh_session session, const char *address,
int port, int *bound_port){
return ssh_forward_listen(session, address, port, bound_port);
return ssh_channel_listen_forward(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(string_data(pubkey), ssh_string_len(pubkey));
pubkey_64 = bin_to_base64(ssh_string_data(pubkey), ssh_string_len(pubkey));
if (pubkey_64 == NULL) {
return SSH_ERROR;
}

318
src/libcrypto-compat.c Normal file
View File

@@ -0,0 +1,318 @@
/*
* 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;
}

42
src/libcrypto-compat.h Normal file
View File

@@ -0,0 +1,42 @@
#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,6 +43,8 @@
#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
@@ -68,6 +70,8 @@ struct ssh_mac_ctx_struct {
union {
SHACTX sha1_ctx;
SHA256CTX sha256_ctx;
SHA384CTX sha384_ctx;
SHA512CTX sha512_ctx;
} ctx;
};
@@ -131,18 +135,19 @@ 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 *md = EVP_MD_CTX_new();
EVP_DigestInit(&md, evp_md);
EVP_DigestUpdate(&md, digest, len);
EVP_DigestFinal(&md, hash, hlen);
EVP_DigestInit(md, evp_md);
EVP_DigestUpdate(md, digest, len);
EVP_DigestFinal(md, hash, hlen);
EVP_MD_CTX_free(md);
}
EVPCTX evp_init(int nid)
{
const EVP_MD *evp_md = nid_to_evpmd(nid);
EVPCTX ctx = malloc(sizeof(EVP_MD_CTX));
EVPCTX ctx = EVP_MD_CTX_new();
if (ctx == NULL) {
return NULL;
}
@@ -160,6 +165,7 @@ 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
@@ -186,6 +192,52 @@ 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) {
@@ -221,7 +273,11 @@ 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;
@@ -237,7 +293,11 @@ 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;
}
@@ -252,7 +312,11 @@ 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;
}
@@ -262,23 +326,33 @@ 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 = malloc(sizeof(*ctx));
ctx = HMAC_CTX_new();
if (ctx == NULL) {
return NULL;
}
#ifndef OLD_CRYPTO
HMAC_CTX_init(ctx); // openssl 0.9.7 requires it.
HMAC_CTX_reset(ctx); // openssl 0.9.7 requires it.
#endif
switch(type) {
case SSH_HMAC_SHA1:
HMAC_Init(ctx, key, len, EVP_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);
break;
case SSH_HMAC_MD5:
HMAC_Init(ctx, key, len, EVP_md5());
HMAC_Init_ex(ctx, key, len, EVP_md5(), NULL);
break;
default:
HMAC_CTX_free(ctx);
SAFE_FREE(ctx);
ctx = NULL;
}
@@ -294,7 +368,8 @@ void hmac_final(HMACCTX ctx, unsigned char *hashmacbuf, unsigned int *len) {
HMAC_Final(ctx,hashmacbuf,len);
#ifndef OLD_CRYPTO
HMAC_CTX_cleanup(ctx);
HMAC_CTX_free(ctx);
ctx = NULL;
#else
HMAC_cleanup(ctx);
#endif
@@ -386,7 +461,12 @@ 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,10 +69,69 @@ 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);
@@ -122,19 +181,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;
size_t len = 0;
switch(ctx->mac_type){
case SSH_MAC_SHA1:
len=SHA_DIGEST_LEN;
break;
case SSH_MAC_SHA256:
len=SHA256_DIGEST_LENGTH;
len=SHA256_DIGEST_LEN;
break;
case SSH_MAC_SHA384:
len=SHA384_DIGEST_LENGTH;
len=SHA384_DIGEST_LEN;
break;
case SSH_MAC_SHA512:
len=SHA512_DIGEST_LENGTH;
len=SHA512_DIGEST_LEN;
break;
}
gcry_md_final(ctx->ctx);
@@ -150,6 +209,15 @@ 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;
@@ -410,8 +478,8 @@ static struct ssh_cipher_struct ssh_ciphertab[] = {
.keysize = 128,
.set_encrypt_key = blowfish_set_key,
.set_decrypt_key = blowfish_set_key,
.cbc_encrypt = blowfish_encrypt,
.cbc_decrypt = blowfish_decrypt
.encrypt = blowfish_encrypt,
.decrypt = blowfish_decrypt
},
{
.name = "aes128-ctr",
@@ -421,8 +489,8 @@ static struct ssh_cipher_struct ssh_ciphertab[] = {
.keysize = 128,
.set_encrypt_key = aes_set_key,
.set_decrypt_key = aes_set_key,
.cbc_encrypt = aes_encrypt,
.cbc_decrypt = aes_encrypt
.encrypt = aes_encrypt,
.decrypt = aes_encrypt
},
{
.name = "aes192-ctr",
@@ -432,8 +500,8 @@ static struct ssh_cipher_struct ssh_ciphertab[] = {
.keysize = 192,
.set_encrypt_key = aes_set_key,
.set_decrypt_key = aes_set_key,
.cbc_encrypt = aes_encrypt,
.cbc_decrypt = aes_encrypt
.encrypt = aes_encrypt,
.decrypt = aes_encrypt
},
{
.name = "aes256-ctr",
@@ -443,8 +511,8 @@ static struct ssh_cipher_struct ssh_ciphertab[] = {
.keysize = 256,
.set_encrypt_key = aes_set_key,
.set_decrypt_key = aes_set_key,
.cbc_encrypt = aes_encrypt,
.cbc_decrypt = aes_encrypt
.encrypt = aes_encrypt,
.decrypt = aes_encrypt
},
{
.name = "aes128-cbc",
@@ -454,8 +522,8 @@ static struct ssh_cipher_struct ssh_ciphertab[] = {
.keysize = 128,
.set_encrypt_key = aes_set_key,
.set_decrypt_key = aes_set_key,
.cbc_encrypt = aes_encrypt,
.cbc_decrypt = aes_decrypt
.encrypt = aes_encrypt,
.decrypt = aes_decrypt
},
{
.name = "aes192-cbc",
@@ -465,8 +533,8 @@ static struct ssh_cipher_struct ssh_ciphertab[] = {
.keysize = 192,
.set_encrypt_key = aes_set_key,
.set_decrypt_key = aes_set_key,
.cbc_encrypt = aes_encrypt,
.cbc_decrypt = aes_decrypt
.encrypt = aes_encrypt,
.decrypt = aes_decrypt
},
{
.name = "aes256-cbc",
@@ -476,8 +544,8 @@ static struct ssh_cipher_struct ssh_ciphertab[] = {
.keysize = 256,
.set_encrypt_key = aes_set_key,
.set_decrypt_key = aes_set_key,
.cbc_encrypt = aes_encrypt,
.cbc_decrypt = aes_decrypt
.encrypt = aes_encrypt,
.decrypt = aes_decrypt
},
{
.name = "3des-cbc",
@@ -487,8 +555,8 @@ static struct ssh_cipher_struct ssh_ciphertab[] = {
.keysize = 192,
.set_encrypt_key = des3_set_key,
.set_decrypt_key = des3_set_key,
.cbc_encrypt = des3_encrypt,
.cbc_decrypt = des3_decrypt
.encrypt = des3_encrypt,
.decrypt = des3_decrypt
},
{
.name = "3des-cbc-ssh1",
@@ -498,8 +566,8 @@ static struct ssh_cipher_struct ssh_ciphertab[] = {
.keysize = 192,
.set_encrypt_key = des3_1_set_key,
.set_decrypt_key = des3_1_set_key,
.cbc_encrypt = des3_1_encrypt,
.cbc_decrypt = des3_1_decrypt
.encrypt = des3_1_encrypt,
.decrypt = des3_1_decrypt
},
{
.name = "des-cbc-ssh1",
@@ -509,8 +577,8 @@ static struct ssh_cipher_struct ssh_ciphertab[] = {
.keysize = 64,
.set_encrypt_key = des1_set_key,
.set_decrypt_key = des1_set_key,
.cbc_encrypt = des1_1_encrypt,
.cbc_decrypt = des1_1_decrypt
.encrypt = des1_1_encrypt,
.decrypt = des1_1_decrypt
},
{
.name = NULL,
@@ -520,8 +588,8 @@ static struct ssh_cipher_struct ssh_ciphertab[] = {
.keysize = 0,
.set_encrypt_key = NULL,
.set_decrypt_key = NULL,
.cbc_encrypt = NULL,
.cbc_decrypt = NULL
.encrypt = NULL,
.decrypt = NULL
}
};

View File

@@ -215,6 +215,10 @@ 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,6 +524,25 @@ 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);
@@ -585,104 +604,34 @@ 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;
ssh_string str=NULL;
int rc;
buffer = ssh_buffer_new();
if (buffer == NULL) {
return NULL;
}
/* 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;
}
/* Add the type */
rc = buffer_add_u8(buffer, SSH2_MSG_USERAUTH_REQUEST);
if (rc < 0) {
ssh_buffer_free(buffer);
return NULL;
}
/* 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) {
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 */
ssh_string_free(str);
if (rc != SSH_OK) {
ssh_set_error_oom(session);
ssh_buffer_free(buffer);
return NULL;
}
@@ -697,11 +646,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;
uint32_t method_size = 0;
int cmp;
int rc;
(void)user;
(void)type;
@@ -712,35 +661,13 @@ 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);
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) {
if (rc != SSH_OK) {
goto error;
}
@@ -749,33 +676,31 @@ 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 (strncmp(method, "none", method_size) == 0) {
if (strcmp(method, "none") == 0) {
msg->auth_request.method = SSH_AUTH_METHOD_NONE;
goto end;
}
if (strncmp(method, "password", method_size) == 0) {
ssh_string pass = NULL;
if (strcmp(method, "password") == 0) {
uint8_t tmp;
msg->auth_request.method = SSH_AUTH_METHOD_PASSWORD;
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) {
rc = ssh_buffer_unpack(packet, "bs", &tmp, &msg->auth_request.password);
if (rc != SSH_OK) {
goto error;
}
goto end;
}
if (strncmp(method, "keyboard-interactive", method_size) == 0) {
if (strcmp(method, "keyboard-interactive") == 0) {
ssh_string lang = NULL;
ssh_string submethods = NULL;
@@ -805,23 +730,20 @@ SSH_PACKET_CALLBACK(ssh_packet_userauth_request){
goto end;
}
if (strncmp(method, "publickey", method_size) == 0) {
if (strcmp(method, "publickey") == 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);
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;
rc = ssh_buffer_unpack(packet, "bSS",
&has_sign,
&algo,
&pubkey_blob
);
if (rc != SSH_OK) {
goto error;
}
ssh_string_free(algo);
@@ -876,7 +798,7 @@ SSH_PACKET_CALLBACK(ssh_packet_userauth_request){
goto end;
}
#ifdef WITH_GSSAPI
if (strncmp(method, "gssapi-with-mic", method_size) == 0) {
if (strcmp(method, "gssapi-with-mic") == 0) {
uint32_t n_oid;
ssh_string *oids;
ssh_string oid;
@@ -965,6 +887,7 @@ SSH_PACKET_CALLBACK(ssh_packet_userauth_info_response){
uint32_t nanswers;
uint32_t i;
ssh_string tmp;
int rc;
ssh_message msg = NULL;
@@ -992,7 +915,11 @@ SSH_PACKET_CALLBACK(ssh_packet_userauth_info_response){
msg->auth_request.username = NULL;
#endif
buffer_get_u32(packet, &nanswers);
rc = ssh_buffer_unpack(packet, "d", &nanswers);
if (rc != SSH_OK) {
ssh_set_error_invalid(session);
goto error;
}
if (session->kbdint == NULL) {
SSH_LOG(SSH_LOG_PROTOCOL, "Warning: Got a keyboard-interactive "
@@ -1004,9 +931,17 @@ 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,
@@ -1024,7 +959,8 @@ SSH_PACKET_CALLBACK(ssh_packet_userauth_info_response){
" mismatch: p=%u a=%u", session->kbdint->nprompts, nanswers);
}
session->kbdint->nanswers = nanswers;
session->kbdint->answers = malloc(nanswers * sizeof(char *));
session->kbdint->answers = calloc(1, nanswers * sizeof(char *));
if (session->kbdint->answers == NULL) {
session->kbdint->nanswers = 0;
ssh_set_error_oom(session);
@@ -1033,7 +969,6 @@ 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);
@@ -1070,9 +1005,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 sender, window, packet_size, originator_port, destination_port;
uint32_t originator_port, destination_port;
int rc;
(void)type;
(void)user;
@@ -1083,30 +1018,18 @@ SSH_PACKET_CALLBACK(ssh_packet_channel_open){
}
msg->type = SSH_REQUEST_CHANNEL_OPEN;
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;
rc = ssh_buffer_unpack(packet, "s", &type_c);
if (rc != SSH_OK){
goto error;
}
SSH_LOG(SSH_LOG_PACKET,
"Clients wants to open a %s channel", type_c);
ssh_string_free(type_s);
type_s=NULL;
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);
ssh_buffer_unpack(packet,"ddd",
&msg->channel_request_open.sender,
&msg->channel_request_open.window,
&msg->channel_request_open.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)");
@@ -1120,96 +1043,46 @@ SSH_PACKET_CALLBACK(ssh_packet_channel_open){
}
if (strcmp(type_c,"direct-tcpip") == 0) {
destination = buffer_get_ssh_string(packet);
if (destination == NULL) {
ssh_set_error_oom(session);
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 = 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) {
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);
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;
msg->channel_request_open.type = SSH_CHANNEL_FORWARDED_TCPIP;
goto end;
}
if (strcmp(type_c,"x11") == 0) {
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);
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;
msg->channel_request_open.type = SSH_CHANNEL_X11;
goto end;
}
@@ -1221,8 +1094,6 @@ 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);
@@ -1247,29 +1118,17 @@ 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 = 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) {
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);
return SSH_ERROR;
}
@@ -1326,6 +1185,7 @@ 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) {
@@ -1342,37 +1202,18 @@ 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) {
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);
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
);
msg->channel_request.type = SSH_CHANNEL_REQUEST_PTY;
msg->channel_request.TERM = term_c;
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);
if (rc != SSH_OK) {
goto error;
}
goto end;
@@ -1380,39 +1221,24 @@ 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;
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);
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;
}
goto end;
}
if (strcmp(request, "subsystem") == 0) {
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);
rc = ssh_buffer_unpack(packet, "s",
&msg->channel_request.subsystem);
msg->channel_request.type = SSH_CHANNEL_REQUEST_SUBSYSTEM;
msg->channel_request.subsystem = subsys_c;
if (rc != SSH_OK){
goto error;
}
goto end;
}
@@ -1422,84 +1248,37 @@ int ssh_message_handle_channel_request(ssh_session session, ssh_channel channel,
}
if (strcmp(request, "exec") == 0) {
ssh_string cmd = NULL;
cmd = buffer_get_ssh_string(packet);
if (cmd == NULL) {
ssh_set_error_oom(session);
goto error;
}
rc = ssh_buffer_unpack(packet, "s",
&msg->channel_request.command);
msg->channel_request.type = SSH_CHANNEL_REQUEST_EXEC;
msg->channel_request.command = ssh_string_to_char(cmd);
ssh_string_free(cmd);
if (msg->channel_request.command == NULL) {
if (rc != SSH_OK) {
goto error;
}
goto end;
}
if (strcmp(request, "env") == 0) {
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;
}
rc = ssh_buffer_unpack(packet, "ss",
&msg->channel_request.var_name,
&msg->channel_request.var_value);
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);
if (rc != SSH_OK) {
goto error;
}
ssh_string_free(name);
ssh_string_free(value);
goto end;
}
if (strcmp(request, "x11-req") == 0) {
ssh_string auth_protocol = NULL;
ssh_string auth_cookie = NULL;
uint32_t screen_number;
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;
}
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);
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);
if (rc != SSH_OK) {
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;
}
@@ -1517,6 +1296,7 @@ error:
int ssh_message_channel_request_reply_success(ssh_message msg) {
uint32_t channel;
int rc;
if (msg == NULL) {
return SSH_ERROR;
@@ -1528,10 +1308,12 @@ int ssh_message_channel_request_reply_success(ssh_message msg) {
SSH_LOG(SSH_LOG_PACKET,
"Sending a channel_request success to channel %d", channel);
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) {
rc = ssh_buffer_pack(msg->session->out_buffer,
"bd",
SSH2_MSG_CHANNEL_SUCCESS,
channel);
if (rc != SSH_OK){
ssh_set_error_oom(msg->session);
return SSH_ERROR;
}
@@ -1547,77 +1329,74 @@ 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;
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");
r = ssh_buffer_unpack(packet, "sb",
&request,
&want_reply);
if (r != SSH_OK){
goto error;
}
msg = ssh_message_new(session);
if (msg == NULL) {
ssh_string_free_char(request);
return SSH_PACKET_NOT_USED;
ssh_set_error_oom(session);
goto error;
}
msg->type = SSH_REQUEST_GLOBAL;
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);
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;
}
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, bind_addr, 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);
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, bind_addr, bind_port);
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);
session->common.callbacks->global_request_function(session, msg, session->common.callbacks->userdata);
} else {
ssh_message_reply_default(msg);
SAFE_FREE(request);
ssh_message_queue(session, msg);
return rc;
}
} 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);
} 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;
}
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, bind_addr, 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);
if(ssh_callbacks_exists(session->common.callbacks, global_request_function)) {
session->common.callbacks->global_request_function(session, msg, session->common.callbacks->userdata);
} else {
ssh_message_reply_default(msg);
SAFE_FREE(request);
ssh_message_queue(session, msg);
return rc;
}
} else {
SSH_LOG(SSH_LOG_PROTOCOL, "UNKNOWN SSH_MSG_GLOBAL_REQUEST %s %d", request, want_reply);
@@ -1626,9 +1405,12 @@ 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,9 +33,10 @@
#include <netinet/in.h>
#include <arpa/inet.h>
#ifndef HAVE_CLOCK_GETTIME
#ifdef HAVE_SYS_TIME_H
#include <sys/time.h>
#endif /* HAVE_CLOCK_GETTIME */
#endif /* HAVE_SYS_TIME_H */
#endif /* _WIN32 */
#include <limits.h>
@@ -289,23 +290,6 @@ 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;
@@ -862,7 +846,7 @@ int ssh_analyze_banner(ssh_session session, int server, int *ssh1, int *ssh2) {
openssh = strstr(banner, "OpenSSH");
if (openssh != NULL) {
int major, minor;
unsigned int major, minor;
/*
* The banner is typical:
@@ -870,8 +854,22 @@ int ssh_analyze_banner(ssh_session session, int server, int *ssh1, int *ssh2) {
* 012345678901234567890
*/
if (strlen(openssh) > 9) {
major = strtol(openssh + 8, (char **) NULL, 10);
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;
}
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)",
@@ -1030,6 +1028,27 @@ 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,12 +93,6 @@ 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;
@@ -136,7 +130,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) {
@@ -338,7 +332,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-dsa,ecdh-sha2-nistp256"
* "ssh-rsa,ssh-dss,ecdh-sha2-nistp256"
*
* - SSH_OPTIONS_COMPRESSION_C_S:
* Set the compression to use for client to server
@@ -716,6 +710,26 @@ 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') {
@@ -1287,25 +1301,6 @@ 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) {
@@ -1331,8 +1326,12 @@ static int ssh_bind_set_key(ssh_bind sshbind, char **key_loc,
* following:
*
* - SSH_BIND_OPTIONS_HOSTKEY:
* Set the server public key type: ssh-rsa or ssh-dss
* (const char *).
* 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 *).
*
* - SSH_BIND_OPTIONS_BINDADDR:
* Set the IP address to bind (const char *).
@@ -1351,10 +1350,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_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_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_BIND_OPTIONS_LOG_VERBOSITY_STR:
* Set the session logging verbosity via a
@@ -1400,8 +1399,61 @@ int ssh_bind_options_set(ssh_bind sshbind, enum ssh_bind_options_e type,
ssh_set_error_invalid(sshbind);
return -1;
} else {
if (ssh_bind_options_set_algo(sshbind, SSH_HOSTKEYS, value) < 0)
return -1;
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;
}
break;
case SSH_BIND_OPTIONS_BINDADDR:

View File

@@ -48,8 +48,6 @@
#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
@@ -129,6 +127,776 @@ 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. */
@@ -146,15 +914,20 @@ 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);
int current_macsize = session->current_crypto ? MACSIZE : 0;
unsigned char mac[30] = {0};
unsigned char mac[DIGEST_MAX_LEN] = {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;
@@ -177,7 +950,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 = buffer_reinit(session->in_buffer);
rc = ssh_buffer_reinit(session->in_buffer);
if (rc < 0) {
goto error;
}
@@ -192,7 +965,7 @@ int ssh_packet_socket_callback(const void *data, size_t receivedlen, void *user)
processed += blocksize;
len = packet_decrypt_len(session, buffer);
rc = buffer_add_data(session->in_buffer, buffer, blocksize);
rc = ssh_buffer_add_data(session->in_buffer, buffer, blocksize);
if (rc < 0) {
goto error;
}
@@ -237,7 +1010,7 @@ int ssh_packet_socket_callback(const void *data, size_t receivedlen, void *user)
to_be_read - current_macsize);
#endif
rc = buffer_add_data(session->in_buffer,
rc = ssh_buffer_add_data(session->in_buffer,
packet,
to_be_read - current_macsize);
if (rc < 0) {
@@ -267,9 +1040,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, MACSIZE);
memcpy(mac, packet, current_macsize);
rc = packet_hmac_verify(session, session->in_buffer, mac);
rc = packet_hmac_verify(session, session->in_buffer, mac, session->current_crypto->in_hmac);
if (rc < 0) {
ssh_set_error(session, SSH_FATAL, "HMAC error");
goto error;
@@ -311,6 +1084,10 @@ 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
@@ -322,8 +1099,21 @@ 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);
/* Execute callbacks */
ssh_packet_process(session, session->in_packet.type);
/* 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;
}
session->packet_state = PACKET_STATE_INIT;
if (processed < receivedlen) {
/* Handle a potential packet left in socket buffer */
@@ -339,7 +1129,7 @@ int ssh_packet_socket_callback(const void *data, size_t receivedlen, void *user)
return processed;
case PACKET_STATE_PROCESSING:
SSH_LOG(SSH_LOG_RARE, "Nested packet processing. Delaying.");
SSH_LOG(SSH_LOG_PACKET, "Nested packet processing. Delaying.");
return 0;
}
@@ -436,34 +1226,42 @@ 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 r;
int rc;
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);
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);
return r;
return rc;
}
/** @internal
* @brief handles a SSH_MSG_UNIMPLEMENTED packet
*/
SSH_PACKET_CALLBACK(ssh_packet_unimplemented){
uint32_t seq;
uint32_t seq;
int rc;
(void)session; /* unused */
(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;
(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;
}
/** @internal
@@ -502,6 +1300,8 @@ 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 };
@@ -540,7 +1340,7 @@ static int packet_send2(ssh_session session) {
if (rc < 0) {
goto error;
}
rc = buffer_add_data(session->out_buffer, padstring, padding);
rc = ssh_buffer_add_data(session->out_buffer, padstring, padding);
if (rc < 0) {
goto error;
}
@@ -554,18 +1354,23 @@ 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) {
if (buffer_add_data(session->out_buffer, hmac, 20) < 0) {
rc = ssh_buffer_add_data(session->out_buffer, hmac, hmac_digest_len(hmac_type));
if (rc < 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 (buffer_reinit(session->out_buffer) < 0) {
if (ssh_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 (buffer_reinit(session->in_buffer) < 0) {
if (ssh_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 (buffer_add_data(session->in_buffer,packet,to_be_read) < 0) {
if (ssh_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_RARE, "Nested packet processing. Delaying.");
SSH_LOG(SSH_LOG_PACKET, "Nested packet processing. Delaying.");
return 0;
}
@@ -322,7 +322,7 @@ int packet_send1(ssh_session session) {
session->send_seq++;
if (buffer_reinit(session->out_buffer) < 0) {
if (ssh_buffer_reinit(session->out_buffer) < 0) {
rc = SSH_ERROR;
}
error:

View File

@@ -24,6 +24,9 @@
#include "config.h"
#include <stdlib.h>
#ifdef HAVE_ARPA_INET_H
#include <arpa/inet.h>
#endif
#include "libssh/priv.h"
#include "libssh/buffer.h"

View File

@@ -77,11 +77,10 @@ int packet_decrypt(ssh_session session, void *data,uint32_t len) {
SAFE_FREE(out);
return -1;
}
crypto->cbc_decrypt(crypto,data,out,len);
crypto->decrypt(crypto,data,out,len);
memcpy(data,out,len);
memset(out,0,len);
BURN_BUFFER(out, len);
SAFE_FREE(out);
return 0;
}
@@ -92,6 +91,7 @@ unsigned char *packet_encrypt(ssh_session session, void *data, uint32_t len) {
char *out = NULL;
unsigned int finallen;
uint32_t seq;
enum ssh_hmac_e type;
assert(len);
@@ -107,6 +107,7 @@ unsigned char *packet_encrypt(ssh_session session, void *data, uint32_t len) {
return NULL;
}
type = session->current_crypto->out_hmac;
seq = ntohl(session->send_seq);
crypto = session->current_crypto->out_cipher;
@@ -117,7 +118,7 @@ unsigned char *packet_encrypt(ssh_session session, void *data, uint32_t len) {
}
if (session->version == 2) {
ctx = hmac_init(session->current_crypto->encryptMAC,20,SSH_HMAC_SHA1);
ctx = hmac_init(session->current_crypto->encryptMAC, hmac_digest_len(type), type);
if (ctx == NULL) {
SAFE_FREE(out);
return NULL;
@@ -126,18 +127,18 @@ unsigned char *packet_encrypt(ssh_session session, void *data, uint32_t len) {
hmac_update(ctx,data,len);
hmac_final(ctx,session->current_crypto->hmacbuf,&finallen);
#ifdef DEBUG_CRYPTO
ssh_print_hexa("mac: ",data,len);
if (finallen != 20) {
ssh_print_hexa("mac: ",data,hmac_digest_len(type));
if (finallen != hmac_digest_len(type)) {
printf("Final len is %d\n",finallen);
}
ssh_print_hexa("Packet hmac", session->current_crypto->hmacbuf, 20);
ssh_print_hexa("Packet hmac", session->current_crypto->hmacbuf, hmac_digest_len(type));
#endif
}
crypto->cbc_encrypt(crypto, data, out, len);
crypto->encrypt(crypto, data, out, len);
memcpy(data, out, len);
memset(out, 0, len);
BURN_BUFFER(out, len);
SAFE_FREE(out);
if (session->version == 2) {
@@ -160,13 +161,13 @@ unsigned char *packet_encrypt(ssh_session session, void *data, uint32_t len) {
* occurred.
*/
int packet_hmac_verify(ssh_session session, ssh_buffer buffer,
unsigned char *mac) {
unsigned char hmacbuf[EVP_MAX_MD_SIZE] = {0};
unsigned char *mac, enum ssh_hmac_e type) {
unsigned char hmacbuf[DIGEST_MAX_LEN] = {0};
HMACCTX ctx;
unsigned int len;
uint32_t seq;
ctx = hmac_init(session->current_crypto->decryptMAC, 20, SSH_HMAC_SHA1);
ctx = hmac_init(session->current_crypto->decryptMAC, hmac_digest_len(type), type);
if (ctx == NULL) {
return -1;
}

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