From 02d4c2ac3daa0f36264392972709ccd7676ab3e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dag-Erling=20Sm=C3=B8rgrav?= Date: Thu, 30 Jan 2014 10:56:49 +0000 Subject: [PATCH] Vendor import of OpenSSH 6.5p1. --- ChangeLog | 3103 ++++++++++-------------------- Makefile.in | 31 +- PROTOCOL | 27 +- PROTOCOL.chacha20poly1305 | 105 + PROTOCOL.key | 68 + README | 4 +- aclocal.m4 | 86 +- addrmatch.c | 6 +- atomicio.c | 4 + auth-krb5.c | 3 +- auth-options.c | 18 +- auth-pam.c | 4 +- auth2-hostbased.c | 8 +- auth2-pubkey.c | 8 +- authfd.c | 63 +- authfile.c | 382 +++- authfile.h | 5 +- blocks.c | 248 +++ bufaux.c | 76 +- bufbn.c | 3 +- buffer.c | 3 +- buffer.h | 6 +- canohost.c | 17 +- chacha.c | 219 +++ chacha.h | 35 + channels.c | 25 +- cipher-chachapoly.c | 114 ++ cipher-chachapoly.h | 41 + cipher.c | 81 +- cipher.h | 12 +- clientloop.c | 10 +- compat.c | 61 +- compat.h | 3 +- config.h.in | 74 +- configure | 1008 +++++++++- configure.ac | 308 ++- contrib/caldera/openssh.spec | 4 +- contrib/cygwin/ssh-host-config | 52 +- contrib/redhat/openssh.spec | 2 +- contrib/suse/openssh.spec | 2 +- crypto_api.h | 44 + defines.h | 26 +- dh.c | 53 +- dh.h | 3 +- digest.c | 149 ++ digest.h | 55 + ed25519.c | 144 ++ fe25519.c | 337 ++++ fe25519.h | 70 + ge25519.c | 321 ++++ ge25519.h | 43 + ge25519_base.data | 858 +++++++++ gss-serv-krb5.c | 6 + hash.c | 76 + hostfile.c | 3 +- kex.c | 143 +- kex.h | 31 +- kexc25519.c | 122 ++ kexc25519c.c | 129 ++ kexc25519s.c | 126 ++ kexdh.c | 17 +- kexdhc.c | 4 +- kexdhs.c | 8 +- kexecdh.c | 18 +- kexecdhc.c | 6 +- kexecdhs.c | 11 +- kexgex.c | 24 +- kexgexc.c | 8 +- kexgexs.c | 6 +- key.c | 510 ++++- key.h | 19 +- loginrec.c | 11 +- mac.c | 12 +- mac.h | 4 +- match.c | 6 +- misc.c | 10 +- misc.h | 4 +- moduli.c | 106 +- monitor.c | 3 +- monitor_mm.c | 29 +- monitor_mm.h | 4 +- myproposal.h | 21 +- openbsd-compat/Makefile.in | 6 +- openbsd-compat/arc4random.c | 294 +++ openbsd-compat/bcrypt_pbkdf.c | 170 ++ openbsd-compat/blf.h | 88 + openbsd-compat/blowfish.c | 694 +++++++ openbsd-compat/bsd-arc4random.c | 150 -- openbsd-compat/bsd-cygwin_util.h | 8 +- openbsd-compat/bsd-misc.c | 1 + openbsd-compat/bsd-poll.c | 7 +- openbsd-compat/bsd-setres_id.c | 3 +- openbsd-compat/bsd-snprintf.c | 46 +- openbsd-compat/bsd-statvfs.c | 55 +- openbsd-compat/bsd-statvfs.h | 11 +- openbsd-compat/chacha_private.h | 222 +++ openbsd-compat/openbsd-compat.h | 16 +- openbsd-compat/openssl-compat.c | 30 +- openbsd-compat/openssl-compat.h | 18 +- openbsd-compat/setproctitle.c | 9 +- packet.c | 39 +- pathnames.h | 4 +- pkcs11.h | 18 +- platform.c | 16 +- platform.h | 3 +- poly1305.c | 160 ++ poly1305.h | 22 + progressmeter.c | 8 +- readconf.c | 578 ++++-- readconf.h | 34 +- regress/Makefile | 20 +- regress/agent-ptrace.sh | 12 +- regress/agent.sh | 34 +- regress/cert-hostkey.sh | 60 +- regress/cert-userkey.sh | 31 +- regress/cipher-speed.sh | 23 +- regress/forward-control.sh | 2 +- regress/integrity.sh | 24 +- regress/kextype.sh | 14 +- regress/keytype.sh | 16 +- regress/krl.sh | 5 +- regress/modpipe.c | 6 +- regress/rekey.sh | 63 +- regress/scp-ssh-wrapper.sh | 6 +- regress/scp.sh | 1 + regress/setuid-allowed.c | 56 + regress/sftp-perm.sh | 269 +++ regress/test-exec.sh | 21 +- regress/try-ciphers.sh | 31 +- roaming_client.c | 20 +- roaming_common.c | 18 +- sandbox-capsicum.c | 120 ++ sandbox-darwin.c | 2 +- sandbox-null.c | 2 +- sandbox-rlimit.c | 4 +- sandbox-seccomp-filter.c | 2 +- sandbox-systrace.c | 2 +- sc25519.c | 308 +++ sc25519.h | 80 + schnorr.c | 57 +- schnorr.h | 8 +- scp.0 | 7 +- scp.1 | 14 +- scp.c | 6 +- servconf.c | 84 +- servconf.h | 6 +- serverloop.c | 5 +- session.c | 61 +- session.h | 3 +- sftp-client.c | 193 +- sftp-client.h | 16 +- sftp-common.c | 8 +- sftp-glob.c | 3 +- sftp-server.0 | 24 +- sftp-server.8 | 38 +- sftp-server.c | 460 +++-- sftp.0 | 34 +- sftp.1 | 43 +- sftp.c | 242 ++- smult_curve25519_ref.c | 265 +++ ssh-add.0 | 16 +- ssh-add.1 | 9 +- ssh-add.c | 16 +- ssh-agent.0 | 33 +- ssh-agent.1 | 11 +- ssh-agent.c | 134 +- ssh-dss.c | 58 +- ssh-ecdsa.c | 50 +- ssh-ed25519.c | 143 ++ ssh-keygen.0 | 86 +- ssh-keygen.1 | 57 +- ssh-keygen.c | 93 +- ssh-keyscan.0 | 10 +- ssh-keyscan.1 | 8 +- ssh-keyscan.c | 17 +- ssh-keysign.0 | 4 +- ssh-keysign.8 | 6 +- ssh-keysign.c | 8 +- ssh-pkcs11-helper.c | 5 +- ssh-pkcs11.c | 136 +- ssh-rsa.c | 106 +- ssh-sandbox.h | 3 +- ssh.0 | 65 +- ssh.1 | 55 +- ssh.c | 301 ++- ssh_config | 2 +- ssh_config.0 | 131 +- ssh_config.5 | 176 +- sshconnect.c | 248 ++- sshconnect.h | 8 +- sshconnect1.c | 5 +- sshconnect2.c | 36 +- sshd.0 | 37 +- sshd.8 | 17 +- sshd.c | 56 +- sshd_config | 9 +- sshd_config.0 | 66 +- sshd_config.5 | 49 +- uidswap.c | 7 +- verify.c | 49 + version.h | 4 +- xmalloc.c | 12 +- 202 files changed, 13383 insertions(+), 4407 deletions(-) create mode 100644 PROTOCOL.chacha20poly1305 create mode 100644 PROTOCOL.key create mode 100644 blocks.c create mode 100644 chacha.c create mode 100644 chacha.h create mode 100644 cipher-chachapoly.c create mode 100644 cipher-chachapoly.h create mode 100644 crypto_api.h create mode 100644 digest.c create mode 100644 digest.h create mode 100644 ed25519.c create mode 100644 fe25519.c create mode 100644 fe25519.h create mode 100644 ge25519.c create mode 100644 ge25519.h create mode 100644 ge25519_base.data create mode 100644 hash.c create mode 100644 kexc25519.c create mode 100644 kexc25519c.c create mode 100644 kexc25519s.c create mode 100644 openbsd-compat/arc4random.c create mode 100644 openbsd-compat/bcrypt_pbkdf.c create mode 100644 openbsd-compat/blf.h create mode 100644 openbsd-compat/blowfish.c delete mode 100644 openbsd-compat/bsd-arc4random.c create mode 100644 openbsd-compat/chacha_private.h create mode 100644 poly1305.c create mode 100644 poly1305.h create mode 100644 regress/setuid-allowed.c create mode 100644 regress/sftp-perm.sh create mode 100644 sandbox-capsicum.c create mode 100644 sc25519.c create mode 100644 sc25519.h create mode 100644 smult_curve25519_ref.c create mode 100644 ssh-ed25519.c create mode 100644 verify.c diff --git a/ChangeLog b/ChangeLog index 6175764f5bfd..c0dab651bfff 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,25 +1,1042 @@ -20131108 +20140130 + - (djm) [configure.ac] Only check for width-specified integer types + in headers that actually exist. patch from Tom G. Christensen; + ok dtucker@ + - (djm) [configure.ac atomicio.c] Kludge around NetBSD offering + different symbols for 'read' when various compiler flags are + in use, causing atomicio.c comparisons against it to break and + read/write operations to hang; ok dtucker + - (djm) Release openssh-6.5p1 + +20140129 + - (djm) [configure.ac] Fix broken shell test '==' vs '='; patch from + Tom G. Christensen + +20140128 + - (djm) [configure.ac] Search for inet_ntop in libnsl and libresovl; + ok dtucker + - (djm) [sshd.c] Use kill(0, ...) instead of killpg(0, ...); the + latter being specified to have undefined behaviour in SUSv3; + ok dtucker + - (tim) [regress/agent.sh regress/agent-ptrace.sh] Assign $? to a variable + when used as an error message inside an if statement so we display the + correct into. agent.sh patch from Petr Lautrbach. + +20140127 + - (dtucker) [Makefile.in] Remove trailing backslash which some make + implementations (eg older Solaris) do not cope with. + +20140126 + - OpenBSD CVS Sync + - dtucker@cvs.openbsd.org 2014/01/25 10:12:50 + [cipher.c cipher.h kex.c kex.h kexgexc.c] + Add a special case for the DH group size for 3des-cbc, which has an + effective strength much lower than the key size. This causes problems + with some cryptlib implementations, which don't support group sizes larger + than 4k but also don't use the largest group size it does support as + specified in the RFC. Based on a patch from Petr Lautrbach at Redhat, + reduced by me with input from Markus. ok djm@ markus@ + - markus@cvs.openbsd.org 2014/01/25 20:35:37 + [kex.c] + dh_need needs to be set to max(seclen, blocksize, ivlen, mac_len) + ok dtucker@, noted by mancha + - (djm) [configure.ac sandbox-capsicum.c sandbox-rlimit.c] Disable + RLIMIT_NOFILE pseudo-sandbox on FreeBSD. In some configurations, + libc will attempt to open additional file descriptors for crypto + offload and crash if they cannot be opened. + - (djm) [configure.ac] correct AC_DEFINE for previous. + +20140125 + - (djm) [configure.ac] Fix detection of capsicum sandbox on FreeBSD + - (djm) [configure.ac] Do not attempt to use capsicum sandbox unless + sys/capability.h exists and cap_rights_limit is in libc. Fixes + build on FreeBSD9x which provides the header but not the libc + support. + - (djm) [configure.ac] autoconf sets finds to 'yes' not '1', so test + against the correct thing. + +20140124 + - (djm) [Makefile.in regress/scp-ssh-wrapper.sh regress/scp.sh] Make + the scp regress test actually test the built scp rather than the one + in $PATH. ok dtucker@ + +20140123 + - (tim) [session.c] Improve error reporting on set_id(). + - (dtucker) [configure.ac] NetBSD's (and FreeBSD's) strnvis is gratuitously + incompatible with OpenBSD's despite post-dating it by more than a decade. + Declare it as broken, and document FreeBSD's as the same. ok djm@ + +20140122 + - (djm) [openbsd-compat/setproctitle.c] Don't fail to compile if a + platform that is expected to use the reuse-argv style setproctitle + hack surprises us by providing a setproctitle in libc; ok dtucker + - (djm) [configure.ac] Unless specifically requested, only attempt + to build Position Independent Executables on gcc >= 4.x; ok dtucker + - (djm) [configure.ac aclocal.m4] More tests to detect fallout from + platform hardening options: include some long long int arithmatic + to detect missing support functions for -ftrapv in libgcc and + equivalents, actually test linking when -ftrapv is supplied and + set either both -pie/-fPIE or neither. feedback and ok dtucker@ + +20140121 + - (dtucker) [configure.ac] Make PIE a configure-time option which defaults + to on platforms where it's known to be reliably detected and off elsewhere. + Works around platforms such as FreeBSD 9.1 where it does not interop with + -ftrapv (it seems to work but fails when trying to link ssh). ok djm@ + - (dtucker) [aclocal.m4] Differentiate between compile-time and link-time + tests in the configure output. ok djm. + - (tim) [platform.c session.c] Fix bug affecting SVR5 platforms introduced + with sftp chroot support. Move set_id call after chroot. + - (djm) [aclocal.m4] Flesh out the code run in the OSSH_CHECK_CFLAG_COMPILE + and OSSH_CHECK_LDFLAG_LINK tests to give them a better chance of + detecting toolchain-related problems; ok dtucker + +20140120 + - (dtucker) [gss-serv-krb5.c] Fall back to krb5_cc_gen_new if the Kerberos + implementation does not have krb5_cc_new_unique, similar to what we do + in auth-krb5.c. + - (djm) [regress/cert-hostkey.sh] Fix regress failure on platforms that + skip one or more key types (e.g. RHEL/CentOS 6.5); ok dtucker@ - (djm) OpenBSD CVS Sync - - markus@cvs.openbsd.org 2013/11/06 16:52:11 - [monitor_wrap.c] - fix rekeying for AES-GCM modes; ok deraadt + - djm@cvs.openbsd.org 2014/01/20 00:08:48 + [digest.c] + memleak; found by Loganaden Velvindron @ AfriNIC; ok markus@ + +20140119 + - (dtucker) OpenBSD CVS Sync + - dtucker@cvs.openbsd.org 2014/01/17 06:23:24 + [sftp-server.c] + fix log message statvfs. ok djm + - dtucker@cvs.openbsd.org 2014/01/18 09:36:26 + [session.c] + explicitly define USE_PIPES to 1 to prevent redefinition warnings in + portable on platforms that use pipes for everything. From vinschen at + redhat. + - dtucker@cvs.openbsd.org 2014/01/19 04:17:29 + [canohost.c addrmatch.c] + Cast socklen_t when comparing to size_t and use socklen_t to iterate over + the ip options, both to prevent signed/unsigned comparison warnings. + Patch from vinschen at redhat via portable openssh, begrudging ok deraadt. + - djm@cvs.openbsd.org 2014/01/19 04:48:08 + [ssh_config.5] + fix inverted meaning of 'no' and 'yes' for CanonicalizeFallbackLocal + - dtucker@cvs.openbsd.org 2014/01/19 11:21:51 + [addrmatch.c] + Cast the sizeof to socklen_t so it'll work even if the supplied len is + negative. Suggested by and ok djm, ok deraadt. + +20140118 + - (dtucker) [uidswap.c] Prevent unused variable warnings on Cygwin. Patch + from vinschen at redhat.com + - (dtucker) [openbsd-compat/bsd-cygwin_util.h] Add missing function + declarations that stopped being included when we stopped including + from openbsd-compat/bsd-cygwin_util.h. Patch from vinschen at + redhat.com. + - (dtucker) [configure.ac] On Cygwin the getopt variables (like optargs, + optind) are defined in getopt.h already. Unfortunately they are defined as + "declspec(dllimport)" for historical reasons, because the GNU linker didn't + allow auto-import on PE/COFF targets way back when. The problem is the + dllexport attributes collide with the definitions in the various source + files in OpenSSH, which obviousy define the variables without + declspec(dllimport). The least intrusive way to get rid of these warnings + is to disable warnings for GCC compiler attributes when building on Cygwin. + Patch from vinschen at redhat.com. + - (dtucker) [sandbox-capsicum.c] Correct some error messages and make the + return value check for cap_enter() consistent with the other uses in + FreeBSD. From by Loganaden Velvindron @ AfriNIC via bz#2140. + +20140117 + - (dtucker) [aclocal.m4 configure.ac] Add some additional compiler/toolchain + hardening flags including -fstack-protector-strong. These default to on + if the toolchain supports them, but there is a configure-time knob + (--without-hardening) to disable them if necessary. ok djm@ + - (djm) [sftp-client.c] signed/unsigned comparison fix + - (dtucker) [loginrec.c] Cast to the types specfied in the format + specification to prevent warnings. + - (dtucker) [crypto_api.h] Wrap stdlib.h include inside #ifdef HAVE_STDINT_H. + - (dtucker) [poly1305.c] Wrap stdlib.h include inside #ifdef HAVE_STDINT_H. + - (dtucker) [blocks.c fe25519.c ge25519.c hash.c sc25519.c verify.c] Include + includes.h to pull in all of the compatibility stuff. + - (dtucker) [openbsd-compat/bcrypt_pbkdf.c] Wrap stdlib.h include inside + #ifdef HAVE_STDINT_H. + - (dtucker) [defines.h] Add typedefs for uintXX_t types for platforms that + don't have them. + - (dtucker) [configure.ac] Split AC_CHECK_FUNCS for OpenSSL functions into + separate lines and alphabetize for easier diffing of changes. + - (dtucker) OpenBSD CVS Sync + - djm@cvs.openbsd.org 2014/01/17 00:21:06 + [sftp-client.c] + signed/unsigned comparison warning fix; from portable (Id sync only) + - dtucker@cvs.openbsd.org 2014/01/17 05:26:41 + [digest.c] + remove unused includes. ok djm@ + - (djm) [Makefile.in configure.ac sandbox-capsicum.c sandbox-darwin.c] + [sandbox-null.c sandbox-rlimit.c sandbox-seccomp-filter.c] + [sandbox-systrace.c ssh-sandbox.h sshd.c] Support preauth sandboxing + using the Capsicum API introduced in FreeBSD 10. Patch by Dag-Erling + Smorgrav, updated by Loganaden Velvindron @ AfriNIC; ok dtucker@ + - (dtucker) [configure.ac digest.c openbsd-compat/openssl-compat.c + openbsd-compat/openssl-compat.h] Add compatibility layer for older + openssl versions. ok djm@ + - (dtucker) Fix typo in #ifndef. + - (dtucker) [configure.ac openbsd-compat/bsd-statvfs.c + openbsd-compat/bsd-statvfs.h] Implement enough of statvfs on top of statfs + to be useful (and for the regression tests to pass) on platforms that + have statfs and fstatfs. ok djm@ + - (dtucker) [openbsd-compat/bsd-statvfs.h] Only start including headers if we + need them to cut down on the name collisions. + - (dtucker) [configure.ac] Also look in inttypes.h for uintXX_t types. + - (dtucker) [configure.ac] Have --without-hardening not turn off + stack-protector since that has a separate flag that's been around a while. + - (dtucker) [readconf.c] Wrap paths.h inside an ifdef. Allows building on + Solaris. + - (dtucker) [defines.h] Move our definitions of uintXX_t types down to after + they're defined if we have to define them ourselves. Fixes builds on old + AIX. + +20140118 + - (djm) OpenBSD CVS Sync + - djm@cvs.openbsd.org 2014/01/16 07:31:09 + [sftp-client.c] + needless and incorrect cast to size_t can break resumption of + large download; patch from tobias@ + - djm@cvs.openbsd.org 2014/01/16 07:32:00 + [version.h] + openssh-6.5 + - (djm) [contrib/caldera/openssh.spec contrib/redhat/openssh.spec] + [contrib/suse/openssh.spec] Crank RPM spec version numbers. + - (djm) [README] update release notes URL. + +20140112 + - (djm) OpenBSD CVS Sync + - djm@cvs.openbsd.org 2014/01/10 05:59:19 + [sshd_config] + the /etc/ssh/ssh_host_ed25519_key is loaded by default too + - djm@cvs.openbsd.org 2014/01/12 08:13:13 + [bufaux.c buffer.h kex.c kex.h kexc25519.c kexc25519c.c kexc25519s.c] + [kexdhc.c kexdhs.c kexecdhc.c kexecdhs.c kexgexc.c kexgexs.c] + avoid use of OpenSSL BIGNUM type and functions for KEX with + Curve25519 by adding a buffer_put_bignum2_from_string() that stores + a string using the bignum encoding rules. Will make it easier to + build a reduced-feature OpenSSH without OpenSSL in the future; + ok markus@ + +20140110 + - (djm) OpenBSD CVS Sync + - tedu@cvs.openbsd.org 2014/01/04 17:50:55 + [mac.c monitor_mm.c monitor_mm.h xmalloc.c] + use standard types and formats for size_t like variables. ok dtucker + - guenther@cvs.openbsd.org 2014/01/09 03:26:00 + [sftp-common.c] + When formating the time for "ls -l"-style output, show dates in the future + with the year, and rearrange a comparison to avoid a potentional signed + arithmetic overflow that would give the wrong result. + ok djm@ + - djm@cvs.openbsd.org 2014/01/09 23:20:00 + [digest.c digest.h hostfile.c kex.c kex.h kexc25519.c kexc25519c.c] + [kexc25519s.c kexdh.c kexecdh.c kexecdhc.c kexecdhs.c kexgex.c kexgexc.c] + [kexgexs.c key.c key.h roaming_client.c roaming_common.c schnorr.c] + [schnorr.h ssh-dss.c ssh-ecdsa.c ssh-rsa.c sshconnect2.c] + Introduce digest API and use it to perform all hashing operations + rather than calling OpenSSL EVP_Digest* directly. Will make it easier + to build a reduced-feature OpenSSH without OpenSSL in future; + feedback, ok markus@ + - djm@cvs.openbsd.org 2014/01/09 23:26:48 + [sshconnect.c sshd.c] + ban clients/servers that suffer from SSH_BUG_DERIVEKEY, they are ancient, + deranged and might make some attacks on KEX easier; ok markus@ + +20140108 + - (djm) [regress/.cvsignore] Ignore regress test droppings; ok dtucker@ + +20131231 + - (djm) OpenBSD CVS Sync + - djm@cvs.openbsd.org 2013/12/30 23:52:28 + [auth2-hostbased.c auth2-pubkey.c compat.c compat.h ssh-rsa.c] + [sshconnect.c sshconnect2.c sshd.c] + refuse RSA keys from old proprietary clients/servers that use the + obsolete RSA+MD5 signature scheme. it will still be possible to connect + with these clients/servers but only DSA keys will be accepted, and we'll + deprecate them entirely in a future release. ok markus@ + +20131229 + - (djm) [loginrec.c] Check for username truncation when looking up lastlog + entries + - (djm) [regress/Makefile] Add some generated files for cleaning + - (djm) OpenBSD CVS Sync + - djm@cvs.openbsd.org 2013/12/19 00:10:30 + [ssh-add.c] + skip requesting smartcard PIN when removing keys from agent; bz#2187 + patch from jay AT slushpupie.com; ok dtucker + - dtucker@cvs.openbsd.org 2013/12/19 00:19:12 + [serverloop.c] + Cast client_alive_interval to u_int64_t before assinging to + max_time_milliseconds to avoid potential integer overflow in the timeout. + bz#2170, patch from Loganaden Velvindron, ok djm@ + - djm@cvs.openbsd.org 2013/12/19 00:27:57 + [auth-options.c] + simplify freeing of source-address certificate restriction + - djm@cvs.openbsd.org 2013/12/19 01:04:36 + [channels.c] + bz#2147: fix multiple remote forwardings with dynamically assigned + listen ports. In the s->c message to open the channel we were sending + zero (the magic number to request a dynamic port) instead of the actual + listen port. The client therefore had no way of discriminating between + them. + + Diagnosis and fix by ronf AT timeheart.net + - djm@cvs.openbsd.org 2013/12/19 01:19:41 + [ssh-agent.c] + bz#2186: don't crash (NULL deref) when deleting PKCS#11 keys from an agent + that has a mix of normal and PKCS#11 keys; fix from jay AT slushpupie.com; + ok dtucker + - djm@cvs.openbsd.org 2013/12/19 22:57:13 + [poly1305.c poly1305.h] + use full name for author, with his permission + - tedu@cvs.openbsd.org 2013/12/21 07:10:47 + [ssh-keygen.1] + small typo + - djm@cvs.openbsd.org 2013/12/27 22:30:17 + [ssh-dss.c ssh-ecdsa.c ssh-rsa.c] + make the original RSA and DSA signing/verification code look more like + the ECDSA/Ed25519 ones: use key_type_plain() when checking the key type + rather than tediously listing all variants, use __func__ for debug/ + error messages + - djm@cvs.openbsd.org 2013/12/27 22:37:18 + [ssh-rsa.c] + correct comment + - djm@cvs.openbsd.org 2013/12/29 02:28:10 + [key.c] + allow ed25519 keys to appear as certificate authorities + - djm@cvs.openbsd.org 2013/12/29 02:37:04 + [key.c] + correct comment for key_to_certified() + - djm@cvs.openbsd.org 2013/12/29 02:49:52 + [key.c] + correct comment for key_drop_cert() + - djm@cvs.openbsd.org 2013/12/29 04:20:04 + [key.c] + to make sure we don't omit any key types as valid CA keys again, + factor the valid key type check into a key_type_is_valid_ca() + function + - djm@cvs.openbsd.org 2013/12/29 04:29:25 + [authfd.c] + allow deletion of ed25519 keys from the agent + - djm@cvs.openbsd.org 2013/12/29 04:35:50 + [authfile.c] + don't refuse to load Ed25519 certificates + - djm@cvs.openbsd.org 2013/12/29 05:42:16 + [ssh.c] + don't forget to load Ed25519 certs too + - djm@cvs.openbsd.org 2013/12/29 05:57:02 + [sshconnect.c] + when showing other hostkeys, don't forget Ed25519 keys + +20131221 + - (dtucker) [regress/keytype.sh] Actually test ecdsa key types. + +20131219 + - (dtucker) [configure.ac] bz#2178: Don't try to use BSM on Solaris versions + greater than 11 either rather than just 11. Patch from Tomas Kuthan. + - (dtucker) [auth-pam.c] bz#2163: check return value from pam_get_item(). + Patch from Loganaden Velvindron. + +20131218 + - (djm) OpenBSD CVS Sync + - djm@cvs.openbsd.org 2013/12/07 08:08:26 + [ssh-keygen.1] + document -a and -o wrt new key format + - naddy@cvs.openbsd.org 2013/12/07 11:58:46 + [ssh-add.1 ssh-agent.1 ssh-keygen.1 ssh-keyscan.1 ssh-keysign.8 ssh.1] + [ssh_config.5 sshd.8 sshd_config.5] + add missing mentions of ed25519; ok djm@ + - dtucker@cvs.openbsd.org 2013/12/08 09:53:27 + [sshd_config.5] + Use a literal for the default value of KEXAlgorithms. ok deraadt jmc + - markus@cvs.openbsd.org 2013/12/09 11:03:45 + [blocks.c ed25519.c fe25519.c fe25519.h ge25519.c ge25519.h] + [ge25519_base.data hash.c sc25519.c sc25519.h verify.c] + Add Authors for the public domain ed25519/nacl code. + see also http://nacl.cr.yp.to/features.html + All of the NaCl software is in the public domain. + and http://ed25519.cr.yp.to/software.html + The Ed25519 software is in the public domain. + - markus@cvs.openbsd.org 2013/12/09 11:08:17 + [crypto_api.h] + remove unused defines + - pascal@cvs.openbsd.org 2013/12/15 18:17:26 + [ssh-add.c] + Make ssh-add also add .ssh/id_ed25519; fixes lie in manual page. + ok markus@ + - djm@cvs.openbsd.org 2013/12/15 21:42:35 + [cipher-chachapoly.c] + add some comments and constify a constant + - markus@cvs.openbsd.org 2013/12/17 10:36:38 + [crypto_api.h] + I've assempled the header file by cut&pasting from generated headers + and the source files. + +20131208 + - (djm) [openbsd-compat/bsd-setres_id.c] Missing header; from Corinna + Vinschen + - (djm) [Makefile.in regress/Makefile regress/agent-ptrace.sh] + [regress/setuid-allowed.c] Check that ssh-agent is not on a no-setuid + filesystem before running agent-ptrace.sh; ok dtucker + +20131207 + - (djm) OpenBSD CVS Sync + - djm@cvs.openbsd.org 2013/12/05 22:59:45 + [sftp-client.c] + fix memory leak in error path in do_readdir(); pointed out by + Loganaden Velvindron @ AfriNIC in bz#2163 + - djm@cvs.openbsd.org 2013/12/06 03:40:51 + [ssh-keygen.c] + remove duplicated character ('g') in getopt() string; + document the (few) remaining option characters so we don't have to + rummage next time. + - markus@cvs.openbsd.org 2013/12/06 13:30:08 + [authfd.c key.c key.h ssh-agent.c] + move private key (de)serialization to key.c; ok djm + - markus@cvs.openbsd.org 2013/12/06 13:34:54 + [authfile.c authfile.h cipher.c cipher.h key.c packet.c ssh-agent.c] + [ssh-keygen.c PROTOCOL.key] new private key format, bcrypt as KDF by + default; details in PROTOCOL.key; feedback and lots help from djm; + ok djm@ + - markus@cvs.openbsd.org 2013/12/06 13:39:49 + [authfd.c authfile.c key.c key.h myproposal.h pathnames.h readconf.c] + [servconf.c ssh-agent.c ssh-keygen.c ssh-keyscan.1 ssh-keyscan.c] + [ssh-keysign.c ssh.c ssh_config.5 sshd.8 sshd.c verify.c ssh-ed25519.c] + [sc25519.h sc25519.c hash.c ge25519_base.data ge25519.h ge25519.c] + [fe25519.h fe25519.c ed25519.c crypto_api.h blocks.c] + support ed25519 keys (hostkeys and user identities) using the public + domain ed25519 reference code from SUPERCOP, see + http://ed25519.cr.yp.to/software.html + feedback, help & ok djm@ + - jmc@cvs.openbsd.org 2013/12/06 15:29:07 + [sshd.8] + missing comma; + - djm@cvs.openbsd.org 2013/12/07 00:19:15 + [key.c] + set k->cert = NULL after freeing it + - markus@cvs.openbsd.org 2013/12/06 13:52:46 + [regress/Makefile regress/agent.sh regress/cert-hostkey.sh] + [regress/cert-userkey.sh regress/keytype.sh] + test ed25519 support; from djm@ + - (djm) [blocks.c ed25519.c fe25519.c fe25519.h ge25519.c ge25519.h] + [ge25519_base.data hash.c sc25519.c sc25519.h verify.c] Fix RCS idents + - (djm) [Makefile.in] Add ed25519 sources + - (djm) [authfile.c] Conditionalise inclusion of util.h + - (djm) [configure.ac openbsd-compat/Makefile.in openbsd-compat/bcrypt_pbkdf.c] + [openbsd-compat/blf.h openbsd-compat/blowfish.c] + [openbsd-compat/openbsd-compat.h] Start at supporting bcrypt_pbkdf in + portable. + - (djm) [ed25519.c ssh-ed25519.c openbsd-compat/Makefile.in] + [openbsd-compat/bcrypt_pbkdf.c] Make ed25519/new key format compile on + Linux + - (djm) [regress/cert-hostkey.sh] Fix merge botch + - (djm) [Makefile.in] PATHSUBS and keygen bits for Ed25519; from + Loganaden Velvindron @ AfriNIC in bz#2179 + +20131205 + - (djm) OpenBSD CVS Sync + - jmc@cvs.openbsd.org 2013/11/21 08:05:09 + [ssh_config.5 sshd_config.5] + no need for .Pp before displays; + - deraadt@cvs.openbsd.org 2013/11/25 18:04:21 + [ssh.1 ssh.c] + improve -Q usage and such. One usage change is that the option is now + case-sensitive + ok dtucker markus djm + - jmc@cvs.openbsd.org 2013/11/26 12:14:54 + [ssh.1 ssh.c] + - put -Q in the right place + - Ar was a poor choice for the arguments to -Q. i've chosen an + admittedly equally poor Cm, at least consistent with the rest + of the docs. also no need for multiple instances + - zap a now redundant Nm + - usage() sync + - deraadt@cvs.openbsd.org 2013/11/26 19:15:09 + [pkcs11.h] + cleanup 1 << 31 idioms. Resurrection of this issue pointed out by + Eitan Adler ok markus for ssh, implies same change in kerberosV + - djm@cvs.openbsd.org 2013/12/01 23:19:05 + [PROTOCOL] + mention curve25519-sha256@libssh.org key exchange algorithm + - djm@cvs.openbsd.org 2013/12/02 02:50:27 + [PROTOCOL.chacha20poly1305] + typo; from Jon Cave + - djm@cvs.openbsd.org 2013/12/02 02:56:17 + [ssh-pkcs11-helper.c] + use-after-free; bz#2175 patch from Loganaden Velvindron @ AfriNIC + - djm@cvs.openbsd.org 2013/12/02 03:09:22 + [key.c] + make key_to_blob() return a NULL blob on failure; part of + bz#2175 from Loganaden Velvindron @ AfriNIC + - djm@cvs.openbsd.org 2013/12/02 03:13:14 + [cipher.c] + correct bzero of chacha20+poly1305 key context. bz#2177 from + Loganaden Velvindron @ AfriNIC + + Also make it a memset for consistency with the rest of cipher.c + - djm@cvs.openbsd.org 2013/12/04 04:20:01 + [sftp-client.c] + bz#2171: don't leak local_fd on error; from Loganaden Velvindron @ + AfriNIC + - djm@cvs.openbsd.org 2013/12/05 01:16:41 + [servconf.c servconf.h] + bz#2161 - fix AuthorizedKeysCommand inside a Match block and + rearrange things so the same error is harder to make next time; + with and ok dtucker@ + - (dtucker) [configure.ac] bz#2173: use pkg-config --libs to include correct + -L location for libedit. Patch from Serge van den Boom. + +20131121 + - (djm) OpenBSD CVS Sync + - dtucker@cvs.openbsd.org 2013/11/08 11:15:19 + [bufaux.c bufbn.c buffer.c sftp-client.c sftp-common.c sftp-glob.c] + [uidswap.c] Include stdlib.h for free() as per the man page. + - markus@cvs.openbsd.org 2013/11/13 13:48:20 + [ssh-pkcs11.c] + add missing braces found by pedro + - djm@cvs.openbsd.org 2013/11/20 02:19:01 + [sshd.c] + delay closure of in/out fds until after "Bad protocol version + identification..." message, as get_remote_ipaddr/get_remote_port + require them open. + - deraadt@cvs.openbsd.org 2013/11/20 20:53:10 + [scp.c] + unsigned casts for ctype macros where neccessary + ok guenther millert markus + - deraadt@cvs.openbsd.org 2013/11/20 20:54:10 + [canohost.c clientloop.c match.c readconf.c sftp.c] + unsigned casts for ctype macros where neccessary + ok guenther millert markus + - djm@cvs.openbsd.org 2013/11/21 00:45:44 + [Makefile.in PROTOCOL PROTOCOL.chacha20poly1305 authfile.c chacha.c] + [chacha.h cipher-chachapoly.c cipher-chachapoly.h cipher.c cipher.h] + [dh.c myproposal.h packet.c poly1305.c poly1305.h servconf.c ssh.1] + [ssh.c ssh_config.5 sshd_config.5] Add a new protocol 2 transport + cipher "chacha20-poly1305@openssh.com" that combines Daniel + Bernstein's ChaCha20 stream cipher and Poly1305 MAC to build an + authenticated encryption mode. + + Inspired by and similar to Adam Langley's proposal for TLS: + http://tools.ietf.org/html/draft-agl-tls-chacha20poly1305-03 + but differs in layout used for the MAC calculation and the use of a + second ChaCha20 instance to separately encrypt packet lengths. + Details are in the PROTOCOL.chacha20poly1305 file. + + Feedback markus@, naddy@; manpage bits Loganden Velvindron @ AfriNIC + ok markus@ naddy@ + - naddy@cvs.openbsd.org 2013/11/18 05:09:32 + [regress/forward-control.sh] + bump timeout to 10 seconds to allow slow machines (e.g. Alpha PC164) + to successfully run this; ok djm@ + - djm@cvs.openbsd.org 2013/11/21 03:15:46 + [regress/krl.sh] + add some reminders for additional tests that I'd like to implement + - djm@cvs.openbsd.org 2013/11/21 03:16:47 + [regress/modpipe.c] + use unsigned long long instead of u_int64_t here to avoid warnings + on some systems portable OpenSSH is built on. + - djm@cvs.openbsd.org 2013/11/21 03:18:51 + [regress/cipher-speed.sh regress/integrity.sh regress/rekey.sh] + [regress/try-ciphers.sh] + use new "ssh -Q cipher-auth" query to obtain lists of authenticated + encryption ciphers instead of specifying them manually; ensures that + the new chacha20poly1305@openssh.com mode is tested; + + ok markus@ and naddy@ as part of the diff to add + chacha20poly1305@openssh.com + +20131110 + - (dtucker) [regress/keytype.sh] Populate ECDSA key types to be tested by + querying the ones that are compiled in. + +20131109 + - (dtucker) OpenBSD CVS Sync + - dtucker@cvs.openbsd.org 2013/11/09 05:41:34 + [regress/test-exec.sh regress/rekey.sh] + Use smaller test data files to speed up tests. Grow test datafiles + where necessary for a specific test. + - (dtucker) [configure.ac kex.c key.c myproposal.h] Test for the presence of + NID_X9_62_prime256v1, NID_secp384r1 and NID_secp521r1 and test that the + latter actually works before using it. Fedora (at least) has NID_secp521r1 + that doesn't work (see https://bugzilla.redhat.com/show_bug.cgi?id=1021897). + - (dtucker) [configure.ac] Fix brackets in NID_secp521r1 test. + - (dtucker) [configure.ac] Add missing "test". + - (dtucker) [key.c] Check for the correct defines for NID_secp521r1. + +20131108 + - (dtucker) OpenBSD CVS Sync + - dtucker@cvs.openbsd.org 2013/11/08 01:06:14 + [regress/rekey.sh] + Rekey less frequently during tests to speed them up + - (djm) OpenBSD CVS Sync + - dtucker@cvs.openbsd.org 2013/11/07 11:58:27 + [cipher.c cipher.h kex.c kex.h mac.c mac.h servconf.c ssh.c] + Output the effective values of Ciphers, MACs and KexAlgorithms when + the default has not been overridden. ok markus@ - djm@cvs.openbsd.org 2013/11/08 00:39:15 [auth-options.c auth2-chall.c authfd.c channels.c cipher-3des1.c] [clientloop.c gss-genr.c monitor_mm.c packet.c schnorr.c umac.c] [sftp-client.c sftp-glob.c] use calloc for all structure allocations; from markus@ - - (djm) [README contrib/caldera/openssh.spec contrib/redhat/openssh.spec] - [contrib/suse/openssh.spec] update version numbers - djm@cvs.openbsd.org 2013/11/08 01:38:11 [version.h] openssh-6.4 - - (djm) Release 6.4p1 + - (djm) [README contrib/caldera/openssh.spec contrib/redhat/openssh.spec] + [contrib/suse/openssh.spec] Update version numbers following release. + - (dtucker) [openbsd-compat/openbsd-compat.h] Add null implementation of + arc4random_stir for platforms that have arc4random but don't have + arc4random_stir (right now this is only OpenBSD -current). + - (dtucker) [kex.c] Only enable CURVE25519_SHA256 if we actually have + EVP_sha256. + - (dtucker) [myproposal.h] Conditionally enable CURVE25519_SHA256. + - (dtucker) [openbsd-compat/bsd-poll.c] Add headers to prevent compile + warnings. + - (dtucker) [Makefile.in configure.ac] Set MALLOC_OPTIONS per platform + and pass in TEST_ENV. use stderr to get polluted + and the stderr-data test to fail. + - (dtucker) [contrib/cygwin/ssh-host-config] Simplify host key generation: + rather than testing and generating each key, call ssh-keygen -A. + Patch from vinschen at redhat.com. + - (dtucker) OpenBSD CVS Sync + - dtucker@cvs.openbsd.org 2013/11/09 05:41:34 + [regress/test-exec.sh regress/rekey.sh] + Use smaller test data files to speed up tests. Grow test datafiles + where necessary for a specific test. -20130913 - - (djm) [channels.c] Fix unaligned access on sparc machines in SOCKS5 code; - ok dtucker@ - - (djm) [channels.c] sigh, typo s/buffet_/buffer_/ - - (djm) Release 6.3p1 +20131107 + - (djm) [ssh-pkcs11.c] Bring back "non-constant initialiser" fix (rev 1.5) + that got lost in recent merge. + - (djm) [Makefile.in monitor.c] Missed chunks of curve25519 KEX diff + - (djm) [regress/modpipe.c regress/rekey.sh] Never intended to commit these + - (djm) [configure.ac defines.h] Skip arc4random_stir() calls on platforms + that lack it but have arc4random_uniform() + - (djm) OpenBSD CVS Sync + - markus@cvs.openbsd.org 2013/11/04 11:51:16 + [monitor.c] + fix rekeying for KEX_C25519_SHA256; noted by dtucker@ + RCSID sync only; I thought this was a merge botch and fixed it already + - markus@cvs.openbsd.org 2013/11/06 16:52:11 + [monitor_wrap.c] + fix rekeying for AES-GCM modes; ok deraadt + - djm@cvs.openbsd.org 2013/11/06 23:05:59 + [ssh-pkcs11.c] + from portable: s/true/true_val/ to avoid name collisions on dump platforms + RCSID sync only + - (dtucker) OpenBSD CVS Sync + - djm@cvs.openbsd.org 2013/10/09 23:44:14 + [regress/Makefile] (ID sync only) + regression test for sftp request white/blacklisting and readonly mode. + - markus@cvs.openbsd.org 2013/11/02 22:39:53 + [regress/kextype.sh] + add curve25519-sha256@libssh.org + - dtucker@cvs.openbsd.org 2013/11/04 12:27:42 + [regress/rekey.sh] + Test rekeying with all KexAlgorithms. + - dtucker@cvs.openbsd.org 2013/11/07 00:12:05 + [regress/rekey.sh] + Test rekeying for every Cipher, MAC and KEX, plus test every KEX with + the GCM ciphers. + - dtucker@cvs.openbsd.org 2013/11/07 01:12:51 + [regress/rekey.sh] + Factor out the data transfer rekey tests + - dtucker@cvs.openbsd.org 2013/11/07 02:48:38 + [regress/integrity.sh regress/cipher-speed.sh regress/try-ciphers.sh] + Use ssh -Q instead of hardcoding lists of ciphers or MACs. + - dtucker@cvs.openbsd.org 2013/11/07 03:55:41 + [regress/kextype.sh] + Use ssh -Q to get kex types instead of a static list. + - dtucker@cvs.openbsd.org 2013/11/07 04:26:56 + [regress/kextype.sh] + trailing space + - (dtucker) [Makefile.in configure.ac] Remove TEST_SSH_SHA256 environment + variable. It's no longer used now that we get the supported MACs from + ssh -Q. + +20131104 + - (djm) OpenBSD CVS Sync + - markus@cvs.openbsd.org 2013/11/02 20:03:54 + [ssh-pkcs11.c] + support pkcs#11 tokes that only provide x509 zerts instead of raw pubkeys; + fixes bz#1908; based on patch from Laurent Barbe; ok djm + - markus@cvs.openbsd.org 2013/11/02 21:59:15 + [kex.c kex.h myproposal.h ssh-keyscan.c sshconnect2.c sshd.c] + use curve25519 for default key exchange (curve25519-sha256@libssh.org); + initial patch from Aris Adamantiadis; ok djm@ + - markus@cvs.openbsd.org 2013/11/02 22:10:15 + [kexdhs.c kexecdhs.c] + no need to include monitor_wrap.h + - markus@cvs.openbsd.org 2013/11/02 22:24:24 + [kexdhs.c kexecdhs.c] + no need to include ssh-gss.h + - markus@cvs.openbsd.org 2013/11/02 22:34:01 + [auth-options.c] + no need to include monitor_wrap.h and ssh-gss.h + - markus@cvs.openbsd.org 2013/11/02 22:39:19 + [ssh_config.5 sshd_config.5] + the default kex is now curve25519-sha256@libssh.org + - djm@cvs.openbsd.org 2013/11/03 10:37:19 + [roaming_common.c] + fix a couple of function definitions foo() -> foo(void) + (-Wold-style-definition) + - (djm) [kexc25519.c kexc25519c.c kexc25519s.c] Import missed files from + KEX/curve25519 change + +20131103 + - (dtucker) [openbsd-compat/bsd-misc.c] Include time.h for nanosleep. + From OpenSMTPD where it prevents "implicit declaration" warnings (it's + a no-op in OpenSSH). From chl at openbsd. + - (dtucker) [openbsd-compat/setproctitle.c] Handle error case form the 2nd + vsnprintf. From eric at openbsd via chl@. + - (dtucker) [configure.ac defines.h] Add typedefs for intmax_t and uintmax_t + for platforms that don't have them. + +20131030 + - (djm) OpenBSD CVS Sync + - djm@cvs.openbsd.org 2013/10/29 09:42:11 + [key.c key.h] + fix potential stack exhaustion caused by nested certificates; + report by Mateusz Kocielski; ok dtucker@ markus@ + - djm@cvs.openbsd.org 2013/10/29 09:48:02 + [servconf.c servconf.h session.c sshd_config sshd_config.5] + shd_config PermitTTY to disallow TTY allocation, mirroring the + longstanding no-pty authorized_keys option; + bz#2070, patch from Teran McKinney; ok markus@ + - jmc@cvs.openbsd.org 2013/10/29 18:49:32 + [sshd_config.5] + pty(4), not pty(7); + +20131026 + - (djm) OpenBSD CVS Sync + - djm@cvs.openbsd.org 2013/10/25 23:04:51 + [ssh.c] + fix crash when using ProxyCommand caused by previous commit - was calling + freeaddrinfo(NULL); spotted by sthen@ and Tim Ruehsen, patch by sthen@ + +20131025 + - (djm) [ssh-keygen.c ssh-keysign.c sshconnect1.c sshd.c] Remove + unnecessary arc4random_stir() calls. The only ones left are to ensure + that the PRNG gets a different state after fork() for platforms that + have broken the API. + +20131024 + - (djm) [auth-krb5.c] bz#2032 - use local username in krb5_kuserok check + rather than full client name which may be of form user@REALM; + patch from Miguel Sanders; ok dtucker@ + - (djm) OpenBSD CVS Sync + - dtucker@cvs.openbsd.org 2013/10/23 05:40:58 + [servconf.c] + fix comment + - djm@cvs.openbsd.org 2013/10/23 23:35:32 + [sshd.c] + include local address and port in "Connection from ..." message (only + shown at loglevel>=verbose) + - dtucker@cvs.openbsd.org 2013/10/24 00:49:49 + [moduli.c] + Periodically print progress and, if possible, expected time to completion + when screening moduli for DH groups. ok deraadt djm + - dtucker@cvs.openbsd.org 2013/10/24 00:51:48 + [readconf.c servconf.c ssh_config.5 sshd_config.5] + Disallow empty Match statements and add "Match all" which matches + everything. ok djm, man page help jmc@ + - djm@cvs.openbsd.org 2013/10/24 08:19:36 + [ssh.c] + fix bug introduced in hostname canonicalisation commit: don't try to + resolve hostnames when a ProxyCommand is set unless the user has forced + canonicalisation; spotted by Iain Morgan + - (tim) [regress/sftp-perm.sh] We need a shell that understands "! somecmd" + +20131023 + - (djm) OpenBSD CVS Sync + - djm@cvs.openbsd.org 2013/10/20 04:39:28 + [ssh_config.5] + document % expansions performed by "Match command ..." + - djm@cvs.openbsd.org 2013/10/20 06:19:28 + [readconf.c ssh_config.5] + rename "command" subclause of the recently-added "Match" keyword to + "exec"; it's shorter, clearer in intent and we might want to add the + ability to match against the command being executed at the remote end in + the future. + - djm@cvs.openbsd.org 2013/10/20 09:51:26 + [scp.1 sftp.1] + add canonicalisation options to -o lists + - jmc@cvs.openbsd.org 2013/10/20 18:00:13 + [ssh_config.5] + tweak the "exec" description, as worded by djm; + - djm@cvs.openbsd.org 2013/10/23 03:03:07 + [readconf.c] + Hostname may have %h sequences that should be expanded prior to Match + evaluation; spotted by Iain Morgan + - djm@cvs.openbsd.org 2013/10/23 03:05:19 + [readconf.c ssh.c] + comment + - djm@cvs.openbsd.org 2013/10/23 04:16:22 + [ssh-keygen.c] + Make code match documentation: relative-specified certificate expiry time + should be relative to current time and not the validity start time. + Reported by Petr Lautrbach; ok deraadt@ + +20131018 + - (djm) OpenBSD CVS Sync + - djm@cvs.openbsd.org 2013/10/09 23:44:14 + [regress/Makefile regress/sftp-perm.sh] + regression test for sftp request white/blacklisting and readonly mode. + - jmc@cvs.openbsd.org 2013/10/17 07:35:48 + [sftp.1 sftp.c] + tweak previous; + - djm@cvs.openbsd.org 2013/10/17 22:08:04 + [sshd.c] + include remote port in bad banner message; bz#2162 + +20131017 + - (djm) OpenBSD CVS Sync + - jmc@cvs.openbsd.org 2013/10/15 14:10:25 + [ssh.1 ssh_config.5] + tweak previous; + - djm@cvs.openbsd.org 2013/10/16 02:31:47 + [readconf.c readconf.h roaming_client.c ssh.1 ssh.c ssh_config.5] + [sshconnect.c sshconnect.h] + Implement client-side hostname canonicalisation to allow an explicit + search path of domain suffixes to use to convert unqualified host names + to fully-qualified ones for host key matching. + This is particularly useful for host certificates, which would otherwise + need to list unqualified names alongside fully-qualified ones (and this + causes a number of problems). + "looks fine" markus@ + - jmc@cvs.openbsd.org 2013/10/16 06:42:25 + [ssh_config.5] + tweak previous; + - djm@cvs.openbsd.org 2013/10/16 22:49:39 + [readconf.c readconf.h ssh.1 ssh.c ssh_config.5] + s/canonicalise/canonicalize/ for consistency with existing spelling, + e.g. authorized_keys; pointed out by naddy@ + - djm@cvs.openbsd.org 2013/10/16 22:58:01 + [ssh.c ssh_config.5] + one I missed in previous: s/isation/ization/ + - djm@cvs.openbsd.org 2013/10/17 00:30:13 + [PROTOCOL sftp-client.c sftp-client.h sftp-server.c sftp.1 sftp.c] + fsync@openssh.com protocol extension for sftp-server + client support to allow calling fsync() faster successful transfer + patch mostly by imorgan AT nas.nasa.gov; bz#1798 + "fine" markus@ "grumble OK" deraadt@ "doesn't sound bad to me" millert@ + - djm@cvs.openbsd.org 2013/10/17 00:46:49 + [ssh.c] + rearrange check to reduce diff against -portable + (Id sync only) + +20131015 + - (djm) OpenBSD CVS Sync + - djm@cvs.openbsd.org 2013/10/09 23:42:17 + [sftp-server.8 sftp-server.c] + Add ability to whitelist and/or blacklist sftp protocol requests by name. + Refactor dispatch loop and consolidate read-only mode checks. + Make global variables static, since sftp-server is linked into sshd(8). + ok dtucker@ + - djm@cvs.openbsd.org 2013/10/10 00:53:25 + [sftp-server.c] + add -Q, -P and -p to usage() before jmc@ catches me + - djm@cvs.openbsd.org 2013/10/10 01:43:03 + [sshd.c] + bz#2139: fix re-exec fallback by ensuring that startup_pipe is correctly + updated; ok dtucker@ + - djm@cvs.openbsd.org 2013/10/11 02:45:36 + [sftp-client.c] + rename flag arguments to be more clear and consistent. + reorder some internal function arguments to make adding additional flags + easier. + no functional change + - djm@cvs.openbsd.org 2013/10/11 02:52:23 + [sftp-client.c] + missed one arg reorder + - djm@cvs.openbsd.org 2013/10/11 02:53:45 + [sftp-client.h] + obsolete comment + - jmc@cvs.openbsd.org 2013/10/14 14:18:56 + [sftp-server.8 sftp-server.c] + tweak previous; + ok djm + - djm@cvs.openbsd.org 2013/10/14 21:20:52 + [session.c session.h] + Add logging of session starts in a useful format; ok markus@ feedback and + ok dtucker@ + - djm@cvs.openbsd.org 2013/10/14 22:22:05 + [readconf.c readconf.h ssh-keysign.c ssh.c ssh_config.5] + add a "Match" keyword to ssh_config that allows matching on hostname, + user and result of arbitrary commands. "nice work" markus@ + - djm@cvs.openbsd.org 2013/10/14 23:28:23 + [canohost.c misc.c misc.h readconf.c sftp-server.c ssh.c] + refactor client config code a little: + add multistate option partsing to readconf.c, similar to servconf.c's + existing code. + move checking of options that accept "none" as an argument to readconf.c + add a lowercase() function and use it instead of explicit tolower() in + loops + part of a larger diff that was ok markus@ + - djm@cvs.openbsd.org 2013/10/14 23:31:01 + [ssh.c] + whitespace at EOL; pointed out by markus@ + - [ssh.c] g/c unused variable. + +20131010 + - (dtucker) OpenBSD CVS Sync + - sthen@cvs.openbsd.org 2013/09/16 11:35:43 + [ssh_config] + Remove gssapi config parts from ssh_config, as was already done for + sshd_config. Req by/ok ajacoutot@ + ID SYNC ONLY for portable; kerberos/gssapi is still pretty popular + - djm@cvs.openbsd.org 2013/09/19 00:24:52 + [progressmeter.c] + store the initial file offset so the progress meter doesn't freak out + when resuming sftp transfers. bz#2137; patch from Iain Morgan; ok dtucker@` + - djm@cvs.openbsd.org 2013/09/19 00:49:12 + [sftp-client.c] + fix swapped pflag and printflag in sftp upload_dir; from Iain Morgan + - djm@cvs.openbsd.org 2013/09/19 01:24:46 + [channels.c] + bz#1297 - tell the client (via packet_send_debug) when their preferred + listen address has been overridden by the server's GatewayPorts; + ok dtucker@ + - djm@cvs.openbsd.org 2013/09/19 01:26:29 + [sshconnect.c] + bz#1211: make BindAddress work with UsePrivilegedPort=yes; patch from + swp AT swp.pp.ru; ok dtucker@ + - dtucker@cvs.openbsd.org 2013/10/08 11:42:13 + [dh.c dh.h] + Increase the size of the Diffie-Hellman groups requested for a each + symmetric key size. New values from NIST Special Publication 800-57 with + the upper limit specified by RFC4419. Pointed out by Peter Backes, ok + djm@. + +20131009 + - (djm) [openbsd-compat/arc4random.c openbsd-compat/chacha_private.h] Pull + in OpenBSD implementation of arc4random, shortly to replace the existing + bsd-arc4random.c + - (djm) [openbsd-compat/Makefile.in openbsd-compat/arc4random.c] + [openbsd-compat/bsd-arc4random.c] Replace old RC4-based arc4random + implementation with recent OpenBSD's ChaCha-based PRNG. ok dtucker@, + tested tim@ + +20130922 + - (dtucker) [platform.c platform.h sshd.c] bz#2156: restore Linux oom_adj + setting when handling SIGHUP to maintain behaviour over retart. Patch + from Matthew Ife. + +20130918 + - (dtucker) [sshd_config] Trailing whitespace; from jstjohn at purdue edu. + +20130914 + - (djm) OpenBSD CVS Sync + - djm@cvs.openbsd.org 2013/08/22 19:02:21 + [sshd.c] + Stir PRNG after post-accept fork. The child gets a different PRNG state + anyway via rexec and explicit privsep reseeds, but it's good to be sure. + ok markus@ + - mikeb@cvs.openbsd.org 2013/08/28 12:34:27 + [ssh-keygen.c] + improve batch processing a bit by making use of the quite flag a bit + more often and exit with a non zero code if asked to find a hostname + in a known_hosts file and it wasn't there; + originally from reyk@, ok djm + - djm@cvs.openbsd.org 2013/08/31 00:13:54 + [sftp.c] + make ^w match ksh behaviour (delete previous word instead of entire line) + - deraadt@cvs.openbsd.org 2013/09/02 22:00:34 + [ssh-keygen.c sshconnect1.c sshd.c] + All the instances of arc4random_stir() are bogus, since arc4random() + does this itself, inside itself, and has for a very long time.. Actually, + this was probably reducing the entropy available. + ok djm + ID SYNC ONLY for portable; we don't trust other arc4random implementations + to do this right. + - sthen@cvs.openbsd.org 2013/09/07 13:53:11 + [sshd_config] + Remove commented-out kerberos/gssapi config options from sample config, + kerberos support is currently not enabled in ssh in OpenBSD. Discussed with + various people; ok deraadt@ + ID SYNC ONLY for portable; kerberos/gssapi is still pretty popular + - djm@cvs.openbsd.org 2013/09/12 01:41:12 + [clientloop.c] + fix connection crash when sending break (~B) on ControlPersist'd session; + ok dtucker@ + - djm@cvs.openbsd.org 2013/09/13 06:54:34 + [channels.c] + avoid unaligned access in code that reused a buffer to send a + struct in_addr in a reply; simpler just use use buffer_put_int(); + from portable; spotted by and ok dtucker@ + +20130828 + - (djm) [openbsd-compat/bsd-snprintf.c] teach our local snprintf code the + 'j' (intmax_t/uintmax_t) and 'z' (size_t/ssize_t) conversions in case we + start to use them in the future. + - (djm) [openbsd-compat/bsd-snprintf.c] #ifdef noytet for intmax_t bits + until we have configure support. + +20130821 + - (djm) OpenBSD CVS Sync + - djm@cvs.openbsd.org 2013/08/06 23:03:49 + [sftp.c] + fix some whitespace at EOL + make list of commands an enum rather than a long list of defines + add -a to usage() + - djm@cvs.openbsd.org 2013/08/06 23:05:01 + [sftp.1] + document top-level -a option (the -a option to 'get' was already + documented) + - djm@cvs.openbsd.org 2013/08/06 23:06:01 + [servconf.c] + add cast to avoid format warning; from portable + - jmc@cvs.openbsd.org 2013/08/07 06:24:51 + [sftp.1 sftp.c] + sort -a; + - djm@cvs.openbsd.org 2013/08/08 04:52:04 + [sftp.c] + fix two year old regression: symlinking a file would incorrectly + canonicalise the target path. bz#2129 report from delphij AT freebsd.org + - djm@cvs.openbsd.org 2013/08/08 05:04:03 + [sftp-client.c sftp-client.h sftp.c] + add a "-l" flag for the rename command to force it to use the silly + standard SSH_FXP_RENAME command instead of the POSIX-rename- like + posix-rename@openssh.com extension. + + intended for use in regress tests, so no documentation. + - djm@cvs.openbsd.org 2013/08/09 03:37:25 + [sftp.c] + do getopt parsing for all sftp commands (with an empty optstring for + commands without arguments) to ensure consistent behaviour + - djm@cvs.openbsd.org 2013/08/09 03:39:13 + [sftp-client.c] + two problems found by a to-be-committed regress test: 1) msg_id was not + being initialised so was starting at a random value from the heap + (harmless, but confusing). 2) some error conditions were not being + propagated back to the caller + - djm@cvs.openbsd.org 2013/08/09 03:56:42 + [sftp.c] + enable ctrl-left-arrow and ctrl-right-arrow to move forward/back a word; + matching ksh's relatively recent change. + - djm@cvs.openbsd.org 2013/08/13 18:32:08 + [ssh-keygen.c] + typo in error message; from Stephan Rickauer + - djm@cvs.openbsd.org 2013/08/13 18:33:08 + [ssh-keygen.c] + another of the same typo + - jmc@cvs.openbsd.org 2013/08/14 08:39:27 + [scp.1 ssh.1] + some Bx/Ox conversion; + From: Jan Stary + - djm@cvs.openbsd.org 2013/08/20 00:11:38 + [readconf.c readconf.h ssh_config.5 sshconnect.c] + Add a ssh_config ProxyUseFDPass option that supports the use of + ProxyCommands that establish a connection and then pass a connected + file descriptor back to ssh(1). This allows the ProxyCommand to exit + rather than have to shuffle data back and forth and enables ssh to use + getpeername, etc. to obtain address information just like it does with + regular directly-connected sockets. ok markus@ + - jmc@cvs.openbsd.org 2013/08/20 06:56:07 + [ssh.1 ssh_config.5] + some proxyusefdpass tweaks; 20130808 - (dtucker) [regress/Makefile regress/test-exec.sh] Don't try to use test -nt @@ -34,6 +1051,7 @@ - (dtucker) [regress/Makefile regress/test-exec.sh] Roll back the -nt removal. The "make clean" removes modpipe which is built by the top-level directory before running the tests. Spotted by tim@ + - (djm) Release 6.3p1 20130804 - (dtucker) [auth-krb5.c configure.ac openbsd-compat/bsd-misc.h] Add support @@ -668,10 +1686,10 @@ to avoid conflicting definitions of __int64, adding the required bits. Patch from Corinna Vinschen. -20120323 +20130323 - (tim) [Makefile.in] remove some duplication introduced in 20130220 commit. -20120322 +20130322 - (djm) [contrib/ssh-copy-id contrib/ssh-copy-id.1] Updated to Phil Hands' greatly revised version. - (djm) Release 6.2p1 @@ -679,16 +1697,16 @@ - (dtucker) [includes.h] Check if _GNU_SOURCE is already defined before defining it again. Prevents warnings if someone, eg, sets it in CFLAGS. -20120318 +20130318 - (djm) [configure.ac log.c scp.c sshconnect2.c openbsd-compat/vis.c] [openbsd-compat/vis.h] FreeBSD's strnvis isn't compatible with OpenBSD's so mark it as broken. Patch from des AT des.no -20120317 +20130317 - (tim) [configure.ac] OpenServer 5 wants lastlog even though it has none of the bits the configure test looks for. -20120316 +20130316 - (djm) [configure.ac] Disable utmp, wtmp and/or lastlog if the platform is unable to successfully compile them. Based on patch from des AT des.no @@ -698,7 +1716,7 @@ occur after UID switch; patch from John Marshall via des AT des.no; ok dtucker@ -20120312 +20130312 - (dtucker) [regress/Makefile regress/cipher-speed.sh regress/test-exec.sh] Improve portability of cipher-speed test, based mostly on a patch from Iain Morgan. @@ -1645,2052 +2663,3 @@ [contrib/suse/openssh.spec] Update for release 6.0 - (djm) [README] Update URL to release notes. - (djm) Release openssh-6.0 - -20120419 - - (djm) [configure.ac] Fix compilation error on FreeBSD, whose libutil - contains openpty() but not login() - -20120404 - - (djm) [Makefile.in configure.ac sandbox-seccomp-filter.c] Add sandbox - mode for Linux's new seccomp filter; patch from Will Drewry; feedback - and ok dtucker@ - -20120330 - - (dtucker) [contrib/redhat/openssh.spec] Bug #1992: remove now-gone WARNING - file from spec file. From crighter at nuclioss com. - - (djm) [entropy.c] bz#1991: relax OpenSSL version test to allow running - openssh binaries on a newer fix release than they were compiled on. - with and ok dtucker@ - - (djm) [openbsd-compat/bsd-cygwin_util.h] #undef _WIN32 to avoid incorrect - assumptions when building on Cygwin; patch from Corinna Vinschen - -20120309 - - (djm) [openbsd-compat/port-linux.c] bz#1960: fix crash on SELinux - systems where sshd is run in te wrong context. Patch from Sven - Vermeulen; ok dtucker@ - - (djm) [packet.c] bz#1963: Fix IPQoS not being set on non-mapped v4-in-v6 - addressed connections. ok dtucker@ - -20120224 - - (dtucker) [audit-bsm.c configure.ac] bug #1968: enable workarounds for BSM - audit breakage in Solaris 11. Patch from Magnus Johansson. - -20120215 - - (tim) [openbsd-compat/bsd-misc.h sshd.c] Fix conflicting return type for - unsetenv due to rev 1.14 change to setenv.c. Cast unsetenv to void in sshd.c - ok dtucker@ - - (tim) [defines.h] move chunk introduced in 1.125 before MAXPATHLEN so - it actually works. - - (tim) [regress/keytype.sh] stderr redirection needs to be inside back quote - to work. Spotted by Angel Gonzalez - -20120214 - - (djm) [openbsd-compat/bsd-cygwin_util.c] Add PROGRAMFILES to list of - preserved Cygwin environment variables; from Corinna Vinschen - -20120211 - - (djm) OpenBSD CVS Sync - - djm@cvs.openbsd.org 2012/01/05 00:16:56 - [monitor.c] - memleak on error path - - djm@cvs.openbsd.org 2012/01/07 21:11:36 - [mux.c] - fix double-free in new session handler - - miod@cvs.openbsd.org 2012/01/08 13:17:11 - [ssh-ecdsa.c] - Fix memory leak in ssh_ecdsa_verify(); from Loganaden Velvindron, - ok markus@ - - miod@cvs.openbsd.org 2012/01/16 20:34:09 - [ssh-pkcs11-client.c] - Fix a memory leak in pkcs11_rsa_private_encrypt(), reported by Jan Klemkow. - While there, be sure to buffer_clear() between send_msg() and recv_msg(). - ok markus@ - - dtucker@cvs.openbsd.org 2012/01/18 21:46:43 - [clientloop.c] - Ensure that $DISPLAY contains only valid characters before using it to - extract xauth data so that it can't be used to play local shell - metacharacter games. Report from r00t_ati at ihteam.net, ok markus. - - markus@cvs.openbsd.org 2012/01/25 19:26:43 - [packet.c] - do not permit SSH2_MSG_SERVICE_REQUEST/ACCEPT during rekeying; - ok dtucker@, djm@ - - markus@cvs.openbsd.org 2012/01/25 19:36:31 - [authfile.c] - memleak in key_load_file(); from Jan Klemkow - - markus@cvs.openbsd.org 2012/01/25 19:40:09 - [packet.c packet.h] - packet_read_poll() is not used anymore. - - markus@cvs.openbsd.org 2012/02/09 20:00:18 - [version.h] - move from 6.0-beta to 6.0 - -20120206 - - (djm) [ssh-keygen.c] Don't fail in do_gen_all_hostkeys on platforms - that don't support ECC. Patch from Phil Oleson - -20111219 - - OpenBSD CVS Sync - - djm@cvs.openbsd.org 2011/12/02 00:41:56 - [mux.c] - fix bz#1948: ssh -f doesn't fork for multiplexed connection. - ok dtucker@ - - djm@cvs.openbsd.org 2011/12/02 00:43:57 - [mac.c] - fix bz#1934: newer OpenSSL versions will require HMAC_CTX_Init before - HMAC_init (this change in policy seems insane to me) - ok dtucker@ - - djm@cvs.openbsd.org 2011/12/04 23:16:12 - [mux.c] - revert: - > revision 1.32 - > date: 2011/12/02 00:41:56; author: djm; state: Exp; lines: +4 -1 - > fix bz#1948: ssh -f doesn't fork for multiplexed connection. - > ok dtucker@ - it interacts badly with ControlPersist - - djm@cvs.openbsd.org 2011/12/07 05:44:38 - [auth2.c dh.c packet.c roaming.h roaming_client.c roaming_common.c] - fix some harmless and/or unreachable int overflows; - reported Xi Wang, ok markus@ - -20111125 - - OpenBSD CVS Sync - - oga@cvs.openbsd.org 2011/11/16 12:24:28 - [sftp.c] - Don't leak list in complete_cmd_parse if there are no commands found. - Discovered when I was ``borrowing'' this code for something else. - ok djm@ - -20111121 - - (dtucker) [configure.ac] Set _FORTIFY_SOURCE. ok djm@ - -20111104 - - (dtucker) OpenBSD CVS Sync - - djm@cvs.openbsd.org 2011/10/18 05:15:28 - [ssh.c] - ssh(1): skip attempting to create ~/.ssh when -F is passed; ok markus@ - - djm@cvs.openbsd.org 2011/10/18 23:37:42 - [ssh-add.c] - add -k to usage(); reminded by jmc@ - - djm@cvs.openbsd.org 2011/10/19 00:06:10 - [moduli.c] - s/tmpfile/tmp/ to make this -Wshadow clean - - djm@cvs.openbsd.org 2011/10/19 10:39:48 - [umac.c] - typo in comment; patch from Michael W. Bombardieri - - djm@cvs.openbsd.org 2011/10/24 02:10:46 - [ssh.c] - bz#1943: unbreak stdio forwarding when ControlPersist is in user - ssh - was incorrectly requesting the forward in both the control master and - slave. skip requesting it in the master to fix. ok markus@ - - djm@cvs.openbsd.org 2011/10/24 02:13:13 - [session.c] - bz#1859: send tty break to pty master instead of (probably already - closed) slave side; "looks good" markus@ - - dtucker@cvs.openbsd.org 011/11/04 00:09:39 - [moduli] - regenerated moduli file; ok deraadt - - (dtucker) [INSTALL LICENCE configure.ac openbsd-compat/Makefile.in - openbsd-compat/getrrsetbyname-ldns.c openbsd-compat/getrrsetbyname.c] - bz 1320: Add optional support for LDNS, a BSD licensed DNS resolver library - which supports DNSSEC. Patch from Simon Vallet (svallet at genoscope cns fr) - with some rework from myself and djm. ok djm. - -20111025 - - (dtucker) [contrib/cygwin/Makefile] Continue if installing a doc file - fails. Patch from Corinna Vinschen. - -20111018 - - (djm) OpenBSD CVS Sync - - djm@cvs.openbsd.org 2011/10/04 14:17:32 - [sftp-glob.c] - silence error spam for "ls */foo" in directory with files; bz#1683 - - dtucker@cvs.openbsd.org 2011/10/16 11:02:46 - [moduli.c ssh-keygen.1 ssh-keygen.c] - Add optional checkpoints for moduli screening. feedback & ok deraadt - - jmc@cvs.openbsd.org 2011/10/16 15:02:41 - [ssh-keygen.c] - put -K in the right place (usage()); - - stsp@cvs.openbsd.org 2011/10/16 15:51:39 - [moduli.c] - add missing includes to unbreak tree; fix from rpointel - - djm@cvs.openbsd.org 2011/10/18 04:58:26 - [auth-options.c key.c] - remove explict search for \0 in packet strings, this job is now done - implicitly by buffer_get_cstring; ok markus - - djm@cvs.openbsd.org 2011/10/18 05:00:48 - [ssh-add.1 ssh-add.c] - new "ssh-add -k" option to load plain keys (skipping certificates); - "looks ok" markus@ - -20111001 - - (dtucker) [openbsd-compat/mktemp.c] Fix compiler warning. ok djm - - (dtucker) OpenBSD CVS Sync - - dtucker@cvs.openbsd.org 2011/09/23 00:22:04 - [channels.c auth-options.c servconf.c channels.h sshd.8] - Add wildcard support to PermitOpen, allowing things like "PermitOpen - localhost:*". bz #1857, ok djm markus. - - markus@cvs.openbsd.org 2011/09/23 07:45:05 - [mux.c readconf.h channels.h compat.h compat.c ssh.c readconf.c channels.c - version.h] - unbreak remote portforwarding with dynamic allocated listen ports: - 1) send the actual listen port in the open message (instead of 0). - this allows multiple forwardings with a dynamic listen port - 2) update the matching permit-open entry, so we can identify where - to connect to - report: den at skbkontur.ru and P. Szczygielski - feedback and ok djm@ - - djm@cvs.openbsd.org 2011/09/25 05:44:47 - [auth2-pubkey.c] - improve the AuthorizedPrincipalsFile debug log message to include - file and line number - - dtucker@cvs.openbsd.org 2011/09/30 00:47:37 - [sshd.c] - don't attempt privsep cleanup when not using privsep; ok markus@ - - djm@cvs.openbsd.org 2011/09/30 21:22:49 - [sshd.c] - fix inverted test that caused logspam; spotted by henning@ - -20110929 - - (djm) [configure.ac defines.h] No need to detect sizeof(char); patch - from des AT des.no - - (dtucker) [configure.ac openbsd-compat/Makefile.in - openbsd-compat/strnlen.c] Add strnlen to the compat library. - -20110923 - - (djm) [openbsd-compat/getcwd.c] Remove OpenBSD rcsid marker since we no - longer want to sync this file (OpenBSD uses a __getcwd syscall now, we - want this longhand version) - - (djm) [openbsd-compat/getgrouplist.c] Remove OpenBSD rcsid marker: the - upstream version is YPified and we don't want this - - (djm) [openbsd-compat/mktemp.c] forklift upgrade to -current version. - The file was totally rewritten between what we had in tree and -current. - - (djm) [openbsd-compat/sha2.c openbsd-compat/sha2.h] Remove OpenBSD rcsid - marker. The upstream API has changed (function and structure names) - enough to put it out of sync with other providers of this interface. - - (djm) [openbsd-compat/setenv.c] Forklift upgrade, including inclusion - of static __findenv() function from upstream setenv.c - - OpenBSD CVS Sync - - millert@cvs.openbsd.org 2006/05/05 15:27:38 - [openbsd-compat/strlcpy.c] - Convert do {} while loop -> while {} for clarity. No binary change - on most architectures. From Oliver Smith. OK deraadt@ and henning@ - - tobias@cvs.openbsd.org 2007/10/21 11:09:30 - [openbsd-compat/mktemp.c] - Comment fix about time consumption of _gettemp. - FreeBSD did this in revision 1.20. - OK deraadt@, krw@ - - deraadt@cvs.openbsd.org 2008/07/22 21:47:45 - [openbsd-compat/mktemp.c] - use arc4random_uniform(); ok djm millert - - millert@cvs.openbsd.org 2008/08/21 16:54:44 - [openbsd-compat/mktemp.c] - Remove useless code, the kernel will set errno appropriately if an - element in the path does not exist. OK deraadt@ pvalchev@ - - otto@cvs.openbsd.org 2008/12/09 19:38:38 - [openbsd-compat/inet_ntop.c] - fix inet_ntop(3) prototype; ok millert@ libc to be bumbed very soon - -20110922 - - OpenBSD CVS Sync - - pyr@cvs.openbsd.org 2011/05/12 07:15:10 - [openbsd-compat/glob.c] - When the max number of items for a directory has reached GLOB_LIMIT_READDIR - an error is returned but closedir() is not called. - spotted and fix provided by Frank Denis obsd-tech@pureftpd.org - ok otto@, millert@ - - stsp@cvs.openbsd.org 2011/09/20 10:18:46 - [glob.c] - In glob(3), limit recursion during matching attempts. Similar to - fnmatch fix. Also collapse consecutive '*' (from NetBSD). - ok miod deraadt - - djm@cvs.openbsd.org 2011/09/22 06:27:29 - [glob.c] - fix GLOB_KEEPSTAT without GLOB_NOSORT; the implicit sort was being - applied only to the gl_pathv vector and not the corresponding gl_statv - array. reported in OpenSSH bz#1935; feedback and okay matthew@ - - djm@cvs.openbsd.org 2011/08/26 01:45:15 - [ssh.1] - Add some missing ssh_config(5) options that can be used in ssh(1)'s - -o argument. Patch from duclare AT guu.fi - - djm@cvs.openbsd.org 2011/09/05 05:56:13 - [scp.1 sftp.1] - mention ControlPersist and KbdInteractiveAuthentication in the -o - verbiage in these pages too (prompted by jmc@) - - djm@cvs.openbsd.org 2011/09/05 05:59:08 - [misc.c] - fix typo in IPQoS parsing: there is no "AF14" class, but there is - an "AF21" class. Spotted by giesen AT snickers.org; ok markus stevesk - - jmc@cvs.openbsd.org 2011/09/05 07:01:44 - [scp.1] - knock out a useless Ns; - - deraadt@cvs.openbsd.org 2011/09/07 02:18:31 - [ssh-keygen.1] - typo (they vs the) found by Lawrence Teo - - djm@cvs.openbsd.org 2011/09/09 00:43:00 - [ssh_config.5 sshd_config.5] - fix typo in IPQoS parsing: there is no "AF14" class, but there is - an "AF21" class. Spotted by giesen AT snickers.org; ok markus stevesk - - djm@cvs.openbsd.org 2011/09/09 00:44:07 - [PROTOCOL.mux] - MUX_C_CLOSE_FWD includes forward type in message (though it isn't - implemented anyway) - - djm@cvs.openbsd.org 2011/09/09 22:37:01 - [scp.c] - suppress adding '--' to remote commandlines when the first argument - does not start with '-'. saves breakage on some difficult-to-upgrade - embedded/router platforms; feedback & ok dtucker ok markus - - djm@cvs.openbsd.org 2011/09/09 22:38:21 - [sshd.c] - kill the preauth privsep child on fatal errors in the monitor; - ok markus@ - - djm@cvs.openbsd.org 2011/09/09 22:46:44 - [channels.c channels.h clientloop.h mux.c ssh.c] - support for cancelling local and remote port forwards via the multiplex - socket. Use ssh -O cancel -L xx:xx:xx -R yy:yy:yy user@host" to request - the cancellation of the specified forwardings; ok markus@ - - markus@cvs.openbsd.org 2011/09/10 22:26:34 - [channels.c channels.h clientloop.c ssh.1] - support cancellation of local/dynamic forwardings from ~C commandline; - ok & feedback djm@ - - okan@cvs.openbsd.org 2011/09/11 06:59:05 - [ssh.1] - document new -O cancel command; ok djm@ - - markus@cvs.openbsd.org 2011/09/11 16:07:26 - [sftp-client.c] - fix leaks in do_hardlink() and do_readlink(); bz#1921 - from Loganaden Velvindron - - markus@cvs.openbsd.org 2011/09/12 08:46:15 - [sftp-client.c] - fix leak in do_lsreaddir(); ok djm - - djm@cvs.openbsd.org 2011/09/22 06:29:03 - [sftp.c] - don't let remote_glob() implicitly sort its results in do_globbed_ls() - - in all likelihood, they will be resorted anyway - -20110909 - - (dtucker) [entropy.h] Bug #1932: remove old definition of init_rng. From - Colin Watson. - -20110906 - - (djm) [README version.h] Correct version - - (djm) [contrib/redhat/openssh.spec] Correct restorcon => restorecon - - (djm) Respin OpenSSH-5.9p1 release - -20110905 - - (djm) [README contrib/caldera/openssh.spec contrib/redhat/openssh.spec] - [contrib/suse/openssh.spec] Update version numbers. - -20110904 - - (djm) [regress/connect-privsep.sh regress/test-exec.sh] demote fatal - regress errors for the sandbox to warnings. ok tim dtucker - - (dtucker) [ssh-keygen.c ssh-pkcs11.c] Bug #1929: add null implementations - ofsh-pkcs11.cpkcs_init and pkcs_terminate for building without dlopen - support. - -20110829 - - (djm) [openbsd-compat/port-linux.c] Suppress logging when attempting - to switch SELinux context away from unconfined_t, based on patch from - Jan Chadima; bz#1919 ok dtucker@ - -20110827 - - (dtucker) [auth-skey.c] Add log.h to fix build --with-skey. - -20110818 - - (tim) [configure.ac] Typo in error message spotted by Andy Tsouladze - -20110817 - - (tim) [mac.c myproposal.h] Wrap SHA256 and SHA512 in ifdefs for - OpenSSL 0.9.7. ok djm - - (djm) [ openbsd-compat/bsd-cygwin_util.c openbsd-compat/bsd-cygwin_util.h] - binary_pipe is no longer required on Cygwin; patch from Corinna Vinschen - - (djm) [configure.ac] error out if the host lacks the necessary bits for - an explicitly requested sandbox type - - (djm) [contrib/ssh-copy-id] Missing backlslash; spotted by - bisson AT archlinux.org - - (djm) OpenBSD CVS Sync - - dtucker@cvs.openbsd.org 2011/06/03 05:35:10 - [regress/cfgmatch.sh] - use OBJ to find test configs, patch from Tim Rice - - markus@cvs.openbsd.org 2011/06/30 22:44:43 - [regress/connect-privsep.sh] - test with sandbox enabled; ok djm@ - - djm@cvs.openbsd.org 2011/08/02 01:23:41 - [regress/cipher-speed.sh regress/try-ciphers.sh] - add SHA256/SHA512 based HMAC modes - - (djm) [regress/cipher-speed.sh regress/try-ciphers.sh] disable HMAC-SHA2 - MAC tests for platforms that hack EVP_SHA2 support - -20110812 - - (dtucker) [openbsd-compat/port-linux.c] Bug 1924: Improve selinux context - change error by reporting old and new context names Patch from - jchadima at redhat. - - (djm) [contrib/redhat/openssh.spec contrib/redhat/sshd.init] - [contrib/suse/openssh.spec contrib/suse/rc.sshd] Updated RHEL and SLES - init scrips from imorgan AT nas.nasa.gov; bz#1920 - - (djm) [contrib/ssh-copy-id] Fix failure for cases where the path to the - identify file contained whitespace. bz#1828 patch from gwenael.lambrouin - AT gmail.com; ok dtucker@ - -20110807 - - (dtucker) OpenBSD CVS Sync - - jmc@cvs.openbsd.org 2008/06/26 06:59:39 - [moduli.5] - tweak previous; - - sobrado@cvs.openbsd.org 2009/10/28 08:56:54 - [moduli.5] - "Diffie-Hellman" is the usual spelling for the cryptographic protocol - first published by Whitfield Diffie and Martin Hellman in 1976. - ok jmc@ - - jmc@cvs.openbsd.org 2010/10/14 20:41:28 - [moduli.5] - probabalistic -> probabilistic; from naddy - - dtucker@cvs.openbsd.org 2011/08/07 12:55:30 - [sftp.1] - typo, fix from Laurent Gautrot - -20110805 - - OpenBSD CVS Sync - - djm@cvs.openbsd.org 2011/06/23 23:35:42 - [monitor.c] - ignore EINTR errors from poll() - - tedu@cvs.openbsd.org 2011/07/06 18:09:21 - [authfd.c] - bzero the agent address. the kernel was for a while very cranky about - these things. evne though that's fixed, always good to initialize - memory. ok deraadt djm - - djm@cvs.openbsd.org 2011/07/29 14:42:45 - [sandbox-systrace.c] - fail open(2) with EPERM rather than SIGKILLing the whole process. libc - will call open() to do strerror() when NLS is enabled; - feedback and ok markus@ - - markus@cvs.openbsd.org 2011/08/01 19:18:15 - [gss-serv.c] - prevent post-auth resource exhaustion (int overflow leading to 4GB malloc); - report Adam Zabrock; ok djm@, deraadt@ - - djm@cvs.openbsd.org 2011/08/02 01:22:11 - [mac.c myproposal.h ssh.1 ssh_config.5 sshd.8 sshd_config.5] - Add new SHA256 and SHA512 based HMAC modes from - http://www.ietf.org/id/draft-dbider-sha2-mac-for-ssh-02.txt - Patch from mdb AT juniper.net; feedback and ok markus@ - - djm@cvs.openbsd.org 2011/08/02 23:13:01 - [version.h] - crank now, release later - - djm@cvs.openbsd.org 2011/08/02 23:15:03 - [ssh.c] - typo in comment - -20110624 - - (djm) [configure.ac Makefile.in sandbox-darwin.c] Add a sandbox for - Darwin/OS X using sandbox_init() + setrlimit(); feedback and testing - markus@ - -20110623 - - OpenBSD CVS Sync - - djm@cvs.openbsd.org 2011/06/22 21:47:28 - [servconf.c] - reuse the multistate option arrays to pretty-print options for "sshd -T" - - djm@cvs.openbsd.org 2011/06/22 21:57:01 - [servconf.c servconf.h sshd.c sshd_config.5] - [configure.ac Makefile.in] - introduce sandboxing of the pre-auth privsep child using systrace(4). - - This introduces a new "UsePrivilegeSeparation=sandbox" option for - sshd_config that applies mandatory restrictions on the syscalls the - privsep child can perform. This prevents a compromised privsep child - from being used to attack other hosts (by opening sockets and proxying) - or probing local kernel attack surface. - - The sandbox is implemented using systrace(4) in unsupervised "fast-path" - mode, where a list of permitted syscalls is supplied. Any syscall not - on the list results in SIGKILL being sent to the privsep child. Note - that this requires a kernel with the new SYSTR_POLICY_KILL option. - - UsePrivilegeSeparation=sandbox will become the default in the future - so please start testing it now. - - feedback dtucker@; ok markus@ - - djm@cvs.openbsd.org 2011/06/22 22:08:42 - [channels.c channels.h clientloop.c clientloop.h mux.c ssh.c] - hook up a channel confirm callback to warn the user then requested X11 - forwarding was refused by the server; ok markus@ - - djm@cvs.openbsd.org 2011/06/23 09:34:13 - [sshd.c ssh-sandbox.h sandbox.h sandbox-rlimit.c sandbox-systrace.c] - [sandbox-null.c] - rename sandbox.h => ssh-sandbox.h to make things easier for portable - - (djm) [sandbox-null.c] Dummy sandbox for platforms that don't support - setrlimit(2) - -20110620 - - OpenBSD CVS Sync - - djm@cvs.openbsd.org 2011/06/04 00:10:26 - [ssh_config.5] - explain IdentifyFile's semantics a little better, prompted by bz#1898 - ok dtucker jmc - - markus@cvs.openbsd.org 2011/06/14 22:49:18 - [authfile.c] - make sure key_parse_public/private_rsa1() no longer consumes its input - buffer. fixes ssh-add for passphrase-protected ssh1-keys; - noted by naddy@; ok djm@ - - djm@cvs.openbsd.org 2011/06/17 21:44:31 - [log.c log.h monitor.c monitor.h monitor_wrap.c monitor_wrap.h sshd.c] - make the pre-auth privsep slave log via a socketpair shared with the - monitor rather than /var/empty/dev/log; ok dtucker@ deraadt@ markus@ - - djm@cvs.openbsd.org 2011/06/17 21:46:16 - [sftp-server.c] - the protocol version should be unsigned; bz#1913 reported by mb AT - smartftp.com - - djm@cvs.openbsd.org 2011/06/17 21:47:35 - [servconf.c] - factor out multi-choice option parsing into a parse_multistate label - and some support structures; ok dtucker@ - - djm@cvs.openbsd.org 2011/06/17 21:57:25 - [clientloop.c] - setproctitle for a mux master that has been gracefully stopped; - bz#1911 from Bert.Wesarg AT googlemail.com - -20110603 - - (dtucker) [README version.h contrib/caldera/openssh.spec - contrib/redhat/openssh.spec contrib/suse/openssh.spec] Pull the version - bumps from the 5.8p2 branch into HEAD. ok djm. - - (tim) [configure.ac defines.h] Run test program to detect system mail - directory. Add --with-maildir option to override. Fixed OpenServer 6 - getting it wrong. Fixed many systems having MAIL=/var/mail//username - ok dtucker - - (dtucker) [monitor.c] Remove the !HAVE_SOCKETPAIR case. We use socketpair - unconditionally in other places and the survey data we have does not show - any systems that use it. "nuke it" djm@ - - (djm) [configure.ac] enable setproctitle emulation for OS X - - (djm) OpenBSD CVS Sync - - djm@cvs.openbsd.org 2011/06/03 00:54:38 - [ssh.c] - bz#1883 - setproctitle() to identify mux master; patch from Bert.Wesarg - AT googlemail.com; ok dtucker@ - NB. includes additional portability code to enable setproctitle emulation - on platforms that don't support it. - - dtucker@cvs.openbsd.org 2011/06/03 01:37:40 - [ssh-agent.c] - Check current parent process ID against saved one to determine if the parent - has exited, rather than attempting to send a zero signal, since the latter - won't work if the parent has changed privs. bz#1905, patch from Daniel Kahn - Gillmor, ok djm@ - - dtucker@cvs.openbsd.org 2011/05/31 02:01:58 - [regress/dynamic-forward.sh] - back out revs 1.6 and 1.5 since it's not reliable - - dtucker@cvs.openbsd.org 2011/05/31 02:03:34 - [regress/dynamic-forward.sh] - work around startup and teardown races; caught by deraadt - - dtucker@cvs.openbsd.org 2011/06/03 00:29:52 - [regress/dynamic-forward.sh] - Retry establishing the port forwarding after a small delay, should make - the tests less flaky when the previous test is slow to shut down and free - up the port. - - (tim) [regress/cfgmatch.sh] Build/test out of tree fix. - -20110529 - - (djm) OpenBSD CVS Sync - - djm@cvs.openbsd.org 2011/05/23 03:30:07 - [auth-rsa.c auth.c auth.h auth2-pubkey.c monitor.c monitor_wrap.c] - [pathnames.h servconf.c servconf.h sshd.8 sshd_config sshd_config.5] - allow AuthorizedKeysFile to specify multiple files, separated by spaces. - Bring back authorized_keys2 as a default search path (to avoid breaking - existing users of this file), but override this in sshd_config so it will - be no longer used on fresh installs. Maybe in 2015 we can remove it - entierly :) - - feedback and ok markus@ dtucker@ - - djm@cvs.openbsd.org 2011/05/23 03:33:38 - [auth.c] - make secure_filename() spam debug logs less - - djm@cvs.openbsd.org 2011/05/23 03:52:55 - [sshconnect.c] - remove extra newline - - jmc@cvs.openbsd.org 2011/05/23 07:10:21 - [sshd.8 sshd_config.5] - tweak previous; ok djm - - djm@cvs.openbsd.org 2011/05/23 07:24:57 - [authfile.c] - read in key comments for v.2 keys (though note that these are not - passed over the agent protocol); bz#439, based on patch from binder - AT arago.de; ok markus@ - - djm@cvs.openbsd.org 2011/05/24 07:15:47 - [readconf.c readconf.h ssh.c ssh_config.5 sshconnect.c sshconnect2.c] - Remove undocumented legacy options UserKnownHostsFile2 and - GlobalKnownHostsFile2 by making UserKnownHostsFile/GlobalKnownHostsFile - accept multiple paths per line and making their defaults include - known_hosts2; ok markus - - djm@cvs.openbsd.org 2011/05/23 03:31:31 - [regress/cfgmatch.sh] - include testing of multiple/overridden AuthorizedKeysFiles - refactor to simply daemon start/stop and get rid of racy constructs - -20110520 - - (djm) [session.c] call setexeccon() before executing passwd for pw - changes; bz#1891 reported by jchadima AT redhat.com; ok dtucker@ - - (djm) [aclocal.m4 configure.ac] since gcc-4.x ignores all -Wno-options - options, we should corresponding -W-option when trying to determine - whether it is accepted. Also includes a warning fix on the program - fragment uses (bad main() return type). - bz#1900 and bz#1901 reported by g.esp AT free.fr; ok dtucker@ - - (djm) [servconf.c] remove leftover droppings of AuthorizedKeysFile2 - - OpenBSD CVS Sync - - djm@cvs.openbsd.org 2011/05/15 08:09:01 - [authfd.c monitor.c serverloop.c] - use FD_CLOEXEC consistently; patch from zion AT x96.org - - djm@cvs.openbsd.org 2011/05/17 07:13:31 - [key.c] - fatal() if asked to generate a legacy ECDSA cert (these don't exist) - and fix the regress test that was trying to generate them :) - - djm@cvs.openbsd.org 2011/05/20 00:55:02 - [servconf.c] - the options TrustedUserCAKeys, RevokedKeysFile, AuthorizedKeysFile - and AuthorizedPrincipalsFile were not being correctly applied in - Match blocks, despite being overridable there; ok dtucker@ - - dtucker@cvs.openbsd.org 2011/05/20 02:00:19 - [servconf.c] - Add comment documenting what should be after the preauth check. ok djm - - djm@cvs.openbsd.org 2011/05/20 03:25:45 - [monitor.c monitor_wrap.c servconf.c servconf.h] - use a macro to define which string options to copy between configs - for Match. This avoids problems caused by forgetting to keep three - code locations in perfect sync and ordering - - "this is at once beautiful and horrible" + ok dtucker@ - - djm@cvs.openbsd.org 2011/05/17 07:13:31 - [regress/cert-userkey.sh] - fatal() if asked to generate a legacy ECDSA cert (these don't exist) - and fix the regress test that was trying to generate them :) - - djm@cvs.openbsd.org 2011/05/20 02:43:36 - [cert-hostkey.sh] - another attempt to generate a v00 ECDSA key that broke the test - ID sync only - portable already had this somehow - - dtucker@cvs.openbsd.org 2011/05/20 05:19:50 - [dynamic-forward.sh] - Prevent races in dynamic forwarding test; ok djm - - dtucker@cvs.openbsd.org 2011/05/20 06:32:30 - [dynamic-forward.sh] - fix dumb error in dynamic-forward test - -20110515 - - (djm) OpenBSD CVS Sync - - djm@cvs.openbsd.org 2011/05/05 05:12:08 - [mux.c] - gracefully fall back when ControlPath is too large for a - sockaddr_un. ok markus@ as part of a larger diff - - dtucker@cvs.openbsd.org 2011/05/06 01:03:35 - [sshd_config] - clarify language about overriding defaults. bz#1892, from Petr Cerny - - djm@cvs.openbsd.org 2011/05/06 01:09:53 - [sftp.1] - mention that IPv6 addresses must be enclosed in square brackets; - bz#1845 - - djm@cvs.openbsd.org 2011/05/06 02:05:41 - [sshconnect2.c] - fix memory leak; bz#1849 ok dtucker@ - - djm@cvs.openbsd.org 2011/05/06 21:14:05 - [packet.c packet.h] - set traffic class for IPv6 traffic as we do for IPv4 TOS; - patch from lionel AT mamane.lu via Colin Watson in bz#1855; - ok markus@ - - djm@cvs.openbsd.org 2011/05/06 21:18:02 - [ssh.c ssh_config.5] - add a %L expansion (short-form of the local host name) for ControlPath; - sync some more expansions with LocalCommand; ok markus@ - - djm@cvs.openbsd.org 2011/05/06 21:31:38 - [readconf.c ssh_config.5] - support negated Host matching, e.g. - - Host *.example.org !c.example.org - User mekmitasdigoat - - Will match "a.example.org", "b.example.org", but not "c.example.org" - ok markus@ - - djm@cvs.openbsd.org 2011/05/06 21:34:32 - [clientloop.c mux.c readconf.c readconf.h ssh.c ssh_config.5] - Add a RequestTTY ssh_config option to allow configuration-based - control over tty allocation (like -t/-T); ok markus@ - - djm@cvs.openbsd.org 2011/05/06 21:38:58 - [ssh.c] - fix dropping from previous diff - - djm@cvs.openbsd.org 2011/05/06 22:20:10 - [PROTOCOL.mux] - fix numbering; from bert.wesarg AT googlemail.com - - jmc@cvs.openbsd.org 2011/05/07 23:19:39 - [ssh_config.5] - - tweak previous - - come consistency fixes - ok djm - - jmc@cvs.openbsd.org 2011/05/07 23:20:25 - [ssh.1] - +.It RequestTTY - - djm@cvs.openbsd.org 2011/05/08 12:52:01 - [PROTOCOL.mux clientloop.c clientloop.h mux.c] - improve our behaviour when TTY allocation fails: if we are in - RequestTTY=auto mode (the default), then do not treat at TTY - allocation error as fatal but rather just restore the local TTY - to cooked mode and continue. This is more graceful on devices that - never allocate TTYs. - - If RequestTTY is set to "yes" or "force", then failure to allocate - a TTY is fatal. - - ok markus@ - - djm@cvs.openbsd.org 2011/05/10 05:46:46 - [authfile.c] - despam debug() logs by detecting that we are trying to load a private key - in key_try_load_public() and returning early; ok markus@ - - djm@cvs.openbsd.org 2011/05/11 04:47:06 - [auth.c auth.h auth2-pubkey.c pathnames.h servconf.c servconf.h] - remove support for authorized_keys2; it is a relic from the early days - of protocol v.2 support and has been undocumented for many years; - ok markus@ - - djm@cvs.openbsd.org 2011/05/13 00:05:36 - [authfile.c] - warn on unexpected key type in key_parse_private_type() - - (djm) [packet.c] unbreak portability #endif - -20110510 - - (dtucker) [openbsd-compat/openssl-compat.{c,h}] Bug #1882: fix - --with-ssl-engine which was broken with the change from deprecated - SSLeay_add_all_algorithms(). ok djm - -20110506 - - (dtucker) [openbsd-compat/regress/closefromtest.c] Bug #1875: add prototype - for closefrom() in test code. Report from Dan Wallis via Gentoo. - -20110505 - - (djm) [defines.h] Move up include of netinet/ip.h for IPTOS - definitions. From des AT des.no - - (djm) [Makefile.in WARNING.RNG aclocal.m4 buildpkg.sh.in configure.ac] - [entropy.c ssh-add.c ssh-agent.c ssh-keygen.c ssh-keyscan.c] - [ssh-keysign.c ssh-pkcs11-helper.c ssh-rand-helper.8 ssh-rand-helper.c] - [ssh.c ssh_prng_cmds.in sshd.c contrib/aix/buildbff.sh] - [regress/README.regress] Remove ssh-rand-helper and all its - tentacles. PRNGd seeding has been rolled into entropy.c directly. - Thanks to tim@ for testing on affected platforms. - - OpenBSD CVS Sync - - djm@cvs.openbsd.org 2011/03/10 02:52:57 - [auth2-gss.c auth2.c auth.h] - allow GSSAPI authentication to detect when a server-side failure causes - authentication failure and don't count such failures against MaxAuthTries; - bz#1244 from simon AT sxw.org.uk; ok markus@ before lock - - okan@cvs.openbsd.org 2011/03/15 10:36:02 - [ssh-keyscan.c] - use timerclear macro - ok djm@ - - stevesk@cvs.openbsd.org 2011/03/23 15:16:22 - [ssh-keygen.1 ssh-keygen.c] - Add -A option. For each of the key types (rsa1, rsa, dsa and ecdsa) - for which host keys do not exist, generate the host keys with the - default key file path, an empty passphrase, default bits for the key - type, and default comment. This will be used by /etc/rc to generate - new host keys. Idea from deraadt. - ok deraadt - - stevesk@cvs.openbsd.org 2011/03/23 16:24:56 - [ssh-keygen.1] - -q not used in /etc/rc now so remove statement. - - stevesk@cvs.openbsd.org 2011/03/23 16:50:04 - [ssh-keygen.c] - remove -d, documentation removed >10 years ago; ok markus - - jmc@cvs.openbsd.org 2011/03/24 15:29:30 - [ssh-keygen.1] - zap trailing whitespace; - - stevesk@cvs.openbsd.org 2011/03/24 22:14:54 - [ssh-keygen.c] - use strcasecmp() for "clear" cert permission option also; ok djm - - stevesk@cvs.openbsd.org 2011/03/29 18:54:17 - [misc.c misc.h servconf.c] - print ipqos friendly string for sshd -T; ok markus - # sshd -Tf sshd_config|grep ipqos - ipqos lowdelay throughput - - djm@cvs.openbsd.org 2011/04/12 04:23:50 - [ssh-keygen.c] - fix -Wshadow - - djm@cvs.openbsd.org 2011/04/12 05:32:49 - [sshd.c] - exit with 0 status on SIGTERM; bz#1879 - - djm@cvs.openbsd.org 2011/04/13 04:02:48 - [ssh-keygen.1] - improve wording; bz#1861 - - djm@cvs.openbsd.org 2011/04/13 04:09:37 - [ssh-keygen.1] - mention valid -b sizes for ECDSA keys; bz#1862 - - djm@cvs.openbsd.org 2011/04/17 22:42:42 - [PROTOCOL.mux clientloop.c clientloop.h mux.c ssh.1 ssh.c] - allow graceful shutdown of multiplexing: request that a mux server - removes its listener socket and refuse future multiplexing requests; - ok markus@ - - djm@cvs.openbsd.org 2011/04/18 00:46:05 - [ssh-keygen.c] - certificate options are supposed to be packed in lexical order of - option name (though we don't actually enforce this at present). - Move one up that was out of sequence - - djm@cvs.openbsd.org 2011/05/04 21:15:29 - [authfile.c authfile.h ssh-add.c] - allow "ssh-add - < key"; feedback and ok markus@ - - (tim) [configure.ac] Add AC_LANG_SOURCE to OPENSSH_CHECK_CFLAG_COMPILE - so autoreconf 2.68 is happy. - - (tim) [defines.h] Deal with platforms that do not have S_IFSOCK ok djm@ - -20110221 - - (dtucker) [contrib/cygwin/ssh-host-config] From Corinna: revamp of the - Cygwin-specific service installer script ssh-host-config. The actual - functionality is the same, the revisited version is just more - exact when it comes to check for problems which disallow to run - certain aspects of the script. So, part of this script and the also - rearranged service helper script library "csih" is to check if all - the tools required to run the script are available on the system. - The new script also is more thorough to inform the user why the - script failed. Patch from vinschen at redhat com. - -20110218 - - OpenBSD CVS Sync - - djm@cvs.openbsd.org 2011/02/16 00:31:14 - [ssh-keysign.c] - make hostbased auth with ECDSA keys work correctly. Based on patch - by harvey.eneman AT oracle.com in bz#1858; ok markus@ (pre-lock) - -20110206 - - (dtucker) [openbsd-compat/port-linux.c] Bug #1851: fix syntax error in - selinux code. Patch from Leonardo Chiquitto - - (dtucker) [contrib/cygwin/ssh-{host,user}-config] Add ECDSA key - generation and simplify. Patch from Corinna Vinschen. - -20110204 - - OpenBSD CVS Sync - - djm@cvs.openbsd.org 2011/01/31 21:42:15 - [PROTOCOL.mux] - cut'n'pasto; from bert.wesarg AT googlemail.com - - djm@cvs.openbsd.org 2011/02/04 00:44:21 - [key.c] - fix uninitialised nonce variable; reported by Mateusz Kocielski - - djm@cvs.openbsd.org 2011/02/04 00:44:43 - [version.h] - openssh-5.8 - - (djm) [README contrib/caldera/openssh.spec contrib/redhat/openssh.spec] - [contrib/suse/openssh.spec] update versions in docs and spec files. - - Release OpenSSH 5.8p1 - -20110128 - - (djm) [openbsd-compat/port-linux.c] Check whether SELinux is enabled - before attempting setfscreatecon(). Check whether matchpathcon() - succeeded before using its result. Patch from cjwatson AT debian.org; - bz#1851 - -20110127 - - (tim) [config.guess config.sub] Sync with upstream. - - (tim) [configure.ac] Consistent M4 quoting throughout, updated obsolete - AC_TRY_COMPILE with AC_COMPILE_IFELSE, updated obsolete AC_TRY_LINK with - AC_LINK_IFELSE, updated obsolete AC_TRY_RUN with AC_RUN_IFELSE, misc white - space changes for consistency/readability. Makes autoconf 2.68 happy. - "Nice work" djm - -20110125 - - (djm) [configure.ac Makefile.in ssh.c openbsd-compat/port-linux.c - openbsd-compat/port-linux.h] Move SELinux-specific code from ssh.c to - port-linux.c to avoid compilation errors. Add -lselinux to ssh when - building with SELinux support to avoid linking failure; report from - amk AT spamfence.net; ok dtucker - -20110122 - - (dtucker) [configure.ac openbsd-compat/openssl-compat.{c,h}] Add - RSA_get_default_method() for the benefit of openssl versions that don't - have it (at least openssl-engine-0.9.6b). Found and tested by Kevin Brott, - ok djm@. - - OpenBSD CVS Sync - - djm@cvs.openbsd.org 2011/01/22 09:18:53 - [version.h] - crank to OpenSSH-5.7 - - (djm) [README contrib/caldera/openssh.spec contrib/redhat/openssh.spec] - [contrib/suse/openssh.spec] update versions in docs and spec files. - - (djm) Release 5.7p1 - -20110119 - - (tim) [contrib/caldera/openssh.spec] Use CFLAGS from Makefile instead - of RPM so build completes. Signatures were changed to .asc since 4.1p1. - - (djm) [configure.ac] Disable ECC on OpenSSL <0.9.8g. Releases prior to - 0.9.8 lacked it, and 0.9.8a through 0.9.8d have proven buggy in pre- - release testing (random crashes and failure to load ECC keys). - ok dtucker@ - -20110117 - - (djm) [regress/Makefile] use $TEST_SSH_KEYGEN instead of the one in - $PATH, fix cleanup of droppings; reported by openssh AT - roumenpetrov.info; ok dtucker@ - - (djm) [regress/agent-ptrace.sh] Fix false failure on OS X by adding - its unique snowflake of a gdb error to the ones we look for. - - (djm) [regress/agent-getpeereid.sh] leave stdout attached when running - ssh-add to avoid $SUDO failures on Linux - - (dtucker) [openbsd-compat/port-linux.c] Bug #1838: Add support for the new - Linux OOM-killer magic values that changed in 2.6.36 kernels, with fallback - to the old values. Feedback from vapier at gentoo org and djm, ok djm. - - (djm) [configure.ac regress/agent-getpeereid.sh regress/multiplex.sh] - [regress/sftp-glob.sh regress/test-exec.sh] Rework how feature tests are - disabled on platforms that do not support them; add a "config_defined()" - shell function that greps for defines in config.h and use them to decide - on feature tests. - Convert a couple of existing grep's over config.h to use the new function - Add a define "FILESYSTEM_NO_BACKSLASH" for filesystem that can't represent - backslash characters in filenames, enable it for Cygwin and use it to turn - of tests for quotes backslashes in sftp-glob.sh. - based on discussion with vinschen AT redhat.com and dtucker@; ok dtucker@ - - (tim) [regress/agent-getpeereid.sh] shell portability fix. - - (dtucker) [openbsd-compat/port-linux.c] Fix minor bug caught by -Werror on - the tinderbox. - - (dtucker) [LICENCE Makefile.in audit-bsm.c audit-linux.c audit.c audit.h - configure.ac defines.h loginrec.c] Bug #1402: add linux audit subsystem - support, based on patches from Tomas Mraz and jchadima at redhat. - -20110116 - - (dtucker) [Makefile.in configure.ac regress/kextype.sh] Skip sha256-based - on configurations that don't have it. - - OpenBSD CVS Sync - - djm@cvs.openbsd.org 2011/01/16 11:50:05 - [clientloop.c] - Use atomicio when flushing protocol 1 std{out,err} buffers at - session close. This was a latent bug exposed by setting a SIGCHLD - handler and spotted by kevin.brott AT gmail.com; ok dtucker@ - - djm@cvs.openbsd.org 2011/01/16 11:50:36 - [sshconnect.c] - reset the SIGPIPE handler when forking to execute child processes; - ok dtucker@ - - djm@cvs.openbsd.org 2011/01/16 12:05:59 - [clientloop.c] - a couple more tweaks to the post-close protocol 1 stderr/stdout flush: - now that we use atomicio(), convert them from while loops to if statements - add test and cast to compile cleanly with -Wsigned - -20110114 - - OpenBSD CVS Sync - - djm@cvs.openbsd.org 2011/01/13 21:54:53 - [mux.c] - correct error messages; patch from bert.wesarg AT googlemail.com - - djm@cvs.openbsd.org 2011/01/13 21:55:25 - [PROTOCOL.mux] - correct protocol names and add a couple of missing protocol number - defines; patch from bert.wesarg AT googlemail.com - - (djm) [Makefile.in] Use shell test to disable ecdsa key generating in - host-key-force target rather than a substitution that is replaced with a - comment so that the Makefile.in is still a syntactically valid Makefile - (useful to run the distprep target) - - (tim) [regress/cert-hostkey.sh] Typo. Missing $ on variable name. - - (tim) [regress/cert-hostkey.sh] Add missing TEST_SSH_ECC guard around some - ecdsa bits. - -20110113 - - (djm) [misc.c] include time.h for nanosleep() prototype - - (tim) [Makefile.in] test the ECC bits if we have the capability. ok djm - - (tim) [Makefile.in configure.ac opensshd.init.in] Add support for generating - ecdsa keys. ok djm. - - (djm) [entropy.c] cast OPENSSL_VERSION_NUMBER to u_long to avoid - gcc warning on platforms where it defaults to int - - (djm) [regress/Makefile] add a few more generated files to the clean - target - - (djm) [myproposal.h] Fix reversed OPENSSL_VERSION_NUMBER test and bad - #define that was causing diffie-hellman-group-exchange-sha256 to be - incorrectly disabled - - (djm) [regress/kextype.sh] Testing diffie-hellman-group-exchange-sha256 - should not depend on ECC support - -20110112 - - OpenBSD CVS Sync - - nicm@cvs.openbsd.org 2010/10/08 21:48:42 - [openbsd-compat/glob.c] - Extend GLOB_LIMIT to cover readdir and stat and bump the malloc limit - from ARG_MAX to 64K. - Fixes glob-using programs (notably ftp) able to be triggered to hit - resource limits. - Idea from a similar NetBSD change, original problem reported by jasper@. - ok millert tedu jasper - - djm@cvs.openbsd.org 2011/01/12 01:53:14 - avoid some integer overflows mostly with GLOB_APPEND and GLOB_DOOFFS - and sanity check arguments (these will be unnecessary when we switch - struct glob members from being type into to size_t in the future); - "looks ok" tedu@ feedback guenther@ - - (djm) [configure.ac] Turn on -Wno-unused-result for gcc >= 4.4 to avoid - silly warnings on write() calls we don't care succeed or not. - - (djm) [configure.ac] Fix broken test for gcc >= 4.4 with per-compiler - flag tests that don't depend on gcc version at all; suggested by and - ok dtucker@ - -20110111 - - (tim) [regress/host-expand.sh] Fix for building outside of read only - source tree. - - (djm) [platform.c] Some missing includes that show up under -Werror - - OpenBSD CVS Sync - - djm@cvs.openbsd.org 2011/01/08 10:51:51 - [clientloop.c] - use host and not options.hostname, as the latter may have unescaped - substitution characters - - djm@cvs.openbsd.org 2011/01/11 06:06:09 - [sshlogin.c] - fd leak on error paths; from zinovik@ - NB. Id sync only; we use loginrec.c that was also audited and fixed - recently - - djm@cvs.openbsd.org 2011/01/11 06:13:10 - [clientloop.c ssh-keygen.c sshd.c] - some unsigned long long casts that make things a bit easier for - portable without resorting to dropping PRIu64 formats everywhere - -20110109 - - (djm) [Makefile.in] list ssh_host_ecdsa key in PATHSUBS; spotted by - openssh AT roumenpetrov.info - -20110108 - - (djm) [regress/keytype.sh] s/echo -n/echon/ to repair failing regress - test on OSX and others. Reported by imorgan AT nas.nasa.gov - -20110107 - - (djm) [regress/cert-hostkey.sh regress/cert-userkey.sh] fix shell test - for no-ECC case. Patch from cristian.ionescu-idbohrn AT axis.com - - djm@cvs.openbsd.org 2011/01/06 22:23:53 - [ssh.c] - unbreak %n expansion in LocalCommand; patch from bert.wesarg AT - googlemail.com; ok markus@ - - djm@cvs.openbsd.org 2011/01/06 22:23:02 - [clientloop.c] - when exiting due to ServerAliveTimeout, mention the hostname that caused - it (useful with backgrounded controlmaster) - - djm@cvs.openbsd.org 2011/01/06 22:46:21 - [regress/Makefile regress/host-expand.sh] - regress test for LocalCommand %n expansion from bert.wesarg AT - googlemail.com; ok markus@ - - djm@cvs.openbsd.org 2011/01/06 23:01:35 - [sshconnect.c] - reset SIGCHLD handler to SIG_DFL when execuring LocalCommand; - ok markus@ - -20110106 - - (djm) OpenBSD CVS Sync - - markus@cvs.openbsd.org 2010/12/08 22:46:03 - [scp.1 scp.c] - add a new -3 option to scp: Copies between two remote hosts are - transferred through the local host. Without this option the data - is copied directly between the two remote hosts. ok djm@ (bugzilla #1837) - - jmc@cvs.openbsd.org 2010/12/09 14:13:33 - [scp.1 scp.c] - scp.1: grammer fix - scp.c: add -3 to usage() - - markus@cvs.openbsd.org 2010/12/14 11:59:06 - [sshconnect.c] - don't mention key type in key-changed-warning, since we also print - this warning if a new key type appears. ok djm@ - - djm@cvs.openbsd.org 2010/12/15 00:49:27 - [readpass.c] - fix ControlMaster=ask regression - reset SIGCHLD handler before fork (and restore it after) so we don't miss - the the askpass child's exit status. Correct test for exit status/signal to - account for waitpid() failure; with claudio@ ok claudio@ markus@ - - djm@cvs.openbsd.org 2010/12/24 21:41:48 - [auth-options.c] - don't send the actual forced command in a debug message; ok markus deraadt - - otto@cvs.openbsd.org 2011/01/04 20:44:13 - [ssh-keyscan.c] - handle ecdsa-sha2 with various key lengths; hint and ok djm@ - -20110104 - - (djm) [configure.ac Makefile.in] Use mandoc as preferred manpage - formatter if it is present, followed by nroff and groff respectively. - Fixes distprep target on OpenBSD (which has bumped groff/nroff to ports - in favour of mandoc). feedback and ok tim - -20110103 - - (djm) [Makefile.in] revert local hack I didn't intend to commit - -20110102 - - (djm) [loginrec.c] Fix some fd leaks on error paths. ok dtucker - - (djm) [configure.ac] Check whether libdes is needed when building - with Heimdal krb5 support. On OpenBSD this library no longer exists, - so linking it unconditionally causes a build failure; ok dtucker - -20101226 - - (dtucker) OpenBSD CVS Sync - - djm@cvs.openbsd.org 2010/12/08 04:02:47 - [ssh_config.5 sshd_config.5] - explain that IPQoS arguments are separated by whitespace; iirc requested - by jmc@ a while back - -20101205 - - (dtucker) openbsd-compat/openssl-compat.c] remove sleep leftover from - debugging. Spotted by djm. - - (dtucker) OpenBSD CVS Sync - - djm@cvs.openbsd.org 2010/12/03 23:49:26 - [schnorr.c] - check that g^x^q === 1 mod p; recommended by JPAKE author Feng Hao - (this code is still disabled, but apprently people are treating it as - a reference implementation) - - djm@cvs.openbsd.org 2010/12/03 23:55:27 - [auth-rsa.c] - move check for revoked keys to run earlier (in auth_rsa_key_allowed) - bz#1829; patch from ldv AT altlinux.org; ok markus@ - - djm@cvs.openbsd.org 2010/12/04 00:18:01 - [sftp-server.c sftp.1 sftp-client.h sftp.c PROTOCOL sftp-client.c] - add a protocol extension to support a hard link operation. It is - available through the "ln" command in the client. The old "ln" - behaviour of creating a symlink is available using its "-s" option - or through the preexisting "symlink" command; based on a patch from - miklos AT szeredi.hu in bz#1555; ok markus@ - - djm@cvs.openbsd.org 2010/12/04 13:31:37 - [hostfile.c] - fix fd leak; spotted and ok dtucker - - djm@cvs.openbsd.org 2010/12/04 00:21:19 - [regress/sftp-cmds.sh] - adjust for hard-link support - - (dtucker) [regress/Makefile] Id sync. - -20101204 - - (djm) [openbsd-compat/bindresvport.c] Use arc4random_uniform(range) - instead of (arc4random() % range) - - (dtucker) [configure.ac moduli.c openbsd-compat/openssl-compat.{c,h}] Add - shims for the new, non-deprecated OpenSSL key generation functions for - platforms that don't have the new interfaces. - -20101201 - - OpenBSD CVS Sync - - deraadt@cvs.openbsd.org 2010/11/20 05:12:38 - [auth2-pubkey.c] - clean up cases of ;; - - djm@cvs.openbsd.org 2010/11/21 01:01:13 - [clientloop.c misc.c misc.h ssh-agent.1 ssh-agent.c] - honour $TMPDIR for client xauth and ssh-agent temporary directories; - feedback and ok markus@ - - djm@cvs.openbsd.org 2010/11/21 10:57:07 - [authfile.c] - Refactor internals of private key loading and saving to work on memory - buffers rather than directly on files. This will make a few things - easier to do in the future; ok markus@ - - djm@cvs.openbsd.org 2010/11/23 02:35:50 - [auth.c] - use strict_modes already passed as function argument over referencing - global options.strict_modes - - djm@cvs.openbsd.org 2010/11/23 23:57:24 - [clientloop.c] - avoid NULL deref on receiving a channel request on an unknown or invalid - channel; report bz#1842 from jchadima AT redhat.com; ok dtucker@ - - djm@cvs.openbsd.org 2010/11/24 01:24:14 - [channels.c] - remove a debug() that pollutes stderr on client connecting to a server - in debug mode (channel_close_fds is called transitively from the session - code post-fork); bz#1719, ok dtucker - - djm@cvs.openbsd.org 2010/11/25 04:10:09 - [session.c] - replace close() loop for fds 3->64 with closefrom(); - ok markus deraadt dtucker - - djm@cvs.openbsd.org 2010/11/26 05:52:49 - [scp.c] - Pass through ssh command-line flags and options when doing remote-remote - transfers, e.g. to enable agent forwarding which is particularly useful - in this case; bz#1837 ok dtucker@ - - markus@cvs.openbsd.org 2010/11/29 18:57:04 - [authfile.c] - correctly load comment for encrypted rsa1 keys; - report/fix Joachim Schipper; ok djm@ - - djm@cvs.openbsd.org 2010/11/29 23:45:51 - [auth.c hostfile.c hostfile.h ssh.c ssh_config.5 sshconnect.c] - [sshconnect.h sshconnect2.c] - automatically order the hostkeys requested by the client based on - which hostkeys are already recorded in known_hosts. This avoids - hostkey warnings when connecting to servers with new ECDSA keys - that are preferred by default; with markus@ - -20101124 - - (dtucker) [platform.c session.c] Move the getluid call out of session.c and - into the platform-specific code Only affects SCO, tested by and ok tim@. - - (djm) [loginrec.c] Relax permission requirement on btmp logs to allow - group read/write. ok dtucker@ - - (dtucker) [packet.c] Remove redundant local declaration of "int tos". - - (djm) [defines.h] Add IP DSCP defines - -20101122 - - (dtucker) Bug #1840: fix warning when configuring --with-ssl-engine, patch - from vapier at gentoo org. - -20101120 - - OpenBSD CVS Sync - - djm@cvs.openbsd.org 2010/11/05 02:46:47 - [packet.c] - whitespace KNF - - djm@cvs.openbsd.org 2010/11/10 01:33:07 - [kexdhc.c kexdhs.c kexgexc.c kexgexs.c key.c moduli.c] - use only libcrypto APIs that are retained with OPENSSL_NO_DEPRECATED. - these have been around for years by this time. ok markus - - djm@cvs.openbsd.org 2010/11/13 23:27:51 - [clientloop.c misc.c misc.h packet.c packet.h readconf.c readconf.h] - [servconf.c servconf.h session.c ssh.c ssh_config.5 sshd_config.5] - allow ssh and sshd to set arbitrary TOS/DSCP/QoS values instead of - hardcoding lowdelay/throughput. - - bz#1733 patch from philipp AT redfish-solutions.com; ok markus@ deraadt@ - - jmc@cvs.openbsd.org 2010/11/15 07:40:14 - [ssh_config.5] - libary -> library; - - jmc@cvs.openbsd.org 2010/11/18 15:01:00 - [scp.1 sftp.1 ssh.1 sshd_config.5] - add IPQoS to the various -o lists, and zap some trailing whitespace; - -20101111 - - (djm) [servconf.c ssh-add.c ssh-keygen.c] don't look for ECDSA keys on - platforms that don't support ECC. Fixes some spurious warnings reported - by tim@ - -20101109 - - (tim) [regress/kextype.sh] Not all platforms have time in /usr/bin. - Feedback from dtucker@ - - (tim) [configure.ac openbsd-compat/bsd-misc.h openbsd-compat/bsd-misc.c] Add - support for platforms missing isblank(). ok djm@ - -20101108 - - (tim) [regress/Makefile] Fixes to allow building/testing outside source - tree. - - (tim) [regress/kextype.sh] Shell portability fix. - -20101107 - - (dtucker) [platform.c] includes.h instead of defines.h so that we get - the correct typedefs. - -20101105 - - (djm) [loginrec.c loginrec.h] Use correct uid_t/pid_t types instead of - int. Should fix bz#1817 cleanly; ok dtucker@ - - OpenBSD CVS Sync - - djm@cvs.openbsd.org 2010/09/22 12:26:05 - [regress/Makefile regress/kextype.sh] - regress test for each of the key exchange algorithms that we support - - djm@cvs.openbsd.org 2010/10/28 11:22:09 - [authfile.c key.c key.h ssh-keygen.c] - fix a possible NULL deref on loading a corrupt ECDH key - - store ECDH group information in private keys files as "named groups" - rather than as a set of explicit group parameters (by setting - the OPENSSL_EC_NAMED_CURVE flag). This makes for shorter key files and - retrieves the group's OpenSSL NID that we need for various things. - - jmc@cvs.openbsd.org 2010/10/28 18:33:28 - [scp.1 ssh-add.1 ssh-keygen.1 ssh.1 ssh_config.5 sshd.8 sshd_config.5] - knock out some "-*- nroff -*-" lines; - - djm@cvs.openbsd.org 2010/11/04 02:45:34 - [sftp-server.c] - umask should be parsed as octal. reported by candland AT xmission.com; - ok markus@ - - (dtucker) [configure.ac platform.{c,h} session.c - openbsd-compat/port-solaris.{c,h}] Bug #1824: Add Solaris Project support. - Patch from cory.erickson at csu mnscu edu with a bit of rework from me. - ok djm@ - - (dtucker) [platform.c platform.h session.c] Add a platform hook to run - after the user's groups are established and move the selinux calls into it. - - (dtucker) [platform.c session.c] Move the AIX setpcred+chroot hack into - platform.c - - (dtucker) [platform.c session.c] Move the BSDI setpgrp into platform.c. - - (dtucker) [platform.c] Only call setpgrp on BSDI if running as root to - retain previous behavior. - - (dtucker) [platform.c session.c] Move the PAM credential establishment for - the LOGIN_CAP case into platform.c. - - (dtucker) platform.c session.c] Move the USE_LIBIAF fragment into - platform.c - - (dtucker) [platform.c session.c] Move aix_usrinfo frament into platform.c. - - (dtucker) [platform.c session.c] Move irix setusercontext fragment into - platform.c. - - (dtucker) [platform.c session.c] Move PAM credential establishment for the - non-LOGIN_CAP case into platform.c. - - (dtucker) [platform.c platform.h session.c] Move the Cygwin special-case - check into platform.c - - (dtucker) [regress/keytype.sh] Import new test. - - (dtucker) [Makefile configure.ac regress/Makefile regress/keytype.sh] - Import recent changes to regress/Makefile, pass a flag to enable ECC tests - from configure through to regress/Makefile and use it in the tests. - - (dtucker) [regress/kextype.sh] Add missing "test". - - (dtucker) [regress/kextype.sh] Make sha256 test depend on ECC. This is not - strictly correct since while ECC requires sha256 the reverse is not true - however it does prevent spurious test failures. - - (dtucker) [platform.c] Need servconf.h and extern options. - -20101025 - - (tim) [openbsd-compat/glob.h] Remove sys/cdefs.h include that came with - 1.12 to unbreak Solaris build. - ok djm@ - - (dtucker) [defines.h] Use SIZE_T_MAX for SIZE_MAX for platforms that have a - native one. - -20101024 - - (dtucker) [includes.h] Add missing ifdef GLOB_HAS_GL_STATV to fix build. - - (dtucker) [regress/cert-hostkey.sh] Disable ECC-based tests on platforms - which don't have ECC support in libcrypto. - - (dtucker) [regress/cert-userkey.sh] Disable ECC-based tests on platforms - which don't have ECC support in libcrypto. - - (dtucker) [defines.h] Add SIZE_MAX for the benefit of platforms that don't - have it. - - (dtucker) OpenBSD CVS Sync - - sthen@cvs.openbsd.org 2010/10/23 22:06:12 - [sftp.c] - escape '[' in filename tab-completion; fix a type while there. - ok djm@ - -20101021 - - OpenBSD CVS Sync - - dtucker@cvs.openbsd.org 2010/10/12 02:22:24 - [mux.c] - Typo in confirmation message. bz#1827, patch from imorgan at - nas nasa gov - - djm@cvs.openbsd.org 2010/08/31 12:24:09 - [regress/cert-hostkey.sh regress/cert-userkey.sh] - tests for ECDSA certificates - -20101011 - - (djm) [canohost.c] Zero a4 instead of addr to better match type. - bz#1825, reported by foo AT mailinator.com - - (djm) [sshconnect.c] Need signal.h for prototype for kill(2) - -20101011 - - (djm) [configure.ac] Use = instead of == in shell tests. Patch from - dr AT vasco.com - -20101007 - - (djm) [ssh-agent.c] Fix type for curve name. - - (djm) OpenBSD CVS Sync - - matthew@cvs.openbsd.org 2010/09/24 13:33:00 - [misc.c misc.h configure.ac openbsd-compat/openbsd-compat.h] - [openbsd-compat/timingsafe_bcmp.c] - Add timingsafe_bcmp(3) to libc, mention that it's already in the - kernel in kern(9), and remove it from OpenSSH. - ok deraadt@, djm@ - NB. re-added under openbsd-compat/ for portable OpenSSH - - djm@cvs.openbsd.org 2010/09/25 09:30:16 - [sftp.c configure.ac openbsd-compat/glob.c openbsd-compat/glob.h] - make use of new glob(3) GLOB_KEEPSTAT extension to save extra server - rountrips to fetch per-file stat(2) information. - NB. update openbsd-compat/ glob(3) implementation from OpenBSD libc to - match. - - djm@cvs.openbsd.org 2010/09/26 22:26:33 - [sftp.c] - when performing an "ls" in columnated (short) mode, only call - ioctl(TIOCGWINSZ) once to get the window width instead of per- - filename - - djm@cvs.openbsd.org 2010/09/30 11:04:51 - [servconf.c] - prevent free() of string in .rodata when overriding AuthorizedKeys in - a Match block; patch from rein AT basefarm.no - - djm@cvs.openbsd.org 2010/10/01 23:05:32 - [cipher-3des1.c cipher-bf1.c cipher-ctr.c openbsd-compat/openssl-compat.h] - adapt to API changes in openssl-1.0.0a - NB. contains compat code to select correct API for older OpenSSL - - djm@cvs.openbsd.org 2010/10/05 05:13:18 - [sftp.c sshconnect.c] - use default shell /bin/sh if $SHELL is ""; ok markus@ - - djm@cvs.openbsd.org 2010/10/06 06:39:28 - [clientloop.c ssh.c sshconnect.c sshconnect.h] - kill proxy command on fatal() (we already kill it on clean exit); - ok markus@ - - djm@cvs.openbsd.org 2010/10/06 21:10:21 - [sshconnect.c] - swapped args to kill(2) - - (djm) [openbsd-compat/glob.c] restore ARG_MAX compat code. - - (djm) [cipher-acss.c] Add missing header. - - (djm) [openbsd-compat/Makefile.in] Actually link timingsafe_bcmp - -20100924 - - (djm) OpenBSD CVS Sync - - naddy@cvs.openbsd.org 2010/09/10 15:19:29 - [ssh-keygen.1] - * mention ECDSA in more places - * less repetition in FILES section - * SSHv1 keys are still encrypted with 3DES - help and ok jmc@ - - djm@cvs.openbsd.org 2010/09/11 21:44:20 - [ssh.1] - mention RFC 5656 for ECC stuff - - jmc@cvs.openbsd.org 2010/09/19 21:30:05 - [sftp.1] - more wacky macro fixing; - - djm@cvs.openbsd.org 2010/09/20 04:41:47 - [ssh.c] - install a SIGCHLD handler to reap expiried child process; ok markus@ - - djm@cvs.openbsd.org 2010/09/20 04:50:53 - [jpake.c schnorr.c] - check that received values are smaller than the group size in the - disabled and unfinished J-PAKE code. - avoids catastrophic security failure found by Sebastien Martini - - djm@cvs.openbsd.org 2010/09/20 04:54:07 - [jpake.c] - missing #include - - djm@cvs.openbsd.org 2010/09/20 07:19:27 - [mux.c] - "atomically" create the listening mux socket by binding it on a temorary - name and then linking it into position after listen() has succeeded. - this allows the mux clients to determine that the server socket is - either ready or stale without races. stale server sockets are now - automatically removed - ok deraadt - - djm@cvs.openbsd.org 2010/09/22 05:01:30 - [kex.c kex.h kexecdh.c kexecdhc.c kexecdhs.c readconf.c readconf.h] - [servconf.c servconf.h ssh_config.5 sshconnect2.c sshd.c sshd_config.5] - add a KexAlgorithms knob to the client and server configuration to allow - selection of which key exchange methods are used by ssh(1) and sshd(8) - and their order of preference. - ok markus@ - - jmc@cvs.openbsd.org 2010/09/22 08:30:08 - [ssh.1 ssh_config.5] - ssh.1: add kexalgorithms to the -o list - ssh_config.5: format the kexalgorithms in a more consistent - (prettier!) way - ok djm - - djm@cvs.openbsd.org 2010/09/22 22:58:51 - [atomicio.c atomicio.h misc.c misc.h scp.c sftp-client.c] - [sftp-client.h sftp.1 sftp.c] - add an option per-read/write callback to atomicio - - factor out bandwidth limiting code from scp(1) into a generic bandwidth - limiter that can be attached using the atomicio callback mechanism - - add a bandwidth limit option to sftp(1) using the above - "very nice" markus@ - - jmc@cvs.openbsd.org 2010/09/23 13:34:43 - [sftp.c] - add [-l limit] to usage(); - - jmc@cvs.openbsd.org 2010/09/23 13:36:46 - [scp.1 sftp.1] - add KexAlgorithms to the -o list; - -20100910 - - (dtucker) [openbsd-compat/port-linux.c] Check is_selinux_enabled for exact - return code since it can apparently return -1 under some conditions. From - openssh bugs werbittewas de, ok djm@ - - OpenBSD CVS Sync - - djm@cvs.openbsd.org 2010/08/31 12:33:38 - [ssh-add.c ssh-agent.c ssh-keygen.c ssh-keysign.c ssh.c sshd.c] - reintroduce commit from tedu@, which I pulled out for release - engineering: - OpenSSL_add_all_algorithms is the name of the function we have a - man page for, so use that. ok djm - - jmc@cvs.openbsd.org 2010/08/31 17:40:54 - [ssh-agent.1] - fix some macro abuse; - - jmc@cvs.openbsd.org 2010/08/31 21:14:58 - [ssh.1] - small text tweak to accommodate previous; - - naddy@cvs.openbsd.org 2010/09/01 15:21:35 - [servconf.c] - pick up ECDSA host key by default; ok djm@ - - markus@cvs.openbsd.org 2010/09/02 16:07:25 - [ssh-keygen.c] - permit -b 256, 384 or 521 as key size for ECDSA; ok djm@ - - markus@cvs.openbsd.org 2010/09/02 16:08:39 - [ssh.c] - unbreak ControlPersist=yes for ControlMaster=yes; ok djm@ - - naddy@cvs.openbsd.org 2010/09/02 17:21:50 - [ssh-keygen.c] - Switch ECDSA default key size to 256 bits, which according to RFC5656 - should still be better than our current RSA-2048 default. - ok djm@, markus@ - - jmc@cvs.openbsd.org 2010/09/03 11:09:29 - [scp.1] - add an EXIT STATUS section for /usr/bin; - - jmc@cvs.openbsd.org 2010/09/04 09:38:34 - [ssh-add.1 ssh.1] - two more EXIT STATUS sections; - - naddy@cvs.openbsd.org 2010/09/06 17:10:19 - [sshd_config] - add ssh_host_ecdsa_key to /etc; from Mattieu Baptiste - - ok deraadt@ - - djm@cvs.openbsd.org 2010/09/08 03:54:36 - [authfile.c] - typo - - deraadt@cvs.openbsd.org 2010/09/08 04:13:31 - [compress.c] - work around name-space collisions some buggy compilers (looking at you - gcc, at least in earlier versions, but this does not forgive your current - transgressions) seen between zlib and openssl - ok djm - - djm@cvs.openbsd.org 2010/09/09 10:45:45 - [kex.c kex.h kexecdh.c key.c key.h monitor.c ssh-ecdsa.c] - ECDH/ECDSA compliance fix: these methods vary the hash function they use - (SHA256/384/512) depending on the length of the curve in use. The previous - code incorrectly used SHA256 in all cases. - - This fix will cause authentication failure when using 384 or 521-bit curve - keys if one peer hasn't been upgraded and the other has. (256-bit curve - keys work ok). In particular you may need to specify HostkeyAlgorithms - when connecting to a server that has not been upgraded from an upgraded - client. - - ok naddy@ - - (djm) [authfd.c authfile.c bufec.c buffer.h configure.ac kex.h kexecdh.c] - [kexecdhc.c kexecdhs.c key.c key.h myproposal.h packet.c readconf.c] - [ssh-agent.c ssh-ecdsa.c ssh-keygen.c ssh.c] Disable ECDH and ECDSA on - platforms that don't have the requisite OpenSSL support. ok dtucker@ - - (dtucker) [kex.h key.c packet.h ssh-agent.c ssh.c] A few more ECC ifdefs - for missing headers and compiler warnings. - -20100831 - - OpenBSD CVS Sync - - jmc@cvs.openbsd.org 2010/08/08 19:36:30 - [ssh-keysign.8 ssh.1 sshd.8] - use the same template for all FILES sections; i.e. -compact/.Pp where we - have multiple items, and .Pa for path names; - - tedu@cvs.openbsd.org 2010/08/12 23:34:39 - [ssh-add.c ssh-agent.c ssh-keygen.c ssh-keysign.c ssh.c sshd.c] - OpenSSL_add_all_algorithms is the name of the function we have a man page - for, so use that. ok djm - - djm@cvs.openbsd.org 2010/08/16 04:06:06 - [ssh-add.c ssh-agent.c ssh-keygen.c ssh-keysign.c ssh.c sshd.c] - backout previous temporarily; discussed with deraadt@ - - djm@cvs.openbsd.org 2010/08/31 09:58:37 - [auth-options.c auth1.c auth2.c bufaux.c buffer.h kex.c key.c packet.c] - [packet.h ssh-dss.c ssh-rsa.c] - Add buffer_get_cstring() and related functions that verify that the - string extracted from the buffer contains no embedded \0 characters* - This prevents random (possibly malicious) crap from being appended to - strings where it would not be noticed if the string is used with - a string(3) function. - - Use the new API in a few sensitive places. - - * actually, we allow a single one at the end of the string for now because - we don't know how many deployed implementations get this wrong, but don't - count on this to remain indefinitely. - - djm@cvs.openbsd.org 2010/08/31 11:54:45 - [PROTOCOL PROTOCOL.agent PROTOCOL.certkeys auth2-jpake.c authfd.c] - [authfile.c buffer.h dns.c kex.c kex.h key.c key.h monitor.c] - [monitor_wrap.c myproposal.h packet.c packet.h pathnames.h readconf.c] - [ssh-add.1 ssh-add.c ssh-agent.1 ssh-agent.c ssh-keygen.1 ssh-keygen.c] - [ssh-keyscan.1 ssh-keyscan.c ssh-keysign.8 ssh.1 ssh.c ssh2.h] - [ssh_config.5 sshconnect.c sshconnect2.c sshd.8 sshd.c sshd_config.5] - [uuencode.c uuencode.h bufec.c kexecdh.c kexecdhc.c kexecdhs.c ssh-ecdsa.c] - Implement Elliptic Curve Cryptography modes for key exchange (ECDH) and - host/user keys (ECDSA) as specified by RFC5656. ECDH and ECDSA offer - better performance than plain DH and DSA at the same equivalent symmetric - key length, as well as much shorter keys. - - Only the mandatory sections of RFC5656 are implemented, specifically the - three REQUIRED curves nistp256, nistp384 and nistp521 and only ECDH and - ECDSA. Point compression (optional in RFC5656 is NOT implemented). - - Certificate host and user keys using the new ECDSA key types are supported. - - Note that this code has not been tested for interoperability and may be - subject to change. - - feedback and ok markus@ - - (djm) [Makefile.in] Add new ECC files - - (djm) [bufec.c kexecdh.c kexecdhc.c kexecdhs.c ssh-ecdsa.c] include - includes.h - -20100827 - - (dtucker) [contrib/redhat/sshd.init] Bug #1810: initlog is deprecated, - remove. Patch from martynas at venck us - -20100823 - - (djm) Release OpenSSH-5.6p1 - -20100816 - - (dtucker) [configure.ac openbsd-compat/Makefile.in - openbsd-compat/openbsd-compat.h openbsd-compat/strptime.c] Add strptime to - the compat library which helps on platforms like old IRIX. Based on work - by djm, tested by Tom Christensen. - - OpenBSD CVS Sync - - djm@cvs.openbsd.org 2010/08/12 21:49:44 - [ssh.c] - close any extra file descriptors inherited from parent at start and - reopen stdin/stdout to /dev/null when forking for ControlPersist. - - prevents tools that fork and run a captive ssh for communication from - failing to exit when the ssh completes while they wait for these fds to - close. The inherited fds may persist arbitrarily long if a background - mux master has been started by ControlPersist. cvs and scp were effected - by this. - - "please commit" markus@ - - (djm) [regress/README.regress] typo - -20100812 - - (tim) [regress/login-timeout.sh regress/reconfigure.sh regress/reexec.sh - regress/test-exec.sh] Under certain conditions when testing with sudo - tests would fail because the pidfile could not be read by a regular user. - "cat: cannot open ...../regress/pidfile: Permission denied (error 13)" - Make sure cat is run by $SUDO. no objection from me. djm@ - - (tim) [auth.c] add cast to quiet compiler. Change only affects SVR5 systems. - -20100809 - - (djm) bz#1561: don't bother setting IFF_UP on tun(4) device if it is - already set. Makes FreeBSD user openable tunnels useful; patch from - richard.burakowski+ossh AT mrburak.net, ok dtucker@ - - (dtucker) bug #1530: strip trailing ":" from hostname in ssh-copy-id. - based in part on a patch from Colin Watson, ok djm@ - -20100809 - - OpenBSD CVS Sync - - djm@cvs.openbsd.org 2010/08/08 16:26:42 - [version.h] - crank to 5.6 - - (djm) [README contrib/caldera/openssh.spec contrib/redhat/openssh.spec] - [contrib/suse/openssh.spec] Crank version numbers - -20100805 - - OpenBSD CVS Sync - - djm@cvs.openbsd.org 2010/08/04 05:37:01 - [ssh.1 ssh_config.5 sshd.8] - Remove mentions of weird "addr/port" alternate address format for IPv6 - addresses combinations. It hasn't worked for ages and we have supported - the more commen "[addr]:port" format for a long time. ok jmc@ markus@ - - djm@cvs.openbsd.org 2010/08/04 05:40:39 - [PROTOCOL.certkeys ssh-keygen.c] - tighten the rules for certificate encoding by requiring that options - appear in lexical order and make our ssh-keygen comply. ok markus@ - - djm@cvs.openbsd.org 2010/08/04 05:42:47 - [auth.c auth2-hostbased.c authfile.c authfile.h ssh-keysign.8] - [ssh-keysign.c ssh.c] - enable certificates for hostbased authentication, from Iain Morgan; - "looks ok" markus@ - - djm@cvs.openbsd.org 2010/08/04 05:49:22 - [authfile.c] - commited the wrong version of the hostbased certificate diff; this - version replaces some strlc{py,at} verbosity with xasprintf() at - the request of markus@ - - djm@cvs.openbsd.org 2010/08/04 06:07:11 - [ssh-keygen.1 ssh-keygen.c] - Support CA keys in PKCS#11 tokens; feedback and ok markus@ - - djm@cvs.openbsd.org 2010/08/04 06:08:40 - [ssh-keysign.c] - clean for -Wuninitialized (Id sync only; portable had this change) - - djm@cvs.openbsd.org 2010/08/05 13:08:42 - [channels.c] - Fix a trio of bugs in the local/remote window calculation for datagram - data channels (i.e. TunnelForward): - - Calculate local_consumed correctly in channel_handle_wfd() by measuring - the delta to buffer_len(c->output) from when we start to when we finish. - The proximal problem here is that the output_filter we use in portable - modified the length of the dequeued datagram (to futz with the headers - for !OpenBSD). - - In channel_output_poll(), don't enqueue datagrams that won't fit in the - peer's advertised packet size (highly unlikely to ever occur) or which - won't fit in the peer's remaining window (more likely). - - In channel_input_data(), account for the 4-byte string header in - datagram packets that we accept from the peer and enqueue in c->output. - - report, analysis and testing 2/3 cases from wierbows AT us.ibm.com; - "looks good" markus@ - -20100803 - - (dtucker) [monitor.c] Bug #1795: Initialize the values to be returned from - PAM to sane values in case the PAM method doesn't write to them. Spotted by - Bitman Zhou, ok djm@. - - OpenBSD CVS Sync - - djm@cvs.openbsd.org 2010/07/16 04:45:30 - [ssh-keygen.c] - avoid bogus compiler warning - - djm@cvs.openbsd.org 2010/07/16 14:07:35 - [ssh-rsa.c] - more timing paranoia - compare all parts of the expected decrypted - data before returning. AFAIK not exploitable in the SSH protocol. - "groovy" deraadt@ - - djm@cvs.openbsd.org 2010/07/19 03:16:33 - [sftp-client.c] - bz#1797: fix swapped args in upload_dir_internal(), breaking recursive - upload depth checks and causing verbose printing of transfers to always - be turned on; patch from imorgan AT nas.nasa.gov - - djm@cvs.openbsd.org 2010/07/19 09:15:12 - [clientloop.c readconf.c readconf.h ssh.c ssh_config.5] - add a "ControlPersist" option that automatically starts a background - ssh(1) multiplex master when connecting. This connection can stay alive - indefinitely, or can be set to automatically close after a user-specified - duration of inactivity. bz#1330 - patch by dwmw2 AT infradead.org, but - further hacked on by wmertens AT cisco.com, apb AT cequrux.com, - martin-mindrot-bugzilla AT earth.li and myself; "looks ok" markus@ - - djm@cvs.openbsd.org 2010/07/21 02:10:58 - [misc.c] - sync timingsafe_bcmp() with the one dempsky@ committed to sys/lib/libkern - - dtucker@cvs.openbsd.org 2010/07/23 08:49:25 - [ssh.1] - Ciphers is documented in ssh_config(5) these days - -20100819 - - (dtucker) [contrib/ssh-copy-ud.1] Bug #1786: update ssh-copy-id.1 with more - details about its behaviour WRT existing directories. Patch from - asguthrie at gmail com, ok djm. - -20100716 - - (djm) OpenBSD CVS Sync - - djm@cvs.openbsd.org 2010/07/02 04:32:44 - [misc.c] - unbreak strdelim() skipping past quoted strings, e.g. - AllowUsers "blah blah" blah - was broken; report and fix in bz#1757 from bitman.zhou AT centrify.com - ok dtucker; - - djm@cvs.openbsd.org 2010/07/12 22:38:52 - [ssh.c] - Make ExitOnForwardFailure work with fork-after-authentication ("ssh -f") - for protocol 2. ok markus@ - - djm@cvs.openbsd.org 2010/07/12 22:41:13 - [ssh.c ssh_config.5] - expand %h to the hostname in ssh_config Hostname options. While this - sounds useless, it is actually handy for working with unqualified - hostnames: - - Host *.* - Hostname %h - Host * - Hostname %h.example.org - - "I like it" markus@ - - djm@cvs.openbsd.org 2010/07/13 11:52:06 - [auth-rsa.c channels.c jpake.c key.c misc.c misc.h monitor.c] - [packet.c ssh-rsa.c] - implement a timing_safe_cmp() function to compare memory without leaking - timing information by short-circuiting like memcmp() and use it for - some of the more sensitive comparisons (though nothing high-value was - readily attackable anyway); "looks ok" markus@ - - djm@cvs.openbsd.org 2010/07/13 23:13:16 - [auth-rsa.c channels.c jpake.c key.c misc.c misc.h monitor.c packet.c] - [ssh-rsa.c] - s/timing_safe_cmp/timingsafe_bcmp/g - - jmc@cvs.openbsd.org 2010/07/14 17:06:58 - [ssh.1] - finally ssh synopsis looks nice again! this commit just removes a ton of - hacks we had in place to make it work with old groff; - - schwarze@cvs.openbsd.org 2010/07/15 21:20:38 - [ssh-keygen.1] - repair incorrect block nesting, which screwed up indentation; - problem reported and fix OK by jmc@ - -20100714 - - (tim) [contrib/redhat/openssh.spec] Bug 1796: Test for skip_x11_askpass - (line 77) should have been for no_x11_askpass. - -20100702 - - (djm) OpenBSD CVS Sync - - jmc@cvs.openbsd.org 2010/06/26 00:57:07 - [ssh_config.5] - tweak previous; - - djm@cvs.openbsd.org 2010/06/26 23:04:04 - [ssh.c] - oops, forgot to #include ; spotted and patch from chl@ - - djm@cvs.openbsd.org 2010/06/29 23:15:30 - [ssh-keygen.1 ssh-keygen.c] - allow import (-i) and export (-e) of PEM and PKCS#8 encoded keys; - bz#1749; ok markus@ - - djm@cvs.openbsd.org 2010/06/29 23:16:46 - [auth2-pubkey.c sshd_config.5] - allow key options (command="..." and friends) in AuthorizedPrincipals; - ok markus@ - - jmc@cvs.openbsd.org 2010/06/30 07:24:25 - [ssh-keygen.1] - tweak previous; - - jmc@cvs.openbsd.org 2010/06/30 07:26:03 - [ssh-keygen.c] - sort usage(); - - jmc@cvs.openbsd.org 2010/06/30 07:28:34 - [sshd_config.5] - tweak previous; - - millert@cvs.openbsd.org 2010/07/01 13:06:59 - [scp.c] - Fix a longstanding problem where if you suspend scp at the - password/passphrase prompt the terminal mode is not restored. - OK djm@ - - phessler@cvs.openbsd.org 2010/06/27 19:19:56 - [regress/Makefile] - fix how we run the tests so we can successfully use SUDO='sudo -E' - in our env - - djm@cvs.openbsd.org 2010/06/29 23:59:54 - [cert-userkey.sh] - regress tests for key options in AuthorizedPrincipals - -20100627 - - (tim) [openbsd-compat/port-uw.c] Reorder includes. auth-options.h now needs - key.h. - -20100626 - - (djm) OpenBSD CVS Sync - - djm@cvs.openbsd.org 2010/05/21 05:00:36 - [misc.c] - colon() returns char*, so s/return (0)/return NULL/ - - markus@cvs.openbsd.org 2010/06/08 21:32:19 - [ssh-pkcs11.c] - check length of value returned C_GetAttributValue for != 0 - from mdrtbugzilla@codefive.co.uk; bugzilla #1773; ok dtucker@ - - djm@cvs.openbsd.org 2010/06/17 07:07:30 - [mux.c] - Correct sizing of object to be allocated by calloc(), replacing - sizeof(state) with sizeof(*state). This worked by accident since - the struct contained a single int at present, but could have broken - in the future. patch from hyc AT symas.com - - djm@cvs.openbsd.org 2010/06/18 00:58:39 - [sftp.c] - unbreak ls in working directories that contains globbing characters in - their pathnames. bz#1655 reported by vgiffin AT apple.com - - djm@cvs.openbsd.org 2010/06/18 03:16:03 - [session.c] - Missing check for chroot_director == "none" (we already checked against - NULL); bz#1564 from Jan.Pechanec AT Sun.COM - - djm@cvs.openbsd.org 2010/06/18 04:43:08 - [sftp-client.c] - fix memory leak in do_realpath() error path; bz#1771, patch from - anicka AT suse.cz - - djm@cvs.openbsd.org 2010/06/22 04:22:59 - [servconf.c sshd_config.5] - expose some more sshd_config options inside Match blocks: - AuthorizedKeysFile AuthorizedPrincipalsFile - HostbasedUsesNameFromPacketOnly PermitTunnel - bz#1764; feedback from imorgan AT nas.nasa.gov; ok dtucker@ - - djm@cvs.openbsd.org 2010/06/22 04:32:06 - [ssh-keygen.c] - standardise error messages when attempting to open private key - files to include "progname: filename: error reason" - bz#1783; ok dtucker@ - - djm@cvs.openbsd.org 2010/06/22 04:49:47 - [auth.c] - queue auth debug messages for bad ownership or permissions on the user's - keyfiles. These messages will be sent after the user has successfully - authenticated (where our client will display them with LogLevel=debug). - bz#1554; ok dtucker@ - - djm@cvs.openbsd.org 2010/06/22 04:54:30 - [ssh-keyscan.c] - replace verbose and overflow-prone Linebuf code with read_keyfile_line() - based on patch from joachim AT joachimschipper.nl; bz#1565; ok dtucker@ - - djm@cvs.openbsd.org 2010/06/22 04:59:12 - [session.c] - include the user name on "subsystem request for ..." log messages; - bz#1571; ok dtucker@ - - djm@cvs.openbsd.org 2010/06/23 02:59:02 - [ssh-keygen.c] - fix printing of extensions in v01 certificates that I broke in r1.190 - - djm@cvs.openbsd.org 2010/06/25 07:14:46 - [channels.c mux.c readconf.c readconf.h ssh.h] - bz#1327: remove hardcoded limit of 100 permitopen clauses and port - forwards per direction; ok markus@ stevesk@ - - djm@cvs.openbsd.org 2010/06/25 07:20:04 - [channels.c session.c] - bz#1750: fix requirement for /dev/null inside ChrootDirectory for - internal-sftp accidentally introduced in r1.253 by removing the code - that opens and dup /dev/null to stderr and modifying the channels code - to read stderr but discard it instead; ok markus@ - - djm@cvs.openbsd.org 2010/06/25 08:46:17 - [auth1.c auth2-none.c] - skip the initial check for access with an empty password when - PermitEmptyPasswords=no; bz#1638; ok markus@ - - djm@cvs.openbsd.org 2010/06/25 23:10:30 - [ssh.c] - log the hostname and address that we connected to at LogLevel=verbose - after authentication is successful to mitigate "phishing" attacks by - servers with trusted keys that accept authentication silently and - automatically before presenting fake password/passphrase prompts; - "nice!" markus@ - - djm@cvs.openbsd.org 2010/06/25 23:10:30 - [ssh.c] - log the hostname and address that we connected to at LogLevel=verbose - after authentication is successful to mitigate "phishing" attacks by - servers with trusted keys that accept authentication silently and - automatically before presenting fake password/passphrase prompts; - "nice!" markus@ - -20100622 - - (djm) [loginrec.c] crank LINFO_NAMESIZE (username length) to 512 - bz#1579; ok dtucker - -20100618 - - (djm) [contrib/ssh-copy-id] Update key file explicitly under ~ - rather than assuming that $CWD == $HOME. bz#1500, patch from - timothy AT gelter.com - -20100617 - - (tim) [contrib/cygwin/README] Remove a reference to the obsolete - minires-devel package, and to add the reference to the libedit-devel - package since CYgwin now provides libedit. Patch from Corinna Vinschen. - -20100521 - - (djm) OpenBSD CVS Sync - - djm@cvs.openbsd.org 2010/05/07 11:31:26 - [regress/Makefile regress/cert-userkey.sh] - regress tests for AuthorizedPrincipalsFile and "principals=" key option. - feedback and ok markus@ - - djm@cvs.openbsd.org 2010/05/11 02:58:04 - [auth-rsa.c] - don't accept certificates marked as "cert-authority" here; ok markus@ - - djm@cvs.openbsd.org 2010/05/14 00:47:22 - [ssh-add.c] - check that the certificate matches the corresponding private key before - grafting it on - - djm@cvs.openbsd.org 2010/05/14 23:29:23 - [channels.c channels.h mux.c ssh.c] - Pause the mux channel while waiting for reply from aynch callbacks. - Prevents misordering of replies if new requests arrive while waiting. - - Extend channel open confirm callback to allow signalling failure - conditions as well as success. Use this to 1) fix a memory leak, 2) - start using the above pause mechanism and 3) delay sending a success/ - failure message on mux slave session open until we receive a reply from - the server. - - motivated by and with feedback from markus@ - - markus@cvs.openbsd.org 2010/05/16 12:55:51 - [PROTOCOL.mux clientloop.h mux.c readconf.c readconf.h ssh.1 ssh.c] - mux support for remote forwarding with dynamic port allocation, - use with - LPORT=`ssh -S muxsocket -R0:localhost:25 -O forward somehost` - feedback and ok djm@ - - djm@cvs.openbsd.org 2010/05/20 11:25:26 - [auth2-pubkey.c] - fix logspam when key options (from="..." especially) deny non-matching - keys; reported by henning@ also bz#1765; ok markus@ dtucker@ - - djm@cvs.openbsd.org 2010/05/20 23:46:02 - [PROTOCOL.certkeys auth-options.c ssh-keygen.c] - Move the permit-* options to the non-critical "extensions" field for v01 - certificates. The logic is that if another implementation fails to - implement them then the connection just loses features rather than fails - outright. - - ok markus@ - -20100511 - - (dtucker) [Makefile.in] Bug #1770: Link libopenbsd-compat twice to solve - circular dependency problem on old or odd platforms. From Tom Lane, ok - djm@. - - (djm) [openbsd-compat/openssl-compat.h] Fix build breakage on older - libcrypto by defining OPENSSL_[DR]SA_MAX_MODULUS_BITS if they aren't - already. ok dtucker@ - -20100510 - - OpenBSD CVS Sync - - djm@cvs.openbsd.org 2010/04/23 01:47:41 - [ssh-keygen.c] - bz#1740: display a more helpful error message when $HOME is - inaccessible while trying to create .ssh directory. Based on patch - from jchadima AT redhat.com; ok dtucker@ - - djm@cvs.openbsd.org 2010/04/23 22:27:38 - [mux.c] - set "detach_close" flag when registering channel cleanup callbacks. - This causes the channel to close normally when its fds close and - hangs when terminating a mux slave using ~. bz#1758; ok markus@ - - djm@cvs.openbsd.org 2010/04/23 22:42:05 - [session.c] - set stderr to /dev/null for subsystems rather than just closing it. - avoids hangs if a subsystem or shell initialisation writes to stderr. - bz#1750; ok markus@ - - djm@cvs.openbsd.org 2010/04/23 22:48:31 - [ssh-keygen.c] - refuse to generate keys longer than OPENSSL_[RD]SA_MAX_MODULUS_BITS, - since we would refuse to use them anyway. bz#1516; ok dtucker@ - - djm@cvs.openbsd.org 2010/04/26 22:28:24 - [sshconnect2.c] - bz#1502: authctxt.success is declared as an int, but passed by - reference to function that accepts sig_atomic_t*. Convert it to - the latter; ok markus@ dtucker@ - - djm@cvs.openbsd.org 2010/05/01 02:50:50 - [PROTOCOL.certkeys] - typo; jmeltzer@ - - dtucker@cvs.openbsd.org 2010/05/05 04:22:09 - [sftp.c] - restore mput and mget which got lost in the tab-completion changes. - found by Kenneth Whitaker, ok djm@ - - djm@cvs.openbsd.org 2010/05/07 11:30:30 - [auth-options.c auth-options.h auth.c auth.h auth2-pubkey.c] - [key.c servconf.c servconf.h sshd.8 sshd_config.5] - add some optional indirection to matching of principal names listed - in certificates. Currently, a certificate must include the a user's name - to be accepted for authentication. This change adds the ability to - specify a list of certificate principal names that are acceptable. - - When authenticating using a CA trusted through ~/.ssh/authorized_keys, - this adds a new principals="name1[,name2,...]" key option. - - For CAs listed through sshd_config's TrustedCAKeys option, a new config - option "AuthorizedPrincipalsFile" specifies a per-user file containing - the list of acceptable names. - - If either option is absent, the current behaviour of requiring the - username to appear in principals continues to apply. - - These options are useful for role accounts, disjoint account namespaces - and "user@realm"-style naming policies in certificates. - - feedback and ok markus@ - - jmc@cvs.openbsd.org 2010/05/07 12:49:17 - [sshd_config.5] - tweak previous; - -20100423 - - (dtucker) [configure.ac] Bug #1756: Check for the existence of a lib64 dir - in the openssl install directory (some newer openssl versions do this on at - least some amd64 platforms). - -20100418 - - OpenBSD CVS Sync - - jmc@cvs.openbsd.org 2010/04/16 06:45:01 - [ssh_config.5] - tweak previous; ok djm - - jmc@cvs.openbsd.org 2010/04/16 06:47:04 - [ssh-keygen.1 ssh-keygen.c] - tweak previous; ok djm - - djm@cvs.openbsd.org 2010/04/16 21:14:27 - [sshconnect.c] - oops, %r => remote username, not %u - - djm@cvs.openbsd.org 2010/04/16 01:58:45 - [regress/cert-hostkey.sh regress/cert-userkey.sh] - regression tests for v01 certificate format - includes interop tests for v00 certs - - (dtucker) [contrib/aix/buildbff.sh] Fix creation of ssh_prng_cmds.default - file. - -20100416 - - (djm) Release openssh-5.5p1 - - OpenBSD CVS Sync - - djm@cvs.openbsd.org 2010/03/26 03:13:17 - [bufaux.c] - allow buffer_get_int_ret/buffer_get_int64_ret to take a NULL pointer - argument to allow skipping past values in a buffer - - jmc@cvs.openbsd.org 2010/03/26 06:54:36 - [ssh.1] - tweak previous; - - jmc@cvs.openbsd.org 2010/03/27 14:26:55 - [ssh_config.5] - tweak previous; ok dtucker - - djm@cvs.openbsd.org 2010/04/10 00:00:16 - [ssh.c] - bz#1746 - suppress spurious tty warning when using -O and stdin - is not a tty; ok dtucker@ markus@ - - djm@cvs.openbsd.org 2010/04/10 00:04:30 - [sshconnect.c] - fix terminology: we didn't find a certificate in known_hosts, we found - a CA key - - djm@cvs.openbsd.org 2010/04/10 02:08:44 - [clientloop.c] - bz#1698: kill channel when pty allocation requests fail. Fixed - stuck client if the server refuses pty allocation. - ok dtucker@ "think so" markus@ - - djm@cvs.openbsd.org 2010/04/10 02:10:56 - [sshconnect2.c] - show the key type that we are offering in debug(), helps distinguish - between certs and plain keys as the path to the private key is usually - the same. - - djm@cvs.openbsd.org 2010/04/10 05:48:16 - [mux.c] - fix NULL dereference; from matthew.haub AT alumni.adelaide.edu.au - - djm@cvs.openbsd.org 2010/04/14 22:27:42 - [ssh_config.5 sshconnect.c] - expand %r => remote username in ssh_config:ProxyCommand; - ok deraadt markus - - markus@cvs.openbsd.org 2010/04/15 20:32:55 - [ssh-pkcs11.c] - retry lookup for private key if there's no matching key with CKA_SIGN - attribute enabled; this fixes fixes MuscleCard support (bugzilla #1736) - ok djm@ - - djm@cvs.openbsd.org 2010/04/16 01:47:26 - [PROTOCOL.certkeys auth-options.c auth-options.h auth-rsa.c] - [auth2-pubkey.c authfd.c key.c key.h myproposal.h ssh-add.c] - [ssh-agent.c ssh-dss.c ssh-keygen.1 ssh-keygen.c ssh-rsa.c] - [sshconnect.c sshconnect2.c sshd.c] - revised certificate format ssh-{dss,rsa}-cert-v01@openssh.com with the - following changes: - - move the nonce field to the beginning of the certificate where it can - better protect against chosen-prefix attacks on the signature hash - - Rename "constraints" field to "critical options" - - Add a new non-critical "extensions" field - - Add a serial number - - The older format is still support for authentication and cert generation - (use "ssh-keygen -t v00 -s ca_key ..." to generate a v00 certificate) - - ok markus@ diff --git a/Makefile.in b/Makefile.in index 92c95a928356..a8aa1272ad19 100644 --- a/Makefile.in +++ b/Makefile.in @@ -1,4 +1,4 @@ -# $Id: Makefile.in,v 1.340 2013/06/11 01:26:10 dtucker Exp $ +# $Id: Makefile.in,v 1.352 2014/01/27 06:35:04 dtucker Exp $ # uncomment if you run a non bourne compatable shell. Ie. csh #SHELL = @SH@ @@ -73,7 +73,10 @@ LIBSSH_OBJS=authfd.o authfile.o bufaux.o bufbn.o buffer.o \ monitor_fdpass.o rijndael.o ssh-dss.o ssh-ecdsa.o ssh-rsa.o dh.o \ kexdh.o kexgex.o kexdhc.o kexgexc.o bufec.o kexecdh.o kexecdhc.o \ msg.o progressmeter.o dns.o entropy.o gss-genr.o umac.o umac128.o \ - jpake.o schnorr.o ssh-pkcs11.o krl.o + jpake.o schnorr.o ssh-pkcs11.o krl.o smult_curve25519_ref.o \ + kexc25519.o kexc25519c.o poly1305.o chacha.o cipher-chachapoly.o \ + ssh-ed25519.o digest.o \ + sc25519.o ge25519.o fe25519.o ed25519.o verify.o hash.o blocks.o SSHOBJS= ssh.o readconf.o clientloop.o sshtty.o \ sshconnect.o sshconnect1.o sshconnect2.o mux.o \ @@ -87,13 +90,13 @@ SSHDOBJS=sshd.o auth-rhosts.o auth-passwd.o auth-rsa.o auth-rh-rsa.o \ auth-skey.o auth-bsdauth.o auth2-hostbased.o auth2-kbdint.o \ auth2-none.o auth2-passwd.o auth2-pubkey.o auth2-jpake.o \ monitor_mm.o monitor.o monitor_wrap.o kexdhs.o kexgexs.o kexecdhs.o \ - auth-krb5.o \ + kexc25519s.o auth-krb5.o \ auth2-gss.o gss-serv.o gss-serv-krb5.o \ loginrec.o auth-pam.o auth-shadow.o auth-sia.o md5crypt.o \ sftp-server.o sftp-common.o \ roaming_common.o roaming_serv.o \ sandbox-null.o sandbox-rlimit.o sandbox-systrace.o sandbox-darwin.o \ - sandbox-seccomp-filter.o + sandbox-seccomp-filter.o sandbox-capsicum.o MANPAGES = moduli.5.out scp.1.out ssh-add.1.out ssh-agent.1.out ssh-keygen.1.out ssh-keyscan.1.out ssh.1.out sshd.8.out sftp-server.8.out sftp.1.out ssh-keysign.8.out ssh-pkcs11-helper.8.out sshd_config.5.out ssh_config.5.out MANPAGES_IN = moduli.5 scp.1 ssh-add.1 ssh-agent.1 ssh-keygen.1 ssh-keyscan.1 ssh.1 sshd.8 sftp-server.8 sftp.1 ssh-keysign.8 ssh-pkcs11-helper.8 sshd_config.5 ssh_config.5 @@ -112,6 +115,7 @@ PATHSUBS = \ -e 's|/etc/ssh/ssh_host_ecdsa_key|$(sysconfdir)/ssh_host_ecdsa_key|g' \ -e 's|/etc/ssh/ssh_host_dsa_key|$(sysconfdir)/ssh_host_dsa_key|g' \ -e 's|/etc/ssh/ssh_host_rsa_key|$(sysconfdir)/ssh_host_rsa_key|g' \ + -e 's|/etc/ssh/ssh_host_ed25519_key|$(sysconfdir)/ssh_host_ed25519_key|g' \ -e 's|/var/run/sshd.pid|$(piddir)/sshd.pid|g' \ -e 's|/etc/moduli|$(sysconfdir)/moduli|g' \ -e 's|/etc/ssh/moduli|$(sysconfdir)/moduli|g' \ @@ -332,6 +336,11 @@ host-key: ssh-keygen$(EXEEXT) else \ ./ssh-keygen -t rsa -f $(sysconfdir)/ssh_host_rsa_key -N "" ; \ fi ; \ + if [ -f $(sysconfdir)/ssh_host_ed25519_key ] ; then \ + echo "$(sysconfdir)/ssh_host_ed25519_key already exists, skipping." ; \ + else \ + ./ssh-keygen -t ed25519 -f $(sysconfdir)/ssh_host_ed25519_key -N "" ; \ + fi ; \ if [ -z "@COMMENT_OUT_ECC@" ] ; then \ if [ -f $(sysconfdir)/ssh_host_ecdsa_key ] ; then \ echo "$(sysconfdir)/ssh_host_ecdsa_key already exists, skipping." ; \ @@ -345,6 +354,7 @@ host-key-force: ssh-keygen$(EXEEXT) ./ssh-keygen -t rsa1 -f $(DESTDIR)$(sysconfdir)/ssh_host_key -N "" ./ssh-keygen -t dsa -f $(DESTDIR)$(sysconfdir)/ssh_host_dsa_key -N "" ./ssh-keygen -t rsa -f $(DESTDIR)$(sysconfdir)/ssh_host_rsa_key -N "" + ./ssh-keygen -t ed25519 -f $(DESTDIR)$(sysconfdir)/ssh_host_ed25519_key -N "" test -z "@COMMENT_OUT_ECC@" && ./ssh-keygen -t ecdsa -f $(DESTDIR)$(sysconfdir)/ssh_host_ecdsa_key -N "" uninstallall: uninstall @@ -391,9 +401,17 @@ regress/modpipe$(EXEEXT): $(srcdir)/regress/modpipe.c $(CC) $(CFLAGS) $(CPPFLAGS) -o $@ $? \ $(LDFLAGS) -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(LIBS) +regress/setuid-allowed$(EXEEXT): $(srcdir)/regress/setuid-allowed.c + [ -d `pwd`/regress ] || mkdir -p `pwd`/regress + [ -f `pwd`/regress/Makefile ] || \ + ln -s `cd $(srcdir) && pwd`/regress/Makefile `pwd`/regress/Makefile + $(CC) $(CFLAGS) $(CPPFLAGS) -o $@ $? \ + $(LDFLAGS) -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(LIBS) + tests interop-tests: $(TARGETS) regress/modpipe$(EXEEXT) BUILDDIR=`pwd`; \ TEST_SHELL="@TEST_SHELL@"; \ + TEST_SSH_SCP="$${BUILDDIR}/scp"; \ TEST_SSH_SSH="$${BUILDDIR}/ssh"; \ TEST_SSH_SSHD="$${BUILDDIR}/sshd"; \ TEST_SSH_SSHAGENT="$${BUILDDIR}/ssh-agent"; \ @@ -408,7 +426,6 @@ tests interop-tests: $(TARGETS) regress/modpipe$(EXEEXT) TEST_SSH_CONCH="conch"; \ TEST_SSH_IPV6="@TEST_SSH_IPV6@" ; \ TEST_SSH_ECC="@TEST_SSH_ECC@" ; \ - TEST_SSH_SHA256="@TEST_SSH_SHA256@" ; \ cd $(srcdir)/regress || exit $$?; \ $(MAKE) \ .OBJDIR="$${BUILDDIR}/regress" \ @@ -416,7 +433,9 @@ tests interop-tests: $(TARGETS) regress/modpipe$(EXEEXT) BUILDDIR="$${BUILDDIR}" \ OBJ="$${BUILDDIR}/regress/" \ PATH="$${BUILDDIR}:$${PATH}" \ + TEST_ENV=MALLOC_OPTIONS="@TEST_MALLOC_OPTIONS@" \ TEST_SHELL="$${TEST_SHELL}" \ + TEST_SSH_SCP="$${TEST_SSH_SCP}" \ TEST_SSH_SSH="$${TEST_SSH_SSH}" \ TEST_SSH_SSHD="$${TEST_SSH_SSHD}" \ TEST_SSH_SSHAGENT="$${TEST_SSH_SSHAGENT}" \ @@ -431,7 +450,6 @@ tests interop-tests: $(TARGETS) regress/modpipe$(EXEEXT) TEST_SSH_CONCH="$${TEST_SSH_CONCH}" \ TEST_SSH_IPV6="$${TEST_SSH_IPV6}" \ TEST_SSH_ECC="$${TEST_SSH_ECC}" \ - TEST_SSH_SHA256="$${TEST_SSH_SHA256}" \ EXEEXT="$(EXEEXT)" \ $@ && echo all tests passed @@ -456,4 +474,3 @@ package: $(CONFIGFILES) $(MANPAGES) $(TARGETS) if [ "@MAKE_PACKAGE_SUPPORTED@" = yes ]; then \ sh buildpkg.sh; \ fi - diff --git a/PROTOCOL b/PROTOCOL index 48b3a4400750..4a5088f90b50 100644 --- a/PROTOCOL +++ b/PROTOCOL @@ -91,6 +91,17 @@ an MAC algorithm. Additionally, if AES-GCM is selected as the cipher the exchanged MAC algorithms are ignored and there doesn't have to be a matching MAC. +1.7 transport: chacha20-poly1305@openssh.com authenticated encryption + +OpenSSH supports authenticated encryption using ChaCha20 and Poly1305 +as described in PROTOCOL.chacha20poly1305. + +1.8 transport: curve25519-sha256@libssh.org key exchange algorithm + +OpenSSH supports the use of ECDH in Curve25519 for key exchange as +described at: +http://git.libssh.org/users/aris/libssh.git/plain/doc/curve25519-sha256@libssh.org.txt?h=curve25519 + 2. Connection protocol changes 2.1. connection: Channel write close extension "eow@openssh.com" @@ -331,4 +342,18 @@ link(oldpath, newpath) and will respond with a SSH_FXP_STATUS message. This extension is advertised in the SSH_FXP_VERSION hello with version "1". -$OpenBSD: PROTOCOL,v 1.20 2013/01/08 18:49:04 markus Exp $ +10. sftp: Extension request "fsync@openssh.com" + +This request asks the server to call fsync(2) on an open file handle. + + uint32 id + string "fsync@openssh.com" + string handle + +One receiving this request, a server will call fsync(handle_fd) and will +respond with a SSH_FXP_STATUS message. + +This extension is advertised in the SSH_FXP_VERSION hello with version +"1". + +$OpenBSD: PROTOCOL,v 1.23 2013/12/01 23:19:05 djm Exp $ diff --git a/PROTOCOL.chacha20poly1305 b/PROTOCOL.chacha20poly1305 new file mode 100644 index 000000000000..9cf73a926bb7 --- /dev/null +++ b/PROTOCOL.chacha20poly1305 @@ -0,0 +1,105 @@ +This document describes the chacha20-poly1305@openssh.com authenticated +encryption cipher supported by OpenSSH. + +Background +---------- + +ChaCha20 is a stream cipher designed by Daniel Bernstein and described +in [1]. It operates by permuting 128 fixed bits, 128 or 256 bits of key, +a 64 bit nonce and a 64 bit counter into 64 bytes of output. This output +is used as a keystream, with any unused bytes simply discarded. + +Poly1305[2], also by Daniel Bernstein, is a one-time Carter-Wegman MAC +that computes a 128 bit integrity tag given a message and a single-use +256 bit secret key. + +The chacha20-poly1305@openssh.com combines these two primitives into an +authenticated encryption mode. The construction used is based on that +proposed for TLS by Adam Langley in [3], but differs in the layout of +data passed to the MAC and in the addition of encyption of the packet +lengths. + +Negotiation +----------- + +The chacha20-poly1305@openssh.com offers both encryption and +authentication. As such, no separate MAC is required. If the +chacha20-poly1305@openssh.com cipher is selected in key exchange, +the offered MAC algorithms are ignored and no MAC is required to be +negotiated. + +Detailed Construction +--------------------- + +The chacha20-poly1305@openssh.com cipher requires 512 bits of key +material as output from the SSH key exchange. This forms two 256 bit +keys (K_1 and K_2), used by two separate instances of chacha20. + +The instance keyed by K_1 is a stream cipher that is used only +to encrypt the 4 byte packet length field. The second instance, +keyed by K_2, is used in conjunction with poly1305 to build an AEAD +(Authenticated Encryption with Associated Data) that is used to encrypt +and authenticate the entire packet. + +Two separate cipher instances are used here so as to keep the packet +lengths confidential but not create an oracle for the packet payload +cipher by decrypting and using the packet length prior to checking +the MAC. By using an independently-keyed cipher instance to encrypt the +length, an active attacker seeking to exploit the packet input handling +as a decryption oracle can learn nothing about the payload contents or +its MAC (assuming key derivation, ChaCha20 and Poly1305 are secure). + +The AEAD is constructed as follows: for each packet, generate a Poly1305 +key by taking the first 256 bits of ChaCha20 stream output generated +using K_2, an IV consisting of the packet sequence number encoded as an +uint64 under the SSH wire encoding rules and a ChaCha20 block counter of +zero. The K_2 ChaCha20 block counter is then set to the little-endian +encoding of 1 (i.e. {1, 0, 0, 0, 0, 0, 0, 0}) and this instance is used +for encryption of the packet payload. + +Packet Handling +--------------- + +When receiving a packet, the length must be decrypted first. When 4 +bytes of ciphertext length have been received, they may be decrypted +using the K_1 key, a nonce consisting of the packet sequence number +encoded as a uint64 under the usual SSH wire encoding and a zero block +counter to obtain the plaintext length. + +Once the entire packet has been received, the MAC MUST be checked +before decryption. A per-packet Poly1305 key is generated as described +above and the MAC tag calculated using Poly1305 with this key over the +ciphertext of the packet length and the payload together. The calculated +MAC is then compared in constant time with the one appended to the +packet and the packet decrypted using ChaCha20 as described above (with +K_2, the packet sequence number as nonce and a starting block counter of +1). + +To send a packet, first encode the 4 byte length and encrypt it using +K_1. Encrypt the packet payload (using K_2) and append it to the +encrypted length. Finally, calculate a MAC tag and append it. + +Rekeying +-------- + +ChaCha20 must never reuse a {key, nonce} for encryption nor may it be +used to encrypt more than 2^70 bytes under the same {key, nonce}. The +SSH Transport protocol (RFC4253) recommends a far more conservative +rekeying every 1GB of data sent or received. If this recommendation +is followed, then chacha20-poly1305@openssh.com requires no special +handling in this area. + +References +---------- + +[1] "ChaCha, a variant of Salsa20", Daniel Bernstein + http://cr.yp.to/chacha/chacha-20080128.pdf + +[2] "The Poly1305-AES message-authentication code", Daniel Bernstein + http://cr.yp.to/mac/poly1305-20050329.pdf + +[3] "ChaCha20 and Poly1305 based Cipher Suites for TLS", Adam Langley + http://tools.ietf.org/html/draft-agl-tls-chacha20poly1305-03 + +$OpenBSD: PROTOCOL.chacha20poly1305,v 1.2 2013/12/02 02:50:27 djm Exp $ + diff --git a/PROTOCOL.key b/PROTOCOL.key new file mode 100644 index 000000000000..959bd7aeec22 --- /dev/null +++ b/PROTOCOL.key @@ -0,0 +1,68 @@ +This document describes the private key format for OpenSSH. + +1. Overall format + +The key consists of a header, a list of public keys, and +an encrypted list of matching private keys. + +#define AUTH_MAGIC "openssh-key-v1" + + byte[] AUTH_MAGIC + string ciphername + string kdfname + string kdfoptions + int number of keys N + string publickey1 + string publickey2 + ... + string publickeyN + string encrypted, padded list of private keys + +2. KDF options for kdfname "bcrypt" + +The options: + + string salt + uint32 rounds + +are concatenated and represented as a string. + +3. Unencrypted list of N private keys + +The list of privatekey/comment pairs is padded with the +bytes 1, 2, 3, ... until the total length is a multiple +of the cipher block size. + + uint32 checkint + uint32 checkint + string privatekey1 + string comment1 + string privatekey2 + string comment2 + ... + string privatekeyN + string commentN + char 1 + char 2 + char 3 + ... + char padlen % 255 + +Before the key is encrypted, a random integer is assigned +to both checkint fields so successful decryption can be +quickly checked by verifying that both checkint fields +hold the same value. + +4. Encryption + +The KDF is used to derive a key, IV (and other values required by +the cipher) from the passphrase. These values are then used to +encrypt the unencrypted list of private keys. + +5. No encryption + +For unencrypted keys the cipher "none" and the KDF "none" +are used with empty passphrases. The options if the KDF "none" +are the empty string. + +$OpenBSD: PROTOCOL.key,v 1.1 2013/12/06 13:34:54 markus Exp $ diff --git a/README b/README index 0c52f1371482..8da9759efe43 100644 --- a/README +++ b/README @@ -1,4 +1,4 @@ -See http://www.openssh.com/txt/release-6.4 for the release notes. +See http://www.openssh.com/txt/release-6.5 for the release notes. - A Japanese translation of this document and of the OpenSSH FAQ is - available at http://www.unixuser.org/~haruyama/security/openssh/index.html @@ -62,4 +62,4 @@ References - [6] http://www.openbsd.org/cgi-bin/man.cgi?query=style&sektion=9 [7] http://www.openssh.com/faq.html -$Id: README,v 1.83.4.1 2013/11/08 01:36:17 djm Exp $ +$Id: README,v 1.85 2014/01/16 07:51:45 djm Exp $ diff --git a/aclocal.m4 b/aclocal.m4 index 1b3bed790539..1640683e1d1d 100644 --- a/aclocal.m4 +++ b/aclocal.m4 @@ -1,4 +1,4 @@ -dnl $Id: aclocal.m4,v 1.9 2013/06/02 21:31:27 tim Exp $ +dnl $Id: aclocal.m4,v 1.13 2014/01/22 10:30:12 djm Exp $ dnl dnl OpenSSH-specific autoconf macros dnl @@ -8,12 +8,24 @@ dnl Check that $CC accepts a flag 'check_flag'. If it is supported append dnl 'define_flag' to $CFLAGS. If 'define_flag' is not specified, then append dnl 'check_flag'. AC_DEFUN([OSSH_CHECK_CFLAG_COMPILE], [{ - AC_MSG_CHECKING([if $CC supports $1]) + AC_MSG_CHECKING([if $CC supports compile flag $1]) saved_CFLAGS="$CFLAGS" - CFLAGS="$CFLAGS $1" + CFLAGS="$CFLAGS $WERROR $1" _define_flag="$2" test "x$_define_flag" = "x" && _define_flag="$1" - AC_COMPILE_IFELSE([AC_LANG_SOURCE([[int main(void) { return 0; }]])], + AC_COMPILE_IFELSE([AC_LANG_SOURCE([[ +#include +#include +int main(int argc, char **argv) { + /* Some math to catch -ftrapv problems in the toolchain */ + int i = 123 * argc, j = 456 + argc, k = 789 - argc; + float l = i * 2.1; + double m = l / 0.5; + long long int n = argc * 12345LL, o = 12345LL * (long long int)argc; + printf("%d %d %d %f %f %lld %lld\n", i, j, k, l, m, n, o); + exit(0); +} + ]])], [ if `grep -i "unrecognized option" conftest.err >/dev/null` then @@ -28,6 +40,72 @@ fi], ) }]) +dnl OSSH_CHECK_CFLAG_LINK(check_flag[, define_flag]) +dnl Check that $CC accepts a flag 'check_flag'. If it is supported append +dnl 'define_flag' to $CFLAGS. If 'define_flag' is not specified, then append +dnl 'check_flag'. +AC_DEFUN([OSSH_CHECK_CFLAG_LINK], [{ + AC_MSG_CHECKING([if $CC supports compile flag $1 and linking succeeds]) + saved_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS $WERROR $1" + _define_flag="$2" + test "x$_define_flag" = "x" && _define_flag="$1" + AC_LINK_IFELSE([AC_LANG_SOURCE([[ +#include +#include +int main(int argc, char **argv) { + /* Some math to catch -ftrapv problems in the toolchain */ + int i = 123 * argc, j = 456 + argc, k = 789 - argc; + float l = i * 2.1; + double m = l / 0.5; + long long int n = argc * 12345LL, o = 12345LL * (long long int)argc; + printf("%d %d %d %f %f %lld %lld\n", i, j, k, l, m, n, o); + exit(0); +} + ]])], + [ +if `grep -i "unrecognized option" conftest.err >/dev/null` +then + AC_MSG_RESULT([no]) + CFLAGS="$saved_CFLAGS" +else + AC_MSG_RESULT([yes]) + CFLAGS="$saved_CFLAGS $_define_flag" +fi], + [ AC_MSG_RESULT([no]) + CFLAGS="$saved_CFLAGS" ] + ) +}]) + +dnl OSSH_CHECK_LDFLAG_LINK(check_flag[, define_flag]) +dnl Check that $LD accepts a flag 'check_flag'. If it is supported append +dnl 'define_flag' to $LDFLAGS. If 'define_flag' is not specified, then append +dnl 'check_flag'. +AC_DEFUN([OSSH_CHECK_LDFLAG_LINK], [{ + AC_MSG_CHECKING([if $LD supports link flag $1]) + saved_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS $WERROR $1" + _define_flag="$2" + test "x$_define_flag" = "x" && _define_flag="$1" + AC_LINK_IFELSE([AC_LANG_SOURCE([[ +#include +#include +int main(int argc, char **argv) { + /* Some math to catch -ftrapv problems in the toolchain */ + int i = 123 * argc, j = 456 + argc, k = 789 - argc; + float l = i * 2.1; + double m = l / 0.5; + long long int n = argc * 12345LL, o = 12345LL * (long long int)argc; + printf("%d %d %d %f %f %lld %lld\n", i, j, k, l, m, n, o); + exit(0); +} + ]])], + [ AC_MSG_RESULT([yes]) + LDFLAGS="$saved_LDFLAGS $_define_flag"], + [ AC_MSG_RESULT([no]) + LDFLAGS="$saved_LDFLAGS" ] + ) +}]) dnl OSSH_CHECK_HEADER_FOR_FIELD(field, header, symbol) dnl Does AC_EGREP_HEADER on 'header' for the string 'field' diff --git a/addrmatch.c b/addrmatch.c index fb6de92e777b..c443146323dc 100644 --- a/addrmatch.c +++ b/addrmatch.c @@ -1,4 +1,4 @@ -/* $OpenBSD: addrmatch.c,v 1.7 2013/05/17 00:13:13 djm Exp $ */ +/* $OpenBSD: addrmatch.c,v 1.9 2014/01/19 11:21:51 dtucker Exp $ */ /* * Copyright (c) 2004-2008 Damien Miller @@ -88,13 +88,13 @@ addr_sa_to_xaddr(struct sockaddr *sa, socklen_t slen, struct xaddr *xa) switch (sa->sa_family) { case AF_INET: - if (slen < sizeof(*in4)) + if (slen < (socklen_t)sizeof(*in4)) return -1; xa->af = AF_INET; memcpy(&xa->v4, &in4->sin_addr, sizeof(xa->v4)); break; case AF_INET6: - if (slen < sizeof(*in6)) + if (slen < (socklen_t)sizeof(*in6)) return -1; xa->af = AF_INET6; memcpy(&xa->v6, &in6->sin6_addr, sizeof(xa->v6)); diff --git a/atomicio.c b/atomicio.c index 601b3c371c21..2bac36c91cd7 100644 --- a/atomicio.c +++ b/atomicio.c @@ -56,8 +56,10 @@ atomicio6(ssize_t (*f) (int, void *, size_t), int fd, void *_s, size_t n, ssize_t res; struct pollfd pfd; +#ifndef BROKEN_READ_COMPARISON pfd.fd = fd; pfd.events = f == read ? POLLIN : POLLOUT; +#endif while (n > pos) { res = (f) (fd, s + pos, n - pos); switch (res) { @@ -65,7 +67,9 @@ atomicio6(ssize_t (*f) (int, void *, size_t), int fd, void *_s, size_t n, if (errno == EINTR) continue; if (errno == EAGAIN || errno == EWOULDBLOCK) { +#ifndef BROKEN_READ_COMPARISON (void)poll(&pfd, 1, -1); +#endif continue; } return 0; diff --git a/auth-krb5.c b/auth-krb5.c index 7c83f597f049..6c62bdf54a51 100644 --- a/auth-krb5.c +++ b/auth-krb5.c @@ -157,7 +157,8 @@ auth_krb5_password(Authctxt *authctxt, const char *password) if (problem) goto out; - if (!krb5_kuserok(authctxt->krb5_ctx, authctxt->krb5_user, client)) { + if (!krb5_kuserok(authctxt->krb5_ctx, authctxt->krb5_user, + authctxt->pw->pw_name)) { problem = -1; goto out; } diff --git a/auth-options.c b/auth-options.c index 12e2e1dcac9e..fa209eaab813 100644 --- a/auth-options.c +++ b/auth-options.c @@ -1,4 +1,4 @@ -/* $OpenBSD: auth-options.c,v 1.61 2013/11/08 00:39:14 djm Exp $ */ +/* $OpenBSD: auth-options.c,v 1.62 2013/12/19 00:27:57 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -33,10 +33,6 @@ #include "auth-options.h" #include "hostfile.h" #include "auth.h" -#ifdef GSSAPI -#include "ssh-gss.h" -#endif -#include "monitor_wrap.h" /* Flags set authorized_keys flags */ int no_port_forwarding_flag = 0; @@ -436,7 +432,7 @@ parse_option_list(u_char *optblob, size_t optblob_len, struct passwd *pw, u_char *data_blob = NULL; u_int nlen, dlen, clen; Buffer c, data; - int ret = -1, found; + int ret = -1, result, found; buffer_init(&data); @@ -505,11 +501,12 @@ parse_option_list(u_char *optblob, size_t optblob_len, struct passwd *pw, goto out; } remote_ip = get_remote_ipaddr(); - switch (addr_match_cidr_list(remote_ip, - allowed)) { + result = addr_match_cidr_list(remote_ip, + allowed); + free(allowed); + switch (result) { case 1: /* accepted */ - free(allowed); break; case 0: /* no match */ @@ -522,12 +519,11 @@ parse_option_list(u_char *optblob, size_t optblob_len, struct passwd *pw, "is not permitted to use this " "certificate for login.", remote_ip); - free(allowed); goto out; case -1: + default: error("Certificate source-address " "contents invalid"); - free(allowed); goto out; } found = 1; diff --git a/auth-pam.c b/auth-pam.c index d51318b3a216..d789bad7b9bd 100644 --- a/auth-pam.c +++ b/auth-pam.c @@ -438,8 +438,10 @@ sshpam_thread(void *ctxtp) const char **ptr_pam_user = &pam_user; char *tz = getenv("TZ"); - pam_get_item(sshpam_handle, PAM_USER, + sshpam_err = pam_get_item(sshpam_handle, PAM_USER, (sshpam_const void **)ptr_pam_user); + if (sshpam_err != PAM_SUCCESS) + goto auth_fail; environ[0] = NULL; if (tz != NULL) diff --git a/auth2-hostbased.c b/auth2-hostbased.c index a344dcc1f797..488008f62289 100644 --- a/auth2-hostbased.c +++ b/auth2-hostbased.c @@ -1,4 +1,4 @@ -/* $OpenBSD: auth2-hostbased.c,v 1.16 2013/06/21 00:34:49 djm Exp $ */ +/* $OpenBSD: auth2-hostbased.c,v 1.17 2013/12/30 23:52:27 djm Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. * @@ -100,6 +100,12 @@ userauth_hostbased(Authctxt *authctxt) "(received %d, expected %d)", key->type, pktype); goto done; } + if (key_type_plain(key->type) == KEY_RSA && + (datafellows & SSH_BUG_RSASIGMD5) != 0) { + error("Refusing RSA key because peer uses unsafe " + "signature format"); + goto done; + } service = datafellows & SSH_BUG_HBSERVICE ? "ssh-userauth" : authctxt->service; buffer_init(&b); diff --git a/auth2-pubkey.c b/auth2-pubkey.c index 2b3ecb10405d..0fd27bb9283c 100644 --- a/auth2-pubkey.c +++ b/auth2-pubkey.c @@ -1,4 +1,4 @@ -/* $OpenBSD: auth2-pubkey.c,v 1.38 2013/06/21 00:34:49 djm Exp $ */ +/* $OpenBSD: auth2-pubkey.c,v 1.39 2013/12/30 23:52:27 djm Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. * @@ -116,6 +116,12 @@ userauth_pubkey(Authctxt *authctxt) "(received %d, expected %d)", key->type, pktype); goto done; } + if (key_type_plain(key->type) == KEY_RSA && + (datafellows & SSH_BUG_RSASIGMD5) != 0) { + logit("Refusing RSA key because client uses unsafe " + "signature scheme"); + goto done; + } if (have_sig) { sig = packet_get_string(&slen); packet_check_eom(); diff --git a/authfd.c b/authfd.c index 5cce93b76a57..f9636903ad40 100644 --- a/authfd.c +++ b/authfd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: authfd.c,v 1.88 2013/11/08 00:39:14 djm Exp $ */ +/* $OpenBSD: authfd.c,v 1.91 2013/12/29 04:29:25 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -42,8 +42,8 @@ #include #include - #include + #include #include #include @@ -474,58 +474,7 @@ ssh_encode_identity_rsa1(Buffer *b, RSA *key, const char *comment) static void ssh_encode_identity_ssh2(Buffer *b, Key *key, const char *comment) { - buffer_put_cstring(b, key_ssh_name(key)); - switch (key->type) { - case KEY_RSA: - buffer_put_bignum2(b, key->rsa->n); - buffer_put_bignum2(b, key->rsa->e); - buffer_put_bignum2(b, key->rsa->d); - buffer_put_bignum2(b, key->rsa->iqmp); - buffer_put_bignum2(b, key->rsa->p); - buffer_put_bignum2(b, key->rsa->q); - break; - case KEY_RSA_CERT_V00: - case KEY_RSA_CERT: - if (key->cert == NULL || buffer_len(&key->cert->certblob) == 0) - fatal("%s: no cert/certblob", __func__); - buffer_put_string(b, buffer_ptr(&key->cert->certblob), - buffer_len(&key->cert->certblob)); - buffer_put_bignum2(b, key->rsa->d); - buffer_put_bignum2(b, key->rsa->iqmp); - buffer_put_bignum2(b, key->rsa->p); - buffer_put_bignum2(b, key->rsa->q); - break; - case KEY_DSA: - buffer_put_bignum2(b, key->dsa->p); - buffer_put_bignum2(b, key->dsa->q); - buffer_put_bignum2(b, key->dsa->g); - buffer_put_bignum2(b, key->dsa->pub_key); - buffer_put_bignum2(b, key->dsa->priv_key); - break; - case KEY_DSA_CERT_V00: - case KEY_DSA_CERT: - if (key->cert == NULL || buffer_len(&key->cert->certblob) == 0) - fatal("%s: no cert/certblob", __func__); - buffer_put_string(b, buffer_ptr(&key->cert->certblob), - buffer_len(&key->cert->certblob)); - buffer_put_bignum2(b, key->dsa->priv_key); - break; -#ifdef OPENSSL_HAS_ECC - case KEY_ECDSA: - buffer_put_cstring(b, key_curve_nid_to_name(key->ecdsa_nid)); - buffer_put_ecpoint(b, EC_KEY_get0_group(key->ecdsa), - EC_KEY_get0_public_key(key->ecdsa)); - buffer_put_bignum2(b, EC_KEY_get0_private_key(key->ecdsa)); - break; - case KEY_ECDSA_CERT: - if (key->cert == NULL || buffer_len(&key->cert->certblob) == 0) - fatal("%s: no cert/certblob", __func__); - buffer_put_string(b, buffer_ptr(&key->cert->certblob), - buffer_len(&key->cert->certblob)); - buffer_put_bignum2(b, EC_KEY_get0_private_key(key->ecdsa)); - break; -#endif - } + key_private_serialize(key, b); buffer_put_cstring(b, comment); } @@ -559,6 +508,8 @@ ssh_add_identity_constrained(AuthenticationConnection *auth, Key *key, case KEY_DSA_CERT_V00: case KEY_ECDSA: case KEY_ECDSA_CERT: + case KEY_ED25519: + case KEY_ED25519_CERT: type = constrained ? SSH2_AGENTC_ADD_ID_CONSTRAINED : SSH2_AGENTC_ADD_IDENTITY; @@ -606,9 +557,7 @@ ssh_remove_identity(AuthenticationConnection *auth, Key *key) buffer_put_int(&msg, BN_num_bits(key->rsa->n)); buffer_put_bignum(&msg, key->rsa->e); buffer_put_bignum(&msg, key->rsa->n); - } else if (key_type_plain(key->type) == KEY_DSA || - key_type_plain(key->type) == KEY_RSA || - key_type_plain(key->type) == KEY_ECDSA) { + } else if (key->type != KEY_UNSPEC) { key_to_blob(key, &blob, &blen); buffer_put_char(&msg, SSH2_AGENTC_REMOVE_IDENTITY); buffer_put_string(&msg, blob, blen); diff --git a/authfile.c b/authfile.c index 63ae16bbd99f..7eccbb2c993b 100644 --- a/authfile.c +++ b/authfile.c @@ -1,4 +1,4 @@ -/* $OpenBSD: authfile.c,v 1.97 2013/05/17 00:13:13 djm Exp $ */ +/* $OpenBSD: authfile.c,v 1.101 2013/12/29 04:35:50 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -13,7 +13,7 @@ * called by a name other than "ssh" or "Secure Shell". * * - * Copyright (c) 2000 Markus Friedl. All rights reserved. + * Copyright (c) 2000, 2013 Markus Friedl. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -50,6 +50,8 @@ /* compatibility with old or broken OpenSSL versions */ #include "openbsd-compat/openssl-compat.h" +#include "crypto_api.h" + #include #include #include @@ -58,6 +60,10 @@ #include #include +#ifdef HAVE_UTIL_H +#include +#endif + #include "xmalloc.h" #include "cipher.h" #include "buffer.h" @@ -68,6 +74,16 @@ #include "rsa.h" #include "misc.h" #include "atomicio.h" +#include "uuencode.h" + +/* openssh private key file format */ +#define MARK_BEGIN "-----BEGIN OPENSSH PRIVATE KEY-----\n" +#define MARK_END "-----END OPENSSH PRIVATE KEY-----\n" +#define KDFNAME "bcrypt" +#define AUTH_MAGIC "openssh-key-v1" +#define SALT_LEN 16 +#define DEFAULT_CIPHERNAME "aes256-cbc" +#define DEFAULT_ROUNDS 16 #define MAX_KEY_FILE_SIZE (1024 * 1024) @@ -75,6 +91,333 @@ static const char authfile_id_string[] = "SSH PRIVATE KEY FILE FORMAT 1.1\n"; +static int +key_private_to_blob2(Key *prv, Buffer *blob, const char *passphrase, + const char *comment, const char *ciphername, int rounds) +{ + u_char *key, *cp, salt[SALT_LEN]; + size_t keylen, ivlen, blocksize, authlen; + u_int len, check; + int i, n; + const Cipher *c; + Buffer encoded, b, kdf; + CipherContext ctx; + const char *kdfname = KDFNAME; + + if (rounds <= 0) + rounds = DEFAULT_ROUNDS; + if (passphrase == NULL || !strlen(passphrase)) { + ciphername = "none"; + kdfname = "none"; + } else if (ciphername == NULL) + ciphername = DEFAULT_CIPHERNAME; + else if (cipher_number(ciphername) != SSH_CIPHER_SSH2) + fatal("invalid cipher"); + + if ((c = cipher_by_name(ciphername)) == NULL) + fatal("unknown cipher name"); + buffer_init(&kdf); + blocksize = cipher_blocksize(c); + keylen = cipher_keylen(c); + ivlen = cipher_ivlen(c); + authlen = cipher_authlen(c); + key = xcalloc(1, keylen + ivlen); + if (strcmp(kdfname, "none") != 0) { + arc4random_buf(salt, SALT_LEN); + if (bcrypt_pbkdf(passphrase, strlen(passphrase), + salt, SALT_LEN, key, keylen + ivlen, rounds) < 0) + fatal("bcrypt_pbkdf failed"); + buffer_put_string(&kdf, salt, SALT_LEN); + buffer_put_int(&kdf, rounds); + } + cipher_init(&ctx, c, key, keylen, key + keylen , ivlen, 1); + memset(key, 0, keylen + ivlen); + free(key); + + buffer_init(&encoded); + buffer_append(&encoded, AUTH_MAGIC, sizeof(AUTH_MAGIC)); + buffer_put_cstring(&encoded, ciphername); + buffer_put_cstring(&encoded, kdfname); + buffer_put_string(&encoded, buffer_ptr(&kdf), buffer_len(&kdf)); + buffer_put_int(&encoded, 1); /* number of keys */ + key_to_blob(prv, &cp, &len); /* public key */ + buffer_put_string(&encoded, cp, len); + + memset(cp, 0, len); + free(cp); + + buffer_free(&kdf); + + /* set up the buffer that will be encrypted */ + buffer_init(&b); + + /* Random check bytes */ + check = arc4random(); + buffer_put_int(&b, check); + buffer_put_int(&b, check); + + /* append private key and comment*/ + key_private_serialize(prv, &b); + buffer_put_cstring(&b, comment); + + /* padding */ + i = 0; + while (buffer_len(&b) % blocksize) + buffer_put_char(&b, ++i & 0xff); + + /* length */ + buffer_put_int(&encoded, buffer_len(&b)); + + /* encrypt */ + cp = buffer_append_space(&encoded, buffer_len(&b) + authlen); + if (cipher_crypt(&ctx, 0, cp, buffer_ptr(&b), buffer_len(&b), 0, + authlen) != 0) + fatal("%s: cipher_crypt failed", __func__); + buffer_free(&b); + cipher_cleanup(&ctx); + + /* uuencode */ + len = 2 * buffer_len(&encoded); + cp = xmalloc(len); + n = uuencode(buffer_ptr(&encoded), buffer_len(&encoded), + (char *)cp, len); + if (n < 0) + fatal("%s: uuencode", __func__); + + buffer_clear(blob); + buffer_append(blob, MARK_BEGIN, sizeof(MARK_BEGIN) - 1); + for (i = 0; i < n; i++) { + buffer_put_char(blob, cp[i]); + if (i % 70 == 69) + buffer_put_char(blob, '\n'); + } + if (i % 70 != 69) + buffer_put_char(blob, '\n'); + buffer_append(blob, MARK_END, sizeof(MARK_END) - 1); + free(cp); + + return buffer_len(blob); +} + +static Key * +key_parse_private2(Buffer *blob, int type, const char *passphrase, + char **commentp) +{ + u_char *key = NULL, *cp, *salt = NULL, pad, last; + char *comment = NULL, *ciphername = NULL, *kdfname = NULL, *kdfp; + u_int keylen = 0, ivlen, blocksize, slen, klen, len, rounds, nkeys; + u_int check1, check2, m1len, m2len; + size_t authlen; + const Cipher *c; + Buffer b, encoded, copy, kdf; + CipherContext ctx; + Key *k = NULL; + int dlen, ret, i; + + buffer_init(&b); + buffer_init(&kdf); + buffer_init(&encoded); + buffer_init(©); + + /* uudecode */ + m1len = sizeof(MARK_BEGIN) - 1; + m2len = sizeof(MARK_END) - 1; + cp = buffer_ptr(blob); + len = buffer_len(blob); + if (len < m1len || memcmp(cp, MARK_BEGIN, m1len)) { + debug("%s: missing begin marker", __func__); + goto out; + } + cp += m1len; + len -= m1len; + while (len) { + if (*cp != '\n' && *cp != '\r') + buffer_put_char(&encoded, *cp); + last = *cp; + len--; + cp++; + if (last == '\n') { + if (len >= m2len && !memcmp(cp, MARK_END, m2len)) { + buffer_put_char(&encoded, '\0'); + break; + } + } + } + if (!len) { + debug("%s: no end marker", __func__); + goto out; + } + len = buffer_len(&encoded); + if ((cp = buffer_append_space(©, len)) == NULL) { + error("%s: buffer_append_space", __func__); + goto out; + } + if ((dlen = uudecode(buffer_ptr(&encoded), cp, len)) < 0) { + error("%s: uudecode failed", __func__); + goto out; + } + if ((u_int)dlen > len) { + error("%s: crazy uudecode length %d > %u", __func__, dlen, len); + goto out; + } + buffer_consume_end(©, len - dlen); + if (buffer_len(©) < sizeof(AUTH_MAGIC) || + memcmp(buffer_ptr(©), AUTH_MAGIC, sizeof(AUTH_MAGIC))) { + error("%s: bad magic", __func__); + goto out; + } + buffer_consume(©, sizeof(AUTH_MAGIC)); + + ciphername = buffer_get_cstring_ret(©, NULL); + if (ciphername == NULL || + (c = cipher_by_name(ciphername)) == NULL) { + error("%s: unknown cipher name", __func__); + goto out; + } + if ((passphrase == NULL || !strlen(passphrase)) && + strcmp(ciphername, "none") != 0) { + /* passphrase required */ + goto out; + } + kdfname = buffer_get_cstring_ret(©, NULL); + if (kdfname == NULL || + (!strcmp(kdfname, "none") && !strcmp(kdfname, "bcrypt"))) { + error("%s: unknown kdf name", __func__); + goto out; + } + if (!strcmp(kdfname, "none") && strcmp(ciphername, "none") != 0) { + error("%s: cipher %s requires kdf", __func__, ciphername); + goto out; + } + /* kdf options */ + kdfp = buffer_get_string_ptr_ret(©, &klen); + if (kdfp == NULL) { + error("%s: kdf options not set", __func__); + goto out; + } + if (klen > 0) { + if ((cp = buffer_append_space(&kdf, klen)) == NULL) { + error("%s: kdf alloc failed", __func__); + goto out; + } + memcpy(cp, kdfp, klen); + } + /* number of keys */ + if (buffer_get_int_ret(&nkeys, ©) < 0) { + error("%s: key counter missing", __func__); + goto out; + } + if (nkeys != 1) { + error("%s: only one key supported", __func__); + goto out; + } + /* pubkey */ + if ((cp = buffer_get_string_ret(©, &len)) == NULL) { + error("%s: pubkey not found", __func__); + goto out; + } + free(cp); /* XXX check pubkey against decrypted private key */ + + /* size of encrypted key blob */ + len = buffer_get_int(©); + blocksize = cipher_blocksize(c); + authlen = cipher_authlen(c); + if (len < blocksize) { + error("%s: encrypted data too small", __func__); + goto out; + } + if (len % blocksize) { + error("%s: length not multiple of blocksize", __func__); + goto out; + } + + /* setup key */ + keylen = cipher_keylen(c); + ivlen = cipher_ivlen(c); + key = xcalloc(1, keylen + ivlen); + if (!strcmp(kdfname, "bcrypt")) { + if ((salt = buffer_get_string_ret(&kdf, &slen)) == NULL) { + error("%s: salt not set", __func__); + goto out; + } + if (buffer_get_int_ret(&rounds, &kdf) < 0) { + error("%s: rounds not set", __func__); + goto out; + } + if (bcrypt_pbkdf(passphrase, strlen(passphrase), salt, slen, + key, keylen + ivlen, rounds) < 0) { + error("%s: bcrypt_pbkdf failed", __func__); + goto out; + } + } + + cp = buffer_append_space(&b, len); + cipher_init(&ctx, c, key, keylen, key + keylen, ivlen, 0); + ret = cipher_crypt(&ctx, 0, cp, buffer_ptr(©), len, 0, authlen); + cipher_cleanup(&ctx); + buffer_consume(©, len); + + /* fail silently on decryption errors */ + if (ret != 0) { + debug("%s: decrypt failed", __func__); + goto out; + } + + if (buffer_len(©) != 0) { + error("%s: key blob has trailing data (len = %u)", __func__, + buffer_len(©)); + goto out; + } + + /* check bytes */ + if (buffer_get_int_ret(&check1, &b) < 0 || + buffer_get_int_ret(&check2, &b) < 0) { + error("check bytes missing"); + goto out; + } + if (check1 != check2) { + debug("%s: decrypt failed: 0x%08x != 0x%08x", __func__, + check1, check2); + goto out; + } + + k = key_private_deserialize(&b); + + /* comment */ + comment = buffer_get_cstring_ret(&b, NULL); + + i = 0; + while (buffer_len(&b)) { + if (buffer_get_char_ret(&pad, &b) == -1 || + pad != (++i & 0xff)) { + error("%s: bad padding", __func__); + key_free(k); + k = NULL; + goto out; + } + } + + if (k && commentp) { + *commentp = comment; + comment = NULL; + } + + /* XXX decode pubkey and check against private */ + out: + free(ciphername); + free(kdfname); + free(salt); + free(comment); + if (key) + memset(key, 0, keylen + ivlen); + free(key); + buffer_free(&encoded); + buffer_free(©); + buffer_free(&kdf); + buffer_free(&b); + return k; +} + /* * Serialises the authentication (private) key to a blob, encrypting it with * passphrase. The identification of the blob (lowest 64 bits of n) will @@ -149,8 +492,9 @@ key_private_rsa1_to_blob(Key *key, Buffer *blob, const char *passphrase, cipher_set_key_string(&ciphercontext, cipher, passphrase, CIPHER_ENCRYPT); - cipher_crypt(&ciphercontext, cp, - buffer_ptr(&buffer), buffer_len(&buffer), 0, 0); + if (cipher_crypt(&ciphercontext, 0, cp, + buffer_ptr(&buffer), buffer_len(&buffer), 0, 0) != 0) + fatal("%s: cipher_crypt failed", __func__); cipher_cleanup(&ciphercontext); memset(&ciphercontext, 0, sizeof(ciphercontext)); @@ -239,7 +583,8 @@ key_save_private_blob(Buffer *keybuf, const char *filename) /* Serialise "key" to buffer "blob" */ static int key_private_to_blob(Key *key, Buffer *blob, const char *passphrase, - const char *comment) + const char *comment, int force_new_format, const char *new_format_cipher, + int new_format_rounds) { switch (key->type) { case KEY_RSA1: @@ -247,7 +592,14 @@ key_private_to_blob(Key *key, Buffer *blob, const char *passphrase, case KEY_DSA: case KEY_ECDSA: case KEY_RSA: + if (force_new_format) { + return key_private_to_blob2(key, blob, passphrase, + comment, new_format_cipher, new_format_rounds); + } return key_private_pem_to_blob(key, blob, passphrase, comment); + case KEY_ED25519: + return key_private_to_blob2(key, blob, passphrase, + comment, new_format_cipher, new_format_rounds); default: error("%s: cannot save key type %d", __func__, key->type); return 0; @@ -256,13 +608,15 @@ key_private_to_blob(Key *key, Buffer *blob, const char *passphrase, int key_save_private(Key *key, const char *filename, const char *passphrase, - const char *comment) + const char *comment, int force_new_format, const char *new_format_cipher, + int new_format_rounds) { Buffer keyblob; int success = 0; buffer_init(&keyblob); - if (!key_private_to_blob(key, &keyblob, passphrase, comment)) + if (!key_private_to_blob(key, &keyblob, passphrase, comment, + force_new_format, new_format_cipher, new_format_rounds)) goto out; if (!key_save_private_blob(&keyblob, filename)) goto out; @@ -473,8 +827,9 @@ key_parse_private_rsa1(Buffer *blob, const char *passphrase, char **commentp) /* Rest of the buffer is encrypted. Decrypt it using the passphrase. */ cipher_set_key_string(&ciphercontext, cipher, passphrase, CIPHER_DECRYPT); - cipher_crypt(&ciphercontext, cp, - buffer_ptr(©), buffer_len(©), 0, 0); + if (cipher_crypt(&ciphercontext, 0, cp, + buffer_ptr(©), buffer_len(©), 0, 0) != 0) + fatal("%s: cipher_crypt failed", __func__); cipher_cleanup(&ciphercontext); memset(&ciphercontext, 0, sizeof(ciphercontext)); buffer_free(©); @@ -641,13 +996,20 @@ static Key * key_parse_private_type(Buffer *blob, int type, const char *passphrase, char **commentp) { + Key *k; + switch (type) { case KEY_RSA1: return key_parse_private_rsa1(blob, passphrase, commentp); case KEY_DSA: case KEY_ECDSA: case KEY_RSA: + return key_parse_private_pem(blob, type, passphrase, commentp); + case KEY_ED25519: + return key_parse_private2(blob, type, passphrase, commentp); case KEY_UNSPEC: + if ((k = key_parse_private2(blob, type, passphrase, commentp))) + return k; return key_parse_private_pem(blob, type, passphrase, commentp); default: error("%s: cannot parse key type %d", __func__, type); @@ -851,6 +1213,7 @@ key_load_private_cert(int type, const char *filename, const char *passphrase, case KEY_RSA: case KEY_DSA: case KEY_ECDSA: + case KEY_ED25519: break; default: error("%s: unsupported key type", __func__); @@ -943,4 +1306,3 @@ key_in_file(Key *key, const char *filename, int strict_type) fclose(f); return ret; } - diff --git a/authfile.h b/authfile.h index 78349beb5615..8ba1c2dbe5fd 100644 --- a/authfile.h +++ b/authfile.h @@ -1,4 +1,4 @@ -/* $OpenBSD: authfile.h,v 1.16 2011/05/04 21:15:29 djm Exp $ */ +/* $OpenBSD: authfile.h,v 1.17 2013/12/06 13:34:54 markus Exp $ */ /* * Author: Tatu Ylonen @@ -15,7 +15,8 @@ #ifndef AUTHFILE_H #define AUTHFILE_H -int key_save_private(Key *, const char *, const char *, const char *); +int key_save_private(Key *, const char *, const char *, const char *, + int, const char *, int); int key_load_file(int, const char *, Buffer *); Key *key_load_cert(const char *); Key *key_load_public(const char *, char **); diff --git a/blocks.c b/blocks.c new file mode 100644 index 000000000000..ad93fe509980 --- /dev/null +++ b/blocks.c @@ -0,0 +1,248 @@ +/* $OpenBSD: blocks.c,v 1.3 2013/12/09 11:03:45 markus Exp $ */ + +/* + * Public Domain, Author: Daniel J. Bernstein + * Copied from nacl-20110221/crypto_hashblocks/sha512/ref/blocks.c + */ + +#include "includes.h" + +#include "crypto_api.h" + +typedef unsigned long long uint64; + +static uint64 load_bigendian(const unsigned char *x) +{ + return + (uint64) (x[7]) \ + | (((uint64) (x[6])) << 8) \ + | (((uint64) (x[5])) << 16) \ + | (((uint64) (x[4])) << 24) \ + | (((uint64) (x[3])) << 32) \ + | (((uint64) (x[2])) << 40) \ + | (((uint64) (x[1])) << 48) \ + | (((uint64) (x[0])) << 56) + ; +} + +static void store_bigendian(unsigned char *x,uint64 u) +{ + x[7] = u; u >>= 8; + x[6] = u; u >>= 8; + x[5] = u; u >>= 8; + x[4] = u; u >>= 8; + x[3] = u; u >>= 8; + x[2] = u; u >>= 8; + x[1] = u; u >>= 8; + x[0] = u; +} + +#define SHR(x,c) ((x) >> (c)) +#define ROTR(x,c) (((x) >> (c)) | ((x) << (64 - (c)))) + +#define Ch(x,y,z) ((x & y) ^ (~x & z)) +#define Maj(x,y,z) ((x & y) ^ (x & z) ^ (y & z)) +#define Sigma0(x) (ROTR(x,28) ^ ROTR(x,34) ^ ROTR(x,39)) +#define Sigma1(x) (ROTR(x,14) ^ ROTR(x,18) ^ ROTR(x,41)) +#define sigma0(x) (ROTR(x, 1) ^ ROTR(x, 8) ^ SHR(x,7)) +#define sigma1(x) (ROTR(x,19) ^ ROTR(x,61) ^ SHR(x,6)) + +#define M(w0,w14,w9,w1) w0 = sigma1(w14) + w9 + sigma0(w1) + w0; + +#define EXPAND \ + M(w0 ,w14,w9 ,w1 ) \ + M(w1 ,w15,w10,w2 ) \ + M(w2 ,w0 ,w11,w3 ) \ + M(w3 ,w1 ,w12,w4 ) \ + M(w4 ,w2 ,w13,w5 ) \ + M(w5 ,w3 ,w14,w6 ) \ + M(w6 ,w4 ,w15,w7 ) \ + M(w7 ,w5 ,w0 ,w8 ) \ + M(w8 ,w6 ,w1 ,w9 ) \ + M(w9 ,w7 ,w2 ,w10) \ + M(w10,w8 ,w3 ,w11) \ + M(w11,w9 ,w4 ,w12) \ + M(w12,w10,w5 ,w13) \ + M(w13,w11,w6 ,w14) \ + M(w14,w12,w7 ,w15) \ + M(w15,w13,w8 ,w0 ) + +#define F(w,k) \ + T1 = h + Sigma1(e) + Ch(e,f,g) + k + w; \ + T2 = Sigma0(a) + Maj(a,b,c); \ + h = g; \ + g = f; \ + f = e; \ + e = d + T1; \ + d = c; \ + c = b; \ + b = a; \ + a = T1 + T2; + +int crypto_hashblocks_sha512(unsigned char *statebytes,const unsigned char *in,unsigned long long inlen) +{ + uint64 state[8]; + uint64 a; + uint64 b; + uint64 c; + uint64 d; + uint64 e; + uint64 f; + uint64 g; + uint64 h; + uint64 T1; + uint64 T2; + + a = load_bigendian(statebytes + 0); state[0] = a; + b = load_bigendian(statebytes + 8); state[1] = b; + c = load_bigendian(statebytes + 16); state[2] = c; + d = load_bigendian(statebytes + 24); state[3] = d; + e = load_bigendian(statebytes + 32); state[4] = e; + f = load_bigendian(statebytes + 40); state[5] = f; + g = load_bigendian(statebytes + 48); state[6] = g; + h = load_bigendian(statebytes + 56); state[7] = h; + + while (inlen >= 128) { + uint64 w0 = load_bigendian(in + 0); + uint64 w1 = load_bigendian(in + 8); + uint64 w2 = load_bigendian(in + 16); + uint64 w3 = load_bigendian(in + 24); + uint64 w4 = load_bigendian(in + 32); + uint64 w5 = load_bigendian(in + 40); + uint64 w6 = load_bigendian(in + 48); + uint64 w7 = load_bigendian(in + 56); + uint64 w8 = load_bigendian(in + 64); + uint64 w9 = load_bigendian(in + 72); + uint64 w10 = load_bigendian(in + 80); + uint64 w11 = load_bigendian(in + 88); + uint64 w12 = load_bigendian(in + 96); + uint64 w13 = load_bigendian(in + 104); + uint64 w14 = load_bigendian(in + 112); + uint64 w15 = load_bigendian(in + 120); + + F(w0 ,0x428a2f98d728ae22ULL) + F(w1 ,0x7137449123ef65cdULL) + F(w2 ,0xb5c0fbcfec4d3b2fULL) + F(w3 ,0xe9b5dba58189dbbcULL) + F(w4 ,0x3956c25bf348b538ULL) + F(w5 ,0x59f111f1b605d019ULL) + F(w6 ,0x923f82a4af194f9bULL) + F(w7 ,0xab1c5ed5da6d8118ULL) + F(w8 ,0xd807aa98a3030242ULL) + F(w9 ,0x12835b0145706fbeULL) + F(w10,0x243185be4ee4b28cULL) + F(w11,0x550c7dc3d5ffb4e2ULL) + F(w12,0x72be5d74f27b896fULL) + F(w13,0x80deb1fe3b1696b1ULL) + F(w14,0x9bdc06a725c71235ULL) + F(w15,0xc19bf174cf692694ULL) + + EXPAND + + F(w0 ,0xe49b69c19ef14ad2ULL) + F(w1 ,0xefbe4786384f25e3ULL) + F(w2 ,0x0fc19dc68b8cd5b5ULL) + F(w3 ,0x240ca1cc77ac9c65ULL) + F(w4 ,0x2de92c6f592b0275ULL) + F(w5 ,0x4a7484aa6ea6e483ULL) + F(w6 ,0x5cb0a9dcbd41fbd4ULL) + F(w7 ,0x76f988da831153b5ULL) + F(w8 ,0x983e5152ee66dfabULL) + F(w9 ,0xa831c66d2db43210ULL) + F(w10,0xb00327c898fb213fULL) + F(w11,0xbf597fc7beef0ee4ULL) + F(w12,0xc6e00bf33da88fc2ULL) + F(w13,0xd5a79147930aa725ULL) + F(w14,0x06ca6351e003826fULL) + F(w15,0x142929670a0e6e70ULL) + + EXPAND + + F(w0 ,0x27b70a8546d22ffcULL) + F(w1 ,0x2e1b21385c26c926ULL) + F(w2 ,0x4d2c6dfc5ac42aedULL) + F(w3 ,0x53380d139d95b3dfULL) + F(w4 ,0x650a73548baf63deULL) + F(w5 ,0x766a0abb3c77b2a8ULL) + F(w6 ,0x81c2c92e47edaee6ULL) + F(w7 ,0x92722c851482353bULL) + F(w8 ,0xa2bfe8a14cf10364ULL) + F(w9 ,0xa81a664bbc423001ULL) + F(w10,0xc24b8b70d0f89791ULL) + F(w11,0xc76c51a30654be30ULL) + F(w12,0xd192e819d6ef5218ULL) + F(w13,0xd69906245565a910ULL) + F(w14,0xf40e35855771202aULL) + F(w15,0x106aa07032bbd1b8ULL) + + EXPAND + + F(w0 ,0x19a4c116b8d2d0c8ULL) + F(w1 ,0x1e376c085141ab53ULL) + F(w2 ,0x2748774cdf8eeb99ULL) + F(w3 ,0x34b0bcb5e19b48a8ULL) + F(w4 ,0x391c0cb3c5c95a63ULL) + F(w5 ,0x4ed8aa4ae3418acbULL) + F(w6 ,0x5b9cca4f7763e373ULL) + F(w7 ,0x682e6ff3d6b2b8a3ULL) + F(w8 ,0x748f82ee5defb2fcULL) + F(w9 ,0x78a5636f43172f60ULL) + F(w10,0x84c87814a1f0ab72ULL) + F(w11,0x8cc702081a6439ecULL) + F(w12,0x90befffa23631e28ULL) + F(w13,0xa4506cebde82bde9ULL) + F(w14,0xbef9a3f7b2c67915ULL) + F(w15,0xc67178f2e372532bULL) + + EXPAND + + F(w0 ,0xca273eceea26619cULL) + F(w1 ,0xd186b8c721c0c207ULL) + F(w2 ,0xeada7dd6cde0eb1eULL) + F(w3 ,0xf57d4f7fee6ed178ULL) + F(w4 ,0x06f067aa72176fbaULL) + F(w5 ,0x0a637dc5a2c898a6ULL) + F(w6 ,0x113f9804bef90daeULL) + F(w7 ,0x1b710b35131c471bULL) + F(w8 ,0x28db77f523047d84ULL) + F(w9 ,0x32caab7b40c72493ULL) + F(w10,0x3c9ebe0a15c9bebcULL) + F(w11,0x431d67c49c100d4cULL) + F(w12,0x4cc5d4becb3e42b6ULL) + F(w13,0x597f299cfc657e2aULL) + F(w14,0x5fcb6fab3ad6faecULL) + F(w15,0x6c44198c4a475817ULL) + + a += state[0]; + b += state[1]; + c += state[2]; + d += state[3]; + e += state[4]; + f += state[5]; + g += state[6]; + h += state[7]; + + state[0] = a; + state[1] = b; + state[2] = c; + state[3] = d; + state[4] = e; + state[5] = f; + state[6] = g; + state[7] = h; + + in += 128; + inlen -= 128; + } + + store_bigendian(statebytes + 0,state[0]); + store_bigendian(statebytes + 8,state[1]); + store_bigendian(statebytes + 16,state[2]); + store_bigendian(statebytes + 24,state[3]); + store_bigendian(statebytes + 32,state[4]); + store_bigendian(statebytes + 40,state[5]); + store_bigendian(statebytes + 48,state[6]); + store_bigendian(statebytes + 56,state[7]); + + return inlen; +} diff --git a/bufaux.c b/bufaux.c index de5b3ca1aa57..9401fe1d09be 100644 --- a/bufaux.c +++ b/bufaux.c @@ -1,4 +1,4 @@ -/* $OpenBSD: bufaux.c,v 1.52 2013/07/12 00:19:58 djm Exp $ */ +/* $OpenBSD: bufaux.c,v 1.54 2014/01/12 08:13:13 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -45,6 +45,7 @@ #include #include +#include #include "xmalloc.h" #include "buffer.h" @@ -314,3 +315,76 @@ buffer_put_char(Buffer *buffer, int value) buffer_append(buffer, &ch, 1); } + +/* Pseudo bignum functions */ + +void * +buffer_get_bignum2_as_string_ret(Buffer *buffer, u_int *length_ptr) +{ + u_int len; + u_char *bin, *p, *ret; + + if ((p = bin = buffer_get_string_ret(buffer, &len)) == NULL) { + error("%s: invalid bignum", __func__); + return NULL; + } + + if (len > 0 && (bin[0] & 0x80)) { + error("%s: negative numbers not supported", __func__); + free(bin); + return NULL; + } + if (len > 8 * 1024) { + error("%s: cannot handle BN of size %d", __func__, len); + free(bin); + return NULL; + } + /* Skip zero prefix on numbers with the MSB set */ + if (len > 1 && bin[0] == 0x00 && (bin[1] & 0x80) != 0) { + p++; + len--; + } + ret = xmalloc(len); + memcpy(ret, p, len); + memset(p, '\0', len); + free(bin); + return ret; +} + +void * +buffer_get_bignum2_as_string(Buffer *buffer, u_int *l) +{ + void *ret = buffer_get_bignum2_as_string_ret(buffer, l); + + if (ret == NULL) + fatal("%s: buffer error", __func__); + return ret; +} + +/* + * Stores a string using the bignum encoding rules (\0 pad if MSB set). + */ +void +buffer_put_bignum2_from_string(Buffer *buffer, const u_char *s, u_int l) +{ + u_char *buf, *p; + int pad = 0; + + if (l > 8 * 1024) + fatal("%s: length %u too long", __func__, l); + p = buf = xmalloc(l + 1); + /* + * If most significant bit is set then prepend a zero byte to + * avoid interpretation as a negative number. + */ + if (l > 0 && (s[0] & 0x80) != 0) { + *p++ = '\0'; + pad = 1; + } + memcpy(p, s, l); + buffer_put_string(buffer, buf, l + pad); + memset(buf, '\0', l + pad); + free(buf); +} + + diff --git a/bufbn.c b/bufbn.c index 1fbfbbcc985d..2ebc80a2732d 100644 --- a/bufbn.c +++ b/bufbn.c @@ -1,4 +1,4 @@ -/* $OpenBSD: bufbn.c,v 1.7 2013/05/17 00:13:13 djm Exp $*/ +/* $OpenBSD: bufbn.c,v 1.8 2013/11/08 11:15:19 dtucker Exp $*/ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -45,6 +45,7 @@ #include #include +#include #include "xmalloc.h" #include "buffer.h" diff --git a/buffer.c b/buffer.c index 007e7f94e31e..9e7c40a5a874 100644 --- a/buffer.c +++ b/buffer.c @@ -1,4 +1,4 @@ -/* $OpenBSD: buffer.c,v 1.33 2013/05/17 00:13:13 djm Exp $ */ +/* $OpenBSD: buffer.c,v 1.34 2013/11/08 11:15:19 dtucker Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -19,6 +19,7 @@ #include #include #include +#include #include "xmalloc.h" #include "buffer.h" diff --git a/buffer.h b/buffer.h index 4fa2ca112613..7df8a38fa18d 100644 --- a/buffer.h +++ b/buffer.h @@ -1,4 +1,4 @@ -/* $OpenBSD: buffer.h,v 1.22 2013/07/12 00:19:58 djm Exp $ */ +/* $OpenBSD: buffer.h,v 1.23 2014/01/12 08:13:13 djm Exp $ */ /* * Author: Tatu Ylonen @@ -86,6 +86,10 @@ char *buffer_get_cstring_ret(Buffer *, u_int *); void *buffer_get_string_ptr_ret(Buffer *, u_int *); int buffer_get_char_ret(u_char *, Buffer *); +void *buffer_get_bignum2_as_string_ret(Buffer *, u_int *); +void *buffer_get_bignum2_as_string(Buffer *, u_int *); +void buffer_put_bignum2_from_string(Buffer *, const u_char *, u_int); + #ifdef OPENSSL_HAS_ECC #include diff --git a/canohost.c b/canohost.c index 69e8e6f6d9dc..a19a60cdaffc 100644 --- a/canohost.c +++ b/canohost.c @@ -1,4 +1,4 @@ -/* $OpenBSD: canohost.c,v 1.67 2013/05/17 00:13:13 djm Exp $ */ +/* $OpenBSD: canohost.c,v 1.70 2014/01/19 04:17:29 dtucker Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -20,7 +20,6 @@ #include #include -#include #include #include #include @@ -48,7 +47,6 @@ static char * get_remote_hostname(int sock, int use_dns) { struct sockaddr_storage from; - int i; socklen_t fromlen; struct addrinfo hints, *ai, *aitop; char name[NI_MAXHOST], ntop[NI_MAXHOST], ntop2[NI_MAXHOST]; @@ -99,13 +97,9 @@ get_remote_hostname(int sock, int use_dns) return xstrdup(ntop); } - /* - * Convert it to all lowercase (which is expected by the rest - * of this software). - */ - for (i = 0; name[i]; i++) - if (isupper(name[i])) - name[i] = (char)tolower(name[i]); + /* Names are stores in lowercase. */ + lowercase(name); + /* * Map it back to an IP address and check that the given * address actually is an address of this host. This is @@ -160,8 +154,7 @@ check_ip_options(int sock, char *ipaddr) #ifdef IP_OPTIONS u_char options[200]; char text[sizeof(options) * 3 + 1]; - socklen_t option_size; - u_int i; + socklen_t option_size, i; int ipproto; struct protoent *ip; diff --git a/chacha.c b/chacha.c new file mode 100644 index 000000000000..a84c25ea88ce --- /dev/null +++ b/chacha.c @@ -0,0 +1,219 @@ +/* +chacha-merged.c version 20080118 +D. J. Bernstein +Public domain. +*/ + +#include "includes.h" + +#include "chacha.h" + +/* $OpenBSD: chacha.c,v 1.1 2013/11/21 00:45:44 djm Exp $ */ + +typedef unsigned char u8; +typedef unsigned int u32; + +typedef struct chacha_ctx chacha_ctx; + +#define U8C(v) (v##U) +#define U32C(v) (v##U) + +#define U8V(v) ((u8)(v) & U8C(0xFF)) +#define U32V(v) ((u32)(v) & U32C(0xFFFFFFFF)) + +#define ROTL32(v, n) \ + (U32V((v) << (n)) | ((v) >> (32 - (n)))) + +#define U8TO32_LITTLE(p) \ + (((u32)((p)[0]) ) | \ + ((u32)((p)[1]) << 8) | \ + ((u32)((p)[2]) << 16) | \ + ((u32)((p)[3]) << 24)) + +#define U32TO8_LITTLE(p, v) \ + do { \ + (p)[0] = U8V((v) ); \ + (p)[1] = U8V((v) >> 8); \ + (p)[2] = U8V((v) >> 16); \ + (p)[3] = U8V((v) >> 24); \ + } while (0) + +#define ROTATE(v,c) (ROTL32(v,c)) +#define XOR(v,w) ((v) ^ (w)) +#define PLUS(v,w) (U32V((v) + (w))) +#define PLUSONE(v) (PLUS((v),1)) + +#define QUARTERROUND(a,b,c,d) \ + a = PLUS(a,b); d = ROTATE(XOR(d,a),16); \ + c = PLUS(c,d); b = ROTATE(XOR(b,c),12); \ + a = PLUS(a,b); d = ROTATE(XOR(d,a), 8); \ + c = PLUS(c,d); b = ROTATE(XOR(b,c), 7); + +static const char sigma[16] = "expand 32-byte k"; +static const char tau[16] = "expand 16-byte k"; + +void +chacha_keysetup(chacha_ctx *x,const u8 *k,u32 kbits) +{ + const char *constants; + + x->input[4] = U8TO32_LITTLE(k + 0); + x->input[5] = U8TO32_LITTLE(k + 4); + x->input[6] = U8TO32_LITTLE(k + 8); + x->input[7] = U8TO32_LITTLE(k + 12); + if (kbits == 256) { /* recommended */ + k += 16; + constants = sigma; + } else { /* kbits == 128 */ + constants = tau; + } + x->input[8] = U8TO32_LITTLE(k + 0); + x->input[9] = U8TO32_LITTLE(k + 4); + x->input[10] = U8TO32_LITTLE(k + 8); + x->input[11] = U8TO32_LITTLE(k + 12); + x->input[0] = U8TO32_LITTLE(constants + 0); + x->input[1] = U8TO32_LITTLE(constants + 4); + x->input[2] = U8TO32_LITTLE(constants + 8); + x->input[3] = U8TO32_LITTLE(constants + 12); +} + +void +chacha_ivsetup(chacha_ctx *x, const u8 *iv, const u8 *counter) +{ + x->input[12] = counter == NULL ? 0 : U8TO32_LITTLE(counter + 0); + x->input[13] = counter == NULL ? 0 : U8TO32_LITTLE(counter + 4); + x->input[14] = U8TO32_LITTLE(iv + 0); + x->input[15] = U8TO32_LITTLE(iv + 4); +} + +void +chacha_encrypt_bytes(chacha_ctx *x,const u8 *m,u8 *c,u32 bytes) +{ + u32 x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15; + u32 j0, j1, j2, j3, j4, j5, j6, j7, j8, j9, j10, j11, j12, j13, j14, j15; + u8 *ctarget = NULL; + u8 tmp[64]; + u_int i; + + if (!bytes) return; + + j0 = x->input[0]; + j1 = x->input[1]; + j2 = x->input[2]; + j3 = x->input[3]; + j4 = x->input[4]; + j5 = x->input[5]; + j6 = x->input[6]; + j7 = x->input[7]; + j8 = x->input[8]; + j9 = x->input[9]; + j10 = x->input[10]; + j11 = x->input[11]; + j12 = x->input[12]; + j13 = x->input[13]; + j14 = x->input[14]; + j15 = x->input[15]; + + for (;;) { + if (bytes < 64) { + for (i = 0;i < bytes;++i) tmp[i] = m[i]; + m = tmp; + ctarget = c; + c = tmp; + } + x0 = j0; + x1 = j1; + x2 = j2; + x3 = j3; + x4 = j4; + x5 = j5; + x6 = j6; + x7 = j7; + x8 = j8; + x9 = j9; + x10 = j10; + x11 = j11; + x12 = j12; + x13 = j13; + x14 = j14; + x15 = j15; + for (i = 20;i > 0;i -= 2) { + QUARTERROUND( x0, x4, x8,x12) + QUARTERROUND( x1, x5, x9,x13) + QUARTERROUND( x2, x6,x10,x14) + QUARTERROUND( x3, x7,x11,x15) + QUARTERROUND( x0, x5,x10,x15) + QUARTERROUND( x1, x6,x11,x12) + QUARTERROUND( x2, x7, x8,x13) + QUARTERROUND( x3, x4, x9,x14) + } + x0 = PLUS(x0,j0); + x1 = PLUS(x1,j1); + x2 = PLUS(x2,j2); + x3 = PLUS(x3,j3); + x4 = PLUS(x4,j4); + x5 = PLUS(x5,j5); + x6 = PLUS(x6,j6); + x7 = PLUS(x7,j7); + x8 = PLUS(x8,j8); + x9 = PLUS(x9,j9); + x10 = PLUS(x10,j10); + x11 = PLUS(x11,j11); + x12 = PLUS(x12,j12); + x13 = PLUS(x13,j13); + x14 = PLUS(x14,j14); + x15 = PLUS(x15,j15); + + x0 = XOR(x0,U8TO32_LITTLE(m + 0)); + x1 = XOR(x1,U8TO32_LITTLE(m + 4)); + x2 = XOR(x2,U8TO32_LITTLE(m + 8)); + x3 = XOR(x3,U8TO32_LITTLE(m + 12)); + x4 = XOR(x4,U8TO32_LITTLE(m + 16)); + x5 = XOR(x5,U8TO32_LITTLE(m + 20)); + x6 = XOR(x6,U8TO32_LITTLE(m + 24)); + x7 = XOR(x7,U8TO32_LITTLE(m + 28)); + x8 = XOR(x8,U8TO32_LITTLE(m + 32)); + x9 = XOR(x9,U8TO32_LITTLE(m + 36)); + x10 = XOR(x10,U8TO32_LITTLE(m + 40)); + x11 = XOR(x11,U8TO32_LITTLE(m + 44)); + x12 = XOR(x12,U8TO32_LITTLE(m + 48)); + x13 = XOR(x13,U8TO32_LITTLE(m + 52)); + x14 = XOR(x14,U8TO32_LITTLE(m + 56)); + x15 = XOR(x15,U8TO32_LITTLE(m + 60)); + + j12 = PLUSONE(j12); + if (!j12) { + j13 = PLUSONE(j13); + /* stopping at 2^70 bytes per nonce is user's responsibility */ + } + + U32TO8_LITTLE(c + 0,x0); + U32TO8_LITTLE(c + 4,x1); + U32TO8_LITTLE(c + 8,x2); + U32TO8_LITTLE(c + 12,x3); + U32TO8_LITTLE(c + 16,x4); + U32TO8_LITTLE(c + 20,x5); + U32TO8_LITTLE(c + 24,x6); + U32TO8_LITTLE(c + 28,x7); + U32TO8_LITTLE(c + 32,x8); + U32TO8_LITTLE(c + 36,x9); + U32TO8_LITTLE(c + 40,x10); + U32TO8_LITTLE(c + 44,x11); + U32TO8_LITTLE(c + 48,x12); + U32TO8_LITTLE(c + 52,x13); + U32TO8_LITTLE(c + 56,x14); + U32TO8_LITTLE(c + 60,x15); + + if (bytes <= 64) { + if (bytes < 64) { + for (i = 0;i < bytes;++i) ctarget[i] = c[i]; + } + x->input[12] = j12; + x->input[13] = j13; + return; + } + bytes -= 64; + c += 64; + m += 64; + } +} diff --git a/chacha.h b/chacha.h new file mode 100644 index 000000000000..4ef42cc70cf1 --- /dev/null +++ b/chacha.h @@ -0,0 +1,35 @@ +/* $OpenBSD: chacha.h,v 1.1 2013/11/21 00:45:44 djm Exp $ */ + +/* +chacha-merged.c version 20080118 +D. J. Bernstein +Public domain. +*/ + +#ifndef CHACHA_H +#define CHACHA_H + +#include + +struct chacha_ctx { + u_int input[16]; +}; + +#define CHACHA_MINKEYLEN 16 +#define CHACHA_NONCELEN 8 +#define CHACHA_CTRLEN 8 +#define CHACHA_STATELEN (CHACHA_NONCELEN+CHACHA_CTRLEN) +#define CHACHA_BLOCKLEN 64 + +void chacha_keysetup(struct chacha_ctx *x, const u_char *k, u_int kbits) + __attribute__((__bounded__(__minbytes__, 2, CHACHA_MINKEYLEN))); +void chacha_ivsetup(struct chacha_ctx *x, const u_char *iv, const u_char *ctr) + __attribute__((__bounded__(__minbytes__, 2, CHACHA_NONCELEN))) + __attribute__((__bounded__(__minbytes__, 3, CHACHA_CTRLEN))); +void chacha_encrypt_bytes(struct chacha_ctx *x, const u_char *m, + u_char *c, u_int bytes) + __attribute__((__bounded__(__buffer__, 2, 4))) + __attribute__((__bounded__(__buffer__, 3, 4))); + +#endif /* CHACHA_H */ + diff --git a/channels.c b/channels.c index a1c31d8a004a..e741f29b97b0 100644 --- a/channels.c +++ b/channels.c @@ -1,4 +1,4 @@ -/* $OpenBSD: channels.c,v 1.327 2013/11/08 00:39:15 djm Exp $ */ +/* $OpenBSD: channels.c,v 1.328 2013/12/19 01:04:36 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -1385,6 +1385,8 @@ port_open_helper(Channel *c, char *rtype) { int direct; char buf[1024]; + char *local_ipaddr = get_local_ipaddr(c->sock); + int local_port = get_sock_port(c->sock, 1); char *remote_ipaddr = get_peer_ipaddr(c->sock); int remote_port = get_peer_port(c->sock); @@ -1399,9 +1401,9 @@ port_open_helper(Channel *c, char *rtype) snprintf(buf, sizeof buf, "%s: listening port %d for %.100s port %d, " - "connect from %.200s port %d", + "connect from %.200s port %d to %.100s port %d", rtype, c->listening_port, c->path, c->host_port, - remote_ipaddr, remote_port); + remote_ipaddr, remote_port, local_ipaddr, local_port); free(c->remote_name); c->remote_name = xstrdup(buf); @@ -1419,7 +1421,7 @@ port_open_helper(Channel *c, char *rtype) } else { /* listen address, port */ packet_put_cstring(c->path); - packet_put_int(c->listening_port); + packet_put_int(local_port); } /* originator host and port */ packet_put_cstring(remote_ipaddr); @@ -1436,6 +1438,7 @@ port_open_helper(Channel *c, char *rtype) packet_send(); } free(remote_ipaddr); + free(local_ipaddr); } static void @@ -2710,8 +2713,20 @@ channel_fwd_bind_addr(const char *listen_addr, int *wildcardp, if (((datafellows & SSH_OLD_FORWARD_ADDR) && strcmp(listen_addr, "0.0.0.0") == 0 && is_client == 0) || *listen_addr == '\0' || strcmp(listen_addr, "*") == 0 || - (!is_client && gateway_ports == 1)) + (!is_client && gateway_ports == 1)) { wildcard = 1; + /* + * Notify client if they requested a specific listen + * address and it was overridden. + */ + if (*listen_addr != '\0' && + strcmp(listen_addr, "0.0.0.0") != 0 && + strcmp(listen_addr, "*") != 0) { + packet_send_debug("Forwarding listen address " + "\"%s\" overridden by server " + "GatewayPorts", listen_addr); + } + } else if (strcmp(listen_addr, "localhost") != 0) addr = listen_addr; } diff --git a/cipher-chachapoly.c b/cipher-chachapoly.c new file mode 100644 index 000000000000..91b0830fd9bb --- /dev/null +++ b/cipher-chachapoly.c @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2013 Damien Miller + * + * 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. + */ + +/* $OpenBSD: cipher-chachapoly.c,v 1.3 2013/12/15 21:42:35 djm Exp $ */ + +#include "includes.h" + +#include +#include /* needed for log.h */ +#include +#include /* needed for misc.h */ + +#include "log.h" +#include "misc.h" +#include "cipher-chachapoly.h" + +void chachapoly_init(struct chachapoly_ctx *ctx, + const u_char *key, u_int keylen) +{ + if (keylen != (32 + 32)) /* 2 x 256 bit keys */ + fatal("%s: invalid keylen %u", __func__, keylen); + chacha_keysetup(&ctx->main_ctx, key, 256); + chacha_keysetup(&ctx->header_ctx, key + 32, 256); +} + +/* + * chachapoly_crypt() operates as following: + * En/decrypt with header key 'aadlen' bytes from 'src', storing result + * to 'dest'. The ciphertext here is treated as additional authenticated + * data for MAC calculation. + * En/decrypt 'len' bytes at offset 'aadlen' from 'src' to 'dest'. Use + * POLY1305_TAGLEN bytes at offset 'len'+'aadlen' as the authentication + * tag. This tag is written on encryption and verified on decryption. + */ +int +chachapoly_crypt(struct chachapoly_ctx *ctx, u_int seqnr, u_char *dest, + const u_char *src, u_int len, u_int aadlen, u_int authlen, int do_encrypt) +{ + u_char seqbuf[8]; + const u_char one[8] = { 1, 0, 0, 0, 0, 0, 0, 0 }; /* NB little-endian */ + u_char expected_tag[POLY1305_TAGLEN], poly_key[POLY1305_KEYLEN]; + int r = -1; + + /* + * Run ChaCha20 once to generate the Poly1305 key. The IV is the + * packet sequence number. + */ + bzero(poly_key, sizeof(poly_key)); + put_u64(seqbuf, seqnr); + chacha_ivsetup(&ctx->main_ctx, seqbuf, NULL); + chacha_encrypt_bytes(&ctx->main_ctx, + poly_key, poly_key, sizeof(poly_key)); + /* Set Chacha's block counter to 1 */ + chacha_ivsetup(&ctx->main_ctx, seqbuf, one); + + /* If decrypting, check tag before anything else */ + if (!do_encrypt) { + const u_char *tag = src + aadlen + len; + + poly1305_auth(expected_tag, src, aadlen + len, poly_key); + if (timingsafe_bcmp(expected_tag, tag, POLY1305_TAGLEN) != 0) + goto out; + } + /* Crypt additional data */ + if (aadlen) { + chacha_ivsetup(&ctx->header_ctx, seqbuf, NULL); + chacha_encrypt_bytes(&ctx->header_ctx, src, dest, aadlen); + } + chacha_encrypt_bytes(&ctx->main_ctx, src + aadlen, + dest + aadlen, len); + + /* If encrypting, calculate and append tag */ + if (do_encrypt) { + poly1305_auth(dest + aadlen + len, dest, aadlen + len, + poly_key); + } + r = 0; + + out: + bzero(expected_tag, sizeof(expected_tag)); + bzero(seqbuf, sizeof(seqbuf)); + bzero(poly_key, sizeof(poly_key)); + return r; +} + +/* Decrypt and extract the encrypted packet length */ +int +chachapoly_get_length(struct chachapoly_ctx *ctx, + u_int *plenp, u_int seqnr, const u_char *cp, u_int len) +{ + u_char buf[4], seqbuf[8]; + + if (len < 4) + return -1; /* Insufficient length */ + put_u64(seqbuf, seqnr); + chacha_ivsetup(&ctx->header_ctx, seqbuf, NULL); + chacha_encrypt_bytes(&ctx->header_ctx, cp, buf, 4); + *plenp = get_u32(buf); + return 0; +} + diff --git a/cipher-chachapoly.h b/cipher-chachapoly.h new file mode 100644 index 000000000000..1628693b200a --- /dev/null +++ b/cipher-chachapoly.h @@ -0,0 +1,41 @@ +/* $OpenBSD: cipher-chachapoly.h,v 1.1 2013/11/21 00:45:44 djm Exp $ */ + +/* + * Copyright (c) Damien Miller 2013 + * + * 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. + */ +#ifndef CHACHA_POLY_AEAD_H +#define CHACHA_POLY_AEAD_H + +#include +#include "chacha.h" +#include "poly1305.h" + +#define CHACHA_KEYLEN 32 /* Only 256 bit keys used here */ + +struct chachapoly_ctx { + struct chacha_ctx main_ctx, header_ctx; +}; + +void chachapoly_init(struct chachapoly_ctx *cpctx, + const u_char *key, u_int keylen) + __attribute__((__bounded__(__buffer__, 2, 3))); +int chachapoly_crypt(struct chachapoly_ctx *cpctx, u_int seqnr, + u_char *dest, const u_char *src, u_int len, u_int aadlen, u_int authlen, + int do_encrypt); +int chachapoly_get_length(struct chachapoly_ctx *cpctx, + u_int *plenp, u_int seqnr, const u_char *cp, u_int len) + __attribute__((__bounded__(__buffer__, 4, 5))); + +#endif /* CHACHA_POLY_AEAD_H */ diff --git a/cipher.c b/cipher.c index a2cbe2beab32..2476e6539d1c 100644 --- a/cipher.c +++ b/cipher.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cipher.c,v 1.89 2013/05/17 00:13:13 djm Exp $ */ +/* $OpenBSD: cipher.c,v 1.94 2014/01/25 10:12:50 dtucker Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -43,9 +43,11 @@ #include #include +#include #include "xmalloc.h" #include "log.h" +#include "misc.h" #include "cipher.h" /* compatibility with old or broken OpenSSL versions */ @@ -63,7 +65,9 @@ struct Cipher { u_int iv_len; /* defaults to block_size */ u_int auth_len; u_int discard_len; - u_int cbc_mode; + u_int flags; +#define CFLAG_CBC (1<<0) +#define CFLAG_CHACHAPOLY (1<<1) const EVP_CIPHER *(*evptype)(void); }; @@ -95,14 +99,16 @@ static const struct Cipher ciphers[] = { { "aes256-gcm@openssh.com", SSH_CIPHER_SSH2, 16, 32, 12, 16, 0, 0, EVP_aes_256_gcm }, #endif + { "chacha20-poly1305@openssh.com", + SSH_CIPHER_SSH2, 8, 64, 0, 16, 0, CFLAG_CHACHAPOLY, NULL }, { NULL, SSH_CIPHER_INVALID, 0, 0, 0, 0, 0, 0, NULL } }; /*--*/ -/* Returns a comma-separated list of supported ciphers. */ +/* Returns a list of supported ciphers separated by the specified char. */ char * -cipher_alg_list(void) +cipher_alg_list(char sep, int auth_only) { char *ret = NULL; size_t nlen, rlen = 0; @@ -111,8 +117,10 @@ cipher_alg_list(void) for (c = ciphers; c->name != NULL; c++) { if (c->number != SSH_CIPHER_SSH2) continue; + if (auth_only && c->auth_len == 0) + continue; if (ret != NULL) - ret[rlen++] = '\n'; + ret[rlen++] = sep; nlen = strlen(c->name); ret = xrealloc(ret, 1, rlen + nlen + 2); memcpy(ret + rlen, c->name, nlen + 1); @@ -133,6 +141,14 @@ cipher_keylen(const Cipher *c) return (c->key_len); } +u_int +cipher_seclen(const Cipher *c) +{ + if (strcmp("3des-cbc", c->name) == 0) + return 14; + return cipher_keylen(c); +} + u_int cipher_authlen(const Cipher *c) { @@ -142,7 +158,12 @@ cipher_authlen(const Cipher *c) u_int cipher_ivlen(const Cipher *c) { - return (c->iv_len ? c->iv_len : c->block_size); + /* + * Default is cipher block size, except for chacha20+poly1305 that + * needs no IV. XXX make iv_len == -1 default? + */ + return (c->iv_len != 0 || (c->flags & CFLAG_CHACHAPOLY) != 0) ? + c->iv_len : c->block_size; } u_int @@ -154,7 +175,7 @@ cipher_get_number(const Cipher *c) u_int cipher_is_cbc(const Cipher *c) { - return (c->cbc_mode); + return (c->flags & CFLAG_CBC) != 0; } u_int @@ -274,8 +295,11 @@ cipher_init(CipherContext *cc, const Cipher *cipher, ivlen, cipher->name); cc->cipher = cipher; + if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0) { + chachapoly_init(&cc->cp_ctx, key, keylen); + return; + } type = (*cipher->evptype)(); - EVP_CIPHER_CTX_init(&cc->evp); #ifdef SSH_OLD_EVP if (type->key_len > 0 && type->key_len != keylen) { @@ -328,11 +352,16 @@ cipher_init(CipherContext *cc, const Cipher *cipher, * Use 'authlen' bytes at offset 'len'+'aadlen' as the authentication tag. * This tag is written on encryption and verified on decryption. * Both 'aadlen' and 'authlen' can be set to 0. + * cipher_crypt() returns 0 on success and -1 if the decryption integrity + * check fails. */ -void -cipher_crypt(CipherContext *cc, u_char *dest, const u_char *src, +int +cipher_crypt(CipherContext *cc, u_int seqnr, u_char *dest, const u_char *src, u_int len, u_int aadlen, u_int authlen) { + if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0) + return chachapoly_crypt(&cc->cp_ctx, seqnr, dest, src, len, + aadlen, authlen, cc->encrypt); if (authlen) { u_char lastiv[1]; @@ -365,19 +394,36 @@ cipher_crypt(CipherContext *cc, u_char *dest, const u_char *src, if (cc->encrypt) fatal("%s: EVP_Cipher(final) failed", __func__); else - fatal("Decryption integrity check failed"); + return -1; } if (cc->encrypt && !EVP_CIPHER_CTX_ctrl(&cc->evp, EVP_CTRL_GCM_GET_TAG, authlen, dest + aadlen + len)) fatal("%s: EVP_CTRL_GCM_GET_TAG", __func__); } + return 0; +} + +/* Extract the packet length, including any decryption necessary beforehand */ +int +cipher_get_length(CipherContext *cc, u_int *plenp, u_int seqnr, + const u_char *cp, u_int len) +{ + if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0) + return chachapoly_get_length(&cc->cp_ctx, plenp, seqnr, + cp, len); + if (len < 4) + return -1; + *plenp = get_u32(cp); + return 0; } void cipher_cleanup(CipherContext *cc) { - if (EVP_CIPHER_CTX_cleanup(&cc->evp) == 0) + if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0) + memset(&cc->cp_ctx, 0, sizeof(cc->cp_ctx)); + else if (EVP_CIPHER_CTX_cleanup(&cc->evp) == 0) error("cipher_cleanup: EVP_CIPHER_CTX_cleanup failed"); } @@ -417,6 +463,8 @@ cipher_get_keyiv_len(const CipherContext *cc) if (c->number == SSH_CIPHER_3DES) ivlen = 24; + else if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0) + ivlen = 0; else ivlen = EVP_CIPHER_CTX_iv_length(&cc->evp); return (ivlen); @@ -428,6 +476,12 @@ cipher_get_keyiv(CipherContext *cc, u_char *iv, u_int len) const Cipher *c = cc->cipher; int evplen; + if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0) { + if (len != 0) + fatal("%s: wrong iv length %d != %d", __func__, len, 0); + return; + } + switch (c->number) { case SSH_CIPHER_SSH2: case SSH_CIPHER_DES: @@ -464,6 +518,9 @@ cipher_set_keyiv(CipherContext *cc, u_char *iv) const Cipher *c = cc->cipher; int evplen = 0; + if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0) + return; + switch (c->number) { case SSH_CIPHER_SSH2: case SSH_CIPHER_DES: diff --git a/cipher.h b/cipher.h index b878d50f4fc6..133d2e73d2ec 100644 --- a/cipher.h +++ b/cipher.h @@ -1,4 +1,4 @@ -/* $OpenBSD: cipher.h,v 1.40 2013/04/19 01:06:50 djm Exp $ */ +/* $OpenBSD: cipher.h,v 1.44 2014/01/25 10:12:50 dtucker Exp $ */ /* * Author: Tatu Ylonen @@ -38,6 +38,8 @@ #define CIPHER_H #include +#include "cipher-chachapoly.h" + /* * Cipher types for SSH-1. New types can be added, but old types should not * be removed for compatibility. The maximum allowed value is 31. @@ -66,6 +68,7 @@ struct CipherContext { int plaintext; int encrypt; EVP_CIPHER_CTX evp; + struct chachapoly_ctx cp_ctx; /* XXX union with evp? */ const Cipher *cipher; }; @@ -75,15 +78,18 @@ const Cipher *cipher_by_number(int); int cipher_number(const char *); char *cipher_name(int); int ciphers_valid(const char *); -char *cipher_alg_list(void); +char *cipher_alg_list(char, int); void cipher_init(CipherContext *, const Cipher *, const u_char *, u_int, const u_char *, u_int, int); -void cipher_crypt(CipherContext *, u_char *, const u_char *, +int cipher_crypt(CipherContext *, u_int, u_char *, const u_char *, u_int, u_int, u_int); +int cipher_get_length(CipherContext *, u_int *, u_int, + const u_char *, u_int); void cipher_cleanup(CipherContext *); void cipher_set_key_string(CipherContext *, const Cipher *, const char *, int); u_int cipher_blocksize(const Cipher *); u_int cipher_keylen(const Cipher *); +u_int cipher_seclen(const Cipher *); u_int cipher_authlen(const Cipher *); u_int cipher_ivlen(const Cipher *); u_int cipher_is_cbc(const Cipher *); diff --git a/clientloop.c b/clientloop.c index 23c2f2396f5b..f30c8b6b5da5 100644 --- a/clientloop.c +++ b/clientloop.c @@ -1,4 +1,4 @@ -/* $OpenBSD: clientloop.c,v 1.255 2013/11/08 00:39:15 djm Exp $ */ +/* $OpenBSD: clientloop.c,v 1.256 2013/11/20 20:54:10 deraadt Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -289,7 +289,7 @@ client_x11_display_valid(const char *display) dlen = strlen(display); for (i = 0; i < dlen; i++) { - if (!isalnum(display[i]) && + if (!isalnum((u_char)display[i]) && strchr(SSH_X11_VALID_DISPLAY_CHARS, display[i]) == NULL) { debug("Invalid character '%c' in DISPLAY", display[i]); return 0; @@ -884,7 +884,7 @@ process_cmdline(void) cmd = s = read_passphrase("\r\nssh> ", RP_ECHO); if (s == NULL) goto out; - while (isspace(*s)) + while (isspace((u_char)*s)) s++; if (*s == '-') s++; /* Skip cmdline '-', if any */ @@ -938,7 +938,7 @@ process_cmdline(void) goto out; } - while (isspace(*++s)) + while (isspace((u_char)*++s)) ; /* XXX update list of forwards in options */ @@ -1153,7 +1153,7 @@ process_escapes(Channel *c, Buffer *bin, Buffer *bout, Buffer *berr, "%cB\r\n", escape_char); buffer_append(berr, string, strlen(string)); - channel_request_start(session_ident, + channel_request_start(c->self, "break", 0); packet_put_int(1000); packet_send(); diff --git a/compat.c b/compat.c index ac353a706f52..9d9fabef3b45 100644 --- a/compat.c +++ b/compat.c @@ -1,4 +1,4 @@ -/* $OpenBSD: compat.c,v 1.81 2013/05/17 00:13:13 djm Exp $ */ +/* $OpenBSD: compat.c,v 1.82 2013/12/30 23:52:27 djm Exp $ */ /* * Copyright (c) 1999, 2000, 2001, 2002 Markus Friedl. All rights reserved. * @@ -171,8 +171,9 @@ compat_datafellows(const char *version) for (i = 0; check[i].pat; i++) { if (match_pattern_list(version, check[i].pat, strlen(check[i].pat), 0) == 1) { - debug("match: %s pat %s", version, check[i].pat); datafellows = check[i].bugs; + debug("match: %s pat %s compat 0x%08x", + version, check[i].pat, datafellows); return; } } @@ -208,33 +209,59 @@ proto_spec(const char *spec) return ret; } -char * -compat_cipher_proposal(char *cipher_prop) +/* + * Filters a proposal string, excluding any algorithm matching the 'filter' + * pattern list. + */ +static char * +filter_proposal(char *proposal, const char *filter) { Buffer b; - char *orig_prop, *fix_ciphers; + char *orig_prop, *fix_prop; char *cp, *tmp; - if (!(datafellows & SSH_BUG_BIGENDIANAES)) - return(cipher_prop); - buffer_init(&b); - tmp = orig_prop = xstrdup(cipher_prop); + tmp = orig_prop = xstrdup(proposal); while ((cp = strsep(&tmp, ",")) != NULL) { - if (strncmp(cp, "aes", 3) != 0) { + if (match_pattern_list(cp, filter, strlen(cp), 0) != 1) { if (buffer_len(&b) > 0) buffer_append(&b, ",", 1); buffer_append(&b, cp, strlen(cp)); - } + } else + debug2("Compat: skipping algorithm \"%s\"", cp); } buffer_append(&b, "\0", 1); - fix_ciphers = xstrdup(buffer_ptr(&b)); + fix_prop = xstrdup(buffer_ptr(&b)); buffer_free(&b); free(orig_prop); - debug2("Original cipher proposal: %s", cipher_prop); - debug2("Compat cipher proposal: %s", fix_ciphers); - if (!*fix_ciphers) - fatal("No available ciphers found."); - return(fix_ciphers); + return fix_prop; } + +char * +compat_cipher_proposal(char *cipher_prop) +{ + if (!(datafellows & SSH_BUG_BIGENDIANAES)) + return cipher_prop; + debug2("%s: original cipher proposal: %s", __func__, cipher_prop); + cipher_prop = filter_proposal(cipher_prop, "aes*"); + debug2("%s: compat cipher proposal: %s", __func__, cipher_prop); + if (*cipher_prop == '\0') + fatal("No supported ciphers found"); + return cipher_prop; +} + + +char * +compat_pkalg_proposal(char *pkalg_prop) +{ + if (!(datafellows & SSH_BUG_RSASIGMD5)) + return pkalg_prop; + debug2("%s: original public key proposal: %s", __func__, pkalg_prop); + pkalg_prop = filter_proposal(pkalg_prop, "ssh-rsa"); + debug2("%s: compat public key proposal: %s", __func__, pkalg_prop); + if (*pkalg_prop == '\0') + fatal("No supported PK algorithms found"); + return pkalg_prop; +} + diff --git a/compat.h b/compat.h index 3ae5d9c7836e..b174fa1719c0 100644 --- a/compat.h +++ b/compat.h @@ -1,4 +1,4 @@ -/* $OpenBSD: compat.h,v 1.43 2011/09/23 07:45:05 markus Exp $ */ +/* $OpenBSD: compat.h,v 1.44 2013/12/30 23:52:27 djm Exp $ */ /* * Copyright (c) 1999, 2000, 2001 Markus Friedl. All rights reserved. @@ -65,6 +65,7 @@ void enable_compat20(void); void compat_datafellows(const char *); int proto_spec(const char *); char *compat_cipher_proposal(char *); +char *compat_pkalg_proposal(char *); extern int compat13; extern int compat20; diff --git a/config.h.in b/config.h.in index b75e501b2042..075c619f6144 100644 --- a/config.h.in +++ b/config.h.in @@ -47,6 +47,10 @@ /* Can't do comparisons on readv */ #undef BROKEN_READV_COMPARISON +/* NetBSD read function is sometimes redirected, breaking atomicio comparisons + against it */ +#undef BROKEN_READ_COMPARISON + /* Define if you have a broken realpath. */ #undef BROKEN_REALPATH @@ -74,7 +78,7 @@ /* Define if your snprintf is busted */ #undef BROKEN_SNPRINTF -/* FreeBSD strnvis does not do what we need */ +/* FreeBSD strnvis argument order is swapped compared to OpenBSD */ #undef BROKEN_STRNVIS /* tcgetattr with ICANON may hang */ @@ -182,6 +186,9 @@ /* Define to 1 if you have the `arc4random_buf' function. */ #undef HAVE_ARC4RANDOM_BUF +/* Define to 1 if you have the `arc4random_stir' function. */ +#undef HAVE_ARC4RANDOM_STIR + /* Define to 1 if you have the `arc4random_uniform' function. */ #undef HAVE_ARC4RANDOM_UNIFORM @@ -212,9 +219,30 @@ /* Define to 1 if you have the `bcopy' function. */ #undef HAVE_BCOPY +/* Define to 1 if you have the `bcrypt_pbkdf' function. */ +#undef HAVE_BCRYPT_PBKDF + /* Define to 1 if you have the `bindresvport_sa' function. */ #undef HAVE_BINDRESVPORT_SA +/* Define to 1 if you have the `blf_enc' function. */ +#undef HAVE_BLF_ENC + +/* Define to 1 if you have the header file. */ +#undef HAVE_BLF_H + +/* Define to 1 if you have the `Blowfish_expand0state' function. */ +#undef HAVE_BLOWFISH_EXPAND0STATE + +/* Define to 1 if you have the `Blowfish_expandstate' function. */ +#undef HAVE_BLOWFISH_EXPANDSTATE + +/* Define to 1 if you have the `Blowfish_initstate' function. */ +#undef HAVE_BLOWFISH_INITSTATE + +/* Define to 1 if you have the `Blowfish_stream2word' function. */ +#undef HAVE_BLOWFISH_STREAM2WORD + /* Define to 1 if you have the `BN_is_prime_ex' function. */ #undef HAVE_BN_IS_PRIME_EX @@ -227,6 +255,9 @@ /* Define to 1 if you have the header file. */ #undef HAVE_BSTRING_H +/* Define to 1 if you have the `cap_rights_limit' function. */ +#undef HAVE_CAP_RIGHTS_LIMIT + /* Define to 1 if you have the `clock' function. */ #undef HAVE_CLOCK @@ -374,6 +405,18 @@ /* Define if libcrypto has EVP_CIPHER_CTX_ctrl */ #undef HAVE_EVP_CIPHER_CTX_CTRL +/* Define to 1 if you have the `EVP_DigestFinal_ex' function. */ +#undef HAVE_EVP_DIGESTFINAL_EX + +/* Define to 1 if you have the `EVP_DigestInit_ex' function. */ +#undef HAVE_EVP_DIGESTINIT_EX + +/* Define to 1 if you have the `EVP_MD_CTX_cleanup' function. */ +#undef HAVE_EVP_MD_CTX_CLEANUP + +/* Define to 1 if you have the `EVP_MD_CTX_init' function. */ +#undef HAVE_EVP_MD_CTX_INIT + /* Define to 1 if you have the `EVP_sha256' function. */ #undef HAVE_EVP_SHA256 @@ -413,6 +456,9 @@ /* Define to 1 if the system has the type `fsfilcnt_t'. */ #undef HAVE_FSFILCNT_T +/* Define to 1 if you have the `fstatfs' function. */ +#undef HAVE_FSTATFS + /* Define to 1 if you have the `fstatvfs' function. */ #undef HAVE_FSTATVFS @@ -584,6 +630,9 @@ /* define if you have int64_t data type */ #undef HAVE_INT64_T +/* Define to 1 if the system has the type `intmax_t'. */ +#undef HAVE_INTMAX_T + /* Define to 1 if you have the header file. */ #undef HAVE_INTTYPES_H @@ -1083,6 +1132,9 @@ /* Define to 1 if you have the header file. */ #undef HAVE_SYS_BSDTTY_H +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_CAPABILITY_H + /* Define to 1 if you have the header file. */ #undef HAVE_SYS_CDEFS_H @@ -1197,6 +1249,9 @@ /* Define to 1 if you have the header file. */ #undef HAVE_UCRED_H +/* Define to 1 if the system has the type `uintmax_t'. */ +#undef HAVE_UINTMAX_T + /* define if you have uintxx_t data type */ #undef HAVE_UINTXX_T @@ -1385,9 +1440,18 @@ /* Define if EVP_DigestUpdate returns void */ #undef OPENSSL_EVP_DIGESTUPDATE_VOID -/* libcrypto includes complete ECC support */ +/* OpenSSL has ECC */ #undef OPENSSL_HAS_ECC +/* libcrypto has NID_X9_62_prime256v1 */ +#undef OPENSSL_HAS_NISTP256 + +/* libcrypto has NID_secp384r1 */ +#undef OPENSSL_HAS_NISTP384 + +/* libcrypto has NID_secp521r1 */ +#undef OPENSSL_HAS_NISTP521 + /* libcrypto has EVP AES CTR */ #undef OPENSSL_HAVE_EVPCTR @@ -1440,6 +1504,9 @@ /* read(1) can return 0 for a non-closed fd */ #undef PTY_ZEROREAD +/* Sandbox using capsicum */ +#undef SANDBOX_CAPSICUM + /* Sandbox using Darwin sandbox_init(3) */ #undef SANDBOX_DARWIN @@ -1455,6 +1522,9 @@ /* setrlimit RLIMIT_FSIZE works */ #undef SANDBOX_SKIP_RLIMIT_FSIZE +/* define if setrlimit RLIMIT_NOFILE breaks things */ +#undef SANDBOX_SKIP_RLIMIT_NOFILE + /* Sandbox using systrace(4) */ #undef SANDBOX_SYSTRACE diff --git a/configure b/configure index 0d6fad5f4cab..2d714acae359 100755 --- a/configure +++ b/configure @@ -1,5 +1,5 @@ #! /bin/sh -# From configure.ac Revision: 1.536 . +# From configure.ac Revision: 1.568 . # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.68 for OpenSSH Portable. # @@ -606,6 +606,7 @@ ac_includes_default="\ ac_subst_vars='LTLIBOBJS LIBOBJS UNSUPPORTED_ALGORITHMS +TEST_MALLOC_OPTIONS TEST_SSH_IPV6 piddir user_path @@ -623,7 +624,6 @@ SSHLIBS SSH_PRIVSEP_USER COMMENT_OUT_ECC TEST_SSH_ECC -TEST_SSH_SHA256 LIBEDIT PKGCONFIG LD @@ -712,6 +712,7 @@ ac_user_opts=' enable_option_checking enable_largefile with_stackprotect +with_hardening with_rpath with_cflags with_cppflags @@ -728,6 +729,7 @@ with_tcp_wrappers with_ldns with_libedit with_audit +with_pie with_ssl_dir with_openssl_header_check with_ssl_engine @@ -1402,6 +1404,7 @@ Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) --without-stackprotect Don't use compiler's stack protection + --without-hardening Don't use toolchain hardening flags --without-rpath Disable auto-added -R linker paths --with-cflags Specify additional flags to pass to compiler --with-cppflags Specify additional flags to pass to preprocessor @@ -1418,6 +1421,7 @@ Optional Packages: --with-ldns[=PATH] Use ldns for DNSSEC support (optionally in PATH) --with-libedit[=PATH] Enable libedit support for sftp --with-audit=module Enable audit support (modules=debug,bsm,linux) + --with-pie Build Position Independent Executables if possible --with-ssl-dir=PATH Specify path to OpenSSL installation --without-openssl-header-check Disable OpenSSL version consistency check --with-ssl-engine Enable OpenSSL (hardware) ENGINE support @@ -1425,7 +1429,7 @@ Optional Packages: --with-prngd-socket=FILE read entropy from PRNGD/EGD socket FILE (default=/var/run/egd-pool) --with-pam Enable PAM support --with-privsep-user=user Specify non-privileged user for privilege separation - --with-sandbox=style Specify privilege separation sandbox (no, darwin, rlimit, systrace, seccomp_filter) + --with-sandbox=style Specify privilege separation sandbox (no, darwin, rlimit, systrace, seccomp_filter, capsicum) --with-selinux Enable SELinux support --with-kerberos5=PATH Enable Kerberos 5 support --with-privsep-path=xxx Path for privilege separation chroot (default=/var/empty) @@ -5590,7 +5594,9 @@ if test "x$ac_cv_have_decl_PR_SET_NO_NEW_PRIVS" = xyes; then : have_linux_no_new_privs=1 fi + use_stack_protector=1 +use_toolchain_hardening=1 # Check whether --with-stackprotect was given. if test "${with_stackprotect+set}" = set; then : @@ -5601,18 +5607,61 @@ if test "${with_stackprotect+set}" = set; then : fi +# Check whether --with-hardening was given. +if test "${with_hardening+set}" = set; then : + withval=$with_hardening; + if test "x$withval" = "xno"; then + use_toolchain_hardening=0 + fi +fi + + +# We use -Werror for the tests only so that we catch warnings like "this is +# on by default" for things like -fPIE. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC supports -Werror" >&5 +$as_echo_n "checking if $CC supports -Werror... " >&6; } +saved_CFLAGS="$CFLAGS" +CFLAGS="$CFLAGS -Werror" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +int main(void) { return 0; } +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + WERROR="-Werror" +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + WERROR="" + +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +CFLAGS="$saved_CFLAGS" if test "$GCC" = "yes" || test "$GCC" = "egcs"; then { - { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC supports -Qunused-arguments -Werror" >&5 -$as_echo_n "checking if $CC supports -Qunused-arguments -Werror... " >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC supports compile flag -Qunused-arguments" >&5 +$as_echo_n "checking if $CC supports compile flag -Qunused-arguments... " >&6; } saved_CFLAGS="$CFLAGS" - CFLAGS="$CFLAGS -Qunused-arguments -Werror" - _define_flag="-Qunused-arguments" - test "x$_define_flag" = "x" && _define_flag="-Qunused-arguments -Werror" + CFLAGS="$CFLAGS $WERROR -Qunused-arguments" + _define_flag="" + test "x$_define_flag" = "x" && _define_flag="-Qunused-arguments" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -int main(void) { return 0; } + +#include +#include +int main(int argc, char **argv) { + /* Some math to catch -ftrapv problems in the toolchain */ + int i = 123 * argc, j = 456 + argc, k = 789 - argc; + float l = i * 2.1; + double m = l / 0.5; + long long int n = argc * 12345LL, o = 12345LL * (long long int)argc; + printf("%d %d %d %f %f %lld %lld\n", i, j, k, l, m, n, o); + exit(0); +} + _ACEOF if ac_fn_c_try_compile "$LINENO"; then : @@ -5635,15 +5684,27 @@ fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext } { - { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC supports -Wunknown-warning-option -Werror" >&5 -$as_echo_n "checking if $CC supports -Wunknown-warning-option -Werror... " >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC supports compile flag -Wunknown-warning-option" >&5 +$as_echo_n "checking if $CC supports compile flag -Wunknown-warning-option... " >&6; } saved_CFLAGS="$CFLAGS" - CFLAGS="$CFLAGS -Wunknown-warning-option -Werror" - _define_flag="-Wno-unknown-warning-option" - test "x$_define_flag" = "x" && _define_flag="-Wunknown-warning-option -Werror" + CFLAGS="$CFLAGS $WERROR -Wunknown-warning-option" + _define_flag="" + test "x$_define_flag" = "x" && _define_flag="-Wunknown-warning-option" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -int main(void) { return 0; } + +#include +#include +int main(int argc, char **argv) { + /* Some math to catch -ftrapv problems in the toolchain */ + int i = 123 * argc, j = 456 + argc, k = 789 - argc; + float l = i * 2.1; + double m = l / 0.5; + long long int n = argc * 12345LL, o = 12345LL * (long long int)argc; + printf("%d %d %d %f %f %lld %lld\n", i, j, k, l, m, n, o); + exit(0); +} + _ACEOF if ac_fn_c_try_compile "$LINENO"; then : @@ -5666,15 +5727,27 @@ fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext } { - { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC supports -Wall" >&5 -$as_echo_n "checking if $CC supports -Wall... " >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC supports compile flag -Wall" >&5 +$as_echo_n "checking if $CC supports compile flag -Wall... " >&6; } saved_CFLAGS="$CFLAGS" - CFLAGS="$CFLAGS -Wall" + CFLAGS="$CFLAGS $WERROR -Wall" _define_flag="" test "x$_define_flag" = "x" && _define_flag="-Wall" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -int main(void) { return 0; } + +#include +#include +int main(int argc, char **argv) { + /* Some math to catch -ftrapv problems in the toolchain */ + int i = 123 * argc, j = 456 + argc, k = 789 - argc; + float l = i * 2.1; + double m = l / 0.5; + long long int n = argc * 12345LL, o = 12345LL * (long long int)argc; + printf("%d %d %d %f %f %lld %lld\n", i, j, k, l, m, n, o); + exit(0); +} + _ACEOF if ac_fn_c_try_compile "$LINENO"; then : @@ -5697,15 +5770,27 @@ fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext } { - { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC supports -Wpointer-arith" >&5 -$as_echo_n "checking if $CC supports -Wpointer-arith... " >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC supports compile flag -Wpointer-arith" >&5 +$as_echo_n "checking if $CC supports compile flag -Wpointer-arith... " >&6; } saved_CFLAGS="$CFLAGS" - CFLAGS="$CFLAGS -Wpointer-arith" + CFLAGS="$CFLAGS $WERROR -Wpointer-arith" _define_flag="" test "x$_define_flag" = "x" && _define_flag="-Wpointer-arith" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -int main(void) { return 0; } + +#include +#include +int main(int argc, char **argv) { + /* Some math to catch -ftrapv problems in the toolchain */ + int i = 123 * argc, j = 456 + argc, k = 789 - argc; + float l = i * 2.1; + double m = l / 0.5; + long long int n = argc * 12345LL, o = 12345LL * (long long int)argc; + printf("%d %d %d %f %f %lld %lld\n", i, j, k, l, m, n, o); + exit(0); +} + _ACEOF if ac_fn_c_try_compile "$LINENO"; then : @@ -5728,15 +5813,27 @@ fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext } { - { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC supports -Wuninitialized" >&5 -$as_echo_n "checking if $CC supports -Wuninitialized... " >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC supports compile flag -Wuninitialized" >&5 +$as_echo_n "checking if $CC supports compile flag -Wuninitialized... " >&6; } saved_CFLAGS="$CFLAGS" - CFLAGS="$CFLAGS -Wuninitialized" + CFLAGS="$CFLAGS $WERROR -Wuninitialized" _define_flag="" test "x$_define_flag" = "x" && _define_flag="-Wuninitialized" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -int main(void) { return 0; } + +#include +#include +int main(int argc, char **argv) { + /* Some math to catch -ftrapv problems in the toolchain */ + int i = 123 * argc, j = 456 + argc, k = 789 - argc; + float l = i * 2.1; + double m = l / 0.5; + long long int n = argc * 12345LL, o = 12345LL * (long long int)argc; + printf("%d %d %d %f %f %lld %lld\n", i, j, k, l, m, n, o); + exit(0); +} + _ACEOF if ac_fn_c_try_compile "$LINENO"; then : @@ -5759,15 +5856,27 @@ fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext } { - { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC supports -Wsign-compare" >&5 -$as_echo_n "checking if $CC supports -Wsign-compare... " >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC supports compile flag -Wsign-compare" >&5 +$as_echo_n "checking if $CC supports compile flag -Wsign-compare... " >&6; } saved_CFLAGS="$CFLAGS" - CFLAGS="$CFLAGS -Wsign-compare" + CFLAGS="$CFLAGS $WERROR -Wsign-compare" _define_flag="" test "x$_define_flag" = "x" && _define_flag="-Wsign-compare" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -int main(void) { return 0; } + +#include +#include +int main(int argc, char **argv) { + /* Some math to catch -ftrapv problems in the toolchain */ + int i = 123 * argc, j = 456 + argc, k = 789 - argc; + float l = i * 2.1; + double m = l / 0.5; + long long int n = argc * 12345LL, o = 12345LL * (long long int)argc; + printf("%d %d %d %f %f %lld %lld\n", i, j, k, l, m, n, o); + exit(0); +} + _ACEOF if ac_fn_c_try_compile "$LINENO"; then : @@ -5790,15 +5899,27 @@ fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext } { - { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC supports -Wformat-security" >&5 -$as_echo_n "checking if $CC supports -Wformat-security... " >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC supports compile flag -Wformat-security" >&5 +$as_echo_n "checking if $CC supports compile flag -Wformat-security... " >&6; } saved_CFLAGS="$CFLAGS" - CFLAGS="$CFLAGS -Wformat-security" + CFLAGS="$CFLAGS $WERROR -Wformat-security" _define_flag="" test "x$_define_flag" = "x" && _define_flag="-Wformat-security" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -int main(void) { return 0; } + +#include +#include +int main(int argc, char **argv) { + /* Some math to catch -ftrapv problems in the toolchain */ + int i = 123 * argc, j = 456 + argc, k = 789 - argc; + float l = i * 2.1; + double m = l / 0.5; + long long int n = argc * 12345LL, o = 12345LL * (long long int)argc; + printf("%d %d %d %f %f %lld %lld\n", i, j, k, l, m, n, o); + exit(0); +} + _ACEOF if ac_fn_c_try_compile "$LINENO"; then : @@ -5821,15 +5942,27 @@ fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext } { - { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC supports -Wsizeof-pointer-memaccess" >&5 -$as_echo_n "checking if $CC supports -Wsizeof-pointer-memaccess... " >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC supports compile flag -Wsizeof-pointer-memaccess" >&5 +$as_echo_n "checking if $CC supports compile flag -Wsizeof-pointer-memaccess... " >&6; } saved_CFLAGS="$CFLAGS" - CFLAGS="$CFLAGS -Wsizeof-pointer-memaccess" + CFLAGS="$CFLAGS $WERROR -Wsizeof-pointer-memaccess" _define_flag="" test "x$_define_flag" = "x" && _define_flag="-Wsizeof-pointer-memaccess" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -int main(void) { return 0; } + +#include +#include +int main(int argc, char **argv) { + /* Some math to catch -ftrapv problems in the toolchain */ + int i = 123 * argc, j = 456 + argc, k = 789 - argc; + float l = i * 2.1; + double m = l / 0.5; + long long int n = argc * 12345LL, o = 12345LL * (long long int)argc; + printf("%d %d %d %f %f %lld %lld\n", i, j, k, l, m, n, o); + exit(0); +} + _ACEOF if ac_fn_c_try_compile "$LINENO"; then : @@ -5852,15 +5985,27 @@ fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext } { - { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC supports -Wpointer-sign" >&5 -$as_echo_n "checking if $CC supports -Wpointer-sign... " >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC supports compile flag -Wpointer-sign" >&5 +$as_echo_n "checking if $CC supports compile flag -Wpointer-sign... " >&6; } saved_CFLAGS="$CFLAGS" - CFLAGS="$CFLAGS -Wpointer-sign" + CFLAGS="$CFLAGS $WERROR -Wpointer-sign" _define_flag="-Wno-pointer-sign" test "x$_define_flag" = "x" && _define_flag="-Wpointer-sign" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -int main(void) { return 0; } + +#include +#include +int main(int argc, char **argv) { + /* Some math to catch -ftrapv problems in the toolchain */ + int i = 123 * argc, j = 456 + argc, k = 789 - argc; + float l = i * 2.1; + double m = l / 0.5; + long long int n = argc * 12345LL, o = 12345LL * (long long int)argc; + printf("%d %d %d %f %f %lld %lld\n", i, j, k, l, m, n, o); + exit(0); +} + _ACEOF if ac_fn_c_try_compile "$LINENO"; then : @@ -5883,15 +6028,27 @@ fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext } { - { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC supports -Wunused-result" >&5 -$as_echo_n "checking if $CC supports -Wunused-result... " >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC supports compile flag -Wunused-result" >&5 +$as_echo_n "checking if $CC supports compile flag -Wunused-result... " >&6; } saved_CFLAGS="$CFLAGS" - CFLAGS="$CFLAGS -Wunused-result" + CFLAGS="$CFLAGS $WERROR -Wunused-result" _define_flag="-Wno-unused-result" test "x$_define_flag" = "x" && _define_flag="-Wunused-result" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -int main(void) { return 0; } + +#include +#include +int main(int argc, char **argv) { + /* Some math to catch -ftrapv problems in the toolchain */ + int i = 123 * argc, j = 456 + argc, k = 789 - argc; + float l = i * 2.1; + double m = l / 0.5; + long long int n = argc * 12345LL, o = 12345LL * (long long int)argc; + printf("%d %d %d %f %f %lld %lld\n", i, j, k, l, m, n, o); + exit(0); +} + _ACEOF if ac_fn_c_try_compile "$LINENO"; then : @@ -5914,15 +6071,27 @@ fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext } { - { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC supports -fno-strict-aliasing" >&5 -$as_echo_n "checking if $CC supports -fno-strict-aliasing... " >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC supports compile flag -fno-strict-aliasing" >&5 +$as_echo_n "checking if $CC supports compile flag -fno-strict-aliasing... " >&6; } saved_CFLAGS="$CFLAGS" - CFLAGS="$CFLAGS -fno-strict-aliasing" + CFLAGS="$CFLAGS $WERROR -fno-strict-aliasing" _define_flag="" test "x$_define_flag" = "x" && _define_flag="-fno-strict-aliasing" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -int main(void) { return 0; } + +#include +#include +int main(int argc, char **argv) { + /* Some math to catch -ftrapv problems in the toolchain */ + int i = 123 * argc, j = 456 + argc, k = 789 - argc; + float l = i * 2.1; + double m = l / 0.5; + long long int n = argc * 12345LL, o = 12345LL * (long long int)argc; + printf("%d %d %d %f %f %lld %lld\n", i, j, k, l, m, n, o); + exit(0); +} + _ACEOF if ac_fn_c_try_compile "$LINENO"; then : @@ -5945,15 +6114,27 @@ fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext } { - { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC supports -D_FORTIFY_SOURCE=2" >&5 -$as_echo_n "checking if $CC supports -D_FORTIFY_SOURCE=2... " >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC supports compile flag -D_FORTIFY_SOURCE=2" >&5 +$as_echo_n "checking if $CC supports compile flag -D_FORTIFY_SOURCE=2... " >&6; } saved_CFLAGS="$CFLAGS" - CFLAGS="$CFLAGS -D_FORTIFY_SOURCE=2" + CFLAGS="$CFLAGS $WERROR -D_FORTIFY_SOURCE=2" _define_flag="" test "x$_define_flag" = "x" && _define_flag="-D_FORTIFY_SOURCE=2" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -int main(void) { return 0; } + +#include +#include +int main(int argc, char **argv) { + /* Some math to catch -ftrapv problems in the toolchain */ + int i = 123 * argc, j = 456 + argc, k = 789 - argc; + float l = i * 2.1; + double m = l / 0.5; + long long int n = argc * 12345LL, o = 12345LL * (long long int)argc; + printf("%d %d %d %f %f %lld %lld\n", i, j, k, l, m, n, o); + exit(0); +} + _ACEOF if ac_fn_c_try_compile "$LINENO"; then : @@ -5975,6 +6156,165 @@ $as_echo "no" >&6; } fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext } + if test "x$use_toolchain_hardening" = "x1"; then + { + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $LD supports link flag -Wl,-z,relro" >&5 +$as_echo_n "checking if $LD supports link flag -Wl,-z,relro... " >&6; } + saved_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS $WERROR -Wl,-z,relro" + _define_flag="" + test "x$_define_flag" = "x" && _define_flag="-Wl,-z,relro" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include +#include +int main(int argc, char **argv) { + /* Some math to catch -ftrapv problems in the toolchain */ + int i = 123 * argc, j = 456 + argc, k = 789 - argc; + float l = i * 2.1; + double m = l / 0.5; + long long int n = argc * 12345LL, o = 12345LL * (long long int)argc; + printf("%d %d %d %f %f %lld %lld\n", i, j, k, l, m, n, o); + exit(0); +} + +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + LDFLAGS="$saved_LDFLAGS $_define_flag" +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + LDFLAGS="$saved_LDFLAGS" + +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +} + { + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $LD supports link flag -Wl,-z,now" >&5 +$as_echo_n "checking if $LD supports link flag -Wl,-z,now... " >&6; } + saved_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS $WERROR -Wl,-z,now" + _define_flag="" + test "x$_define_flag" = "x" && _define_flag="-Wl,-z,now" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include +#include +int main(int argc, char **argv) { + /* Some math to catch -ftrapv problems in the toolchain */ + int i = 123 * argc, j = 456 + argc, k = 789 - argc; + float l = i * 2.1; + double m = l / 0.5; + long long int n = argc * 12345LL, o = 12345LL * (long long int)argc; + printf("%d %d %d %f %f %lld %lld\n", i, j, k, l, m, n, o); + exit(0); +} + +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + LDFLAGS="$saved_LDFLAGS $_define_flag" +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + LDFLAGS="$saved_LDFLAGS" + +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +} + { + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $LD supports link flag -Wl,-z,noexecstack" >&5 +$as_echo_n "checking if $LD supports link flag -Wl,-z,noexecstack... " >&6; } + saved_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS $WERROR -Wl,-z,noexecstack" + _define_flag="" + test "x$_define_flag" = "x" && _define_flag="-Wl,-z,noexecstack" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include +#include +int main(int argc, char **argv) { + /* Some math to catch -ftrapv problems in the toolchain */ + int i = 123 * argc, j = 456 + argc, k = 789 - argc; + float l = i * 2.1; + double m = l / 0.5; + long long int n = argc * 12345LL, o = 12345LL * (long long int)argc; + printf("%d %d %d %f %f %lld %lld\n", i, j, k, l, m, n, o); + exit(0); +} + +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + LDFLAGS="$saved_LDFLAGS $_define_flag" +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + LDFLAGS="$saved_LDFLAGS" + +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +} + # NB. -ftrapv expects certain support functions to be present in + # the compiler library (libgcc or similar) to detect integer operations + # that can overflow. We must check that the result of enabling it + # actually links. The test program compiled/linked includes a number + # of integer operations that should exercise this. + { + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC supports compile flag -ftrapv and linking succeeds" >&5 +$as_echo_n "checking if $CC supports compile flag -ftrapv and linking succeeds... " >&6; } + saved_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS $WERROR -ftrapv" + _define_flag="" + test "x$_define_flag" = "x" && _define_flag="-ftrapv" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include +#include +int main(int argc, char **argv) { + /* Some math to catch -ftrapv problems in the toolchain */ + int i = 123 * argc, j = 456 + argc, k = 789 - argc; + float l = i * 2.1; + double m = l / 0.5; + long long int n = argc * 12345LL, o = 12345LL * (long long int)argc; + printf("%d %d %d %f %f %lld %lld\n", i, j, k, l, m, n, o); + exit(0); +} + +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + +if `grep -i "unrecognized option" conftest.err >/dev/null` +then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + CFLAGS="$saved_CFLAGS" +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + CFLAGS="$saved_CFLAGS $_define_flag" +fi +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + CFLAGS="$saved_CFLAGS" + +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +} + fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking gcc version" >&5 $as_echo_n "checking gcc version... " >&6; } GCC_VER=`$CC -v 2>&1 | $AWK '/gcc version /{print $3}'` @@ -6020,7 +6360,8 @@ rm -f core conftest.err conftest.$ac_objext \ # and/or platforms, so we test if we can. If it's not supported # on a given platform gcc will emit a warning so we use -Werror. if test "x$use_stack_protector" = "x1"; then - for t in -fstack-protector-all -fstack-protector; do + for t in -fstack-protector-strong -fstack-protector-all \ + -fstack-protector; do { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC supports $t" >&5 $as_echo_n "checking if $CC supports $t... " >&6; } saved_CFLAGS="$CFLAGS" @@ -6224,6 +6565,7 @@ fi for ac_header in \ + blf.h \ bstring.h \ crypt.h \ crypto/sha2.h \ @@ -6237,6 +6579,7 @@ for ac_header in \ glob.h \ ia.h \ iaf.h \ + inttypes.h \ limits.h \ locale.h \ login.h \ @@ -6261,6 +6604,7 @@ for ac_header in \ sys/audit.h \ sys/bitypes.h \ sys/bsdtty.h \ + sys/capability.h \ sys/cdefs.h \ sys/dir.h \ sys/mman.h \ @@ -6713,6 +7057,51 @@ $as_echo "#define SSH_IOBUFSZ 65535" >>confdefs.h $as_echo "#define FILESYSTEM_NO_BACKSLASH 1" >>confdefs.h + # Cygwin defines optargs, optargs as declspec(dllimport) for historical + # reasons which cause compile warnings, so we disable those warnings. + { + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC supports compile flag -Wno-attributes" >&5 +$as_echo_n "checking if $CC supports compile flag -Wno-attributes... " >&6; } + saved_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS $WERROR -Wno-attributes" + _define_flag="" + test "x$_define_flag" = "x" && _define_flag="-Wno-attributes" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include +#include +int main(int argc, char **argv) { + /* Some math to catch -ftrapv problems in the toolchain */ + int i = 123 * argc, j = 456 + argc, k = 789 - argc; + float l = i * 2.1; + double m = l / 0.5; + long long int n = argc * 12345LL, o = 12345LL * (long long int)argc; + printf("%d %d %d %f %f %lld %lld\n", i, j, k, l, m, n, o); + exit(0); +} + +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + +if `grep -i "unrecognized option" conftest.err >/dev/null` +then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + CFLAGS="$saved_CFLAGS" +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + CFLAGS="$saved_CFLAGS $_define_flag" +fi +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + CFLAGS="$saved_CFLAGS" + +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +} ;; *-*-dgux*) @@ -6726,6 +7115,7 @@ $as_echo "#define IP_TOS_IS_BROKEN 1" >>confdefs.h ;; *-*-darwin*) + use_pie=auto { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we have working getaddrinfo" >&5 $as_echo_n "checking if we have working getaddrinfo... " >&6; } if test "$cross_compiling" = yes; then : @@ -6824,6 +7214,7 @@ done ;; *-*-dragonfly*) SSHDLIBS="$SSHDLIBS -lcrypt" + TEST_MALLOC_OPTIONS="AFGJPRX" ;; *-*-haiku*) LIBS="$LIBS -lbsd " @@ -7046,6 +7437,7 @@ $as_echo "#define USE_BTMP 1" >>confdefs.h ;; *-*-linux*) no_dev_ptmx=1 + use_pie=auto check_for_libcrypt_later=1 check_for_openpty_ctty_bug=1 @@ -7178,6 +7570,13 @@ fi $as_echo "#define SSH_TUN_PREPEND_AF 1" >>confdefs.h + TEST_MALLOC_OPTIONS="AJRX" + +$as_echo "#define BROKEN_STRNVIS 1" >>confdefs.h + + +$as_echo "#define BROKEN_READ_COMPARISON 1" >>confdefs.h + ;; *-*-freebsd*) check_for_libcrypt_later=1 @@ -7203,6 +7602,12 @@ $as_echo "#define BROKEN_GLOB 1" >>confdefs.h $as_echo "#define BROKEN_STRNVIS 1" >>confdefs.h + TEST_MALLOC_OPTIONS="AJRX" + # Preauth crypto occasionally uses file descriptors for crypto offload + # and will crash if they cannot be opened. + +$as_echo "#define SANDBOX_SKIP_RLIMIT_NOFILE 1" >>confdefs.h +], ;; *-*-bsdi*) $as_echo "#define SETEUID_BREAKS_SETUID 1" >>confdefs.h @@ -7229,6 +7634,7 @@ $as_echo "#define BROKEN_SAVED_UIDS 1" >>confdefs.h ;; *-*-openbsd*) + use_pie=auto $as_echo "#define HAVE_ATTRIBUTE__SENTINEL__ 1" >>confdefs.h @@ -7241,6 +7647,7 @@ $as_echo "#define SSH_TUN_OPENBSD 1" >>confdefs.h $as_echo "#define SYSLOG_R_SAFE_IN_SIGHAND 1" >>confdefs.h + TEST_MALLOC_OPTIONS="AFGJPRX" ;; *-*-solaris*) if test "x$withval" != "xno" ; then @@ -8929,6 +9336,64 @@ fi done +# On some platforms, inet_ntop may be found in libresolv or libnsl. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing inet_ntop" >&5 +$as_echo_n "checking for library containing inet_ntop... " >&6; } +if ${ac_cv_search_inet_ntop+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_func_search_save_LIBS=$LIBS +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char inet_ntop (); +int +main () +{ +return inet_ntop (); + ; + return 0; +} +_ACEOF +for ac_lib in '' resolv nsl; do + if test -z "$ac_lib"; then + ac_res="none required" + else + ac_res=-l$ac_lib + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + fi + if ac_fn_c_try_link "$LINENO"; then : + ac_cv_search_inet_ntop=$ac_res +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext + if ${ac_cv_search_inet_ntop+:} false; then : + break +fi +done +if ${ac_cv_search_inet_ntop+:} false; then : + +else + ac_cv_search_inet_ntop=no +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_inet_ntop" >&5 +$as_echo "$ac_cv_search_inet_ntop" >&6; } +ac_res=$ac_cv_search_inet_ntop +if test "$ac_res" != no; then : + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + +fi + + for ac_func in strftime do : ac_fn_c_check_func "$LINENO" "strftime" "ac_cv_func_strftime" @@ -9495,7 +9960,7 @@ $as_echo "no" >&6; } fi fi if test "x$use_pkgconfig_for_libedit" = "xyes"; then - LIBEDIT=`$PKGCONFIG --libs-only-l libedit` + LIBEDIT=`$PKGCONFIG --libs libedit` CPPFLAGS="$CPPFLAGS `$PKGCONFIG --cflags libedit`" else LIBEDIT="-ledit -lcurses" @@ -9689,7 +10154,7 @@ done $as_echo "#define USE_BSM_AUDIT 1" >>confdefs.h - if test "$sol2ver" -eq 11; then + if test "$sol2ver" -ge 11; then SSHDLIBS="$SSHDLIBS -lscf" $as_echo "#define BROKEN_BSM_API 1" >>confdefs.h @@ -9737,9 +10202,155 @@ $as_echo "no" >&6; } fi + +# Check whether --with-pie was given. +if test "${with_pie+set}" = set; then : + withval=$with_pie; + if test "x$withval" = "xno"; then + use_pie=no + fi + if test "x$withval" = "xyes"; then + use_pie=yes + fi + + +fi + +if test "x$use_pie" = "x"; then + use_pie=no +fi +if test "x$use_toolchain_hardening" != "x1" && test "x$use_pie" = "xauto"; then + # Turn off automatic PIE when toolchain hardening is off. + use_pie=no +fi +if test "x$use_pie" = "xauto"; then + # Automatic PIE requires gcc >= 4.x + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gcc >= 4.x" >&5 +$as_echo_n "checking for gcc >= 4.x... " >&6; } + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#if !defined(__GNUC__) || __GNUC__ < 4 +#error gcc is too old +#endif + +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + use_pie=no + +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +if test "x$use_pie" != "xno"; then + SAVED_CFLAGS="$CFLAGS" + SAVED_LDFLAGS="$LDFLAGS" + { + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC supports compile flag -fPIE" >&5 +$as_echo_n "checking if $CC supports compile flag -fPIE... " >&6; } + saved_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS $WERROR -fPIE" + _define_flag="" + test "x$_define_flag" = "x" && _define_flag="-fPIE" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include +#include +int main(int argc, char **argv) { + /* Some math to catch -ftrapv problems in the toolchain */ + int i = 123 * argc, j = 456 + argc, k = 789 - argc; + float l = i * 2.1; + double m = l / 0.5; + long long int n = argc * 12345LL, o = 12345LL * (long long int)argc; + printf("%d %d %d %f %f %lld %lld\n", i, j, k, l, m, n, o); + exit(0); +} + +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + +if `grep -i "unrecognized option" conftest.err >/dev/null` +then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + CFLAGS="$saved_CFLAGS" +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + CFLAGS="$saved_CFLAGS $_define_flag" +fi +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + CFLAGS="$saved_CFLAGS" + +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +} + { + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $LD supports link flag -pie" >&5 +$as_echo_n "checking if $LD supports link flag -pie... " >&6; } + saved_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS $WERROR -pie" + _define_flag="" + test "x$_define_flag" = "x" && _define_flag="-pie" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include +#include +int main(int argc, char **argv) { + /* Some math to catch -ftrapv problems in the toolchain */ + int i = 123 * argc, j = 456 + argc, k = 789 - argc; + float l = i * 2.1; + double m = l / 0.5; + long long int n = argc * 12345LL, o = 12345LL * (long long int)argc; + printf("%d %d %d %f %f %lld %lld\n", i, j, k, l, m, n, o); + exit(0); +} + +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + LDFLAGS="$saved_LDFLAGS $_define_flag" +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + LDFLAGS="$saved_LDFLAGS" + +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +} + # We use both -fPIE and -pie or neither. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether both -fPIE and -pie are supported" >&5 +$as_echo_n "checking whether both -fPIE and -pie are supported... " >&6; } + if echo "x $CFLAGS" | grep ' -fPIE' >/dev/null 2>&1 && \ + echo "x $LDFLAGS" | grep ' -pie' >/dev/null 2>&1 ; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + CFLAGS="$SAVED_CFLAGS" + LDFLAGS="$SAVED_LDFLAGS" + fi +fi + for ac_func in \ + Blowfish_initstate \ + Blowfish_expandstate \ + Blowfish_expand0state \ + Blowfish_stream2word \ arc4random \ arc4random_buf \ + arc4random_stir \ arc4random_uniform \ asprintf \ b64_ntop \ @@ -9747,7 +10358,10 @@ for ac_func in \ b64_pton \ __b64_pton \ bcopy \ + bcrypt_pbkdf \ bindresvport_sa \ + blf_enc \ + cap_rights_limit \ clock \ closefrom \ dirfd \ @@ -9755,6 +10369,7 @@ for ac_func in \ fchmod \ fchown \ freeaddrinfo \ + fstatfs \ fstatvfs \ futimes \ getaddrinfo \ @@ -11491,7 +12106,17 @@ fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext -for ac_func in RSA_generate_key_ex DSA_generate_parameters_ex BN_is_prime_ex RSA_get_default_method HMAC_CTX_init +for ac_func in \ + BN_is_prime_ex \ + DSA_generate_parameters_ex \ + EVP_DigestInit_ex \ + EVP_DigestFinal_ex \ + EVP_MD_CTX_init \ + EVP_MD_CTX_cleanup \ + HMAC_CTX_init \ + RSA_generate_key_ex \ + RSA_get_default_method \ + do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" @@ -11876,10 +12501,9 @@ if eval test \"x\$"$as_ac_var"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF - TEST_SSH_SHA256=yes + else - TEST_SSH_SHA256=no - unsupported_algorithms="$unsupported_algorithms \ + unsupported_algorithms="$unsupported_algorithms \ hmac-sha2-256 hmac-sha2-512 \ diffie-hellman-group-exchange-sha256 \ hmac-sha2-256-etm@openssh.com hmac-sha2-512-etm@openssh.com" @@ -11889,10 +12513,85 @@ fi done - # Check complete ECC support in OpenSSL -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether OpenSSL has complete ECC support" >&5 -$as_echo_n "checking whether OpenSSL has complete ECC support... " >&6; } +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether OpenSSL has NID_X9_62_prime256v1" >&5 +$as_echo_n "checking whether OpenSSL has NID_X9_62_prime256v1... " >&6; } +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include +#include +#include +#include +#include +#include +#if OPENSSL_VERSION_NUMBER < 0x0090807f /* 0.9.8g */ +# error "OpenSSL < 0.9.8g has unreliable ECC code" +#endif + +int +main () +{ + + EC_KEY *e = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1); + const EVP_MD *m = EVP_sha256(); /* We need this too */ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + enable_nistp256=1 +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether OpenSSL has NID_secp384r1" >&5 +$as_echo_n "checking whether OpenSSL has NID_secp384r1... " >&6; } +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include +#include +#include +#include +#include +#include +#if OPENSSL_VERSION_NUMBER < 0x0090807f /* 0.9.8g */ +# error "OpenSSL < 0.9.8g has unreliable ECC code" +#endif + +int +main () +{ + + EC_KEY *e = EC_KEY_new_by_curve_name(NID_secp384r1); + const EVP_MD *m = EVP_sha384(); /* We need this too */ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + enable_nistp384=1 +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether OpenSSL has NID_secp521r1" >&5 +$as_echo_n "checking whether OpenSSL has NID_secp521r1... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -11918,33 +12617,99 @@ main () } _ACEOF if ac_fn_c_try_link "$LINENO"; then : - - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } - -$as_echo "#define OPENSSL_HAS_ECC 1" >>confdefs.h - - TEST_SSH_ECC=yes - COMMENT_OUT_ECC="" + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if OpenSSL's NID_secp521r1 is functional" >&5 +$as_echo_n "checking if OpenSSL's NID_secp521r1 is functional... " >&6; } + if test "$cross_compiling" = yes; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cross-compiling: assuming yes" >&5 +$as_echo "$as_me: WARNING: cross-compiling: assuming yes" >&2;} + enable_nistp521=1 else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +#include +#include +#include +#include +#include +#include + +int +main () +{ + + EC_KEY *e = EC_KEY_new_by_curve_name(NID_secp521r1); + const EVP_MD *m = EVP_sha512(); /* We need this too */ + exit(e == NULL || m == NULL); + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + enable_nistp521=1 +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } - TEST_SSH_ECC=no - COMMENT_OUT_ECC="#no ecc#" - unsupported_algorithms="$unsupported_algorithms \ - ecdh-sha2-nistp256 ecdh-sha2-nistp384 ecdh-sha2-nistp521 \ - ecdsa-sha2-nistp256-cert-v01@openssh.com \ - ecdsa-sha2-nistp384-cert-v01@openssh.com \ - ecdsa-sha2-nistp521-cert-v01@openssh.com \ - ecdsa-sha2-nistp256 ecdsa-sha2-nistp384 ecdsa-sha2-nistp521" +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext +COMMENT_OUT_ECC="#no ecc#" +TEST_SSH_ECC=no + +if test x$enable_nistp256 = x1 || test x$enable_nistp384 = x1 || \ + test x$enable_nistp521 = x1; then + +$as_echo "#define OPENSSL_HAS_ECC 1" >>confdefs.h + +fi +if test x$enable_nistp256 = x1; then + +$as_echo "#define OPENSSL_HAS_NISTP256 1" >>confdefs.h + + TEST_SSH_ECC=yes + COMMENT_OUT_ECC="" +else + unsupported_algorithms="$unsupported_algorithms ecdsa-sha2-nistp256 \ + ecdh-sha2-nistp256 ecdsa-sha2-nistp256-cert-v01@openssh.com" +fi +if test x$enable_nistp384 = x1; then + +$as_echo "#define OPENSSL_HAS_NISTP384 1" >>confdefs.h + + TEST_SSH_ECC=yes + COMMENT_OUT_ECC="" +else + unsupported_algorithms="$unsupported_algorithms ecdsa-sha2-nistp384 \ + ecdh-sha2-nistp384 ecdsa-sha2-nistp384-cert-v01@openssh.com" +fi +if test x$enable_nistp521 = x1; then + +$as_echo "#define OPENSSL_HAS_NISTP521 1" >>confdefs.h + + TEST_SSH_ECC=yes + COMMENT_OUT_ECC="" +else + unsupported_algorithms="$unsupported_algorithms ecdh-sha2-nistp521 \ + ecdsa-sha2-nistp521 ecdsa-sha2-nistp521-cert-v01@openssh.com" +fi + + saved_LIBS="$LIBS" @@ -12635,6 +13400,18 @@ elif test "x$sandbox_arg" = "xseccomp_filter" || \ $as_echo "#define SANDBOX_SECCOMP_FILTER 1" >>confdefs.h +elif test "x$sandbox_arg" = "xcapsicum" || \ + ( test -z "$sandbox_arg" && \ + test "x$ac_cv_header_sys_capability_h" = "xyes" && \ + test "x$ac_cv_func_cap_rights_limit" = "xyes") ; then + test "x$ac_cv_header_sys_capability_h" != "xyes" && \ + as_fn_error $? "capsicum sandbox requires sys/capability.h header" "$LINENO" 5 + test "x$ac_cv_func_cap_rights_limit" != "xyes" && \ + as_fn_error $? "capsicum sandbox requires cap_rights_limit function" "$LINENO" 5 + SANDBOX_STYLE="capsicum" + +$as_echo "#define SANDBOX_CAPSICUM 1" >>confdefs.h + elif test "x$sandbox_arg" = "xrlimit" || \ ( test -z "$sandbox_arg" && test "x$ac_cv_func_setrlimit" = "xyes" && \ test "x$select_works_with_rlimit" = "xyes" && \ @@ -13204,7 +13981,9 @@ $as_echo "#define HAVE_U_INT64_T 1" >>confdefs.h have_u_int64_t=1 fi -if test -z "$have_u_int64_t" ; then +if (test -z "$have_u_int64_t" && \ + test "x$ac_cv_header_sys_bitypes_h" = "xyes") +then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for u_int64_t type in sys/bitypes.h" >&5 $as_echo_n "checking for u_int64_t type in sys/bitypes.h... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -13276,7 +14055,9 @@ $as_echo "#define HAVE_UINTXX_T 1" >>confdefs.h fi fi -if test -z "$have_uintxx_t" ; then +if (test -z "$have_uintxx_t" && \ + test "x$ac_cv_header_stdint_h" = "xyes") +then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for uintXX_t types in stdint.h" >&5 $as_echo_n "checking for uintXX_t types in stdint.h... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -13305,6 +14086,37 @@ fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi +if (test -z "$have_uintxx_t" && \ + test "x$ac_cv_header_inttypes_h" = "xyes") +then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for uintXX_t types in inttypes.h" >&5 +$as_echo_n "checking for uintXX_t types in inttypes.h... " >&6; } + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + #include +int +main () +{ + uint8_t a; uint16_t b; uint32_t c; a = b = c = 1; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + + $as_echo "#define HAVE_UINTXX_T 1" >>confdefs.h + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi + if (test -z "$have_u_intxx_t" || test -z "$have_intxx_t" && \ test "x$ac_cv_header_sys_bitypes_h" = "xyes") then @@ -13379,6 +14191,34 @@ $as_echo "#define HAVE_U_CHAR 1" >>confdefs.h fi +ac_fn_c_check_type "$LINENO" "intmax_t" "ac_cv_type_intmax_t" " +#include +#include + +" +if test "x$ac_cv_type_intmax_t" = xyes; then : + +cat >>confdefs.h <<_ACEOF +#define HAVE_INTMAX_T 1 +_ACEOF + + +fi +ac_fn_c_check_type "$LINENO" "uintmax_t" "ac_cv_type_uintmax_t" " +#include +#include + +" +if test "x$ac_cv_type_uintmax_t" = xyes; then : + +cat >>confdefs.h <<_ACEOF +#define HAVE_UINTMAX_T 1 +_ACEOF + + +fi + + ac_fn_c_check_type "$LINENO" "socklen_t" "ac_cv_type_socklen_t" "#include #include @@ -17492,6 +18332,8 @@ fi TEST_SSH_IPV6=$TEST_SSH_IPV6 +TEST_MALLOC_OPTIONS=$TEST_MALLOC_OPTIONS + UNSUPPORTED_ALGORITHMS=$unsupported_algorithms diff --git a/configure.ac b/configure.ac index 4a1b50331af2..dfd32cd85183 100644 --- a/configure.ac +++ b/configure.ac @@ -1,4 +1,4 @@ -# $Id: configure.ac,v 1.536 2013/08/04 11:48:41 dtucker Exp $ +# $Id: configure.ac,v 1.568 2014/01/30 00:26:46 djm Exp $ # # Copyright (c) 1999-2004 Damien Miller # @@ -15,7 +15,7 @@ # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. AC_INIT([OpenSSH], [Portable], [openssh-unix-dev@mindrot.org]) -AC_REVISION($Revision: 1.536 $) +AC_REVISION($Revision: 1.568 $) AC_CONFIG_SRCDIR([ssh.c]) AC_LANG([C]) @@ -120,19 +120,36 @@ AC_CHECK_DECL([PR_SET_NO_NEW_PRIVS], [have_linux_no_new_privs=1], , [ #include #include ]) + use_stack_protector=1 +use_toolchain_hardening=1 AC_ARG_WITH([stackprotect], [ --without-stackprotect Don't use compiler's stack protection], [ if test "x$withval" = "xno"; then use_stack_protector=0 fi ]) +AC_ARG_WITH([hardening], + [ --without-hardening Don't use toolchain hardening flags], [ + if test "x$withval" = "xno"; then + use_toolchain_hardening=0 + fi ]) +# We use -Werror for the tests only so that we catch warnings like "this is +# on by default" for things like -fPIE. +AC_MSG_CHECKING([if $CC supports -Werror]) +saved_CFLAGS="$CFLAGS" +CFLAGS="$CFLAGS -Werror" +AC_COMPILE_IFELSE([AC_LANG_SOURCE([[int main(void) { return 0; }]])], + [ AC_MSG_RESULT([yes]) + WERROR="-Werror"], + [ AC_MSG_RESULT([no]) + WERROR="" ] +) +CFLAGS="$saved_CFLAGS" if test "$GCC" = "yes" || test "$GCC" = "egcs"; then - OSSH_CHECK_CFLAG_COMPILE([-Qunused-arguments -Werror], - [-Qunused-arguments]) - OSSH_CHECK_CFLAG_COMPILE([-Wunknown-warning-option -Werror], - [-Wno-unknown-warning-option]) + OSSH_CHECK_CFLAG_COMPILE([-Qunused-arguments]) + OSSH_CHECK_CFLAG_COMPILE([-Wunknown-warning-option]) OSSH_CHECK_CFLAG_COMPILE([-Wall]) OSSH_CHECK_CFLAG_COMPILE([-Wpointer-arith]) OSSH_CHECK_CFLAG_COMPILE([-Wuninitialized]) @@ -143,6 +160,17 @@ if test "$GCC" = "yes" || test "$GCC" = "egcs"; then OSSH_CHECK_CFLAG_COMPILE([-Wunused-result], [-Wno-unused-result]) OSSH_CHECK_CFLAG_COMPILE([-fno-strict-aliasing]) OSSH_CHECK_CFLAG_COMPILE([-D_FORTIFY_SOURCE=2]) + if test "x$use_toolchain_hardening" = "x1"; then + OSSH_CHECK_LDFLAG_LINK([-Wl,-z,relro]) + OSSH_CHECK_LDFLAG_LINK([-Wl,-z,now]) + OSSH_CHECK_LDFLAG_LINK([-Wl,-z,noexecstack]) + # NB. -ftrapv expects certain support functions to be present in + # the compiler library (libgcc or similar) to detect integer operations + # that can overflow. We must check that the result of enabling it + # actually links. The test program compiled/linked includes a number + # of integer operations that should exercise this. + OSSH_CHECK_CFLAG_LINK([-ftrapv]) + fi AC_MSG_CHECKING([gcc version]) GCC_VER=`$CC -v 2>&1 | $AWK '/gcc version /{print $3}'` case $GCC_VER in @@ -169,7 +197,8 @@ if test "$GCC" = "yes" || test "$GCC" = "egcs"; then # and/or platforms, so we test if we can. If it's not supported # on a given platform gcc will emit a warning so we use -Werror. if test "x$use_stack_protector" = "x1"; then - for t in -fstack-protector-all -fstack-protector; do + for t in -fstack-protector-strong -fstack-protector-all \ + -fstack-protector; do AC_MSG_CHECKING([if $CC supports $t]) saved_CFLAGS="$CFLAGS" saved_LDFLAGS="$LDFLAGS" @@ -296,6 +325,7 @@ AC_ARG_WITH([Werror], ) AC_CHECK_HEADERS([ \ + blf.h \ bstring.h \ crypt.h \ crypto/sha2.h \ @@ -309,6 +339,7 @@ AC_CHECK_HEADERS([ \ glob.h \ ia.h \ iaf.h \ + inttypes.h \ limits.h \ locale.h \ login.h \ @@ -333,6 +364,7 @@ AC_CHECK_HEADERS([ \ sys/audit.h \ sys/bitypes.h \ sys/bsdtty.h \ + sys/capability.h \ sys/cdefs.h \ sys/dir.h \ sys/mman.h \ @@ -513,7 +545,10 @@ case "$host" in [Define if your platform needs to skip post auth file descriptor passing]) AC_DEFINE([SSH_IOBUFSZ], [65535], [Windows is sensitive to read buffer size]) - AC_DEFINE([FILESYSTEM_NO_BACKSLASH], [1], [File names may not contain backslash characters]) + AC_DEFINE([FILESYSTEM_NO_BACKSLASH], [1], [File names may not contain backslash characters]) + # Cygwin defines optargs, optargs as declspec(dllimport) for historical + # reasons which cause compile warnings, so we disable those warnings. + OSSH_CHECK_CFLAG_COMPILE([-Wno-attributes]) ;; *-*-dgux*) AC_DEFINE([IP_TOS_IS_BROKEN], [1], @@ -523,6 +558,7 @@ case "$host" in AC_DEFINE([BROKEN_SETREGID]) ;; *-*-darwin*) + use_pie=auto AC_MSG_CHECKING([if we have working getaddrinfo]) AC_RUN_IFELSE([AC_LANG_SOURCE([[ #include main() { if (NSVersionOfRunTimeLibrary("System") >= (60 << 16)) @@ -563,6 +599,7 @@ main() { if (NSVersionOfRunTimeLibrary("System") >= (60 << 16)) ;; *-*-dragonfly*) SSHDLIBS="$SSHDLIBS -lcrypt" + TEST_MALLOC_OPTIONS="AFGJPRX" ;; *-*-haiku*) LIBS="$LIBS -lbsd " @@ -660,6 +697,7 @@ main() { if (NSVersionOfRunTimeLibrary("System") >= (60 << 16)) ;; *-*-linux*) no_dev_ptmx=1 + use_pie=auto check_for_libcrypt_later=1 check_for_openpty_ctty_bug=1 AC_DEFINE([PAM_TTY_KLUDGE], [1], @@ -728,6 +766,11 @@ mips-sony-bsd|mips-sony-newsos4) AC_DEFINE([SSH_TUN_NO_L2], [1], [No layer 2 tunnel support])) AC_DEFINE([SSH_TUN_PREPEND_AF], [1], [Prepend the address family to IP tunnel traffic]) + TEST_MALLOC_OPTIONS="AJRX" + AC_DEFINE([BROKEN_STRNVIS], [1], + [NetBSD strnvis argument order is swapped compared to OpenBSD]) + AC_DEFINE([BROKEN_READ_COMPARISON], [1], + [NetBSD read function is sometimes redirected, breaking atomicio comparisons against it]) ;; *-*-freebsd*) check_for_libcrypt_later=1 @@ -736,7 +779,13 @@ mips-sony-bsd|mips-sony-newsos4) AC_CHECK_HEADER([net/if_tap.h], , AC_DEFINE([SSH_TUN_NO_L2], [1], [No layer 2 tunnel support])) AC_DEFINE([BROKEN_GLOB], [1], [FreeBSD glob does not do what we need]) - AC_DEFINE([BROKEN_STRNVIS], [1], [FreeBSD strnvis does not do what we need]) + AC_DEFINE([BROKEN_STRNVIS], [1], + [FreeBSD strnvis argument order is swapped compared to OpenBSD]) + TEST_MALLOC_OPTIONS="AJRX" + # Preauth crypto occasionally uses file descriptors for crypto offload + # and will crash if they cannot be opened. + AC_DEFINE([SANDBOX_SKIP_RLIMIT_NOFILE], [1], + [define if setrlimit RLIMIT_NOFILE breaks things])], ;; *-*-bsdi*) AC_DEFINE([SETEUID_BREAKS_SETUID]) @@ -754,11 +803,13 @@ mips-sony-bsd|mips-sony-newsos4) AC_DEFINE([BROKEN_SAVED_UIDS], [1], [Needed for NeXT]) ;; *-*-openbsd*) + use_pie=auto AC_DEFINE([HAVE_ATTRIBUTE__SENTINEL__], [1], [OpenBSD's gcc has sentinel]) AC_DEFINE([HAVE_ATTRIBUTE__BOUNDED__], [1], [OpenBSD's gcc has bounded]) AC_DEFINE([SSH_TUN_OPENBSD], [1], [Open tunnel devices the OpenBSD way]) AC_DEFINE([SYSLOG_R_SAFE_IN_SIGHAND], [1], [syslog_r function is safe to use in in a signal handler]) + TEST_MALLOC_OPTIONS="AFGJPRX" ;; *-*-solaris*) if test "x$withval" != "xno" ; then @@ -1191,6 +1242,9 @@ AC_SEARCH_LIBS([openpty], [util bsd]) AC_SEARCH_LIBS([updwtmp], [util bsd]) AC_CHECK_FUNCS([fmt_scaled scan_scaled login logout openpty updwtmp logwtmp]) +# On some platforms, inet_ntop may be found in libresolv or libnsl. +AC_SEARCH_LIBS([inet_ntop], [resolv nsl]) + AC_FUNC_STRFTIME # Check for ALTDIRFUNC glob() extension @@ -1442,7 +1496,7 @@ AC_ARG_WITH([libedit], fi fi if test "x$use_pkgconfig_for_libedit" = "xyes"; then - LIBEDIT=`$PKGCONFIG --libs-only-l libedit` + LIBEDIT=`$PKGCONFIG --libs libedit` CPPFLAGS="$CPPFLAGS `$PKGCONFIG --cflags libedit`" else LIBEDIT="-ledit -lcurses" @@ -1496,7 +1550,7 @@ AC_ARG_WITH([audit], # These are optional AC_CHECK_FUNCS([getaudit_addr aug_get_machine]) AC_DEFINE([USE_BSM_AUDIT], [1], [Use BSM audit module]) - if test "$sol2ver" -eq 11; then + if test "$sol2ver" -ge 11; then SSHDLIBS="$SSHDLIBS -lscf" AC_DEFINE([BROKEN_BSM_API], [1], [The system has incomplete BSM API]) @@ -1524,10 +1578,62 @@ AC_ARG_WITH([audit], esac ] ) +AC_ARG_WITH([pie], + [ --with-pie Build Position Independent Executables if possible], [ + if test "x$withval" = "xno"; then + use_pie=no + fi + if test "x$withval" = "xyes"; then + use_pie=yes + fi + ] +) +if test "x$use_pie" = "x"; then + use_pie=no +fi +if test "x$use_toolchain_hardening" != "x1" && test "x$use_pie" = "xauto"; then + # Turn off automatic PIE when toolchain hardening is off. + use_pie=no +fi +if test "x$use_pie" = "xauto"; then + # Automatic PIE requires gcc >= 4.x + AC_MSG_CHECKING([for gcc >= 4.x]) + AC_COMPILE_IFELSE([AC_LANG_SOURCE([[ +#if !defined(__GNUC__) || __GNUC__ < 4 +#error gcc is too old +#endif +]])], + [ AC_MSG_RESULT([yes]) ], + [ AC_MSG_RESULT([no]) + use_pie=no ] +) +fi +if test "x$use_pie" != "xno"; then + SAVED_CFLAGS="$CFLAGS" + SAVED_LDFLAGS="$LDFLAGS" + OSSH_CHECK_CFLAG_COMPILE([-fPIE]) + OSSH_CHECK_LDFLAG_LINK([-pie]) + # We use both -fPIE and -pie or neither. + AC_MSG_CHECKING([whether both -fPIE and -pie are supported]) + if echo "x $CFLAGS" | grep ' -fPIE' >/dev/null 2>&1 && \ + echo "x $LDFLAGS" | grep ' -pie' >/dev/null 2>&1 ; then + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + CFLAGS="$SAVED_CFLAGS" + LDFLAGS="$SAVED_LDFLAGS" + fi +fi + dnl Checks for library functions. Please keep in alphabetical order AC_CHECK_FUNCS([ \ + Blowfish_initstate \ + Blowfish_expandstate \ + Blowfish_expand0state \ + Blowfish_stream2word \ arc4random \ arc4random_buf \ + arc4random_stir \ arc4random_uniform \ asprintf \ b64_ntop \ @@ -1535,7 +1641,10 @@ AC_CHECK_FUNCS([ \ b64_pton \ __b64_pton \ bcopy \ + bcrypt_pbkdf \ bindresvport_sa \ + blf_enc \ + cap_rights_limit \ clock \ closefrom \ dirfd \ @@ -1543,6 +1652,7 @@ AC_CHECK_FUNCS([ \ fchmod \ fchown \ freeaddrinfo \ + fstatfs \ fstatvfs \ futimes \ getaddrinfo \ @@ -2312,7 +2422,17 @@ AC_LINK_IFELSE( ] ) -AC_CHECK_FUNCS([RSA_generate_key_ex DSA_generate_parameters_ex BN_is_prime_ex RSA_get_default_method HMAC_CTX_init]) +AC_CHECK_FUNCS([ \ + BN_is_prime_ex \ + DSA_generate_parameters_ex \ + EVP_DigestInit_ex \ + EVP_DigestFinal_ex \ + EVP_MD_CTX_init \ + EVP_MD_CTX_cleanup \ + HMAC_CTX_init \ + RSA_generate_key_ex \ + RSA_get_default_method \ +]) AC_ARG_WITH([ssl-engine], [ --with-ssl-engine Enable OpenSSL (hardware) ENGINE support ], @@ -2436,19 +2556,58 @@ fi AC_CHECK_FUNCS([crypt DES_crypt]) # Search for SHA256 support in libc and/or OpenSSL -AC_CHECK_FUNCS([SHA256_Update EVP_sha256], - [TEST_SSH_SHA256=yes], - [TEST_SSH_SHA256=no - unsupported_algorithms="$unsupported_algorithms \ +AC_CHECK_FUNCS([SHA256_Update EVP_sha256], , + [unsupported_algorithms="$unsupported_algorithms \ hmac-sha2-256 hmac-sha2-512 \ diffie-hellman-group-exchange-sha256 \ hmac-sha2-256-etm@openssh.com hmac-sha2-512-etm@openssh.com" ] ) -AC_SUBST([TEST_SSH_SHA256]) # Check complete ECC support in OpenSSL -AC_MSG_CHECKING([whether OpenSSL has complete ECC support]) +AC_MSG_CHECKING([whether OpenSSL has NID_X9_62_prime256v1]) +AC_LINK_IFELSE( + [AC_LANG_PROGRAM([[ +#include +#include +#include +#include +#include +#include +#if OPENSSL_VERSION_NUMBER < 0x0090807f /* 0.9.8g */ +# error "OpenSSL < 0.9.8g has unreliable ECC code" +#endif + ]], [[ + EC_KEY *e = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1); + const EVP_MD *m = EVP_sha256(); /* We need this too */ + ]])], + [ AC_MSG_RESULT([yes]) + enable_nistp256=1 ], + [ AC_MSG_RESULT([no]) ] +) + +AC_MSG_CHECKING([whether OpenSSL has NID_secp384r1]) +AC_LINK_IFELSE( + [AC_LANG_PROGRAM([[ +#include +#include +#include +#include +#include +#include +#if OPENSSL_VERSION_NUMBER < 0x0090807f /* 0.9.8g */ +# error "OpenSSL < 0.9.8g has unreliable ECC code" +#endif + ]], [[ + EC_KEY *e = EC_KEY_new_by_curve_name(NID_secp384r1); + const EVP_MD *m = EVP_sha384(); /* We need this too */ + ]])], + [ AC_MSG_RESULT([yes]) + enable_nistp384=1 ], + [ AC_MSG_RESULT([no]) ] +) + +AC_MSG_CHECKING([whether OpenSSL has NID_secp521r1]) AC_LINK_IFELSE( [AC_LANG_PROGRAM([[ #include @@ -2464,25 +2623,63 @@ AC_LINK_IFELSE( EC_KEY *e = EC_KEY_new_by_curve_name(NID_secp521r1); const EVP_MD *m = EVP_sha512(); /* We need this too */ ]])], - [ - AC_MSG_RESULT([yes]) - AC_DEFINE([OPENSSL_HAS_ECC], [1], - [libcrypto includes complete ECC support]) - TEST_SSH_ECC=yes - COMMENT_OUT_ECC="" - ], - [ - AC_MSG_RESULT([no]) - TEST_SSH_ECC=no - COMMENT_OUT_ECC="#no ecc#" - unsupported_algorithms="$unsupported_algorithms \ - ecdh-sha2-nistp256 ecdh-sha2-nistp384 ecdh-sha2-nistp521 \ - ecdsa-sha2-nistp256-cert-v01@openssh.com \ - ecdsa-sha2-nistp384-cert-v01@openssh.com \ - ecdsa-sha2-nistp521-cert-v01@openssh.com \ - ecdsa-sha2-nistp256 ecdsa-sha2-nistp384 ecdsa-sha2-nistp521" - ] + [ AC_MSG_RESULT([yes]) + AC_MSG_CHECKING([if OpenSSL's NID_secp521r1 is functional]) + AC_RUN_IFELSE( + [AC_LANG_PROGRAM([[ +#include +#include +#include +#include +#include +#include + ]],[[ + EC_KEY *e = EC_KEY_new_by_curve_name(NID_secp521r1); + const EVP_MD *m = EVP_sha512(); /* We need this too */ + exit(e == NULL || m == NULL); + ]])], + [ AC_MSG_RESULT([yes]) + enable_nistp521=1 ], + [ AC_MSG_RESULT([no]) ], + [ AC_MSG_WARN([cross-compiling: assuming yes]) + enable_nistp521=1 ] + )], + AC_MSG_RESULT([no]) ) + +COMMENT_OUT_ECC="#no ecc#" +TEST_SSH_ECC=no + +if test x$enable_nistp256 = x1 || test x$enable_nistp384 = x1 || \ + test x$enable_nistp521 = x1; then + AC_DEFINE(OPENSSL_HAS_ECC, [1], [OpenSSL has ECC]) +fi +if test x$enable_nistp256 = x1; then + AC_DEFINE([OPENSSL_HAS_NISTP256], [1], + [libcrypto has NID_X9_62_prime256v1]) + TEST_SSH_ECC=yes + COMMENT_OUT_ECC="" +else + unsupported_algorithms="$unsupported_algorithms ecdsa-sha2-nistp256 \ + ecdh-sha2-nistp256 ecdsa-sha2-nistp256-cert-v01@openssh.com" +fi +if test x$enable_nistp384 = x1; then + AC_DEFINE([OPENSSL_HAS_NISTP384], [1], [libcrypto has NID_secp384r1]) + TEST_SSH_ECC=yes + COMMENT_OUT_ECC="" +else + unsupported_algorithms="$unsupported_algorithms ecdsa-sha2-nistp384 \ + ecdh-sha2-nistp384 ecdsa-sha2-nistp384-cert-v01@openssh.com" +fi +if test x$enable_nistp521 = x1; then + AC_DEFINE([OPENSSL_HAS_NISTP521], [1], [libcrypto has NID_secp521r1]) + TEST_SSH_ECC=yes + COMMENT_OUT_ECC="" +else + unsupported_algorithms="$unsupported_algorithms ecdh-sha2-nistp521 \ + ecdsa-sha2-nistp521 ecdsa-sha2-nistp521-cert-v01@openssh.com" +fi + AC_SUBST([TEST_SSH_ECC]) AC_SUBST([COMMENT_OUT_ECC]) @@ -2714,7 +2911,7 @@ fi # Decide which sandbox style to use sandbox_arg="" AC_ARG_WITH([sandbox], - [ --with-sandbox=style Specify privilege separation sandbox (no, darwin, rlimit, systrace, seccomp_filter)], + [ --with-sandbox=style Specify privilege separation sandbox (no, darwin, rlimit, systrace, seccomp_filter, capsicum)], [ if test "x$withval" = "xyes" ; then sandbox_arg="" @@ -2843,6 +3040,16 @@ elif test "x$sandbox_arg" = "xseccomp_filter" || \ AC_MSG_ERROR([seccomp_filter sandbox requires prctl function]) SANDBOX_STYLE="seccomp_filter" AC_DEFINE([SANDBOX_SECCOMP_FILTER], [1], [Sandbox using seccomp filter]) +elif test "x$sandbox_arg" = "xcapsicum" || \ + ( test -z "$sandbox_arg" && \ + test "x$ac_cv_header_sys_capability_h" = "xyes" && \ + test "x$ac_cv_func_cap_rights_limit" = "xyes") ; then + test "x$ac_cv_header_sys_capability_h" != "xyes" && \ + AC_MSG_ERROR([capsicum sandbox requires sys/capability.h header]) + test "x$ac_cv_func_cap_rights_limit" != "xyes" && \ + AC_MSG_ERROR([capsicum sandbox requires cap_rights_limit function]) + SANDBOX_STYLE="capsicum" + AC_DEFINE([SANDBOX_CAPSICUM], [1], [Sandbox using capsicum]) elif test "x$sandbox_arg" = "xrlimit" || \ ( test -z "$sandbox_arg" && test "x$ac_cv_func_setrlimit" = "xyes" && \ test "x$select_works_with_rlimit" = "xyes" && \ @@ -3066,7 +3273,9 @@ if test "x$ac_cv_have_u_int64_t" = "xyes" ; then have_u_int64_t=1 fi -if test -z "$have_u_int64_t" ; then +if (test -z "$have_u_int64_t" && \ + test "x$ac_cv_header_sys_bitypes_h" = "xyes") +then AC_MSG_CHECKING([for u_int64_t type in sys/bitypes.h]) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include ]], [[ u_int64_t a; a = 1]])], @@ -3096,7 +3305,9 @@ if test -z "$have_u_intxx_t" ; then fi fi -if test -z "$have_uintxx_t" ; then +if (test -z "$have_uintxx_t" && \ + test "x$ac_cv_header_stdint_h" = "xyes") +then AC_MSG_CHECKING([for uintXX_t types in stdint.h]) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include ]], [[ uint8_t a; uint16_t b; uint32_t c; a = b = c = 1;]])], @@ -3107,6 +3318,19 @@ if test -z "$have_uintxx_t" ; then ]) fi +if (test -z "$have_uintxx_t" && \ + test "x$ac_cv_header_inttypes_h" = "xyes") +then + AC_MSG_CHECKING([for uintXX_t types in inttypes.h]) + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include ]], + [[ uint8_t a; uint16_t b; uint32_t c; a = b = c = 1;]])], + [ + AC_DEFINE([HAVE_UINTXX_T]) + AC_MSG_RESULT([yes]) + ], [ AC_MSG_RESULT([no]) + ]) +fi + if (test -z "$have_u_intxx_t" || test -z "$have_intxx_t" && \ test "x$ac_cv_header_sys_bitypes_h" = "xyes") then @@ -3137,6 +3361,11 @@ if test "x$ac_cv_have_u_char" = "xyes" ; then AC_DEFINE([HAVE_U_CHAR], [1], [define if you have u_char data type]) fi +AC_CHECK_TYPES([intmax_t, uintmax_t], , , [ +#include +#include +]) + TYPE_SOCKLEN_T AC_CHECK_TYPES([sig_atomic_t], , , [#include ]) @@ -4561,6 +4790,7 @@ else fi AC_CHECK_DECL([BROKEN_GETADDRINFO], [TEST_SSH_IPV6=no]) AC_SUBST([TEST_SSH_IPV6], [$TEST_SSH_IPV6]) +AC_SUBST([TEST_MALLOC_OPTIONS], [$TEST_MALLOC_OPTIONS]) AC_SUBST([UNSUPPORTED_ALGORITHMS], [$unsupported_algorithms]) AC_EXEEXT diff --git a/contrib/caldera/openssh.spec b/contrib/caldera/openssh.spec index d026b72d8e66..3c417bb8f30e 100644 --- a/contrib/caldera/openssh.spec +++ b/contrib/caldera/openssh.spec @@ -16,7 +16,7 @@ #old cvs stuff. please update before use. may be deprecated. %define use_stable 1 -%define version 6.4p1 +%define version 6.5p1 %if %{use_stable} %define cvs %{nil} %define release 1 @@ -363,4 +363,4 @@ fi * Mon Jan 01 1998 ... Template Version: 1.31 -$Id: openssh.spec,v 1.80.4.1 2013/11/08 01:36:19 djm Exp $ +$Id: openssh.spec,v 1.82 2014/01/16 07:51:10 djm Exp $ diff --git a/contrib/cygwin/ssh-host-config b/contrib/cygwin/ssh-host-config index c542d5cb61f8..05efd3b3bf6b 100644 --- a/contrib/cygwin/ssh-host-config +++ b/contrib/cygwin/ssh-host-config @@ -67,54 +67,6 @@ user_account= password_value= opt_force=no -# ====================================================================== -# Routine: create_host_keys -# ====================================================================== -create_host_keys() { - local ret=0 - - if [ ! -f "${SYSCONFDIR}/ssh_host_key" ] - then - csih_inform "Generating ${SYSCONFDIR}/ssh_host_key" - if ! /usr/bin/ssh-keygen -t rsa1 -f ${SYSCONFDIR}/ssh_host_key -N '' > /dev/null - then - csih_warning "Generating ${SYSCONFDIR}/ssh_host_key failed!" - let ++ret - fi - fi - - if [ ! -f "${SYSCONFDIR}/ssh_host_rsa_key" ] - then - csih_inform "Generating ${SYSCONFDIR}/ssh_host_rsa_key" - if ! /usr/bin/ssh-keygen -t rsa -f ${SYSCONFDIR}/ssh_host_rsa_key -N '' > /dev/null - then - csih_warning "Generating ${SYSCONFDIR}/ssh_host_key failed!" - let ++ret - fi - fi - - if [ ! -f "${SYSCONFDIR}/ssh_host_dsa_key" ] - then - csih_inform "Generating ${SYSCONFDIR}/ssh_host_dsa_key" - if ! /usr/bin/ssh-keygen -t dsa -f ${SYSCONFDIR}/ssh_host_dsa_key -N '' > /dev/null - then - csih_warning "Generating ${SYSCONFDIR}/ssh_host_key failed!" - let ++ret - fi - fi - - if [ ! -f "${SYSCONFDIR}/ssh_host_ecdsa_key" ] - then - csih_inform "Generating ${SYSCONFDIR}/ssh_host_ecdsa_key" - if ! /usr/bin/ssh-keygen -t ecdsa -f ${SYSCONFDIR}/ssh_host_ecdsa_key -N '' > /dev/null - then - csih_warning "Generating ${SYSCONFDIR}/ssh_host_key failed!" - let ++ret - fi - fi - return $ret -} # --- End of create_host_keys --- # - # ====================================================================== # Routine: update_services_file # ====================================================================== @@ -719,8 +671,8 @@ then let ++warning_cnt fi -# host keys -create_host_keys || let warning_cnt+=$? +# generate missing host keys +/usr/bin/ssh-keygen -A || let warning_cnt+=$? # handle ssh_config csih_install_config "${SYSCONFDIR}/ssh_config" "${SYSCONFDIR}/defaults" || let ++warning_cnt diff --git a/contrib/redhat/openssh.spec b/contrib/redhat/openssh.spec index 29a38dedc1f3..d47cf3862e18 100644 --- a/contrib/redhat/openssh.spec +++ b/contrib/redhat/openssh.spec @@ -1,4 +1,4 @@ -%define ver 6.4p1 +%define ver 6.5p1 %define rel 1 # OpenSSH privilege separation requires a user & group ID diff --git a/contrib/suse/openssh.spec b/contrib/suse/openssh.spec index 3a612bd23827..6693fe2bc193 100644 --- a/contrib/suse/openssh.spec +++ b/contrib/suse/openssh.spec @@ -13,7 +13,7 @@ Summary: OpenSSH, a free Secure Shell (SSH) protocol implementation Name: openssh -Version: 6.4p1 +Version: 6.5p1 URL: http://www.openssh.com/ Release: 1 Source0: openssh-%{version}.tar.gz diff --git a/crypto_api.h b/crypto_api.h new file mode 100644 index 000000000000..5820ce8fa1f6 --- /dev/null +++ b/crypto_api.h @@ -0,0 +1,44 @@ +/* $OpenBSD: crypto_api.h,v 1.3 2013/12/17 10:36:38 markus Exp $ */ + +/* + * Assembled from generated headers and source files by Markus Friedl. + * Placed in the public domain. + */ + +#ifndef crypto_api_h +#define crypto_api_h + +#ifdef HAVE_STDINT_H +# include +#endif +#include + +typedef int32_t crypto_int32; +typedef uint32_t crypto_uint32; + +#define randombytes(buf, buf_len) arc4random_buf((buf), (buf_len)) + +#define crypto_hashblocks_sha512_STATEBYTES 64U +#define crypto_hashblocks_sha512_BLOCKBYTES 128U + +int crypto_hashblocks_sha512(unsigned char *, const unsigned char *, + unsigned long long); + +#define crypto_hash_sha512_BYTES 64U + +int crypto_hash_sha512(unsigned char *, const unsigned char *, + unsigned long long); + +int crypto_verify_32(const unsigned char *, const unsigned char *); + +#define crypto_sign_ed25519_SECRETKEYBYTES 64U +#define crypto_sign_ed25519_PUBLICKEYBYTES 32U +#define crypto_sign_ed25519_BYTES 64U + +int crypto_sign_ed25519(unsigned char *, unsigned long long *, + const unsigned char *, unsigned long long, const unsigned char *); +int crypto_sign_ed25519_open(unsigned char *, unsigned long long *, + const unsigned char *, unsigned long long, const unsigned char *); +int crypto_sign_ed25519_keypair(unsigned char *, unsigned char *); + +#endif /* crypto_api_h */ diff --git a/defines.h b/defines.h index d5ce52f32b8b..354d5b614cec 100644 --- a/defines.h +++ b/defines.h @@ -25,7 +25,7 @@ #ifndef _DEFINES_H #define _DEFINES_H -/* $Id: defines.h,v 1.172 2013/06/01 21:18:48 dtucker Exp $ */ +/* $Id: defines.h,v 1.176 2014/01/17 13:12:38 dtucker Exp $ */ /* Constants */ @@ -269,6 +269,21 @@ typedef unsigned long long int u_int64_t; # endif #endif +#ifndef HAVE_UINTXX_T +typedef u_int8_t uint8_t; +typedef u_int16_t uint16_t; +typedef u_int32_t uint32_t; +typedef u_int64_t uint64_t; +#endif + +#ifndef HAVE_INTMAX_T +typedef long long intmax_t; +#endif + +#ifndef HAVE_UINTMAX_T +typedef unsigned long long uintmax_t; +#endif + #ifndef HAVE_U_CHAR typedef unsigned char u_char; # define HAVE_U_CHAR @@ -802,4 +817,13 @@ struct winsize { # endif #endif +/* + * Platforms that have arc4random_uniform() and not arc4random_stir() + * shouldn't need the latter. + */ +#if defined(HAVE_ARC4RANDOM) && defined(HAVE_ARC4RANDOM_UNIFORM) && \ + !defined(HAVE_ARC4RANDOM_STIR) +# define arc4random_stir() +#endif + #endif /* _DEFINES_H */ diff --git a/dh.c b/dh.c index 449dd3858fbf..3331cda6c71c 100644 --- a/dh.c +++ b/dh.c @@ -1,4 +1,4 @@ -/* $OpenBSD: dh.c,v 1.51 2013/07/02 12:31:43 markus Exp $ */ +/* $OpenBSD: dh.c,v 1.53 2013/11/21 00:45:44 djm Exp $ */ /* * Copyright (c) 2000 Niels Provos. All rights reserved. * @@ -254,33 +254,19 @@ dh_pub_is_valid(DH *dh, BIGNUM *dh_pub) void dh_gen_key(DH *dh, int need) { - int i, bits_set, tries = 0; + int pbits; - if (need < 0) - fatal("dh_gen_key: need < 0"); + if (need <= 0) + fatal("%s: need <= 0", __func__); if (dh->p == NULL) - fatal("dh_gen_key: dh->p == NULL"); - if (need > INT_MAX / 2 || 2 * need >= BN_num_bits(dh->p)) - fatal("dh_gen_key: group too small: %d (2*need %d)", - BN_num_bits(dh->p), 2*need); - do { - if (dh->priv_key != NULL) - BN_clear_free(dh->priv_key); - if ((dh->priv_key = BN_new()) == NULL) - fatal("dh_gen_key: BN_new failed"); - /* generate a 2*need bits random private exponent */ - if (!BN_rand(dh->priv_key, 2*need, 0, 0)) - fatal("dh_gen_key: BN_rand failed"); - if (DH_generate_key(dh) == 0) - fatal("DH_generate_key"); - for (i = 0, bits_set = 0; i <= BN_num_bits(dh->priv_key); i++) - if (BN_is_bit_set(dh->priv_key, i)) - bits_set++; - debug2("dh_gen_key: priv key bits set: %d/%d", - bits_set, BN_num_bits(dh->priv_key)); - if (tries++ > 10) - fatal("dh_gen_key: too many bad keys: giving up"); - } while (!dh_pub_is_valid(dh, dh->pub_key)); + fatal("%s: dh->p == NULL", __func__); + if ((pbits = BN_num_bits(dh->p)) <= 0) + fatal("%s: bits(p) <= 0", __func__); + dh->length = MIN(need * 2, pbits - 1); + if (DH_generate_key(dh) == 0) + fatal("%s: key generation failed", __func__); + if (!dh_pub_is_valid(dh, dh->pub_key)) + fatal("%s: generated invalid key", __func__); } DH * @@ -352,17 +338,20 @@ dh_new_group14(void) /* * Estimates the group order for a Diffie-Hellman group that has an - * attack complexity approximately the same as O(2**bits). Estimate - * with: O(exp(1.9223 * (ln q)^(1/3) (ln ln q)^(2/3))) + * attack complexity approximately the same as O(2**bits). + * Values from NIST Special Publication 800-57: Recommendation for Key + * Management Part 1 (rev 3) limited by the recommended maximum value + * from RFC4419 section 3. */ int dh_estimate(int bits) { - + if (bits <= 112) + return 2048; if (bits <= 128) - return (1024); /* O(2**86) */ + return 3072; if (bits <= 192) - return (2048); /* O(2**116) */ - return (4096); /* O(2**156) */ + return 7680; + return 8192; } diff --git a/dh.h b/dh.h index dfc1480eac66..48f7b68eaf4b 100644 --- a/dh.h +++ b/dh.h @@ -1,4 +1,4 @@ -/* $OpenBSD: dh.h,v 1.10 2008/06/26 09:19:40 djm Exp $ */ +/* $OpenBSD: dh.h,v 1.11 2013/10/08 11:42:13 dtucker Exp $ */ /* * Copyright (c) 2000 Niels Provos. All rights reserved. @@ -43,6 +43,7 @@ int dh_pub_is_valid(DH *, BIGNUM *); int dh_estimate(int); +/* Min and max values from RFC4419. */ #define DH_GRP_MIN 1024 #define DH_GRP_MAX 8192 diff --git a/digest.c b/digest.c new file mode 100644 index 000000000000..a221819eba8b --- /dev/null +++ b/digest.c @@ -0,0 +1,149 @@ +/* $OpenBSD: digest.c,v 1.3 2014/01/20 00:08:48 djm Exp $ */ +/* + * Copyright (c) 2013 Damien Miller + * + * 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" + +#include +#include +#include +#include + +#include + +#include "openbsd-compat/openssl-compat.h" + +#include "buffer.h" +#include "digest.h" + +struct ssh_digest_ctx { + int alg; + EVP_MD_CTX mdctx; +}; + +struct ssh_digest { + int id; + const char *name; + size_t digest_len; + const EVP_MD *(*mdfunc)(void); +}; + +/* NB. Indexed directly by algorithm number */ +const struct ssh_digest digests[] = { + { SSH_DIGEST_MD5, "MD5", 16, EVP_md5 }, + { SSH_DIGEST_RIPEMD160, "RIPEMD160", 20, EVP_ripemd160 }, + { SSH_DIGEST_SHA1, "SHA1", 20, EVP_sha1 }, +#ifdef HAVE_EVP_SHA256 /* XXX replace with local if missing */ + { SSH_DIGEST_SHA256, "SHA256", 32, EVP_sha256 }, + { SSH_DIGEST_SHA384, "SHA384", 48, EVP_sha384 }, + { SSH_DIGEST_SHA512, "SHA512", 64, EVP_sha512 }, +#endif + { -1, NULL, 0, NULL }, +}; + +static const struct ssh_digest * +ssh_digest_by_alg(int alg) +{ + if (alg < 0 || alg >= SSH_DIGEST_MAX) + return NULL; + if (digests[alg].id != alg) /* sanity */ + return NULL; + return &(digests[alg]); +} + +size_t +ssh_digest_bytes(int alg) +{ + const struct ssh_digest *digest = ssh_digest_by_alg(alg); + + return digest == NULL ? 0 : digest->digest_len; +} + +struct ssh_digest_ctx * +ssh_digest_start(int alg) +{ + const struct ssh_digest *digest = ssh_digest_by_alg(alg); + struct ssh_digest_ctx *ret; + + if (digest == NULL || ((ret = calloc(1, sizeof(*ret))) == NULL)) + return NULL; + ret->alg = alg; + EVP_MD_CTX_init(&ret->mdctx); + if (EVP_DigestInit_ex(&ret->mdctx, digest->mdfunc(), NULL) != 1) { + free(ret); + return NULL; + } + return ret; +} + +int +ssh_digest_update(struct ssh_digest_ctx *ctx, const void *m, size_t mlen) +{ + if (EVP_DigestUpdate(&ctx->mdctx, m, mlen) != 1) + return -1; + return 0; +} + +int +ssh_digest_update_buffer(struct ssh_digest_ctx *ctx, const Buffer *b) +{ + return ssh_digest_update(ctx, buffer_ptr(b), buffer_len(b)); +} + +int +ssh_digest_final(struct ssh_digest_ctx *ctx, u_char *d, size_t dlen) +{ + const struct ssh_digest *digest = ssh_digest_by_alg(ctx->alg); + u_int l = dlen; + + if (dlen > UINT_MAX) + return -1; + if (dlen < digest->digest_len) /* No truncation allowed */ + return -1; + if (EVP_DigestFinal_ex(&ctx->mdctx, d, &l) != 1) + return -1; + if (l != digest->digest_len) /* sanity */ + return -1; + return 0; +} + +void +ssh_digest_free(struct ssh_digest_ctx *ctx) +{ + EVP_MD_CTX_cleanup(&ctx->mdctx); + memset(ctx, 0, sizeof(*ctx)); + free(ctx); +} + +int +ssh_digest_memory(int alg, const void *m, size_t mlen, u_char *d, size_t dlen) +{ + struct ssh_digest_ctx *ctx = ssh_digest_start(alg); + + if (ctx == NULL) + return -1; + if (ssh_digest_update(ctx, m, mlen) != 0 || + ssh_digest_final(ctx, d, dlen) != 0) + return -1; + ssh_digest_free(ctx); + return 0; +} + +int +ssh_digest_buffer(int alg, const Buffer *b, u_char *d, size_t dlen) +{ + return ssh_digest_memory(alg, buffer_ptr(b), buffer_len(b), d, dlen); +} diff --git a/digest.h b/digest.h new file mode 100644 index 000000000000..faefda3f5335 --- /dev/null +++ b/digest.h @@ -0,0 +1,55 @@ +/* $OpenBSD: digest.h,v 1.1 2014/01/09 23:20:00 djm Exp $ */ +/* + * Copyright (c) 2013 Damien Miller + * + * 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. + */ + +#ifndef _DIGEST_H +#define _DIGEST_H + +/* Maximum digest output length */ +#define SSH_DIGEST_MAX_LENGTH 64 + +/* Digest algorithms */ +#define SSH_DIGEST_MD5 0 +#define SSH_DIGEST_RIPEMD160 1 +#define SSH_DIGEST_SHA1 2 +#define SSH_DIGEST_SHA256 3 +#define SSH_DIGEST_SHA384 4 +#define SSH_DIGEST_SHA512 5 +#define SSH_DIGEST_MAX 6 + +/* Returns the algorithm's digest length in bytes or 0 for invalid algorithm */ +size_t ssh_digest_bytes(int alg); + +/* One-shot API */ +int ssh_digest_memory(int alg, const void *m, size_t mlen, + u_char *d, size_t dlen) + __attribute__((__bounded__(__buffer__, 2, 3))) + __attribute__((__bounded__(__buffer__, 4, 5))); +int ssh_digest_buffer(int alg, const Buffer *b, u_char *d, size_t dlen) + __attribute__((__bounded__(__buffer__, 3, 4))); + +/* Update API */ +struct ssh_digest_ctx; +struct ssh_digest_ctx *ssh_digest_start(int alg); +int ssh_digest_update(struct ssh_digest_ctx *ctx, const void *m, size_t mlen) + __attribute__((__bounded__(__buffer__, 2, 3))); +int ssh_digest_update_buffer(struct ssh_digest_ctx *ctx, const Buffer *b); +int ssh_digest_final(struct ssh_digest_ctx *ctx, u_char *d, size_t dlen) + __attribute__((__bounded__(__buffer__, 2, 3))); +void ssh_digest_free(struct ssh_digest_ctx *ctx); + +#endif /* _DIGEST_H */ + diff --git a/ed25519.c b/ed25519.c new file mode 100644 index 000000000000..767ec24d6df5 --- /dev/null +++ b/ed25519.c @@ -0,0 +1,144 @@ +/* $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 "includes.h" +#include "crypto_api.h" + +#include "ge25519.h" + +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; + + 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]; + + crypto_hash_sha512(hram,playground,smlen); +} + + +int crypto_sign_ed25519_keypair( + unsigned char *pk, + unsigned char *sk + ) +{ + sc25519 scsk; + ge25519 gepk; + unsigned char extsk[64]; + int i; + + randombytes(sk, 32); + crypto_hash_sha512(extsk, sk, 32); + 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; + unsigned char r[32]; + unsigned char s[32]; + unsigned char extsk[64]; + unsigned long long i; + unsigned char hmg[crypto_hash_sha512_BYTES]; + unsigned char hram[crypto_hash_sha512_BYTES]; + + crypto_hash_sha512(extsk, sk, 32); + extsk[0] &= 248; + extsk[31] &= 127; + extsk[31] |= 64; + + *smlen = mlen+64; + for(i=0;i>= 31; /* 1: yes; 0: no */ + return x; +} + +static crypto_uint32 ge(crypto_uint32 a,crypto_uint32 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 crypto_uint32 times19(crypto_uint32 a) +{ + return (a << 4) + (a << 1) + a; +} + +static crypto_uint32 times38(crypto_uint32 a) +{ + return (a << 5) + (a << 2) + (a << 1); +} + +static void reduce_add_sub(fe25519 *r) +{ + crypto_uint32 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) +{ + crypto_uint32 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; + crypto_uint32 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; + crypto_uint32 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; + crypto_uint32 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; + crypto_uint32 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); +} diff --git a/fe25519.h b/fe25519.h new file mode 100644 index 000000000000..41b3cbb49dc6 --- /dev/null +++ b/fe25519.h @@ -0,0 +1,70 @@ +/* $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 "crypto_api.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 +{ + crypto_uint32 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 diff --git a/ge25519.c b/ge25519.c new file mode 100644 index 000000000000..dfe3849b931b --- /dev/null +++ b/ge25519.c @@ -0,0 +1,321 @@ +/* $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 "includes.h" + +#include "fe25519.h" +#include "sc25519.h" +#include "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 */ + crypto_uint32 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); + } +} diff --git a/ge25519.h b/ge25519.h new file mode 100644 index 000000000000..64f63c6f8f41 --- /dev/null +++ b/ge25519.h @@ -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 diff --git a/ge25519_base.data b/ge25519_base.data new file mode 100644 index 000000000000..66fb1b61c67d --- /dev/null +++ b/ge25519_base.data @@ -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}}} diff --git a/gss-serv-krb5.c b/gss-serv-krb5.c index 87f26831a70d..759fa104f782 100644 --- a/gss-serv-krb5.c +++ b/gss-serv-krb5.c @@ -132,10 +132,16 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_client *client) return; #ifdef HEIMDAL +# ifdef HAVE_KRB5_CC_NEW_UNIQUE if ((problem = krb5_cc_new_unique(krb_context, krb5_fcc_ops.prefix, NULL, &ccache)) != 0) { errmsg = krb5_get_error_message(krb_context, problem); logit("krb5_cc_new_unique(): %.100s", errmsg); +# else + if ((problem = krb5_cc_gen_new(krb_context, &krb5_fcc_ops, &ccache))) { + logit("krb5_cc_gen_new(): %.100s", + krb5_get_err_text(krb_context, problem)); +# endif krb5_free_error_message(krb_context, errmsg); return; } diff --git a/hash.c b/hash.c new file mode 100644 index 000000000000..734c6bee2af3 --- /dev/null +++ b/hash.c @@ -0,0 +1,76 @@ +/* $OpenBSD: hash.c,v 1.3 2013/12/09 11:03:45 markus Exp $ */ + +/* Copied from nacl-20110221/crypto_hash/sha512/ref/hash.c */ + +/* +20080913 +D. J. Bernstein +Public domain. +*/ + +#include "includes.h" + +#include "crypto_api.h" + +#define blocks crypto_hashblocks_sha512 + +static const unsigned char iv[64] = { + 0x6a,0x09,0xe6,0x67,0xf3,0xbc,0xc9,0x08, + 0xbb,0x67,0xae,0x85,0x84,0xca,0xa7,0x3b, + 0x3c,0x6e,0xf3,0x72,0xfe,0x94,0xf8,0x2b, + 0xa5,0x4f,0xf5,0x3a,0x5f,0x1d,0x36,0xf1, + 0x51,0x0e,0x52,0x7f,0xad,0xe6,0x82,0xd1, + 0x9b,0x05,0x68,0x8c,0x2b,0x3e,0x6c,0x1f, + 0x1f,0x83,0xd9,0xab,0xfb,0x41,0xbd,0x6b, + 0x5b,0xe0,0xcd,0x19,0x13,0x7e,0x21,0x79 +} ; + +typedef unsigned long long uint64; + +int crypto_hash_sha512(unsigned char *out,const unsigned char *in,unsigned long long inlen) +{ + unsigned char h[64]; + unsigned char padded[256]; + unsigned int i; + unsigned long long bytes = inlen; + + for (i = 0;i < 64;++i) h[i] = iv[i]; + + blocks(h,in,inlen); + in += inlen; + inlen &= 127; + in -= inlen; + + for (i = 0;i < inlen;++i) padded[i] = in[i]; + padded[inlen] = 0x80; + + if (inlen < 112) { + for (i = inlen + 1;i < 119;++i) padded[i] = 0; + padded[119] = bytes >> 61; + padded[120] = bytes >> 53; + padded[121] = bytes >> 45; + padded[122] = bytes >> 37; + padded[123] = bytes >> 29; + padded[124] = bytes >> 21; + padded[125] = bytes >> 13; + padded[126] = bytes >> 5; + padded[127] = bytes << 3; + blocks(h,padded,128); + } else { + for (i = inlen + 1;i < 247;++i) padded[i] = 0; + padded[247] = bytes >> 61; + padded[248] = bytes >> 53; + padded[249] = bytes >> 45; + padded[250] = bytes >> 37; + padded[251] = bytes >> 29; + padded[252] = bytes >> 21; + padded[253] = bytes >> 13; + padded[254] = bytes >> 5; + padded[255] = bytes << 3; + blocks(h,padded,256); + } + + for (i = 0;i < 64;++i) out[i] = h[i]; + + return 0; +} diff --git a/hostfile.c b/hostfile.c index 2ff4c48b4805..2778fb5df208 100644 --- a/hostfile.c +++ b/hostfile.c @@ -1,4 +1,4 @@ -/* $OpenBSD: hostfile.c,v 1.52 2013/07/12 00:19:58 djm Exp $ */ +/* $OpenBSD: hostfile.c,v 1.53 2014/01/09 23:20:00 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -57,6 +57,7 @@ #include "hostfile.h" #include "log.h" #include "misc.h" +#include "digest.h" struct hostkeys { struct hostkey_entry *entries; diff --git a/kex.c b/kex.c index 54bd1a438192..616484b85d22 100644 --- a/kex.c +++ b/kex.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kex.c,v 1.91 2013/05/17 00:13:13 djm Exp $ */ +/* $OpenBSD: kex.c,v 1.97 2014/01/25 20:35:37 markus Exp $ */ /* * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. * @@ -49,6 +49,7 @@ #include "dispatch.h" #include "monitor.h" #include "roaming.h" +#include "digest.h" #if OPENSSL_VERSION_NUMBER >= 0x00907000L # if defined(HAVE_EVP_SHA256) @@ -66,25 +67,34 @@ struct kexalg { char *name; int type; int ec_nid; - const EVP_MD *(*mdfunc)(void); + int hash_alg; }; static const struct kexalg kexalgs[] = { - { KEX_DH1, KEX_DH_GRP1_SHA1, 0, EVP_sha1 }, - { KEX_DH14, KEX_DH_GRP14_SHA1, 0, EVP_sha1 }, - { KEX_DHGEX_SHA1, KEX_DH_GEX_SHA1, 0, EVP_sha1 }, + { KEX_DH1, KEX_DH_GRP1_SHA1, 0, SSH_DIGEST_SHA1 }, + { KEX_DH14, KEX_DH_GRP14_SHA1, 0, SSH_DIGEST_SHA1 }, + { KEX_DHGEX_SHA1, KEX_DH_GEX_SHA1, 0, SSH_DIGEST_SHA1 }, #ifdef HAVE_EVP_SHA256 - { KEX_DHGEX_SHA256, KEX_DH_GEX_SHA256, 0, EVP_sha256 }, + { KEX_DHGEX_SHA256, KEX_DH_GEX_SHA256, 0, SSH_DIGEST_SHA256 }, #endif #ifdef OPENSSL_HAS_ECC - { KEX_ECDH_SHA2_NISTP256, KEX_ECDH_SHA2, NID_X9_62_prime256v1, EVP_sha256 }, - { KEX_ECDH_SHA2_NISTP384, KEX_ECDH_SHA2, NID_secp384r1, EVP_sha384 }, - { KEX_ECDH_SHA2_NISTP521, KEX_ECDH_SHA2, NID_secp521r1, EVP_sha512 }, + { KEX_ECDH_SHA2_NISTP256, KEX_ECDH_SHA2, + NID_X9_62_prime256v1, SSH_DIGEST_SHA256 }, + { KEX_ECDH_SHA2_NISTP384, KEX_ECDH_SHA2, NID_secp384r1, + SSH_DIGEST_SHA384 }, +# ifdef OPENSSL_HAS_NISTP521 + { KEX_ECDH_SHA2_NISTP521, KEX_ECDH_SHA2, NID_secp521r1, + SSH_DIGEST_SHA512 }, +# endif #endif - { NULL, -1, -1, NULL}, + { KEX_DH1, KEX_DH_GRP1_SHA1, 0, SSH_DIGEST_SHA1 }, +#ifdef HAVE_EVP_SHA256 + { KEX_CURVE25519_SHA256, KEX_C25519_SHA256, 0, SSH_DIGEST_SHA256 }, +#endif + { NULL, -1, -1, -1}, }; char * -kex_alg_list(void) +kex_alg_list(char sep) { char *ret = NULL; size_t nlen, rlen = 0; @@ -92,7 +102,7 @@ kex_alg_list(void) for (k = kexalgs; k->name != NULL; k++) { if (ret != NULL) - ret[rlen++] = '\n'; + ret[rlen++] = sep; nlen = strlen(k->name); ret = xrealloc(ret, 1, rlen + nlen + 2); memcpy(ret + rlen, k->name, nlen + 1); @@ -401,7 +411,7 @@ choose_kex(Kex *k, char *client, char *server) if ((kexalg = kex_alg_by_name(k->name)) == NULL) fatal("unsupported kex alg %s", k->name); k->kex_type = kexalg->type; - k->evp_md = kexalg->mdfunc(); + k->hash_alg = kexalg->hash_alg; k->ec_nid = kexalg->ec_nid; } @@ -448,7 +458,7 @@ kex_choose_conf(Kex *kex) char **my, **peer; char **cprop, **sprop; int nenc, nmac, ncomp; - u_int mode, ctos, need, authlen; + u_int mode, ctos, need, dh_need, authlen; int first_kex_follows, type; my = kex_buf2prop(&kex->my, NULL); @@ -496,20 +506,21 @@ kex_choose_conf(Kex *kex) choose_kex(kex, cprop[PROPOSAL_KEX_ALGS], sprop[PROPOSAL_KEX_ALGS]); choose_hostkeyalg(kex, cprop[PROPOSAL_SERVER_HOST_KEY_ALGS], sprop[PROPOSAL_SERVER_HOST_KEY_ALGS]); - need = 0; + need = dh_need = 0; for (mode = 0; mode < MODE_MAX; mode++) { newkeys = kex->newkeys[mode]; - if (need < newkeys->enc.key_len) - need = newkeys->enc.key_len; - if (need < newkeys->enc.block_size) - need = newkeys->enc.block_size; - if (need < newkeys->enc.iv_len) - need = newkeys->enc.iv_len; - if (need < newkeys->mac.key_len) - need = newkeys->mac.key_len; + need = MAX(need, newkeys->enc.key_len); + need = MAX(need, newkeys->enc.block_size); + need = MAX(need, newkeys->enc.iv_len); + need = MAX(need, newkeys->mac.key_len); + dh_need = MAX(dh_need, cipher_seclen(newkeys->enc.cipher)); + dh_need = MAX(dh_need, newkeys->enc.block_size); + dh_need = MAX(dh_need, newkeys->enc.iv_len); + dh_need = MAX(dh_need, newkeys->mac.key_len); } /* XXX need runden? */ kex->we_need = need; + kex->dh_need = dh_need; /* ignore the next message if the proposals do not match */ if (first_kex_follows && !proposals_match(my, peer) && @@ -524,30 +535,34 @@ kex_choose_conf(Kex *kex) static u_char * derive_key(Kex *kex, int id, u_int need, u_char *hash, u_int hashlen, - BIGNUM *shared_secret) + const u_char *shared_secret, u_int slen) { Buffer b; - EVP_MD_CTX md; + struct ssh_digest_ctx *hashctx; char c = id; u_int have; - int mdsz; + size_t mdsz; u_char *digest; - if ((mdsz = EVP_MD_size(kex->evp_md)) <= 0) - fatal("bad kex md size %d", mdsz); + if ((mdsz = ssh_digest_bytes(kex->hash_alg)) == 0) + fatal("bad kex md size %zu", mdsz); digest = xmalloc(roundup(need, mdsz)); buffer_init(&b); - buffer_put_bignum2(&b, shared_secret); + buffer_append(&b, shared_secret, slen); /* K1 = HASH(K || H || "A" || session_id) */ - EVP_DigestInit(&md, kex->evp_md); - if (!(datafellows & SSH_BUG_DERIVEKEY)) - EVP_DigestUpdate(&md, buffer_ptr(&b), buffer_len(&b)); - EVP_DigestUpdate(&md, hash, hashlen); - EVP_DigestUpdate(&md, &c, 1); - EVP_DigestUpdate(&md, kex->session_id, kex->session_id_len); - EVP_DigestFinal(&md, digest, NULL); + if ((hashctx = ssh_digest_start(kex->hash_alg)) == NULL) + fatal("%s: ssh_digest_start failed", __func__); + if (ssh_digest_update_buffer(hashctx, &b) != 0 || + ssh_digest_update(hashctx, hash, hashlen) != 0 || + ssh_digest_update(hashctx, &c, 1) != 0 || + ssh_digest_update(hashctx, kex->session_id, + kex->session_id_len) != 0) + fatal("%s: ssh_digest_update failed", __func__); + if (ssh_digest_final(hashctx, digest, mdsz) != 0) + fatal("%s: ssh_digest_final failed", __func__); + ssh_digest_free(hashctx); /* * expand key: @@ -555,12 +570,15 @@ derive_key(Kex *kex, int id, u_int need, u_char *hash, u_int hashlen, * Key = K1 || K2 || ... || Kn */ for (have = mdsz; need > have; have += mdsz) { - EVP_DigestInit(&md, kex->evp_md); - if (!(datafellows & SSH_BUG_DERIVEKEY)) - EVP_DigestUpdate(&md, buffer_ptr(&b), buffer_len(&b)); - EVP_DigestUpdate(&md, hash, hashlen); - EVP_DigestUpdate(&md, digest, have); - EVP_DigestFinal(&md, digest + have, NULL); + if ((hashctx = ssh_digest_start(kex->hash_alg)) == NULL) + fatal("%s: ssh_digest_start failed", __func__); + if (ssh_digest_update_buffer(hashctx, &b) != 0 || + ssh_digest_update(hashctx, hash, hashlen) != 0 || + ssh_digest_update(hashctx, digest, have) != 0) + fatal("%s: ssh_digest_update failed", __func__); + if (ssh_digest_final(hashctx, digest + have, mdsz) != 0) + fatal("%s: ssh_digest_final failed", __func__); + ssh_digest_free(hashctx); } buffer_free(&b); #ifdef DEBUG_KEX @@ -574,14 +592,15 @@ Newkeys *current_keys[MODE_MAX]; #define NKEYS 6 void -kex_derive_keys(Kex *kex, u_char *hash, u_int hashlen, BIGNUM *shared_secret) +kex_derive_keys(Kex *kex, u_char *hash, u_int hashlen, + const u_char *shared_secret, u_int slen) { u_char *keys[NKEYS]; u_int i, mode, ctos; for (i = 0; i < NKEYS; i++) { keys[i] = derive_key(kex, 'A'+i, kex->we_need, hash, hashlen, - shared_secret); + shared_secret, slen); } debug2("kex_derive_keys"); @@ -596,6 +615,18 @@ kex_derive_keys(Kex *kex, u_char *hash, u_int hashlen, BIGNUM *shared_secret) } } +void +kex_derive_keys_bn(Kex *kex, u_char *hash, u_int hashlen, const BIGNUM *secret) +{ + Buffer shared_secret; + + buffer_init(&shared_secret); + buffer_put_bignum2(&shared_secret, secret); + kex_derive_keys(kex, hash, hashlen, + buffer_ptr(&shared_secret), buffer_len(&shared_secret)); + buffer_free(&shared_secret); +} + Newkeys * kex_get_newkeys(int mode) { @@ -610,33 +641,33 @@ void derive_ssh1_session_id(BIGNUM *host_modulus, BIGNUM *server_modulus, u_int8_t cookie[8], u_int8_t id[16]) { - const EVP_MD *evp_md = EVP_md5(); - EVP_MD_CTX md; - u_int8_t nbuf[2048], obuf[EVP_MAX_MD_SIZE]; + u_int8_t nbuf[2048], obuf[SSH_DIGEST_MAX_LENGTH]; int len; + struct ssh_digest_ctx *hashctx; - EVP_DigestInit(&md, evp_md); + if ((hashctx = ssh_digest_start(SSH_DIGEST_MD5)) == NULL) + fatal("%s: ssh_digest_start", __func__); len = BN_num_bytes(host_modulus); if (len < (512 / 8) || (u_int)len > sizeof(nbuf)) fatal("%s: bad host modulus (len %d)", __func__, len); BN_bn2bin(host_modulus, nbuf); - EVP_DigestUpdate(&md, nbuf, len); + if (ssh_digest_update(hashctx, nbuf, len) != 0) + fatal("%s: ssh_digest_update failed", __func__); len = BN_num_bytes(server_modulus); if (len < (512 / 8) || (u_int)len > sizeof(nbuf)) fatal("%s: bad server modulus (len %d)", __func__, len); BN_bn2bin(server_modulus, nbuf); - EVP_DigestUpdate(&md, nbuf, len); - - EVP_DigestUpdate(&md, cookie, 8); - - EVP_DigestFinal(&md, obuf, NULL); - memcpy(id, obuf, 16); + if (ssh_digest_update(hashctx, nbuf, len) != 0 || + ssh_digest_update(hashctx, cookie, 8) != 0) + fatal("%s: ssh_digest_update failed", __func__); + if (ssh_digest_final(hashctx, obuf, sizeof(obuf)) != 0) + fatal("%s: ssh_digest_final failed", __func__); + memcpy(id, obuf, ssh_digest_bytes(SSH_DIGEST_MD5)); memset(nbuf, 0, sizeof(nbuf)); memset(obuf, 0, sizeof(obuf)); - memset(&md, 0, sizeof(md)); } #if defined(DEBUG_KEX) || defined(DEBUG_KEXDH) || defined(DEBUG_KEXECDH) diff --git a/kex.h b/kex.h index 9f1e1adb39b3..1aa3ec26aa77 100644 --- a/kex.h +++ b/kex.h @@ -1,4 +1,4 @@ -/* $OpenBSD: kex.h,v 1.56 2013/07/19 07:37:48 markus Exp $ */ +/* $OpenBSD: kex.h,v 1.61 2014/01/25 10:12:50 dtucker Exp $ */ /* * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. @@ -43,6 +43,7 @@ #define KEX_ECDH_SHA2_NISTP256 "ecdh-sha2-nistp256" #define KEX_ECDH_SHA2_NISTP384 "ecdh-sha2-nistp384" #define KEX_ECDH_SHA2_NISTP521 "ecdh-sha2-nistp521" +#define KEX_CURVE25519_SHA256 "curve25519-sha256@libssh.org" #define COMP_NONE 0 #define COMP_ZLIB 1 @@ -74,6 +75,7 @@ enum kex_exchange { KEX_DH_GEX_SHA1, KEX_DH_GEX_SHA256, KEX_ECDH_SHA2, + KEX_C25519_SHA256, KEX_MAX }; @@ -122,6 +124,7 @@ struct Kex { u_int session_id_len; Newkeys *newkeys[MODE_MAX]; u_int we_need; + u_int dh_need; int server; char *name; int hostkey_type; @@ -131,7 +134,7 @@ struct Kex { Buffer peer; sig_atomic_t done; int flags; - const EVP_MD *evp_md; + int hash_alg; int ec_nid; char *client_version_string; char *server_version_string; @@ -144,14 +147,15 @@ struct Kex { }; int kex_names_valid(const char *); -char *kex_alg_list(void); +char *kex_alg_list(char); Kex *kex_setup(char *[PROPOSAL_MAX]); void kex_finish(Kex *); void kex_send_kexinit(Kex *); void kex_input_kexinit(int, u_int32_t, void *); -void kex_derive_keys(Kex *, u_char *, u_int, BIGNUM *); +void kex_derive_keys(Kex *, u_char *, u_int, const u_char *, u_int); +void kex_derive_keys_bn(Kex *, u_char *, u_int, const BIGNUM *); Newkeys *kex_get_newkeys(int); @@ -161,20 +165,35 @@ void kexgex_client(Kex *); void kexgex_server(Kex *); void kexecdh_client(Kex *); void kexecdh_server(Kex *); +void kexc25519_client(Kex *); +void kexc25519_server(Kex *); void kex_dh_hash(char *, char *, char *, int, char *, int, u_char *, int, BIGNUM *, BIGNUM *, BIGNUM *, u_char **, u_int *); void -kexgex_hash(const EVP_MD *, char *, char *, char *, int, char *, +kexgex_hash(int, char *, char *, char *, int, char *, int, u_char *, int, int, int, int, BIGNUM *, BIGNUM *, BIGNUM *, BIGNUM *, BIGNUM *, u_char **, u_int *); #ifdef OPENSSL_HAS_ECC void -kex_ecdh_hash(const EVP_MD *, const EC_GROUP *, char *, char *, char *, int, +kex_ecdh_hash(int, const EC_GROUP *, char *, char *, char *, int, char *, int, u_char *, int, const EC_POINT *, const EC_POINT *, const BIGNUM *, u_char **, u_int *); #endif +void +kex_c25519_hash(int, char *, char *, char *, int, + char *, int, u_char *, int, const u_char *, const u_char *, + const u_char *, u_int, u_char **, u_int *); + +#define CURVE25519_SIZE 32 +void kexc25519_keygen(u_char[CURVE25519_SIZE], u_char[CURVE25519_SIZE]) + __attribute__((__bounded__(__minbytes__, 1, CURVE25519_SIZE))) + __attribute__((__bounded__(__minbytes__, 2, CURVE25519_SIZE))); +void kexc25519_shared_key(const u_char key[CURVE25519_SIZE], + const u_char pub[CURVE25519_SIZE], Buffer *out) + __attribute__((__bounded__(__minbytes__, 1, CURVE25519_SIZE))) + __attribute__((__bounded__(__minbytes__, 2, CURVE25519_SIZE))); void derive_ssh1_session_id(BIGNUM *, BIGNUM *, u_int8_t[8], u_int8_t[16]); diff --git a/kexc25519.c b/kexc25519.c new file mode 100644 index 000000000000..48ca4aaa2182 --- /dev/null +++ b/kexc25519.c @@ -0,0 +1,122 @@ +/* $OpenBSD: kexc25519.c,v 1.4 2014/01/12 08:13:13 djm Exp $ */ +/* + * Copyright (c) 2001, 2013 Markus Friedl. All rights reserved. + * Copyright (c) 2010 Damien Miller. All rights reserved. + * Copyright (c) 2013 Aris Adamantiadis. 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. + * + * 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. + */ + +#include "includes.h" + +#include + +#include +#include + +#include +#include + +#include "buffer.h" +#include "ssh2.h" +#include "key.h" +#include "cipher.h" +#include "kex.h" +#include "log.h" +#include "digest.h" + +extern int crypto_scalarmult_curve25519(u_char a[CURVE25519_SIZE], + const u_char b[CURVE25519_SIZE], const u_char c[CURVE25519_SIZE]) + __attribute__((__bounded__(__minbytes__, 1, CURVE25519_SIZE))) + __attribute__((__bounded__(__minbytes__, 2, CURVE25519_SIZE))) + __attribute__((__bounded__(__minbytes__, 3, CURVE25519_SIZE))); + +void +kexc25519_keygen(u_char key[CURVE25519_SIZE], u_char pub[CURVE25519_SIZE]) +{ + static const u_char basepoint[CURVE25519_SIZE] = {9}; + + arc4random_buf(key, CURVE25519_SIZE); + crypto_scalarmult_curve25519(pub, key, basepoint); +} + +void +kexc25519_shared_key(const u_char key[CURVE25519_SIZE], + const u_char pub[CURVE25519_SIZE], Buffer *out) +{ + u_char shared_key[CURVE25519_SIZE]; + + crypto_scalarmult_curve25519(shared_key, key, pub); +#ifdef DEBUG_KEXECDH + dump_digest("shared secret", shared_key, CURVE25519_SIZE); +#endif + buffer_clear(out); + buffer_put_bignum2_from_string(out, shared_key, CURVE25519_SIZE); + memset(shared_key, 0, CURVE25519_SIZE); /* XXX explicit_bzero() */ +} + +void +kex_c25519_hash( + int hash_alg, + char *client_version_string, + char *server_version_string, + char *ckexinit, int ckexinitlen, + char *skexinit, int skexinitlen, + u_char *serverhostkeyblob, int sbloblen, + const u_char client_dh_pub[CURVE25519_SIZE], + const u_char server_dh_pub[CURVE25519_SIZE], + const u_char *shared_secret, u_int secretlen, + u_char **hash, u_int *hashlen) +{ + Buffer b; + static u_char digest[SSH_DIGEST_MAX_LENGTH]; + + buffer_init(&b); + buffer_put_cstring(&b, client_version_string); + buffer_put_cstring(&b, server_version_string); + + /* kexinit messages: fake header: len+SSH2_MSG_KEXINIT */ + buffer_put_int(&b, ckexinitlen+1); + buffer_put_char(&b, SSH2_MSG_KEXINIT); + buffer_append(&b, ckexinit, ckexinitlen); + buffer_put_int(&b, skexinitlen+1); + buffer_put_char(&b, SSH2_MSG_KEXINIT); + buffer_append(&b, skexinit, skexinitlen); + + buffer_put_string(&b, serverhostkeyblob, sbloblen); + buffer_put_string(&b, client_dh_pub, CURVE25519_SIZE); + buffer_put_string(&b, server_dh_pub, CURVE25519_SIZE); + buffer_append(&b, shared_secret, secretlen); + +#ifdef DEBUG_KEX + buffer_dump(&b); +#endif + if (ssh_digest_buffer(hash_alg, &b, digest, sizeof(digest)) != 0) + fatal("%s: digest_buffer failed", __func__); + + buffer_free(&b); + +#ifdef DEBUG_KEX + dump_digest("hash", digest, ssh_digest_bytes(hash_alg)); +#endif + *hash = digest; + *hashlen = ssh_digest_bytes(hash_alg); +} diff --git a/kexc25519c.c b/kexc25519c.c new file mode 100644 index 000000000000..a80678af6c01 --- /dev/null +++ b/kexc25519c.c @@ -0,0 +1,129 @@ +/* $OpenBSD: kexc25519c.c,v 1.4 2014/01/12 08:13:13 djm Exp $ */ +/* + * Copyright (c) 2001 Markus Friedl. All rights reserved. + * Copyright (c) 2010 Damien Miller. All rights reserved. + * Copyright (c) 2013 Aris Adamantiadis. 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. + * + * 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. + */ + +#include "includes.h" + +#include + +#include +#include +#include + +#include "xmalloc.h" +#include "buffer.h" +#include "key.h" +#include "cipher.h" +#include "kex.h" +#include "log.h" +#include "packet.h" +#include "ssh2.h" + +void +kexc25519_client(Kex *kex) +{ + Key *server_host_key; + u_char client_key[CURVE25519_SIZE]; + u_char client_pubkey[CURVE25519_SIZE]; + u_char *server_pubkey = NULL; + u_char *server_host_key_blob = NULL, *signature = NULL; + u_char *hash; + u_int slen, sbloblen, hashlen; + Buffer shared_secret; + + kexc25519_keygen(client_key, client_pubkey); + + packet_start(SSH2_MSG_KEX_ECDH_INIT); + packet_put_string(client_pubkey, sizeof(client_pubkey)); + packet_send(); + debug("sending SSH2_MSG_KEX_ECDH_INIT"); + +#ifdef DEBUG_KEXECDH + dump_digest("client private key:", client_key, sizeof(client_key)); +#endif + + debug("expecting SSH2_MSG_KEX_ECDH_REPLY"); + packet_read_expect(SSH2_MSG_KEX_ECDH_REPLY); + + /* hostkey */ + server_host_key_blob = packet_get_string(&sbloblen); + server_host_key = key_from_blob(server_host_key_blob, sbloblen); + if (server_host_key == NULL) + fatal("cannot decode server_host_key_blob"); + if (server_host_key->type != kex->hostkey_type) + fatal("type mismatch for decoded server_host_key_blob"); + if (kex->verify_host_key == NULL) + fatal("cannot verify server_host_key"); + if (kex->verify_host_key(server_host_key) == -1) + fatal("server_host_key verification failed"); + + /* Q_S, server public key */ + server_pubkey = packet_get_string(&slen); + if (slen != CURVE25519_SIZE) + fatal("Incorrect size for server Curve25519 pubkey: %d", slen); + +#ifdef DEBUG_KEXECDH + dump_digest("server public key:", server_pubkey, CURVE25519_SIZE); +#endif + + /* signed H */ + signature = packet_get_string(&slen); + packet_check_eom(); + + buffer_init(&shared_secret); + kexc25519_shared_key(client_key, server_pubkey, &shared_secret); + + /* calc and verify H */ + kex_c25519_hash( + kex->hash_alg, + kex->client_version_string, + kex->server_version_string, + buffer_ptr(&kex->my), buffer_len(&kex->my), + buffer_ptr(&kex->peer), buffer_len(&kex->peer), + server_host_key_blob, sbloblen, + client_pubkey, + server_pubkey, + buffer_ptr(&shared_secret), buffer_len(&shared_secret), + &hash, &hashlen + ); + free(server_host_key_blob); + free(server_pubkey); + if (key_verify(server_host_key, signature, slen, hash, hashlen) != 1) + fatal("key_verify failed for server_host_key"); + key_free(server_host_key); + free(signature); + + /* save session id */ + if (kex->session_id == NULL) { + kex->session_id_len = hashlen; + kex->session_id = xmalloc(kex->session_id_len); + memcpy(kex->session_id, hash, kex->session_id_len); + } + kex_derive_keys(kex, hash, hashlen, + buffer_ptr(&shared_secret), buffer_len(&shared_secret)); + buffer_free(&shared_secret); + kex_finish(kex); +} diff --git a/kexc25519s.c b/kexc25519s.c new file mode 100644 index 000000000000..2b8e8efa175c --- /dev/null +++ b/kexc25519s.c @@ -0,0 +1,126 @@ +/* $OpenBSD: kexc25519s.c,v 1.4 2014/01/12 08:13:13 djm Exp $ */ +/* + * Copyright (c) 2001 Markus Friedl. All rights reserved. + * Copyright (c) 2010 Damien Miller. All rights reserved. + * Copyright (c) 2013 Aris Adamantiadis. All rights reserved. + * + * 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. + * + * 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. + */ + +#include "includes.h" + +#include +#include +#include + +#include "xmalloc.h" +#include "buffer.h" +#include "key.h" +#include "cipher.h" +#include "kex.h" +#include "log.h" +#include "packet.h" +#include "ssh2.h" + +void +kexc25519_server(Kex *kex) +{ + Key *server_host_private, *server_host_public; + u_char *server_host_key_blob = NULL, *signature = NULL; + u_char server_key[CURVE25519_SIZE]; + u_char *client_pubkey = NULL; + u_char server_pubkey[CURVE25519_SIZE]; + u_char *hash; + u_int slen, sbloblen, hashlen; + Buffer shared_secret; + + /* generate private key */ + kexc25519_keygen(server_key, server_pubkey); +#ifdef DEBUG_KEXECDH + dump_digest("server private key:", server_key, sizeof(server_key)); +#endif + + if (kex->load_host_public_key == NULL || + kex->load_host_private_key == NULL) + fatal("Cannot load hostkey"); + server_host_public = kex->load_host_public_key(kex->hostkey_type); + if (server_host_public == NULL) + fatal("Unsupported hostkey type %d", kex->hostkey_type); + server_host_private = kex->load_host_private_key(kex->hostkey_type); + + debug("expecting SSH2_MSG_KEX_ECDH_INIT"); + packet_read_expect(SSH2_MSG_KEX_ECDH_INIT); + client_pubkey = packet_get_string(&slen); + if (slen != CURVE25519_SIZE) + fatal("Incorrect size for server Curve25519 pubkey: %d", slen); + packet_check_eom(); + +#ifdef DEBUG_KEXECDH + dump_digest("client public key:", client_pubkey, CURVE25519_SIZE); +#endif + + buffer_init(&shared_secret); + kexc25519_shared_key(server_key, client_pubkey, &shared_secret); + + /* calc H */ + key_to_blob(server_host_public, &server_host_key_blob, &sbloblen); + kex_c25519_hash( + kex->hash_alg, + kex->client_version_string, + kex->server_version_string, + buffer_ptr(&kex->peer), buffer_len(&kex->peer), + buffer_ptr(&kex->my), buffer_len(&kex->my), + server_host_key_blob, sbloblen, + client_pubkey, + server_pubkey, + buffer_ptr(&shared_secret), buffer_len(&shared_secret), + &hash, &hashlen + ); + + /* save session id := H */ + if (kex->session_id == NULL) { + kex->session_id_len = hashlen; + kex->session_id = xmalloc(kex->session_id_len); + memcpy(kex->session_id, hash, kex->session_id_len); + } + + /* sign H */ + kex->sign(server_host_private, server_host_public, &signature, &slen, + hash, hashlen); + + /* destroy_sensitive_data(); */ + + /* send server hostkey, ECDH pubkey 'Q_S' and signed H */ + packet_start(SSH2_MSG_KEX_ECDH_REPLY); + packet_put_string(server_host_key_blob, sbloblen); + packet_put_string(server_pubkey, sizeof(server_pubkey)); + packet_put_string(signature, slen); + packet_send(); + + free(signature); + free(server_host_key_blob); + /* have keys, free server key */ + free(client_pubkey); + + kex_derive_keys(kex, hash, hashlen, + buffer_ptr(&shared_secret), buffer_len(&shared_secret)); + buffer_free(&shared_secret); + kex_finish(kex); +} diff --git a/kexdh.c b/kexdh.c index 56e22f5bc890..e7cdadc90046 100644 --- a/kexdh.c +++ b/kexdh.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kexdh.c,v 1.23 2006/08/03 03:34:42 deraadt Exp $ */ +/* $OpenBSD: kexdh.c,v 1.24 2014/01/09 23:20:00 djm Exp $ */ /* * Copyright (c) 2001 Markus Friedl. All rights reserved. * @@ -36,6 +36,8 @@ #include "key.h" #include "cipher.h" #include "kex.h" +#include "digest.h" +#include "log.h" void kex_dh_hash( @@ -50,9 +52,7 @@ kex_dh_hash( u_char **hash, u_int *hashlen) { Buffer b; - static u_char digest[EVP_MAX_MD_SIZE]; - const EVP_MD *evp_md = EVP_sha1(); - EVP_MD_CTX md; + static u_char digest[SSH_DIGEST_MAX_LENGTH]; buffer_init(&b); buffer_put_cstring(&b, client_version_string); @@ -74,15 +74,14 @@ kex_dh_hash( #ifdef DEBUG_KEX buffer_dump(&b); #endif - EVP_DigestInit(&md, evp_md); - EVP_DigestUpdate(&md, buffer_ptr(&b), buffer_len(&b)); - EVP_DigestFinal(&md, digest, NULL); + if (ssh_digest_buffer(SSH_DIGEST_SHA1, &b, digest, sizeof(digest)) != 0) + fatal("%s: ssh_digest_buffer failed", __func__); buffer_free(&b); #ifdef DEBUG_KEX - dump_digest("hash", digest, EVP_MD_size(evp_md)); + dump_digest("hash", digest, ssh_digest_bytes(SSH_DIGEST_SHA1)); #endif *hash = digest; - *hashlen = EVP_MD_size(evp_md); + *hashlen = ssh_digest_bytes(SSH_DIGEST_SHA1); } diff --git a/kexdhc.c b/kexdhc.c index ccd137cacbf3..78509af21144 100644 --- a/kexdhc.c +++ b/kexdhc.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kexdhc.c,v 1.13 2013/05/17 00:13:13 djm Exp $ */ +/* $OpenBSD: kexdhc.c,v 1.14 2014/01/12 08:13:13 djm Exp $ */ /* * Copyright (c) 2001 Markus Friedl. All rights reserved. * @@ -155,7 +155,7 @@ kexdh_client(Kex *kex) memcpy(kex->session_id, hash, kex->session_id_len); } - kex_derive_keys(kex, hash, hashlen, shared_secret); + kex_derive_keys_bn(kex, hash, hashlen, shared_secret); BN_clear_free(shared_secret); kex_finish(kex); } diff --git a/kexdhs.c b/kexdhs.c index 269d80900c90..d2c7adc9636e 100644 --- a/kexdhs.c +++ b/kexdhs.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kexdhs.c,v 1.14 2013/07/19 07:37:48 markus Exp $ */ +/* $OpenBSD: kexdhs.c,v 1.17 2014/01/12 08:13:13 djm Exp $ */ /* * Copyright (c) 2001 Markus Friedl. All rights reserved. * @@ -42,10 +42,6 @@ #include "packet.h" #include "dh.h" #include "ssh2.h" -#ifdef GSSAPI -#include "ssh-gss.h" -#endif -#include "monitor_wrap.h" void kexdh_server(Kex *kex) @@ -158,7 +154,7 @@ kexdh_server(Kex *kex) /* have keys, free DH */ DH_free(dh); - kex_derive_keys(kex, hash, hashlen, shared_secret); + kex_derive_keys_bn(kex, hash, hashlen, shared_secret); BN_clear_free(shared_secret); kex_finish(kex); } diff --git a/kexecdh.c b/kexecdh.c index c948fe20a2f8..c52c5e234743 100644 --- a/kexecdh.c +++ b/kexecdh.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kexecdh.c,v 1.4 2013/04/19 01:06:50 djm Exp $ */ +/* $OpenBSD: kexecdh.c,v 1.5 2014/01/09 23:20:00 djm Exp $ */ /* * Copyright (c) 2001 Markus Friedl. All rights reserved. * Copyright (c) 2010 Damien Miller. All rights reserved. @@ -44,10 +44,11 @@ #include "cipher.h" #include "kex.h" #include "log.h" +#include "digest.h" void kex_ecdh_hash( - const EVP_MD *evp_md, + int hash_alg, const EC_GROUP *ec_group, char *client_version_string, char *server_version_string, @@ -60,8 +61,7 @@ kex_ecdh_hash( u_char **hash, u_int *hashlen) { Buffer b; - EVP_MD_CTX md; - static u_char digest[EVP_MAX_MD_SIZE]; + static u_char digest[SSH_DIGEST_MAX_LENGTH]; buffer_init(&b); buffer_put_cstring(&b, client_version_string); @@ -83,17 +83,15 @@ kex_ecdh_hash( #ifdef DEBUG_KEX buffer_dump(&b); #endif - EVP_DigestInit(&md, evp_md); - EVP_DigestUpdate(&md, buffer_ptr(&b), buffer_len(&b)); - EVP_DigestFinal(&md, digest, NULL); + if (ssh_digest_buffer(hash_alg, &b, digest, sizeof(digest)) != 0) + fatal("%s: ssh_digest_buffer failed", __func__); buffer_free(&b); #ifdef DEBUG_KEX - dump_digest("hash", digest, EVP_MD_size(evp_md)); + dump_digest("hash", digest, ssh_digest_bytes(hash_alg)); #endif *hash = digest; - *hashlen = EVP_MD_size(evp_md); + *hashlen = ssh_digest_bytes(hash_alg); } - #endif /* OPENSSL_HAS_ECC */ diff --git a/kexecdhc.c b/kexecdhc.c index 6193836c7d52..e3d1cf5f9c6d 100644 --- a/kexecdhc.c +++ b/kexecdhc.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kexecdhc.c,v 1.4 2013/05/17 00:13:13 djm Exp $ */ +/* $OpenBSD: kexecdhc.c,v 1.6 2014/01/12 08:13:13 djm Exp $ */ /* * Copyright (c) 2001 Markus Friedl. All rights reserved. * Copyright (c) 2010 Damien Miller. All rights reserved. @@ -124,7 +124,7 @@ kexecdh_client(Kex *kex) /* calc and verify H */ kex_ecdh_hash( - kex->evp_md, + kex->hash_alg, group, kex->client_version_string, kex->server_version_string, @@ -152,7 +152,7 @@ kexecdh_client(Kex *kex) memcpy(kex->session_id, hash, kex->session_id_len); } - kex_derive_keys(kex, hash, hashlen, shared_secret); + kex_derive_keys_bn(kex, hash, hashlen, shared_secret); BN_clear_free(shared_secret); kex_finish(kex); } diff --git a/kexecdhs.c b/kexecdhs.c index 3a580aacf6c4..6fbb79c9dfa8 100644 --- a/kexecdhs.c +++ b/kexecdhs.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kexecdhs.c,v 1.5 2013/07/19 07:37:48 markus Exp $ */ +/* $OpenBSD: kexecdhs.c,v 1.9 2014/01/12 08:13:13 djm Exp $ */ /* * Copyright (c) 2001 Markus Friedl. All rights reserved. * Copyright (c) 2010 Damien Miller. All rights reserved. @@ -37,12 +37,7 @@ #include "kex.h" #include "log.h" #include "packet.h" -#include "dh.h" #include "ssh2.h" -#ifdef GSSAPI -#include "ssh-gss.h" -#endif -#include "monitor_wrap.h" #ifdef OPENSSL_HAS_ECC @@ -114,7 +109,7 @@ kexecdh_server(Kex *kex) /* calc H */ key_to_blob(server_host_public, &server_host_key_blob, &sbloblen); kex_ecdh_hash( - kex->evp_md, + kex->hash_alg, group, kex->client_version_string, kex->server_version_string, @@ -153,7 +148,7 @@ kexecdh_server(Kex *kex) /* have keys, free server key */ EC_KEY_free(server_key); - kex_derive_keys(kex, hash, hashlen, shared_secret); + kex_derive_keys_bn(kex, hash, hashlen, shared_secret); BN_clear_free(shared_secret); kex_finish(kex); } diff --git a/kexgex.c b/kexgex.c index b60ab5c53cc9..c2e6bc16d567 100644 --- a/kexgex.c +++ b/kexgex.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kexgex.c,v 1.27 2006/08/03 03:34:42 deraadt Exp $ */ +/* $OpenBSD: kexgex.c,v 1.28 2014/01/09 23:20:00 djm Exp $ */ /* * Copyright (c) 2000 Niels Provos. All rights reserved. * Copyright (c) 2001 Markus Friedl. All rights reserved. @@ -36,10 +36,12 @@ #include "cipher.h" #include "kex.h" #include "ssh2.h" +#include "digest.h" +#include "log.h" void kexgex_hash( - const EVP_MD *evp_md, + int hash_alg, char *client_version_string, char *server_version_string, char *ckexinit, int ckexinitlen, @@ -52,8 +54,7 @@ kexgex_hash( u_char **hash, u_int *hashlen) { Buffer b; - static u_char digest[EVP_MAX_MD_SIZE]; - EVP_MD_CTX md; + static u_char digest[SSH_DIGEST_MAX_LENGTH]; buffer_init(&b); buffer_put_cstring(&b, client_version_string); @@ -84,15 +85,14 @@ kexgex_hash( #ifdef DEBUG_KEXDH buffer_dump(&b); #endif - - EVP_DigestInit(&md, evp_md); - EVP_DigestUpdate(&md, buffer_ptr(&b), buffer_len(&b)); - EVP_DigestFinal(&md, digest, NULL); + if (ssh_digest_buffer(hash_alg, &b, digest, sizeof(digest)) != 0) + fatal("%s: ssh_digest_buffer failed", __func__); buffer_free(&b); - *hash = digest; - *hashlen = EVP_MD_size(evp_md); -#ifdef DEBUG_KEXDH - dump_digest("hash", digest, *hashlen); + +#ifdef DEBUG_KEX + dump_digest("hash", digest, ssh_digest_bytes(hash_alg)); #endif + *hash = digest; + *hashlen = ssh_digest_bytes(hash_alg); } diff --git a/kexgexc.c b/kexgexc.c index 5a3be200523e..629b5fbbca1a 100644 --- a/kexgexc.c +++ b/kexgexc.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kexgexc.c,v 1.13 2013/05/17 00:13:13 djm Exp $ */ +/* $OpenBSD: kexgexc.c,v 1.16 2014/01/25 10:12:50 dtucker Exp $ */ /* * Copyright (c) 2000 Niels Provos. All rights reserved. * Copyright (c) 2001 Markus Friedl. All rights reserved. @@ -58,7 +58,7 @@ kexgex_client(Kex *kex) int min, max, nbits; DH *dh; - nbits = dh_estimate(kex->we_need * 8); + nbits = dh_estimate(kex->dh_need * 8); if (datafellows & SSH_OLD_DHGEX) { /* Old GEX request */ @@ -170,7 +170,7 @@ kexgex_client(Kex *kex) /* calc and verify H */ kexgex_hash( - kex->evp_md, + kex->hash_alg, kex->client_version_string, kex->server_version_string, buffer_ptr(&kex->my), buffer_len(&kex->my), @@ -200,7 +200,7 @@ kexgex_client(Kex *kex) kex->session_id = xmalloc(kex->session_id_len); memcpy(kex->session_id, hash, kex->session_id_len); } - kex_derive_keys(kex, hash, hashlen, shared_secret); + kex_derive_keys_bn(kex, hash, hashlen, shared_secret); BN_clear_free(shared_secret); kex_finish(kex); diff --git a/kexgexs.c b/kexgexs.c index 4e473fc73869..8773778ed3a0 100644 --- a/kexgexs.c +++ b/kexgexs.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kexgexs.c,v 1.16 2013/07/19 07:37:48 markus Exp $ */ +/* $OpenBSD: kexgexs.c,v 1.18 2014/01/12 08:13:13 djm Exp $ */ /* * Copyright (c) 2000 Niels Provos. All rights reserved. * Copyright (c) 2001 Markus Friedl. All rights reserved. @@ -160,7 +160,7 @@ kexgex_server(Kex *kex) /* calc H */ kexgex_hash( - kex->evp_md, + kex->hash_alg, kex->client_version_string, kex->server_version_string, buffer_ptr(&kex->peer), buffer_len(&kex->peer), @@ -201,7 +201,7 @@ kexgex_server(Kex *kex) /* have keys, free DH */ DH_free(dh); - kex_derive_keys(kex, hash, hashlen, shared_secret); + kex_derive_keys_bn(kex, hash, hashlen, shared_secret); BN_clear_free(shared_secret); kex_finish(kex); diff --git a/key.c b/key.c index 55ee78998b74..9142338085a4 100644 --- a/key.c +++ b/key.c @@ -1,4 +1,4 @@ -/* $OpenBSD: key.c,v 1.104 2013/05/19 02:42:42 djm Exp $ */ +/* $OpenBSD: key.c,v 1.115 2014/01/09 23:20:00 djm Exp $ */ /* * read_bignum(): * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -39,6 +39,8 @@ #include #include +#include "crypto_api.h" + #include #include @@ -54,8 +56,10 @@ #include "log.h" #include "misc.h" #include "ssh2.h" +#include "digest.h" static int to_blob(const Key *, u_char **, u_int *, int); +static Key *key_from_blob2(const u_char *, u_int, int); static struct KeyCert * cert_new(void) @@ -85,6 +89,8 @@ key_new(int type) k->dsa = NULL; k->rsa = NULL; k->cert = NULL; + k->ed25519_sk = NULL; + k->ed25519_pk = NULL; switch (k->type) { case KEY_RSA1: case KEY_RSA: @@ -119,6 +125,10 @@ key_new(int type) /* Cannot do anything until we know the group */ break; #endif + case KEY_ED25519: + case KEY_ED25519_CERT: + /* no need to prealloc */ + break; case KEY_UNSPEC: break; default: @@ -163,6 +173,10 @@ key_add_private(Key *k) case KEY_ECDSA_CERT: /* Cannot do anything until we know the group */ break; + case KEY_ED25519: + case KEY_ED25519_CERT: + /* no need to prealloc */ + break; case KEY_UNSPEC: break; default: @@ -225,6 +239,19 @@ key_free(Key *k) k->ecdsa = NULL; break; #endif + case KEY_ED25519: + case KEY_ED25519_CERT: + if (k->ed25519_pk) { + memset(k->ed25519_pk, 0, ED25519_PK_SZ); + free(k->ed25519_pk); + k->ed25519_pk = NULL; + } + if (k->ed25519_sk) { + memset(k->ed25519_sk, 0, ED25519_SK_SZ); + free(k->ed25519_sk); + k->ed25519_sk = NULL; + } + break; case KEY_UNSPEC: break; default: @@ -306,6 +333,10 @@ key_equal_public(const Key *a, const Key *b) BN_CTX_free(bnctx); return 1; #endif /* OPENSSL_HAS_ECC */ + case KEY_ED25519: + case KEY_ED25519_CERT: + return a->ed25519_pk != NULL && b->ed25519_pk != NULL && + memcmp(a->ed25519_pk, b->ed25519_pk, ED25519_PK_SZ) == 0; default: fatal("key_equal: bad key type %d", a->type); } @@ -328,30 +359,26 @@ u_char* key_fingerprint_raw(const Key *k, enum fp_type dgst_type, u_int *dgst_raw_length) { - const EVP_MD *md = NULL; - EVP_MD_CTX ctx; u_char *blob = NULL; u_char *retval = NULL; u_int len = 0; - int nlen, elen; + int nlen, elen, hash_alg = -1; *dgst_raw_length = 0; + /* XXX switch to DIGEST_* directly? */ switch (dgst_type) { case SSH_FP_MD5: - md = EVP_md5(); + hash_alg = SSH_DIGEST_MD5; break; case SSH_FP_SHA1: - md = EVP_sha1(); + hash_alg = SSH_DIGEST_SHA1; break; -#ifdef HAVE_EVP_SHA256 case SSH_FP_SHA256: - md = EVP_sha256(); + hash_alg = SSH_DIGEST_SHA256; break; -#endif default: - fatal("key_fingerprint_raw: bad digest type %d", - dgst_type); + fatal("%s: bad digest type %d", __func__, dgst_type); } switch (k->type) { case KEY_RSA1: @@ -365,6 +392,7 @@ key_fingerprint_raw(const Key *k, enum fp_type dgst_type, case KEY_DSA: case KEY_ECDSA: case KEY_RSA: + case KEY_ED25519: key_to_blob(k, &blob, &len); break; case KEY_DSA_CERT_V00: @@ -372,24 +400,26 @@ key_fingerprint_raw(const Key *k, enum fp_type dgst_type, case KEY_DSA_CERT: case KEY_ECDSA_CERT: case KEY_RSA_CERT: + case KEY_ED25519_CERT: /* We want a fingerprint of the _key_ not of the cert */ to_blob(k, &blob, &len, 1); break; case KEY_UNSPEC: return retval; default: - fatal("key_fingerprint_raw: bad key type %d", k->type); + fatal("%s: bad key type %d", __func__, k->type); break; } if (blob != NULL) { - retval = xmalloc(EVP_MAX_MD_SIZE); - EVP_DigestInit(&ctx, md); - EVP_DigestUpdate(&ctx, blob, len); - EVP_DigestFinal(&ctx, retval, dgst_raw_length); + retval = xmalloc(SSH_DIGEST_MAX_LENGTH); + if ((ssh_digest_memory(hash_alg, blob, len, + retval, SSH_DIGEST_MAX_LENGTH)) != 0) + fatal("%s: digest_memory failed", __func__); memset(blob, 0, len); free(blob); + *dgst_raw_length = ssh_digest_bytes(hash_alg); } else { - fatal("key_fingerprint_raw: blob is null"); + fatal("%s: blob is null", __func__); } return retval; } @@ -698,11 +728,13 @@ key_read(Key *ret, char **cpp) case KEY_RSA: case KEY_DSA: case KEY_ECDSA: + case KEY_ED25519: case KEY_DSA_CERT_V00: case KEY_RSA_CERT_V00: case KEY_DSA_CERT: case KEY_ECDSA_CERT: case KEY_RSA_CERT: + case KEY_ED25519_CERT: space = strchr(cp, ' '); if (space == NULL) { debug3("key_read: missing whitespace"); @@ -804,6 +836,14 @@ key_read(Key *ret, char **cpp) #endif } #endif + if (key_type_plain(ret->type) == KEY_ED25519) { + free(ret->ed25519_pk); + ret->ed25519_pk = k->ed25519_pk; + k->ed25519_pk = NULL; +#ifdef DEBUG_PK + /* XXX */ +#endif + } success = 1; /*XXXX*/ key_free(k); @@ -867,6 +907,11 @@ key_write(const Key *key, FILE *f) return 0; break; #endif + case KEY_ED25519: + case KEY_ED25519_CERT: + if (key->ed25519_pk == NULL) + return 0; + break; case KEY_RSA: case KEY_RSA_CERT_V00: case KEY_RSA_CERT: @@ -914,10 +959,13 @@ static const struct keytype keytypes[] = { { NULL, "RSA1", KEY_RSA1, 0, 0 }, { "ssh-rsa", "RSA", KEY_RSA, 0, 0 }, { "ssh-dss", "DSA", KEY_DSA, 0, 0 }, + { "ssh-ed25519", "ED25519", KEY_ED25519, 0, 0 }, #ifdef OPENSSL_HAS_ECC { "ecdsa-sha2-nistp256", "ECDSA", KEY_ECDSA, NID_X9_62_prime256v1, 0 }, { "ecdsa-sha2-nistp384", "ECDSA", KEY_ECDSA, NID_secp384r1, 0 }, +# ifdef OPENSSL_HAS_NISTP521 { "ecdsa-sha2-nistp521", "ECDSA", KEY_ECDSA, NID_secp521r1, 0 }, +# endif #endif /* OPENSSL_HAS_ECC */ { "ssh-rsa-cert-v01@openssh.com", "RSA-CERT", KEY_RSA_CERT, 0, 1 }, { "ssh-dss-cert-v01@openssh.com", "DSA-CERT", KEY_DSA_CERT, 0, 1 }, @@ -926,13 +974,17 @@ static const struct keytype keytypes[] = { KEY_ECDSA_CERT, NID_X9_62_prime256v1, 1 }, { "ecdsa-sha2-nistp384-cert-v01@openssh.com", "ECDSA-CERT", KEY_ECDSA_CERT, NID_secp384r1, 1 }, +# ifdef OPENSSL_HAS_NISTP521 { "ecdsa-sha2-nistp521-cert-v01@openssh.com", "ECDSA-CERT", KEY_ECDSA_CERT, NID_secp521r1, 1 }, +# endif #endif /* OPENSSL_HAS_ECC */ { "ssh-rsa-cert-v00@openssh.com", "RSA-CERT-V00", KEY_RSA_CERT_V00, 0, 1 }, { "ssh-dss-cert-v00@openssh.com", "DSA-CERT-V00", KEY_DSA_CERT_V00, 0, 1 }, + { "ssh-ed25519-cert-v01@openssh.com", "ED25519-CERT", + KEY_ED25519_CERT, 0, 1 }, { NULL, NULL, -1, -1, 0 } }; @@ -1004,7 +1056,7 @@ key_ecdsa_nid_from_name(const char *name) } char * -key_alg_list(void) +key_alg_list(int certs_only, int plain_only) { char *ret = NULL; size_t nlen, rlen = 0; @@ -1013,6 +1065,8 @@ key_alg_list(void) for (kt = keytypes; kt->type != -1; kt++) { if (kt->name == NULL) continue; + if ((certs_only && !kt->cert) || (plain_only && kt->cert)) + continue; if (ret != NULL) ret[rlen++] = '\n'; nlen = strlen(kt->name); @@ -1023,6 +1077,32 @@ key_alg_list(void) return ret; } +int +key_type_is_cert(int type) +{ + const struct keytype *kt; + + for (kt = keytypes; kt->type != -1; kt++) { + if (kt->type == type) + return kt->cert; + } + return 0; +} + +static int +key_type_is_valid_ca(int type) +{ + switch (type) { + case KEY_RSA: + case KEY_DSA: + case KEY_ECDSA: + case KEY_ED25519: + return 1; + default: + return 0; + } +} + u_int key_size(const Key *k) { @@ -1036,6 +1116,8 @@ key_size(const Key *k) case KEY_DSA_CERT_V00: case KEY_DSA_CERT: return BN_num_bits(k->dsa->p); + case KEY_ED25519: + return 256; /* XXX */ #ifdef OPENSSL_HAS_ECC case KEY_ECDSA: case KEY_ECDSA_CERT: @@ -1087,8 +1169,10 @@ key_ecdsa_bits_to_nid(int bits) return NID_X9_62_prime256v1; case 384: return NID_secp384r1; +# ifdef OPENSSL_HAS_NISTP521 case 521: return NID_secp521r1; +# endif #endif default: return -1; @@ -1103,7 +1187,9 @@ key_ecdsa_key_to_nid(EC_KEY *k) int nids[] = { NID_X9_62_prime256v1, NID_secp384r1, +# ifdef OPENSSL_HAS_NISTP521 NID_secp521r1, +# endif -1 }; int nid; @@ -1175,6 +1261,11 @@ key_generate(int type, u_int bits) case KEY_RSA1: k->rsa = rsa_generate_private_key(bits); break; + case KEY_ED25519: + k->ed25519_pk = xmalloc(ED25519_PK_SZ); + k->ed25519_sk = xmalloc(ED25519_SK_SZ); + crypto_sign_ed25519_keypair(k->ed25519_pk, k->ed25519_sk); + break; case KEY_RSA_CERT_V00: case KEY_DSA_CERT_V00: case KEY_RSA_CERT: @@ -1268,6 +1359,14 @@ key_from_private(const Key *k) (BN_copy(n->rsa->e, k->rsa->e) == NULL)) fatal("key_from_private: BN_copy failed"); break; + case KEY_ED25519: + case KEY_ED25519_CERT: + n = key_new(k->type); + if (k->ed25519_pk != NULL) { + n->ed25519_pk = xmalloc(ED25519_PK_SZ); + memcpy(n->ed25519_pk, k->ed25519_pk, ED25519_PK_SZ); + } + break; default: fatal("key_from_private: unknown type %d", k->type); break; @@ -1387,14 +1486,12 @@ cert_parse(Buffer *b, Key *key, const u_char *blob, u_int blen) } buffer_clear(&tmp); - if ((key->cert->signature_key = key_from_blob(sig_key, - sklen)) == NULL) { + if ((key->cert->signature_key = key_from_blob2(sig_key, sklen, 0)) + == NULL) { error("%s: Signature key invalid", __func__); goto out; } - if (key->cert->signature_key->type != KEY_RSA && - key->cert->signature_key->type != KEY_DSA && - key->cert->signature_key->type != KEY_ECDSA) { + if (!key_type_is_valid_ca(key->cert->signature_key->type)) { error("%s: Invalid signature key type %s (%d)", __func__, key_type(key->cert->signature_key), key->cert->signature_key->type); @@ -1425,12 +1522,14 @@ cert_parse(Buffer *b, Key *key, const u_char *blob, u_int blen) return ret; } -Key * -key_from_blob(const u_char *blob, u_int blen) +static Key * +key_from_blob2(const u_char *blob, u_int blen, int allow_cert) { Buffer b; int rlen, type; + u_int len; char *ktype = NULL, *curve = NULL; + u_char *pk = NULL; Key *key = NULL; #ifdef OPENSSL_HAS_ECC EC_POINT *q = NULL; @@ -1452,7 +1551,10 @@ key_from_blob(const u_char *blob, u_int blen) if (key_type_plain(type) == KEY_ECDSA) nid = key_ecdsa_nid_from_name(ktype); #endif - + if (!allow_cert && key_type_is_cert(type)) { + error("key_from_blob: certificate not allowed in this context"); + goto out; + } switch (type) { case KEY_RSA_CERT: (void)buffer_get_string_ptr_ret(&b, NULL); /* Skip nonce */ @@ -1526,6 +1628,23 @@ key_from_blob(const u_char *blob, u_int blen) #endif break; #endif /* OPENSSL_HAS_ECC */ + case KEY_ED25519_CERT: + (void)buffer_get_string_ptr_ret(&b, NULL); /* Skip nonce */ + /* FALLTHROUGH */ + case KEY_ED25519: + if ((pk = buffer_get_string_ret(&b, &len)) == NULL) { + error("key_from_blob: can't read ed25519 key"); + goto badkey; + } + if (len != ED25519_PK_SZ) { + error("key_from_blob: ed25519 len %d != %d", + len, ED25519_PK_SZ); + goto badkey; + } + key = key_new(type); + key->ed25519_pk = pk; + pk = NULL; + break; case KEY_UNSPEC: key = key_new(type); break; @@ -1543,6 +1662,7 @@ key_from_blob(const u_char *blob, u_int blen) out: free(ktype); free(curve); + free(pk); #ifdef OPENSSL_HAS_ECC if (q != NULL) EC_POINT_free(q); @@ -1551,12 +1671,22 @@ key_from_blob(const u_char *blob, u_int blen) return key; } +Key * +key_from_blob(const u_char *blob, u_int blen) +{ + return key_from_blob2(blob, blen, 1); +} + static int to_blob(const Key *key, u_char **blobp, u_int *lenp, int force_plain) { Buffer b; int len, type; + if (blobp != NULL) + *blobp = NULL; + if (lenp != NULL) + *lenp = 0; if (key == NULL) { error("key_to_blob: key == NULL"); return 0; @@ -1569,6 +1699,7 @@ to_blob(const Key *key, u_char **blobp, u_int *lenp, int force_plain) case KEY_DSA_CERT: case KEY_ECDSA_CERT: case KEY_RSA_CERT: + case KEY_ED25519_CERT: /* Use the existing blob */ buffer_append(&b, buffer_ptr(&key->cert->certblob), buffer_len(&key->cert->certblob)); @@ -1596,6 +1727,11 @@ to_blob(const Key *key, u_char **blobp, u_int *lenp, int force_plain) buffer_put_bignum2(&b, key->rsa->e); buffer_put_bignum2(&b, key->rsa->n); break; + case KEY_ED25519: + buffer_put_cstring(&b, + key_ssh_name_from_type_nid(type, key->ecdsa_nid)); + buffer_put_string(&b, key->ed25519_pk, ED25519_PK_SZ); + break; default: error("key_to_blob: unsupported key type %d", key->type); buffer_free(&b); @@ -1639,6 +1775,9 @@ key_sign( case KEY_RSA_CERT: case KEY_RSA: return ssh_rsa_sign(key, sigp, lenp, data, datalen); + case KEY_ED25519: + case KEY_ED25519_CERT: + return ssh_ed25519_sign(key, sigp, lenp, data, datalen); default: error("key_sign: invalid key type %d", key->type); return -1; @@ -1672,6 +1811,9 @@ key_verify( case KEY_RSA_CERT: case KEY_RSA: return ssh_rsa_verify(key, signature, signaturelen, data, datalen); + case KEY_ED25519: + case KEY_ED25519_CERT: + return ssh_ed25519_verify(key, signature, signaturelen, data, datalen); default: error("key_verify: invalid key type %d", key->type); return -1; @@ -1691,6 +1833,8 @@ key_demote(const Key *k) pk->dsa = NULL; pk->ecdsa = NULL; pk->rsa = NULL; + pk->ed25519_pk = NULL; + pk->ed25519_sk = NULL; switch (k->type) { case KEY_RSA_CERT_V00: @@ -1734,8 +1878,17 @@ key_demote(const Key *k) fatal("key_demote: EC_KEY_set_public_key failed"); break; #endif + case KEY_ED25519_CERT: + key_cert_copy(k, pk); + /* FALLTHROUGH */ + case KEY_ED25519: + if (k->ed25519_pk != NULL) { + pk->ed25519_pk = xmalloc(ED25519_PK_SZ); + memcpy(pk->ed25519_pk, k->ed25519_pk, ED25519_PK_SZ); + } + break; default: - fatal("key_free: bad key type %d", k->type); + fatal("key_demote: bad key type %d", k->type); break; } @@ -1747,16 +1900,7 @@ key_is_cert(const Key *k) { if (k == NULL) return 0; - switch (k->type) { - case KEY_RSA_CERT_V00: - case KEY_DSA_CERT_V00: - case KEY_RSA_CERT: - case KEY_DSA_CERT: - case KEY_ECDSA_CERT: - return 1; - default: - return 0; - } + return key_type_is_cert(k->type); } /* Return the cert-less equivalent to a certified key type */ @@ -1772,12 +1916,14 @@ key_type_plain(int type) return KEY_DSA; case KEY_ECDSA_CERT: return KEY_ECDSA; + case KEY_ED25519_CERT: + return KEY_ED25519; default: return type; } } -/* Convert a KEY_RSA or KEY_DSA to their _CERT equivalent */ +/* Convert a plain key to their _CERT equivalent */ int key_to_certified(Key *k, int legacy) { @@ -1797,41 +1943,34 @@ key_to_certified(Key *k, int legacy) k->cert = cert_new(); k->type = KEY_ECDSA_CERT; return 0; + case KEY_ED25519: + if (legacy) + fatal("%s: legacy ED25519 certificates are not " + "supported", __func__); + k->cert = cert_new(); + k->type = KEY_ED25519_CERT; + return 0; default: error("%s: key has incorrect type %s", __func__, key_type(k)); return -1; } } -/* Convert a KEY_RSA_CERT or KEY_DSA_CERT to their raw key equivalent */ +/* Convert a certificate to its raw key equivalent */ int key_drop_cert(Key *k) { - switch (k->type) { - case KEY_RSA_CERT_V00: - case KEY_RSA_CERT: - cert_free(k->cert); - k->type = KEY_RSA; - return 0; - case KEY_DSA_CERT_V00: - case KEY_DSA_CERT: - cert_free(k->cert); - k->type = KEY_DSA; - return 0; - case KEY_ECDSA_CERT: - cert_free(k->cert); - k->type = KEY_ECDSA; - return 0; - default: + if (!key_type_is_cert(k->type)) { error("%s: key has incorrect type %s", __func__, key_type(k)); return -1; } + cert_free(k->cert); + k->cert = NULL; + k->type = key_type_plain(k->type); + return 0; } -/* - * Sign a KEY_RSA_CERT, KEY_DSA_CERT or KEY_ECDSA_CERT, (re-)generating - * the signed certblob - */ +/* Sign a certified key, (re-)generating the signed certblob. */ int key_certify(Key *k, Key *ca) { @@ -1850,8 +1989,7 @@ key_certify(Key *k, Key *ca) return -1; } - if (ca->type != KEY_RSA && ca->type != KEY_DSA && - ca->type != KEY_ECDSA) { + if (!key_type_is_valid_ca(ca->type)) { error("%s: CA key has unsupported type %s", __func__, key_type(ca)); return -1; @@ -1867,6 +2005,7 @@ key_certify(Key *k, Key *ca) if (!key_cert_is_legacy(k)) buffer_put_string(&k->cert->certblob, nonce, sizeof(nonce)); + /* XXX this substantially duplicates to_blob(); refactor */ switch (k->type) { case KEY_DSA_CERT_V00: case KEY_DSA_CERT: @@ -1889,6 +2028,10 @@ key_certify(Key *k, Key *ca) buffer_put_bignum2(&k->cert->certblob, k->rsa->e); buffer_put_bignum2(&k->cert->certblob, k->rsa->n); break; + case KEY_ED25519_CERT: + buffer_put_string(&k->cert->certblob, + k->ed25519_pk, ED25519_PK_SZ); + break; default: error("%s: key has incorrect type %s", __func__, key_type(k)); buffer_clear(&k->cert->certblob); @@ -2018,8 +2161,10 @@ key_curve_name_to_nid(const char *name) return NID_X9_62_prime256v1; else if (strcmp(name, "nistp384") == 0) return NID_secp384r1; +# ifdef OPENSSL_HAS_NISTP521 else if (strcmp(name, "nistp521") == 0) return NID_secp521r1; +# endif #endif debug("%s: unsupported EC curve name \"%.100s\"", __func__, name); @@ -2035,8 +2180,10 @@ key_curve_nid_to_bits(int nid) return 256; case NID_secp384r1: return 384; +# ifdef OPENSSL_HAS_NISTP521 case NID_secp521r1: return 521; +# endif #endif default: error("%s: unsupported EC curve nid %d", __func__, nid); @@ -2052,16 +2199,18 @@ key_curve_nid_to_name(int nid) return "nistp256"; else if (nid == NID_secp384r1) return "nistp384"; +# ifdef OPENSSL_HAS_NISTP521 else if (nid == NID_secp521r1) return "nistp521"; +# endif #endif error("%s: unsupported EC curve nid %d", __func__, nid); return NULL; } #ifdef OPENSSL_HAS_ECC -const EVP_MD * -key_ec_nid_to_evpmd(int nid) +int +key_ec_nid_to_hash_alg(int nid) { int kbits = key_curve_nid_to_bits(nid); @@ -2069,11 +2218,11 @@ key_ec_nid_to_evpmd(int nid) fatal("%s: invalid nid %d", __func__, nid); /* RFC5656 section 6.2.1 */ if (kbits <= 256) - return EVP_sha256(); + return SSH_DIGEST_SHA256; else if (kbits <= 384) - return EVP_sha384(); + return SSH_DIGEST_SHA384; else - return EVP_sha512(); + return SSH_DIGEST_SHA512; } int @@ -2245,3 +2394,232 @@ key_dump_ec_key(const EC_KEY *key) } #endif /* defined(DEBUG_KEXECDH) || defined(DEBUG_PK) */ #endif /* OPENSSL_HAS_ECC */ + +void +key_private_serialize(const Key *key, Buffer *b) +{ + buffer_put_cstring(b, key_ssh_name(key)); + switch (key->type) { + case KEY_RSA: + buffer_put_bignum2(b, key->rsa->n); + buffer_put_bignum2(b, key->rsa->e); + buffer_put_bignum2(b, key->rsa->d); + buffer_put_bignum2(b, key->rsa->iqmp); + buffer_put_bignum2(b, key->rsa->p); + buffer_put_bignum2(b, key->rsa->q); + break; + case KEY_RSA_CERT_V00: + case KEY_RSA_CERT: + if (key->cert == NULL || buffer_len(&key->cert->certblob) == 0) + fatal("%s: no cert/certblob", __func__); + buffer_put_string(b, buffer_ptr(&key->cert->certblob), + buffer_len(&key->cert->certblob)); + buffer_put_bignum2(b, key->rsa->d); + buffer_put_bignum2(b, key->rsa->iqmp); + buffer_put_bignum2(b, key->rsa->p); + buffer_put_bignum2(b, key->rsa->q); + break; + case KEY_DSA: + buffer_put_bignum2(b, key->dsa->p); + buffer_put_bignum2(b, key->dsa->q); + buffer_put_bignum2(b, key->dsa->g); + buffer_put_bignum2(b, key->dsa->pub_key); + buffer_put_bignum2(b, key->dsa->priv_key); + break; + case KEY_DSA_CERT_V00: + case KEY_DSA_CERT: + if (key->cert == NULL || buffer_len(&key->cert->certblob) == 0) + fatal("%s: no cert/certblob", __func__); + buffer_put_string(b, buffer_ptr(&key->cert->certblob), + buffer_len(&key->cert->certblob)); + buffer_put_bignum2(b, key->dsa->priv_key); + break; +#ifdef OPENSSL_HAS_ECC + case KEY_ECDSA: + buffer_put_cstring(b, key_curve_nid_to_name(key->ecdsa_nid)); + buffer_put_ecpoint(b, EC_KEY_get0_group(key->ecdsa), + EC_KEY_get0_public_key(key->ecdsa)); + buffer_put_bignum2(b, EC_KEY_get0_private_key(key->ecdsa)); + break; + case KEY_ECDSA_CERT: + if (key->cert == NULL || buffer_len(&key->cert->certblob) == 0) + fatal("%s: no cert/certblob", __func__); + buffer_put_string(b, buffer_ptr(&key->cert->certblob), + buffer_len(&key->cert->certblob)); + buffer_put_bignum2(b, EC_KEY_get0_private_key(key->ecdsa)); + break; +#endif /* OPENSSL_HAS_ECC */ + case KEY_ED25519: + buffer_put_string(b, key->ed25519_pk, ED25519_PK_SZ); + buffer_put_string(b, key->ed25519_sk, ED25519_SK_SZ); + break; + case KEY_ED25519_CERT: + if (key->cert == NULL || buffer_len(&key->cert->certblob) == 0) + fatal("%s: no cert/certblob", __func__); + buffer_put_string(b, buffer_ptr(&key->cert->certblob), + buffer_len(&key->cert->certblob)); + buffer_put_string(b, key->ed25519_pk, ED25519_PK_SZ); + buffer_put_string(b, key->ed25519_sk, ED25519_SK_SZ); + break; + } +} + +Key * +key_private_deserialize(Buffer *blob) +{ + char *type_name; + Key *k = NULL; + u_char *cert; + u_int len, pklen, sklen; + int type; +#ifdef OPENSSL_HAS_ECC + char *curve; + BIGNUM *exponent; + EC_POINT *q; +#endif + + type_name = buffer_get_string(blob, NULL); + type = key_type_from_name(type_name); + switch (type) { + case KEY_DSA: + k = key_new_private(type); + buffer_get_bignum2(blob, k->dsa->p); + buffer_get_bignum2(blob, k->dsa->q); + buffer_get_bignum2(blob, k->dsa->g); + buffer_get_bignum2(blob, k->dsa->pub_key); + buffer_get_bignum2(blob, k->dsa->priv_key); + break; + case KEY_DSA_CERT_V00: + case KEY_DSA_CERT: + cert = buffer_get_string(blob, &len); + if ((k = key_from_blob(cert, len)) == NULL) + fatal("Certificate parse failed"); + free(cert); + key_add_private(k); + buffer_get_bignum2(blob, k->dsa->priv_key); + break; +#ifdef OPENSSL_HAS_ECC + case KEY_ECDSA: + k = key_new_private(type); + k->ecdsa_nid = key_ecdsa_nid_from_name(type_name); + curve = buffer_get_string(blob, NULL); + if (k->ecdsa_nid != key_curve_name_to_nid(curve)) + fatal("%s: curve names mismatch", __func__); + free(curve); + k->ecdsa = EC_KEY_new_by_curve_name(k->ecdsa_nid); + if (k->ecdsa == NULL) + fatal("%s: EC_KEY_new_by_curve_name failed", + __func__); + q = EC_POINT_new(EC_KEY_get0_group(k->ecdsa)); + if (q == NULL) + fatal("%s: BN_new failed", __func__); + if ((exponent = BN_new()) == NULL) + fatal("%s: BN_new failed", __func__); + buffer_get_ecpoint(blob, + EC_KEY_get0_group(k->ecdsa), q); + buffer_get_bignum2(blob, exponent); + if (EC_KEY_set_public_key(k->ecdsa, q) != 1) + fatal("%s: EC_KEY_set_public_key failed", + __func__); + if (EC_KEY_set_private_key(k->ecdsa, exponent) != 1) + fatal("%s: EC_KEY_set_private_key failed", + __func__); + if (key_ec_validate_public(EC_KEY_get0_group(k->ecdsa), + EC_KEY_get0_public_key(k->ecdsa)) != 0) + fatal("%s: bad ECDSA public key", __func__); + if (key_ec_validate_private(k->ecdsa) != 0) + fatal("%s: bad ECDSA private key", __func__); + BN_clear_free(exponent); + EC_POINT_free(q); + break; + case KEY_ECDSA_CERT: + cert = buffer_get_string(blob, &len); + if ((k = key_from_blob(cert, len)) == NULL) + fatal("Certificate parse failed"); + free(cert); + key_add_private(k); + if ((exponent = BN_new()) == NULL) + fatal("%s: BN_new failed", __func__); + buffer_get_bignum2(blob, exponent); + if (EC_KEY_set_private_key(k->ecdsa, exponent) != 1) + fatal("%s: EC_KEY_set_private_key failed", + __func__); + if (key_ec_validate_public(EC_KEY_get0_group(k->ecdsa), + EC_KEY_get0_public_key(k->ecdsa)) != 0 || + key_ec_validate_private(k->ecdsa) != 0) + fatal("%s: bad ECDSA key", __func__); + BN_clear_free(exponent); + break; +#endif + case KEY_RSA: + k = key_new_private(type); + buffer_get_bignum2(blob, k->rsa->n); + buffer_get_bignum2(blob, k->rsa->e); + buffer_get_bignum2(blob, k->rsa->d); + buffer_get_bignum2(blob, k->rsa->iqmp); + buffer_get_bignum2(blob, k->rsa->p); + buffer_get_bignum2(blob, k->rsa->q); + + /* Generate additional parameters */ + rsa_generate_additional_parameters(k->rsa); + break; + case KEY_RSA_CERT_V00: + case KEY_RSA_CERT: + cert = buffer_get_string(blob, &len); + if ((k = key_from_blob(cert, len)) == NULL) + fatal("Certificate parse failed"); + free(cert); + key_add_private(k); + buffer_get_bignum2(blob, k->rsa->d); + buffer_get_bignum2(blob, k->rsa->iqmp); + buffer_get_bignum2(blob, k->rsa->p); + buffer_get_bignum2(blob, k->rsa->q); + break; + case KEY_ED25519: + k = key_new_private(type); + k->ed25519_pk = buffer_get_string(blob, &pklen); + k->ed25519_sk = buffer_get_string(blob, &sklen); + if (pklen != ED25519_PK_SZ) + fatal("%s: ed25519 pklen %d != %d", + __func__, pklen, ED25519_PK_SZ); + if (sklen != ED25519_SK_SZ) + fatal("%s: ed25519 sklen %d != %d", + __func__, sklen, ED25519_SK_SZ); + break; + case KEY_ED25519_CERT: + cert = buffer_get_string(blob, &len); + if ((k = key_from_blob(cert, len)) == NULL) + fatal("Certificate parse failed"); + free(cert); + key_add_private(k); + k->ed25519_pk = buffer_get_string(blob, &pklen); + k->ed25519_sk = buffer_get_string(blob, &sklen); + if (pklen != ED25519_PK_SZ) + fatal("%s: ed25519 pklen %d != %d", + __func__, pklen, ED25519_PK_SZ); + if (sklen != ED25519_SK_SZ) + fatal("%s: ed25519 sklen %d != %d", + __func__, sklen, ED25519_SK_SZ); + break; + default: + free(type_name); + buffer_clear(blob); + return NULL; + } + free(type_name); + + /* enable blinding */ + switch (k->type) { + case KEY_RSA: + case KEY_RSA_CERT_V00: + case KEY_RSA_CERT: + case KEY_RSA1: + if (RSA_blinding_on(k->rsa, NULL) != 1) { + error("%s: RSA_blinding_on failed", __func__); + key_free(k); + return NULL; + } + break; + } + return k; +} diff --git a/key.h b/key.h index 17358ae1f082..d8ad13d080b8 100644 --- a/key.h +++ b/key.h @@ -1,4 +1,4 @@ -/* $OpenBSD: key.h,v 1.37 2013/05/19 02:42:42 djm Exp $ */ +/* $OpenBSD: key.h,v 1.41 2014/01/09 23:20:00 djm Exp $ */ /* * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. @@ -39,9 +39,11 @@ enum types { KEY_RSA, KEY_DSA, KEY_ECDSA, + KEY_ED25519, KEY_RSA_CERT, KEY_DSA_CERT, KEY_ECDSA_CERT, + KEY_ED25519_CERT, KEY_RSA_CERT_V00, KEY_DSA_CERT_V00, KEY_UNSPEC @@ -86,8 +88,13 @@ struct Key { void *ecdsa; #endif struct KeyCert *cert; + u_char *ed25519_sk; + u_char *ed25519_pk; }; +#define ED25519_SK_SZ crypto_sign_ed25519_SECRETKEYBYTES +#define ED25519_PK_SZ crypto_sign_ed25519_PUBLICKEYBYTES + Key *key_new(int); void key_add_private(Key *); Key *key_new_private(int); @@ -107,6 +114,7 @@ Key *key_generate(int, u_int); Key *key_from_private(const Key *); int key_type_from_name(char *); int key_is_cert(const Key *); +int key_type_is_cert(int); int key_type_plain(int); int key_to_certified(Key *, int); int key_drop_cert(Key *); @@ -123,11 +131,11 @@ u_int key_curve_nid_to_bits(int); int key_ecdsa_bits_to_nid(int); #ifdef OPENSSL_HAS_ECC int key_ecdsa_key_to_nid(EC_KEY *); -const EVP_MD *key_ec_nid_to_evpmd(int nid); +int key_ec_nid_to_hash_alg(int nid); int key_ec_validate_public(const EC_GROUP *, const EC_POINT *); int key_ec_validate_private(const EC_KEY *); #endif -char *key_alg_list(void); +char *key_alg_list(int, int); Key *key_from_blob(const u_char *, u_int); int key_to_blob(const Key *, u_char **, u_int *); @@ -144,10 +152,15 @@ int ssh_ecdsa_sign(const Key *, u_char **, u_int *, const u_char *, u_int); int ssh_ecdsa_verify(const Key *, const u_char *, u_int, const u_char *, u_int); int ssh_rsa_sign(const Key *, u_char **, u_int *, const u_char *, u_int); int ssh_rsa_verify(const Key *, const u_char *, u_int, const u_char *, u_int); +int ssh_ed25519_sign(const Key *, u_char **, u_int *, const u_char *, u_int); +int ssh_ed25519_verify(const Key *, const u_char *, u_int, const u_char *, u_int); #if defined(OPENSSL_HAS_ECC) && (defined(DEBUG_KEXECDH) || defined(DEBUG_PK)) void key_dump_ec_point(const EC_GROUP *, const EC_POINT *); void key_dump_ec_key(const EC_KEY *); #endif +void key_private_serialize(const Key *, Buffer *); +Key *key_private_deserialize(Buffer *); + #endif diff --git a/loginrec.c b/loginrec.c index 59e8a44eeeeb..4219b9aef3de 100644 --- a/loginrec.c +++ b/loginrec.c @@ -310,9 +310,13 @@ login_get_lastlog(struct logininfo *li, const uid_t uid) fatal("%s: Cannot find account for uid %ld", __func__, (long)uid); - /* No MIN_SIZEOF here - we absolutely *must not* truncate the - * username (XXX - so check for trunc!) */ - strlcpy(li->username, pw->pw_name, sizeof(li->username)); + if (strlcpy(li->username, pw->pw_name, sizeof(li->username)) >= + sizeof(li->username)) { + error("%s: username too long (%lu > max %lu)", __func__, + (unsigned long)strlen(pw->pw_name), + (unsigned long)sizeof(li->username) - 1); + return NULL; + } if (getlast_entry(li)) return (li); @@ -320,7 +324,6 @@ login_get_lastlog(struct logininfo *li, const uid_t uid) return (NULL); } - /* * login_alloc_entry(int, char*, char*, char*) - Allocate and initialise * a logininfo structure diff --git a/mac.c b/mac.c index c4dfb501dd4d..d3a0b935f4fa 100644 --- a/mac.c +++ b/mac.c @@ -1,4 +1,4 @@ -/* $OpenBSD: mac.c,v 1.24 2013/06/03 00:03:18 dtucker Exp $ */ +/* $OpenBSD: mac.c,v 1.26 2014/01/04 17:50:55 tedu Exp $ */ /* * Copyright (c) 2001 Markus Friedl. All rights reserved. * @@ -91,9 +91,9 @@ static const struct macalg macs[] = { { NULL, 0, NULL, 0, 0, 0, 0 } }; -/* Returns a comma-separated list of supported MACs. */ +/* Returns a list of supported MACs separated by the specified char. */ char * -mac_alg_list(void) +mac_alg_list(char sep) { char *ret = NULL; size_t nlen, rlen = 0; @@ -101,7 +101,7 @@ mac_alg_list(void) for (m = macs; m->name != NULL; m++) { if (ret != NULL) - ret[rlen++] = '\n'; + ret[rlen++] = sep; nlen = strlen(m->name); ret = xrealloc(ret, 1, rlen + nlen + 2); memcpy(ret + rlen, m->name, nlen + 1); @@ -181,8 +181,8 @@ mac_compute(Mac *mac, u_int32_t seqno, u_char *data, int datalen) u_char b[4], nonce[8]; if (mac->mac_len > sizeof(u)) - fatal("mac_compute: mac too long %u %lu", - mac->mac_len, (u_long)sizeof(u)); + fatal("mac_compute: mac too long %u %zu", + mac->mac_len, sizeof(u)); switch (mac->type) { case SSH_EVP: diff --git a/mac.h b/mac.h index 260798ab3b05..fbe18c463bbc 100644 --- a/mac.h +++ b/mac.h @@ -1,4 +1,4 @@ -/* $OpenBSD: mac.h,v 1.7 2013/04/19 01:06:50 djm Exp $ */ +/* $OpenBSD: mac.h,v 1.8 2013/11/07 11:58:27 dtucker Exp $ */ /* * Copyright (c) 2001 Markus Friedl. All rights reserved. * @@ -24,7 +24,7 @@ */ int mac_valid(const char *); -char *mac_alg_list(void); +char *mac_alg_list(char); int mac_setup(Mac *, char *); int mac_init(Mac *); u_char *mac_compute(Mac *, u_int32_t, u_char *, int); diff --git a/match.c b/match.c index 7be7d2c5cd2e..c35e32896353 100644 --- a/match.c +++ b/match.c @@ -1,4 +1,4 @@ -/* $OpenBSD: match.c,v 1.28 2013/05/17 00:13:13 djm Exp $ */ +/* $OpenBSD: match.c,v 1.29 2013/11/20 20:54:10 deraadt Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -141,8 +141,8 @@ match_pattern_list(const char *string, const char *pattern, u_int len, for (subi = 0; i < len && subi < sizeof(sub) - 1 && pattern[i] != ','; subi++, i++) - sub[subi] = dolower && isupper(pattern[i]) ? - (char)tolower(pattern[i]) : pattern[i]; + sub[subi] = dolower && isupper((u_char)pattern[i]) ? + tolower((u_char)pattern[i]) : pattern[i]; /* If subpattern too long, return failure (no match). */ if (subi >= sizeof(sub) - 1) return 0; diff --git a/misc.c b/misc.c index c3c8099434a0..e4c8c3238074 100644 --- a/misc.c +++ b/misc.c @@ -1,4 +1,4 @@ -/* $OpenBSD: misc.c,v 1.91 2013/07/12 00:43:50 djm Exp $ */ +/* $OpenBSD: misc.c,v 1.92 2013/10/14 23:28:23 djm Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. * Copyright (c) 2005,2006 Damien Miller. All rights reserved. @@ -43,6 +43,7 @@ #include #include +#include #include #include #include @@ -1017,6 +1018,13 @@ iptos2str(int iptos) snprintf(iptos_str, sizeof iptos_str, "0x%02x", iptos); return iptos_str; } + +void +lowercase(char *s) +{ + for (; *s; s++) + *s = tolower((u_char)*s); +} void sock_set_v6only(int s) { diff --git a/misc.h b/misc.h index fceb30655635..d4df619cd042 100644 --- a/misc.h +++ b/misc.h @@ -1,4 +1,4 @@ -/* $OpenBSD: misc.h,v 1.49 2013/06/01 13:15:52 dtucker Exp $ */ +/* $OpenBSD: misc.h,v 1.50 2013/10/14 23:28:23 djm Exp $ */ /* * Author: Tatu Ylonen @@ -36,6 +36,8 @@ void sanitise_stdfd(void); void ms_subtract_diff(struct timeval *, int *); void ms_to_timeval(struct timeval *, int); time_t monotime(void); +void lowercase(char *s); + void sock_set_v6only(int); struct passwd *pwcopy(struct passwd *); diff --git a/moduli.c b/moduli.c index 294ff8fde0fa..bb4dd7beb49d 100644 --- a/moduli.c +++ b/moduli.c @@ -1,4 +1,4 @@ -/* $OpenBSD: moduli.c,v 1.27 2013/05/17 00:13:13 djm Exp $ */ +/* $OpenBSD: moduli.c,v 1.28 2013/10/24 00:49:49 dtucker Exp $ */ /* * Copyright 1994 Phil Karn * Copyright 1996-1998, 2003 William Allen Simpson @@ -56,6 +56,7 @@ #include "xmalloc.h" #include "dh.h" #include "log.h" +#include "misc.h" #include "openbsd-compat/openssl-compat.h" @@ -488,6 +489,79 @@ read_checkpoint(char *cpfile) return lineno; } +static unsigned long +count_lines(FILE *f) +{ + unsigned long count = 0; + char lp[QLINESIZE + 1]; + + if (fseek(f, 0, SEEK_SET) != 0) { + debug("input file is not seekable"); + return ULONG_MAX; + } + while (fgets(lp, QLINESIZE + 1, f) != NULL) + count++; + rewind(f); + debug("input file has %lu lines", count); + return count; +} + +static char * +fmt_time(time_t seconds) +{ + int day, hr, min; + static char buf[128]; + + min = (seconds / 60) % 60; + hr = (seconds / 60 / 60) % 24; + day = seconds / 60 / 60 / 24; + if (day > 0) + snprintf(buf, sizeof buf, "%dd %d:%02d", day, hr, min); + else + snprintf(buf, sizeof buf, "%d:%02d", hr, min); + return buf; +} + +static void +print_progress(unsigned long start_lineno, unsigned long current_lineno, + unsigned long end_lineno) +{ + static time_t time_start, time_prev; + time_t time_now, elapsed; + unsigned long num_to_process, processed, remaining, percent, eta; + double time_per_line; + char *eta_str; + + time_now = monotime(); + if (time_start == 0) { + time_start = time_prev = time_now; + return; + } + /* print progress after 1m then once per 5m */ + if (time_now - time_prev < 5 * 60) + return; + time_prev = time_now; + elapsed = time_now - time_start; + processed = current_lineno - start_lineno; + remaining = end_lineno - current_lineno; + num_to_process = end_lineno - start_lineno; + time_per_line = (double)elapsed / processed; + /* if we don't know how many we're processing just report count+time */ + time(&time_now); + if (end_lineno == ULONG_MAX) { + logit("%.24s processed %lu in %s", ctime(&time_now), + processed, fmt_time(elapsed)); + return; + } + percent = 100 * processed / num_to_process; + eta = time_per_line * remaining; + eta_str = xstrdup(fmt_time(eta)); + logit("%.24s processed %lu of %lu (%lu%%) in %s, ETA %s", + ctime(&time_now), processed, num_to_process, percent, + fmt_time(elapsed), eta_str); + free(eta_str); +} + /* * perform a Miller-Rabin primality test * on the list of candidates @@ -512,6 +586,11 @@ prime_test(FILE *in, FILE *out, u_int32_t trials, u_int32_t generator_wanted, return (-1); } + if (num_lines == 0) + end_lineno = count_lines(in); + else + end_lineno = start_lineno + num_lines; + time(&time_start); if ((p = BN_new()) == NULL) @@ -526,26 +605,25 @@ prime_test(FILE *in, FILE *out, u_int32_t trials, u_int32_t generator_wanted, if (checkpoint_file != NULL) last_processed = read_checkpoint(checkpoint_file); - if (start_lineno > last_processed) - last_processed = start_lineno; - if (num_lines == 0) - end_lineno = ULONG_MAX; + last_processed = start_lineno = MAX(last_processed, start_lineno); + if (end_lineno == ULONG_MAX) + debug("process from line %lu from pipe", last_processed); else - end_lineno = last_processed + num_lines; - debug2("process line %lu to line %lu", last_processed, end_lineno); + debug("process from line %lu to line %lu", last_processed, + end_lineno); res = 0; lp = xmalloc(QLINESIZE + 1); while (fgets(lp, QLINESIZE + 1, in) != NULL && count_in < end_lineno) { count_in++; - if (checkpoint_file != NULL) { - if (count_in <= last_processed) { - debug3("skipping line %u, before checkpoint", - count_in); - continue; - } - write_checkpoint(checkpoint_file, count_in); + if (count_in <= last_processed) { + debug3("skipping line %u, before checkpoint or " + "specified start line", count_in); + continue; } + if (checkpoint_file != NULL) + write_checkpoint(checkpoint_file, count_in); + print_progress(start_lineno, count_in, end_lineno); if (strlen(lp) < 14 || *lp == '!' || *lp == '#') { debug2("%10u: comment or short line", count_in); continue; diff --git a/monitor.c b/monitor.c index 44dff98c93c0..03baf1ea9c95 100644 --- a/monitor.c +++ b/monitor.c @@ -1,4 +1,4 @@ -/* $OpenBSD: monitor.c,v 1.127 2013/07/19 07:37:48 markus Exp $ */ +/* $OpenBSD: monitor.c,v 1.128 2013/11/04 11:51:16 markus Exp $ */ /* * Copyright 2002 Niels Provos * Copyright 2002 Markus Friedl @@ -1855,6 +1855,7 @@ mm_get_kex(Buffer *m) kex->kex[KEX_DH_GEX_SHA1] = kexgex_server; kex->kex[KEX_DH_GEX_SHA256] = kexgex_server; kex->kex[KEX_ECDH_SHA2] = kexecdh_server; + kex->kex[KEX_C25519_SHA256] = kexc25519_server; kex->server = 1; kex->hostkey_type = buffer_get_int(m); kex->kex_type = buffer_get_int(m); diff --git a/monitor_mm.c b/monitor_mm.c index d3e6aeee539b..0ba0658a14a5 100644 --- a/monitor_mm.c +++ b/monitor_mm.c @@ -1,4 +1,4 @@ -/* $OpenBSD: monitor_mm.c,v 1.18 2013/11/08 00:39:15 djm Exp $ */ +/* $OpenBSD: monitor_mm.c,v 1.19 2014/01/04 17:50:55 tedu Exp $ */ /* * Copyright 2002 Niels Provos * All rights reserved. @@ -35,6 +35,7 @@ #include #include +#include #include #include @@ -46,7 +47,7 @@ static int mm_compare(struct mm_share *a, struct mm_share *b) { - long diff = (char *)a->address - (char *)b->address; + ptrdiff_t diff = (char *)a->address - (char *)b->address; if (diff == 0) return (0); @@ -73,8 +74,8 @@ mm_make_entry(struct mm_master *mm, struct mmtree *head, tmp2 = RB_INSERT(mmtree, head, tmp); if (tmp2 != NULL) - fatal("mm_make_entry(%p): double address %p->%p(%lu)", - mm, tmp2, address, (u_long)size); + fatal("mm_make_entry(%p): double address %p->%p(%zu)", + mm, tmp2, address, size); return (tmp); } @@ -101,7 +102,7 @@ mm_create(struct mm_master *mmalloc, size_t size) address = xmmap(size); if (address == (void *)MAP_FAILED) - fatal("mmap(%lu): %s", (u_long)size, strerror(errno)); + fatal("mmap(%zu): %s", size, strerror(errno)); mm->address = address; mm->size = size; @@ -141,7 +142,7 @@ mm_destroy(struct mm_master *mm) #ifdef HAVE_MMAP if (munmap(mm->address, mm->size) == -1) - fatal("munmap(%p, %lu): %s", mm->address, (u_long)mm->size, + fatal("munmap(%p, %zu): %s", mm->address, mm->size, strerror(errno)); #else fatal("%s: UsePrivilegeSeparation=yes and Compression=yes not supported", @@ -160,7 +161,7 @@ mm_xmalloc(struct mm_master *mm, size_t size) address = mm_malloc(mm, size); if (address == NULL) - fatal("%s: mm_malloc(%lu)", __func__, (u_long)size); + fatal("%s: mm_malloc(%zu)", __func__, size); memset(address, 0, size); return (address); } @@ -195,7 +196,7 @@ mm_malloc(struct mm_master *mm, size_t size) /* Does not change order in RB tree */ mms->size -= size; - mms->address = (u_char *)mms->address + size; + mms->address = (char *)mms->address + size; if (mms->size == 0) { RB_REMOVE(mmtree, &mm->rb_free, mms); @@ -248,8 +249,8 @@ mm_free(struct mm_master *mm, void *address) /* Check if range does not overlap */ if (prev != NULL && MM_ADDRESS_END(prev) > address) - fatal("mm_free: memory corruption: %p(%lu) > %p", - prev->address, (u_long)prev->size, address); + fatal("mm_free: memory corruption: %p(%zu) > %p", + prev->address, prev->size, address); /* See if we can merge backwards */ if (prev != NULL && MM_ADDRESS_END(prev) == address) { @@ -271,8 +272,8 @@ mm_free(struct mm_master *mm, void *address) return; if (MM_ADDRESS_END(prev) > mms->address) - fatal("mm_free: memory corruption: %p < %p(%lu)", - mms->address, prev->address, (u_long)prev->size); + fatal("mm_free: memory corruption: %p < %p(%zu)", + mms->address, prev->address, prev->size); if (MM_ADDRESS_END(prev) != mms->address) return; @@ -343,12 +344,12 @@ mm_share_sync(struct mm_master **pmm, struct mm_master **pmmalloc) void mm_memvalid(struct mm_master *mm, void *address, size_t size) { - void *end = (u_char *)address + size; + void *end = (char *)address + size; if (address < mm->address) fatal("mm_memvalid: address too small: %p", address); if (end < address) fatal("mm_memvalid: end < address: %p < %p", end, address); - if (end > (void *)((u_char *)mm->address + mm->size)) + if (end > MM_ADDRESS_END(mm)) fatal("mm_memvalid: address too large: %p", address); } diff --git a/monitor_mm.h b/monitor_mm.h index c890f77097df..f1fae7e3bf53 100644 --- a/monitor_mm.h +++ b/monitor_mm.h @@ -1,4 +1,4 @@ -/* $OpenBSD: monitor_mm.h,v 1.5 2008/04/29 11:20:31 otto Exp $ */ +/* $OpenBSD: monitor_mm.h,v 1.6 2014/01/04 17:50:55 tedu Exp $ */ /* * Copyright 2002 Niels Provos @@ -47,7 +47,7 @@ RB_PROTOTYPE(mmtree, mm_share, next, mm_compare) #define MM_MINSIZE 128 -#define MM_ADDRESS_END(x) (void *)((u_char *)(x)->address + (x)->size) +#define MM_ADDRESS_END(x) (void *)((char *)(x)->address + (x)->size) struct mm_master *mm_create(struct mm_master *, size_t); void mm_destroy(struct mm_master *); diff --git a/myproposal.h b/myproposal.h index 4e913e3cedb7..3a0f5aeabd6a 100644 --- a/myproposal.h +++ b/myproposal.h @@ -1,4 +1,4 @@ -/* $OpenBSD: myproposal.h,v 1.32 2013/01/08 18:49:04 markus Exp $ */ +/* $OpenBSD: myproposal.h,v 1.35 2013/12/06 13:39:49 markus Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. @@ -29,6 +29,7 @@ /* conditional algorithm support */ #ifdef OPENSSL_HAS_ECC +#ifdef OPENSSL_HAS_NISTP521 # define KEX_ECDH_METHODS \ "ecdh-sha2-nistp256," \ "ecdh-sha2-nistp384," \ @@ -42,6 +43,17 @@ "ecdsa-sha2-nistp384," \ "ecdsa-sha2-nistp521," #else +# define KEX_ECDH_METHODS \ + "ecdh-sha2-nistp256," \ + "ecdh-sha2-nistp384," +# define HOSTKEY_ECDSA_CERT_METHODS \ + "ecdsa-sha2-nistp256-cert-v01@openssh.com," \ + "ecdsa-sha2-nistp384-cert-v01@openssh.com," +# define HOSTKEY_ECDSA_METHODS \ + "ecdsa-sha2-nistp256," \ + "ecdsa-sha2-nistp384," +#endif +#else # define KEX_ECDH_METHODS # define HOSTKEY_ECDSA_CERT_METHODS # define HOSTKEY_ECDSA_METHODS @@ -57,15 +69,19 @@ #ifdef HAVE_EVP_SHA256 # define KEX_SHA256_METHODS \ "diffie-hellman-group-exchange-sha256," +#define KEX_CURVE25519_METHODS \ + "curve25519-sha256@libssh.org," #define SHA2_HMAC_MODES \ "hmac-sha2-256," \ "hmac-sha2-512," #else # define KEX_SHA256_METHODS +# define KEX_CURVE25519_METHODS # define SHA2_HMAC_MODES #endif # define KEX_DEFAULT_KEX \ + KEX_CURVE25519_METHODS \ KEX_ECDH_METHODS \ KEX_SHA256_METHODS \ "diffie-hellman-group-exchange-sha1," \ @@ -74,11 +90,13 @@ #define KEX_DEFAULT_PK_ALG \ HOSTKEY_ECDSA_CERT_METHODS \ + "ssh-ed25519-cert-v01@openssh.com," \ "ssh-rsa-cert-v01@openssh.com," \ "ssh-dss-cert-v01@openssh.com," \ "ssh-rsa-cert-v00@openssh.com," \ "ssh-dss-cert-v00@openssh.com," \ HOSTKEY_ECDSA_METHODS \ + "ssh-ed25519," \ "ssh-rsa," \ "ssh-dss" @@ -88,6 +106,7 @@ "aes128-ctr,aes192-ctr,aes256-ctr," \ "arcfour256,arcfour128," \ AESGCM_CIPHER_MODES \ + "chacha20-poly1305@openssh.com," \ "aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc," \ "aes192-cbc,aes256-cbc,arcfour,rijndael-cbc@lysator.liu.se" diff --git a/openbsd-compat/Makefile.in b/openbsd-compat/Makefile.in index 365cf006d27a..276646fa6366 100644 --- a/openbsd-compat/Makefile.in +++ b/openbsd-compat/Makefile.in @@ -1,4 +1,4 @@ -# $Id: Makefile.in,v 1.51 2013/05/10 06:28:56 dtucker Exp $ +# $Id: Makefile.in,v 1.54 2013/12/07 01:37:54 djm Exp $ sysconfdir=@sysconfdir@ piddir=@piddir@ @@ -16,9 +16,9 @@ RANLIB=@RANLIB@ INSTALL=@INSTALL@ LDFLAGS=-L. @LDFLAGS@ -OPENBSD=base64.o basename.o bindresvport.o daemon.o dirname.o fmt_scaled.o getcwd.o getgrouplist.o getopt_long.o getrrsetbyname.o glob.o inet_aton.o inet_ntoa.o inet_ntop.o mktemp.o pwcache.o readpassphrase.o realpath.o rresvport.o setenv.o setproctitle.o sha2.o sigact.o strlcat.o strlcpy.o strmode.o strnlen.o strptime.o strsep.o strtonum.o strtoll.o strtoul.o strtoull.o timingsafe_bcmp.o vis.o +OPENBSD=base64.o basename.o bcrypt_pbkdf.o bindresvport.o blowfish.o daemon.o dirname.o fmt_scaled.o getcwd.o getgrouplist.o getopt_long.o getrrsetbyname.o glob.o inet_aton.o inet_ntoa.o inet_ntop.o mktemp.o pwcache.o readpassphrase.o realpath.o rresvport.o setenv.o setproctitle.o sha2.o sigact.o strlcat.o strlcpy.o strmode.o strnlen.o strptime.o strsep.o strtonum.o strtoll.o strtoul.o strtoull.o timingsafe_bcmp.o vis.o blowfish.o bcrypt_pbkdf.o -COMPAT=bsd-arc4random.o bsd-asprintf.o bsd-closefrom.o bsd-cray.o bsd-cygwin_util.o bsd-getpeereid.o getrrsetbyname-ldns.o bsd-misc.o bsd-nextstep.o bsd-openpty.o bsd-poll.o bsd-setres_id.o bsd-snprintf.o bsd-statvfs.o bsd-waitpid.o fake-rfc2553.o openssl-compat.o xmmap.o xcrypt.o +COMPAT=arc4random.o bsd-asprintf.o bsd-closefrom.o bsd-cray.o bsd-cygwin_util.o bsd-getpeereid.o getrrsetbyname-ldns.o bsd-misc.o bsd-nextstep.o bsd-openpty.o bsd-poll.o bsd-setres_id.o bsd-snprintf.o bsd-statvfs.o bsd-waitpid.o fake-rfc2553.o openssl-compat.o xmmap.o xcrypt.o PORTS=port-aix.o port-irix.o port-linux.o port-solaris.o port-tun.o port-uw.o diff --git a/openbsd-compat/arc4random.c b/openbsd-compat/arc4random.c new file mode 100644 index 000000000000..eac073cc01b7 --- /dev/null +++ b/openbsd-compat/arc4random.c @@ -0,0 +1,294 @@ +/* OPENBSD ORIGINAL: lib/libc/crypto/arc4random.c */ + +/* $OpenBSD: arc4random.c,v 1.25 2013/10/01 18:34:57 markus Exp $ */ + +/* + * Copyright (c) 1996, David Mazieres + * Copyright (c) 2008, Damien Miller + * Copyright (c) 2013, Markus Friedl + * + * 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. + */ + +/* + * ChaCha based random number generator for OpenBSD. + */ + +#include "includes.h" + +#include +#include +#include +#include + +#ifndef HAVE_ARC4RANDOM + +#include +#include + +#include "log.h" + +#define KEYSTREAM_ONLY +#include "chacha_private.h" + +#ifdef __GNUC__ +#define inline __inline +#else /* !__GNUC__ */ +#define inline +#endif /* !__GNUC__ */ + +/* OpenSSH isn't multithreaded */ +#define _ARC4_LOCK() +#define _ARC4_UNLOCK() + +#define KEYSZ 32 +#define IVSZ 8 +#define BLOCKSZ 64 +#define RSBUFSZ (16*BLOCKSZ) +static int rs_initialized; +static pid_t rs_stir_pid; +static chacha_ctx rs; /* chacha context for random keystream */ +static u_char rs_buf[RSBUFSZ]; /* keystream blocks */ +static size_t rs_have; /* valid bytes at end of rs_buf */ +static size_t rs_count; /* bytes till reseed */ + +static inline void _rs_rekey(u_char *dat, size_t datlen); + +static inline void +_rs_init(u_char *buf, size_t n) +{ + if (n < KEYSZ + IVSZ) + return; + chacha_keysetup(&rs, buf, KEYSZ * 8, 0); + chacha_ivsetup(&rs, buf + KEYSZ); +} + +static void +_rs_stir(void) +{ + u_char rnd[KEYSZ + IVSZ]; + + if (RAND_bytes(rnd, sizeof(rnd)) <= 0) + fatal("Couldn't obtain random bytes (error %ld)", + ERR_get_error()); + + if (!rs_initialized) { + rs_initialized = 1; + _rs_init(rnd, sizeof(rnd)); + } else + _rs_rekey(rnd, sizeof(rnd)); + memset(rnd, 0, sizeof(rnd)); + + /* invalidate rs_buf */ + rs_have = 0; + memset(rs_buf, 0, RSBUFSZ); + + rs_count = 1600000; +} + +static inline void +_rs_stir_if_needed(size_t len) +{ + pid_t pid = getpid(); + + if (rs_count <= len || !rs_initialized || rs_stir_pid != pid) { + rs_stir_pid = pid; + _rs_stir(); + } else + rs_count -= len; +} + +static inline void +_rs_rekey(u_char *dat, size_t datlen) +{ +#ifndef KEYSTREAM_ONLY + memset(rs_buf, 0,RSBUFSZ); +#endif + /* fill rs_buf with the keystream */ + chacha_encrypt_bytes(&rs, rs_buf, rs_buf, RSBUFSZ); + /* mix in optional user provided data */ + if (dat) { + size_t i, m; + + m = MIN(datlen, KEYSZ + IVSZ); + for (i = 0; i < m; i++) + rs_buf[i] ^= dat[i]; + } + /* immediately reinit for backtracking resistance */ + _rs_init(rs_buf, KEYSZ + IVSZ); + memset(rs_buf, 0, KEYSZ + IVSZ); + rs_have = RSBUFSZ - KEYSZ - IVSZ; +} + +static inline void +_rs_random_buf(void *_buf, size_t n) +{ + u_char *buf = (u_char *)_buf; + size_t m; + + _rs_stir_if_needed(n); + while (n > 0) { + if (rs_have > 0) { + m = MIN(n, rs_have); + memcpy(buf, rs_buf + RSBUFSZ - rs_have, m); + memset(rs_buf + RSBUFSZ - rs_have, 0, m); + buf += m; + n -= m; + rs_have -= m; + } + if (rs_have == 0) + _rs_rekey(NULL, 0); + } +} + +static inline void +_rs_random_u32(u_int32_t *val) +{ + _rs_stir_if_needed(sizeof(*val)); + if (rs_have < sizeof(*val)) + _rs_rekey(NULL, 0); + memcpy(val, rs_buf + RSBUFSZ - rs_have, sizeof(*val)); + memset(rs_buf + RSBUFSZ - rs_have, 0, sizeof(*val)); + rs_have -= sizeof(*val); + return; +} + +void +arc4random_stir(void) +{ + _ARC4_LOCK(); + _rs_stir(); + _ARC4_UNLOCK(); +} + +void +arc4random_addrandom(u_char *dat, int datlen) +{ + int m; + + _ARC4_LOCK(); + if (!rs_initialized) + _rs_stir(); + while (datlen > 0) { + m = MIN(datlen, KEYSZ + IVSZ); + _rs_rekey(dat, m); + dat += m; + datlen -= m; + } + _ARC4_UNLOCK(); +} + +u_int32_t +arc4random(void) +{ + u_int32_t val; + + _ARC4_LOCK(); + _rs_random_u32(&val); + _ARC4_UNLOCK(); + return val; +} + +/* + * If we are providing arc4random, then we can provide a more efficient + * arc4random_buf(). + */ +# ifndef HAVE_ARC4RANDOM_BUF +void +arc4random_buf(void *buf, size_t n) +{ + _ARC4_LOCK(); + _rs_random_buf(buf, n); + _ARC4_UNLOCK(); +} +# endif /* !HAVE_ARC4RANDOM_BUF */ +#endif /* !HAVE_ARC4RANDOM */ + +/* arc4random_buf() that uses platform arc4random() */ +#if !defined(HAVE_ARC4RANDOM_BUF) && defined(HAVE_ARC4RANDOM) +void +arc4random_buf(void *_buf, size_t n) +{ + size_t i; + u_int32_t r = 0; + char *buf = (char *)_buf; + + for (i = 0; i < n; i++) { + if (i % 4 == 0) + r = arc4random(); + buf[i] = r & 0xff; + r >>= 8; + } + i = r = 0; +} +#endif /* !defined(HAVE_ARC4RANDOM_BUF) && defined(HAVE_ARC4RANDOM) */ + +#ifndef HAVE_ARC4RANDOM_UNIFORM +/* + * Calculate a uniformly distributed random number less than upper_bound + * avoiding "modulo bias". + * + * Uniformity is achieved by generating new random numbers until the one + * returned is outside the range [0, 2**32 % upper_bound). This + * guarantees the selected random number will be inside + * [2**32 % upper_bound, 2**32) which maps back to [0, upper_bound) + * after reduction modulo upper_bound. + */ +u_int32_t +arc4random_uniform(u_int32_t upper_bound) +{ + u_int32_t r, min; + + if (upper_bound < 2) + return 0; + + /* 2**32 % x == (2**32 - x) % x */ + min = -upper_bound % upper_bound; + + /* + * This could theoretically loop forever but each retry has + * p > 0.5 (worst case, usually far better) of selecting a + * number inside the range we need, so it should rarely need + * to re-roll. + */ + for (;;) { + r = arc4random(); + if (r >= min) + break; + } + + return r % upper_bound; +} +#endif /* !HAVE_ARC4RANDOM_UNIFORM */ + +#if 0 +/*-------- Test code for i386 --------*/ +#include +#include +int +main(int argc, char **argv) +{ + const int iter = 1000000; + int i; + pctrval v; + + v = rdtsc(); + for (i = 0; i < iter; i++) + arc4random(); + v = rdtsc() - v; + v /= iter; + + printf("%qd cycles\n", v); + exit(0); +} +#endif diff --git a/openbsd-compat/bcrypt_pbkdf.c b/openbsd-compat/bcrypt_pbkdf.c new file mode 100644 index 000000000000..91b6ba07be59 --- /dev/null +++ b/openbsd-compat/bcrypt_pbkdf.c @@ -0,0 +1,170 @@ +/* $OpenBSD: bcrypt_pbkdf.c,v 1.4 2013/07/29 00:55:53 tedu Exp $ */ +/* + * Copyright (c) 2013 Ted Unangst + * + * 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 +#include + +#ifdef HAVE_STDLIB_H +# include +#endif +#include + +#ifdef HAVE_BLF_H +# include +#endif + +#include "crypto_api.h" +#define SHA512_DIGEST_LENGTH crypto_hash_sha512_BYTES + +/* + * 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(u_int8_t *sha2pass, u_int8_t *sha2salt, u_int8_t *out) +{ + blf_ctx state; + u_int8_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 */ + memset(ciphertext, 0, sizeof(ciphertext)); + memset(cdata, 0, sizeof(cdata)); + memset(&state, 0, sizeof(state)); +} + +int +bcrypt_pbkdf(const char *pass, size_t passlen, const u_int8_t *salt, size_t saltlen, + u_int8_t *key, size_t keylen, unsigned int rounds) +{ + u_int8_t sha2pass[SHA512_DIGEST_LENGTH]; + u_int8_t sha2salt[SHA512_DIGEST_LENGTH]; + u_int8_t out[BCRYPT_HASHSIZE]; + u_int8_t tmpout[BCRYPT_HASHSIZE]; + u_int8_t *countsalt; + size_t i, j, amt, stride; + uint32_t count; + + /* 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 */ + crypto_hash_sha512(sha2pass, pass, passlen); + + /* 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 */ + crypto_hash_sha512(sha2salt, countsalt, saltlen + 4); + + bcrypt_hash(sha2pass, sha2salt, tmpout); + memcpy(out, tmpout, sizeof(out)); + + for (i = 1; i < rounds; i++) { + /* subsequent rounds, salt is previous output */ + crypto_hash_sha512(sha2salt, tmpout, sizeof(tmpout)); + 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++) + key[i * stride + (count - 1)] = out[i]; + keylen -= amt; + } + + /* zap */ + memset(out, 0, sizeof(out)); + memset(countsalt, 0, saltlen + 4); + free(countsalt); + + return 0; +} +#endif /* HAVE_BCRYPT_PBKDF */ diff --git a/openbsd-compat/blf.h b/openbsd-compat/blf.h new file mode 100644 index 000000000000..f1ac5a5c2b64 --- /dev/null +++ b/openbsd-compat/blf.h @@ -0,0 +1,88 @@ +/* $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 + * 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 { + u_int32_t S[4][256]; /* S-Boxes */ + u_int32_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 *, u_int32_t *, u_int32_t *); +void Blowfish_decipher(blf_ctx *, u_int32_t *, u_int32_t *); +void Blowfish_initstate(blf_ctx *); +void Blowfish_expand0state(blf_ctx *, const u_int8_t *, u_int16_t); +void Blowfish_expandstate +(blf_ctx *, const u_int8_t *, u_int16_t, const u_int8_t *, u_int16_t); + +/* Standard Blowfish */ + +void blf_key(blf_ctx *, const u_int8_t *, u_int16_t); +void blf_enc(blf_ctx *, u_int32_t *, u_int16_t); +void blf_dec(blf_ctx *, u_int32_t *, u_int16_t); + +void blf_ecb_encrypt(blf_ctx *, u_int8_t *, u_int32_t); +void blf_ecb_decrypt(blf_ctx *, u_int8_t *, u_int32_t); + +void blf_cbc_encrypt(blf_ctx *, u_int8_t *, u_int8_t *, u_int32_t); +void blf_cbc_decrypt(blf_ctx *, u_int8_t *, u_int8_t *, u_int32_t); + +/* Converts u_int8_t to u_int32_t */ +u_int32_t Blowfish_stream2word(const u_int8_t *, u_int16_t , u_int16_t *); + +#endif /* !defined(HAVE_BCRYPT_PBKDF) && !defined(HAVE_BLH_H) */ +#endif /* _BLF_H */ + diff --git a/openbsd-compat/blowfish.c b/openbsd-compat/blowfish.c new file mode 100644 index 000000000000..6c419549e72a --- /dev/null +++ b/openbsd-compat/blowfish.c @@ -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 + * All rights reserved. + * + * Implementation advice by David Mazieres . + * + * 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. + */ + +#include "includes.h" + +#if !defined(HAVE_BCRYPT_PBKDF) && (!defined(HAVE_BLOWFISH_INITSTATE) || \ + !defined(HAVE_BLOWFISH_EXPAND0STATE) || !defined(HAVE_BLF_ENC)) + +#if 0 +#include /* used for debugging */ +#include +#endif + +#include +#include + +#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, u_int32_t *xl, u_int32_t *xr) +{ + u_int32_t Xl; + u_int32_t Xr; + u_int32_t *s = c->S[0]; + u_int32_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, u_int32_t *xl, u_int32_t *xr) +{ + u_int32_t Xl; + u_int32_t Xr; + u_int32_t *s = c->S[0]; + u_int32_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; +} + +u_int32_t +Blowfish_stream2word(const u_int8_t *data, u_int16_t databytes, + u_int16_t *current) +{ + u_int8_t i; + u_int16_t j; + u_int32_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 u_int8_t *key, u_int16_t keybytes) +{ + u_int16_t i; + u_int16_t j; + u_int16_t k; + u_int32_t temp; + u_int32_t datal; + u_int32_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 u_int8_t *data, u_int16_t databytes, + const u_int8_t *key, u_int16_t keybytes) +{ + u_int16_t i; + u_int16_t j; + u_int16_t k; + u_int32_t temp; + u_int32_t datal; + u_int32_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 u_int8_t *k, u_int16_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, u_int32_t *data, u_int16_t blocks) +{ + u_int32_t *d; + u_int16_t i; + + d = data; + for (i = 0; i < blocks; i++) { + Blowfish_encipher(c, d, d + 1); + d += 2; + } +} + +void +blf_dec(blf_ctx *c, u_int32_t *data, u_int16_t blocks) +{ + u_int32_t *d; + u_int16_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, u_int8_t *data, u_int32_t len) +{ + u_int32_t l, r; + u_int32_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, u_int8_t *data, u_int32_t len) +{ + u_int32_t l, r; + u_int32_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, u_int8_t *iv, u_int8_t *data, u_int32_t len) +{ + u_int32_t l, r; + u_int32_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, u_int8_t *iva, u_int8_t *data, u_int32_t len) +{ + u_int32_t l, r; + u_int8_t *iv; + u_int32_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(u_int32_t data[], u_int16_t len) +{ + u_int16_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"; + + u_int32_t data[10]; + u_int32_t data2[] = + {0x424c4f57l, 0x46495348l}; + + u_int16_t i; + + /* First test */ + for (i = 0; i < 10; i++) + data[i] = i; + + blf_key(&c, (u_int8_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, (u_int8_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)) */ + diff --git a/openbsd-compat/bsd-arc4random.c b/openbsd-compat/bsd-arc4random.c deleted file mode 100644 index d7c5862534f4..000000000000 --- a/openbsd-compat/bsd-arc4random.c +++ /dev/null @@ -1,150 +0,0 @@ -/* - * Copyright (c) 1999,2000,2004 Damien Miller - * - * 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" - -#include - -#include -#include -#include - -#include "log.h" - -#ifndef HAVE_ARC4RANDOM - -#include -#include -#include - -/* Size of key to use */ -#define SEED_SIZE 20 - -/* Number of bytes to reseed after */ -#define REKEY_BYTES (1 << 24) - -static int rc4_ready = 0; -static RC4_KEY rc4; - -unsigned int -arc4random(void) -{ - unsigned int r = 0; - static int first_time = 1; - - if (rc4_ready <= 0) { - if (first_time) - seed_rng(); - first_time = 0; - arc4random_stir(); - } - - RC4(&rc4, sizeof(r), (unsigned char *)&r, (unsigned char *)&r); - - rc4_ready -= sizeof(r); - - return(r); -} - -void -arc4random_stir(void) -{ - unsigned char rand_buf[SEED_SIZE]; - int i; - - memset(&rc4, 0, sizeof(rc4)); - if (RAND_bytes(rand_buf, sizeof(rand_buf)) <= 0) - fatal("Couldn't obtain random bytes (error %ld)", - ERR_get_error()); - RC4_set_key(&rc4, sizeof(rand_buf), rand_buf); - - /* - * Discard early keystream, as per recommendations in: - * http://www.wisdom.weizmann.ac.il/~itsik/RC4/Papers/Rc4_ksa.ps - */ - for(i = 0; i <= 256; i += sizeof(rand_buf)) - RC4(&rc4, sizeof(rand_buf), rand_buf, rand_buf); - - memset(rand_buf, 0, sizeof(rand_buf)); - - rc4_ready = REKEY_BYTES; -} -#endif /* !HAVE_ARC4RANDOM */ - -#ifndef HAVE_ARC4RANDOM_BUF -void -arc4random_buf(void *_buf, size_t n) -{ - size_t i; - u_int32_t r = 0; - char *buf = (char *)_buf; - - for (i = 0; i < n; i++) { - if (i % 4 == 0) - r = arc4random(); - buf[i] = r & 0xff; - r >>= 8; - } - i = r = 0; -} -#endif /* !HAVE_ARC4RANDOM_BUF */ - -#ifndef HAVE_ARC4RANDOM_UNIFORM -/* - * Calculate a uniformly distributed random number less than upper_bound - * avoiding "modulo bias". - * - * Uniformity is achieved by generating new random numbers until the one - * returned is outside the range [0, 2**32 % upper_bound). This - * guarantees the selected random number will be inside - * [2**32 % upper_bound, 2**32) which maps back to [0, upper_bound) - * after reduction modulo upper_bound. - */ -u_int32_t -arc4random_uniform(u_int32_t upper_bound) -{ - u_int32_t r, min; - - if (upper_bound < 2) - return 0; - -#if (ULONG_MAX > 0xffffffffUL) - min = 0x100000000UL % upper_bound; -#else - /* Calculate (2**32 % upper_bound) avoiding 64-bit math */ - if (upper_bound > 0x80000000) - min = 1 + ~upper_bound; /* 2**32 - upper_bound */ - else { - /* (2**32 - (x * 2)) % x == 2**32 % x when x <= 2**31 */ - min = ((0xffffffff - (upper_bound * 2)) + 1) % upper_bound; - } -#endif - - /* - * This could theoretically loop forever but each retry has - * p > 0.5 (worst case, usually far better) of selecting a - * number inside the range we need, so it should rarely need - * to re-roll. - */ - for (;;) { - r = arc4random(); - if (r >= min) - break; - } - - return r % upper_bound; -} -#endif /* !HAVE_ARC4RANDOM_UNIFORM */ diff --git a/openbsd-compat/bsd-cygwin_util.h b/openbsd-compat/bsd-cygwin_util.h index 372e41955ee4..1177366f1b05 100644 --- a/openbsd-compat/bsd-cygwin_util.h +++ b/openbsd-compat/bsd-cygwin_util.h @@ -1,4 +1,4 @@ -/* $Id: bsd-cygwin_util.h,v 1.16 2013/04/01 01:40:49 dtucker Exp $ */ +/* $Id: bsd-cygwin_util.h,v 1.17 2014/01/18 10:04:00 dtucker Exp $ */ /* * Copyright (c) 2000, 2001, 2011, 2013 Corinna Vinschen @@ -40,9 +40,15 @@ typedef void *HANDLE; #define INVALID_HANDLE_VALUE ((HANDLE) -1) +/* Cygwin functions for which declarations are only available when including + windows headers, so we have to define them here explicitely. */ +extern HANDLE cygwin_logon_user (const struct passwd *, const char *); +extern void cygwin_set_impersonation_token (const HANDLE); + #include #include + int binary_open(const char *, int , ...); int check_ntsec(const char *); char **fetch_windows_environment(void); diff --git a/openbsd-compat/bsd-misc.c b/openbsd-compat/bsd-misc.c index d75854e83229..65e800397cd6 100644 --- a/openbsd-compat/bsd-misc.c +++ b/openbsd-compat/bsd-misc.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include "xmalloc.h" diff --git a/openbsd-compat/bsd-poll.c b/openbsd-compat/bsd-poll.c index f899d7a244c7..c7ef82776a76 100644 --- a/openbsd-compat/bsd-poll.c +++ b/openbsd-compat/bsd-poll.c @@ -1,4 +1,4 @@ -/* $Id: bsd-poll.c,v 1.4 2008/08/29 21:32:38 dtucker Exp $ */ +/* $Id: bsd-poll.c,v 1.5 2013/11/08 10:12:58 dtucker Exp $ */ /* * Copyright (c) 2004, 2005, 2007 Darren Tucker (dtucker at zip com au). @@ -19,12 +19,15 @@ #include "includes.h" #if !defined(HAVE_POLL) +#include +#include #ifdef HAVE_SYS_SELECT_H # include #endif -#include #include +#include +#include #include "bsd-poll.h" /* diff --git a/openbsd-compat/bsd-setres_id.c b/openbsd-compat/bsd-setres_id.c index 020b214b8f8c..018bde8c7682 100644 --- a/openbsd-compat/bsd-setres_id.c +++ b/openbsd-compat/bsd-setres_id.c @@ -1,4 +1,4 @@ -/* $Id: bsd-setres_id.c,v 1.1 2012/11/05 06:04:37 dtucker Exp $ */ +/* $Id: bsd-setres_id.c,v 1.2 2013/12/07 21:23:09 djm Exp $ */ /* * Copyright (c) 2012 Darren Tucker (dtucker at zip com au). @@ -22,6 +22,7 @@ #include #include +#include #include "log.h" diff --git a/openbsd-compat/bsd-snprintf.c b/openbsd-compat/bsd-snprintf.c index 41d2be23899c..975991e7fab8 100644 --- a/openbsd-compat/bsd-snprintf.c +++ b/openbsd-compat/bsd-snprintf.c @@ -160,6 +160,8 @@ #define DP_C_LONG 2 #define DP_C_LDOUBLE 3 #define DP_C_LLONG 4 +#define DP_C_SIZE 5 +#define DP_C_INTMAX 6 #define char_to_int(p) ((p)- '0') #ifndef MAX @@ -182,7 +184,7 @@ static int dopr(char *buffer, size_t maxlen, const char *format, static int fmtstr(char *buffer, size_t *currlen, size_t maxlen, char *value, int flags, int min, int max); static int fmtint(char *buffer, size_t *currlen, size_t maxlen, - LLONG value, int base, int min, int max, int flags); + intmax_t value, int base, int min, int max, int flags); static int fmtfp(char *buffer, size_t *currlen, size_t maxlen, LDOUBLE fvalue, int min, int max, int flags); @@ -190,7 +192,7 @@ static int dopr(char *buffer, size_t maxlen, const char *format, va_list args_in) { char ch; - LLONG value; + intmax_t value; LDOUBLE fvalue; char *strvalue; int min; @@ -287,6 +289,10 @@ dopr(char *buffer, size_t maxlen, const char *format, va_list args_in) cflags = DP_C_SHORT; ch = *format++; break; + case 'j': + cflags = DP_C_INTMAX; + ch = *format++; + break; case 'l': cflags = DP_C_LONG; ch = *format++; @@ -299,6 +305,10 @@ dopr(char *buffer, size_t maxlen, const char *format, va_list args_in) cflags = DP_C_LDOUBLE; ch = *format++; break; + case 'z': + cflags = DP_C_SIZE; + ch = *format++; + break; default: break; } @@ -314,6 +324,10 @@ dopr(char *buffer, size_t maxlen, const char *format, va_list args_in) value = va_arg (args, long int); else if (cflags == DP_C_LLONG) value = va_arg (args, LLONG); + else if (cflags == DP_C_SIZE) + value = va_arg (args, ssize_t); + else if (cflags == DP_C_INTMAX) + value = va_arg (args, intmax_t); else value = va_arg (args, int); if (fmtint(buffer, &currlen, maxlen, @@ -328,6 +342,12 @@ dopr(char *buffer, size_t maxlen, const char *format, va_list args_in) value = (long)va_arg (args, unsigned long int); else if (cflags == DP_C_LLONG) value = (long)va_arg (args, unsigned LLONG); + else if (cflags == DP_C_SIZE) + value = va_arg (args, size_t); +#ifdef notyet + else if (cflags == DP_C_INTMAX) + value = va_arg (args, uintmax_t); +#endif else value = (long)va_arg (args, unsigned int); if (fmtint(buffer, &currlen, maxlen, value, @@ -342,6 +362,12 @@ dopr(char *buffer, size_t maxlen, const char *format, va_list args_in) value = (long)va_arg (args, unsigned long int); else if (cflags == DP_C_LLONG) value = (LLONG)va_arg (args, unsigned LLONG); + else if (cflags == DP_C_SIZE) + value = va_arg (args, size_t); +#ifdef notyet + else if (cflags == DP_C_INTMAX) + value = va_arg (args, uintmax_t); +#endif else value = (long)va_arg (args, unsigned int); if (fmtint(buffer, &currlen, maxlen, value, @@ -358,6 +384,12 @@ dopr(char *buffer, size_t maxlen, const char *format, va_list args_in) value = (long)va_arg (args, unsigned long int); else if (cflags == DP_C_LLONG) value = (LLONG)va_arg (args, unsigned LLONG); + else if (cflags == DP_C_SIZE) + value = va_arg (args, size_t); +#ifdef notyet + else if (cflags == DP_C_INTMAX) + value = va_arg (args, uintmax_t); +#endif else value = (long)va_arg (args, unsigned int); if (fmtint(buffer, &currlen, maxlen, value, @@ -416,6 +448,7 @@ dopr(char *buffer, size_t maxlen, const char *format, va_list args_in) (long) strvalue, 16, min, max, flags) == -1) return -1; break; +#if we_dont_want_this_in_openssh case 'n': if (cflags == DP_C_SHORT) { short int *num; @@ -429,12 +462,21 @@ dopr(char *buffer, size_t maxlen, const char *format, va_list args_in) LLONG *num; num = va_arg (args, LLONG *); *num = (LLONG)currlen; + } else if (cflags == DP_C_SIZE) { + ssize_t *num; + num = va_arg (args, ssize_t *); + *num = (ssize_t)currlen; + } else if (cflags == DP_C_INTMAX) { + intmax_t *num; + num = va_arg (args, intmax_t *); + *num = (intmax_t)currlen; } else { int *num; num = va_arg (args, int *); *num = currlen; } break; +#endif case '%': DOPR_OUTCH(buffer, currlen, maxlen, ch); break; diff --git a/openbsd-compat/bsd-statvfs.c b/openbsd-compat/bsd-statvfs.c index 844d5b464dfc..2b1da80ec883 100644 --- a/openbsd-compat/bsd-statvfs.c +++ b/openbsd-compat/bsd-statvfs.c @@ -1,7 +1,7 @@ -/* $Id: bsd-statvfs.c,v 1.1 2008/06/08 17:32:29 dtucker Exp $ */ +/* $Id: bsd-statvfs.c,v 1.2 2014/01/17 07:10:59 dtucker Exp $ */ /* - * Copyright (c) 2008 Darren Tucker + * Copyright (c) 2008,2014 Darren Tucker * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -18,20 +18,65 @@ #include "includes.h" +#if !defined(HAVE_STATVFS) || !defined(HAVE_FSTATVFS) + +#include +#ifdef HAVE_SYS_MOUNT_H +# include +#endif + #include -#ifndef HAVE_STATVFS +static void +copy_statfs_to_statvfs(struct statvfs *to, struct statfs *from) +{ + to->f_bsize = from->f_bsize; + to->f_frsize = from->f_bsize; /* no exact equivalent */ + to->f_blocks = from->f_blocks; + to->f_bfree = from->f_bfree; + to->f_bavail = from->f_bavail; + to->f_files = from->f_files; + to->f_ffree = from->f_ffree; + to->f_favail = from->f_ffree; /* no exact equivalent */ + to->f_fsid = 0; /* XXX fix me */ + to->f_flag = from->f_flags; + to->f_namemax = MNAMELEN; +} + +# ifndef HAVE_STATVFS int statvfs(const char *path, struct statvfs *buf) { +# ifdef HAVE_STATFS + struct statfs fs; + + memset(&fs, 0, sizeof(fs)); + if (statfs(path, &fs) == -1) + return -1; + copy_statfs_to_statvfs(buf, &fs); + return 0; +# else errno = ENOSYS; return -1; +# endif } -#endif +# endif -#ifndef HAVE_FSTATVFS +# ifndef HAVE_FSTATVFS int fstatvfs(int fd, struct statvfs *buf) { +# ifdef HAVE_FSTATFS + struct statfs fs; + + memset(&fs, 0, sizeof(fs)); + if (fstatfs(fd, &fs) == -1) + return -1; + copy_statfs_to_statvfs(buf, &fs); + return 0; +# else errno = ENOSYS; return -1; +# endif } +# endif + #endif diff --git a/openbsd-compat/bsd-statvfs.h b/openbsd-compat/bsd-statvfs.h index da215ffc68d1..dfd60997419b 100644 --- a/openbsd-compat/bsd-statvfs.h +++ b/openbsd-compat/bsd-statvfs.h @@ -1,7 +1,7 @@ -/* $Id: bsd-statvfs.h,v 1.1 2008/06/08 17:32:29 dtucker Exp $ */ +/* $Id: bsd-statvfs.h,v 1.3 2014/01/17 07:48:22 dtucker Exp $ */ /* - * Copyright (c) 2008 Darren Tucker + * Copyright (c) 2008,2014 Darren Tucker * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -18,14 +18,17 @@ #include "includes.h" +#if !defined(HAVE_STATVFS) || !defined(HAVE_FSTATVFS) + #include +#ifdef HAVE_SYS_MOUNT_H +#include +#endif #ifdef HAVE_SYS_STATFS_H #include #endif -#ifndef HAVE_STATVFS - #ifndef HAVE_FSBLKCNT_T typedef unsigned long fsblkcnt_t; #endif diff --git a/openbsd-compat/chacha_private.h b/openbsd-compat/chacha_private.h new file mode 100644 index 000000000000..7c3680fa6d64 --- /dev/null +++ b/openbsd-compat/chacha_private.h @@ -0,0 +1,222 @@ +/* +chacha-merged.c version 20080118 +D. J. Bernstein +Public domain. +*/ + +/* $OpenBSD: chacha_private.h,v 1.2 2013/10/04 07:02:27 djm Exp $ */ + +typedef unsigned char u8; +typedef unsigned int u32; + +typedef struct +{ + u32 input[16]; /* could be compressed */ +} chacha_ctx; + +#define U8C(v) (v##U) +#define U32C(v) (v##U) + +#define U8V(v) ((u8)(v) & U8C(0xFF)) +#define U32V(v) ((u32)(v) & U32C(0xFFFFFFFF)) + +#define ROTL32(v, n) \ + (U32V((v) << (n)) | ((v) >> (32 - (n)))) + +#define U8TO32_LITTLE(p) \ + (((u32)((p)[0]) ) | \ + ((u32)((p)[1]) << 8) | \ + ((u32)((p)[2]) << 16) | \ + ((u32)((p)[3]) << 24)) + +#define U32TO8_LITTLE(p, v) \ + do { \ + (p)[0] = U8V((v) ); \ + (p)[1] = U8V((v) >> 8); \ + (p)[2] = U8V((v) >> 16); \ + (p)[3] = U8V((v) >> 24); \ + } while (0) + +#define ROTATE(v,c) (ROTL32(v,c)) +#define XOR(v,w) ((v) ^ (w)) +#define PLUS(v,w) (U32V((v) + (w))) +#define PLUSONE(v) (PLUS((v),1)) + +#define QUARTERROUND(a,b,c,d) \ + a = PLUS(a,b); d = ROTATE(XOR(d,a),16); \ + c = PLUS(c,d); b = ROTATE(XOR(b,c),12); \ + a = PLUS(a,b); d = ROTATE(XOR(d,a), 8); \ + c = PLUS(c,d); b = ROTATE(XOR(b,c), 7); + +static const char sigma[16] = "expand 32-byte k"; +static const char tau[16] = "expand 16-byte k"; + +static void +chacha_keysetup(chacha_ctx *x,const u8 *k,u32 kbits,u32 ivbits) +{ + const char *constants; + + x->input[4] = U8TO32_LITTLE(k + 0); + x->input[5] = U8TO32_LITTLE(k + 4); + x->input[6] = U8TO32_LITTLE(k + 8); + x->input[7] = U8TO32_LITTLE(k + 12); + if (kbits == 256) { /* recommended */ + k += 16; + constants = sigma; + } else { /* kbits == 128 */ + constants = tau; + } + x->input[8] = U8TO32_LITTLE(k + 0); + x->input[9] = U8TO32_LITTLE(k + 4); + x->input[10] = U8TO32_LITTLE(k + 8); + x->input[11] = U8TO32_LITTLE(k + 12); + x->input[0] = U8TO32_LITTLE(constants + 0); + x->input[1] = U8TO32_LITTLE(constants + 4); + x->input[2] = U8TO32_LITTLE(constants + 8); + x->input[3] = U8TO32_LITTLE(constants + 12); +} + +static void +chacha_ivsetup(chacha_ctx *x,const u8 *iv) +{ + x->input[12] = 0; + x->input[13] = 0; + x->input[14] = U8TO32_LITTLE(iv + 0); + x->input[15] = U8TO32_LITTLE(iv + 4); +} + +static void +chacha_encrypt_bytes(chacha_ctx *x,const u8 *m,u8 *c,u32 bytes) +{ + u32 x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15; + u32 j0, j1, j2, j3, j4, j5, j6, j7, j8, j9, j10, j11, j12, j13, j14, j15; + u8 *ctarget = NULL; + u8 tmp[64]; + u_int i; + + if (!bytes) return; + + j0 = x->input[0]; + j1 = x->input[1]; + j2 = x->input[2]; + j3 = x->input[3]; + j4 = x->input[4]; + j5 = x->input[5]; + j6 = x->input[6]; + j7 = x->input[7]; + j8 = x->input[8]; + j9 = x->input[9]; + j10 = x->input[10]; + j11 = x->input[11]; + j12 = x->input[12]; + j13 = x->input[13]; + j14 = x->input[14]; + j15 = x->input[15]; + + for (;;) { + if (bytes < 64) { + for (i = 0;i < bytes;++i) tmp[i] = m[i]; + m = tmp; + ctarget = c; + c = tmp; + } + x0 = j0; + x1 = j1; + x2 = j2; + x3 = j3; + x4 = j4; + x5 = j5; + x6 = j6; + x7 = j7; + x8 = j8; + x9 = j9; + x10 = j10; + x11 = j11; + x12 = j12; + x13 = j13; + x14 = j14; + x15 = j15; + for (i = 20;i > 0;i -= 2) { + QUARTERROUND( x0, x4, x8,x12) + QUARTERROUND( x1, x5, x9,x13) + QUARTERROUND( x2, x6,x10,x14) + QUARTERROUND( x3, x7,x11,x15) + QUARTERROUND( x0, x5,x10,x15) + QUARTERROUND( x1, x6,x11,x12) + QUARTERROUND( x2, x7, x8,x13) + QUARTERROUND( x3, x4, x9,x14) + } + x0 = PLUS(x0,j0); + x1 = PLUS(x1,j1); + x2 = PLUS(x2,j2); + x3 = PLUS(x3,j3); + x4 = PLUS(x4,j4); + x5 = PLUS(x5,j5); + x6 = PLUS(x6,j6); + x7 = PLUS(x7,j7); + x8 = PLUS(x8,j8); + x9 = PLUS(x9,j9); + x10 = PLUS(x10,j10); + x11 = PLUS(x11,j11); + x12 = PLUS(x12,j12); + x13 = PLUS(x13,j13); + x14 = PLUS(x14,j14); + x15 = PLUS(x15,j15); + +#ifndef KEYSTREAM_ONLY + x0 = XOR(x0,U8TO32_LITTLE(m + 0)); + x1 = XOR(x1,U8TO32_LITTLE(m + 4)); + x2 = XOR(x2,U8TO32_LITTLE(m + 8)); + x3 = XOR(x3,U8TO32_LITTLE(m + 12)); + x4 = XOR(x4,U8TO32_LITTLE(m + 16)); + x5 = XOR(x5,U8TO32_LITTLE(m + 20)); + x6 = XOR(x6,U8TO32_LITTLE(m + 24)); + x7 = XOR(x7,U8TO32_LITTLE(m + 28)); + x8 = XOR(x8,U8TO32_LITTLE(m + 32)); + x9 = XOR(x9,U8TO32_LITTLE(m + 36)); + x10 = XOR(x10,U8TO32_LITTLE(m + 40)); + x11 = XOR(x11,U8TO32_LITTLE(m + 44)); + x12 = XOR(x12,U8TO32_LITTLE(m + 48)); + x13 = XOR(x13,U8TO32_LITTLE(m + 52)); + x14 = XOR(x14,U8TO32_LITTLE(m + 56)); + x15 = XOR(x15,U8TO32_LITTLE(m + 60)); +#endif + + j12 = PLUSONE(j12); + if (!j12) { + j13 = PLUSONE(j13); + /* stopping at 2^70 bytes per nonce is user's responsibility */ + } + + U32TO8_LITTLE(c + 0,x0); + U32TO8_LITTLE(c + 4,x1); + U32TO8_LITTLE(c + 8,x2); + U32TO8_LITTLE(c + 12,x3); + U32TO8_LITTLE(c + 16,x4); + U32TO8_LITTLE(c + 20,x5); + U32TO8_LITTLE(c + 24,x6); + U32TO8_LITTLE(c + 28,x7); + U32TO8_LITTLE(c + 32,x8); + U32TO8_LITTLE(c + 36,x9); + U32TO8_LITTLE(c + 40,x10); + U32TO8_LITTLE(c + 44,x11); + U32TO8_LITTLE(c + 48,x12); + U32TO8_LITTLE(c + 52,x13); + U32TO8_LITTLE(c + 56,x14); + U32TO8_LITTLE(c + 60,x15); + + if (bytes <= 64) { + if (bytes < 64) { + for (i = 0;i < bytes;++i) ctarget[i] = c[i]; + } + x->input[12] = j12; + x->input[13] = j13; + return; + } + bytes -= 64; + c += 64; +#ifndef KEYSTREAM_ONLY + m += 64; +#endif + } +} diff --git a/openbsd-compat/openbsd-compat.h b/openbsd-compat/openbsd-compat.h index 392fa38dc09b..f34619e4a096 100644 --- a/openbsd-compat/openbsd-compat.h +++ b/openbsd-compat/openbsd-compat.h @@ -1,4 +1,4 @@ -/* $Id: openbsd-compat.h,v 1.58 2013/06/05 22:30:21 dtucker Exp $ */ +/* $Id: openbsd-compat.h,v 1.60 2013/12/07 00:51:54 djm Exp $ */ /* * Copyright (c) 1999-2003 Damien Miller. All rights reserved. @@ -44,6 +44,7 @@ #include "vis.h" #include "getrrsetbyname.h" #include "sha2.h" +#include "blf.h" #ifndef HAVE_BASENAME char *basename(const char *path); @@ -161,9 +162,13 @@ int writev(int, struct iovec *, int); #ifndef HAVE_GETPEEREID int getpeereid(int , uid_t *, gid_t *); -#endif +#endif -#ifndef HAVE_ARC4RANDOM +#ifdef HAVE_ARC4RANDOM +# ifndef HAVE_ARC4RANDOM_STIR +# define arc4random_stir() +# endif +#else unsigned int arc4random(void); void arc4random_stir(void); #endif /* !HAVE_ARC4RANDOM */ @@ -236,6 +241,11 @@ char *group_from_gid(gid_t, int); int timingsafe_bcmp(const void *, const void *, size_t); #endif +#ifndef HAVE_BCRYPT_PBKDF +int bcrypt_pbkdf(const char *, size_t, const u_int8_t *, size_t, + u_int8_t *, size_t, unsigned int); +#endif + void *xmmap(size_t size); char *xcrypt(const char *password, const char *salt); char *shadow_pw(struct passwd *pw); diff --git a/openbsd-compat/openssl-compat.c b/openbsd-compat/openssl-compat.c index 5189cab61694..60eac4b17cfa 100644 --- a/openbsd-compat/openssl-compat.c +++ b/openbsd-compat/openssl-compat.c @@ -1,4 +1,4 @@ -/* $Id: openssl-compat.c,v 1.14 2011/05/10 01:13:38 dtucker Exp $ */ +/* $Id: openssl-compat.c,v 1.16 2014/01/17 07:00:41 dtucker Exp $ */ /* * Copyright (c) 2005 Darren Tucker @@ -59,6 +59,34 @@ ssh_EVP_CIPHER_CTX_cleanup(EVP_CIPHER_CTX *evp) } #endif +#ifndef HAVE_EVP_DIGESTINIT_EX +int +EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *md, void *engine) +{ + if (engine != NULL) + fatal("%s: ENGINE is not supported", __func__); +# ifdef OPENSSL_EVP_DIGESTUPDATE_VOID + EVP_DigestInit(ctx, md); + return 1; +# else + return EVP_DigestInit(ctx, md); +# endif +} +#endif + +#ifndef HAVE_EVP_DIGESTFINAL_EX +int +EVP_DigestFinal_ex(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *s) +{ +# ifdef OPENSSL_EVP_DIGESTUPDATE_VOID + EVP_DigestFinal(ctx, md, s); + return 1; +# else + return EVP_DigestFinal(ctx, md, s); +# endif +} +#endif + #ifdef OPENSSL_EVP_DIGESTUPDATE_VOID int ssh_EVP_DigestUpdate(EVP_MD_CTX *ctx, const void *d, unsigned int cnt) diff --git a/openbsd-compat/openssl-compat.h b/openbsd-compat/openssl-compat.h index e7439b4e7b02..021ea98f53e2 100644 --- a/openbsd-compat/openssl-compat.h +++ b/openbsd-compat/openssl-compat.h @@ -1,4 +1,4 @@ -/* $Id: openssl-compat.h,v 1.24 2013/02/12 00:00:40 djm Exp $ */ +/* $Id: openssl-compat.h,v 1.25 2014/01/17 06:32:31 dtucker Exp $ */ /* * Copyright (c) 2005 Darren Tucker @@ -148,6 +148,14 @@ int DSA_generate_parameters_ex(DSA *, int, const unsigned char *, int, int *, int RSA_generate_key_ex(RSA *, int, BIGNUM *, void *); # endif +# ifndef HAVE_EVP_DIGESTINIT_EX +int EVP_DigestInit_ex(EVP_MD_CTX *, const EVP_MD *, void *); +# endif + +# ifndef HAVE_EVP_DISESTFINAL_EX +int EVP_DigestFinal_ex(EVP_MD_CTX *, unsigned char *, unsigned int *); +# endif + int ssh_EVP_CipherInit(EVP_CIPHER_CTX *, const EVP_CIPHER *, unsigned char *, unsigned char *, int); int ssh_EVP_Cipher(EVP_CIPHER_CTX *, char *, char *, int); @@ -158,5 +166,13 @@ void ssh_OpenSSL_add_all_algorithms(void); # define HMAC_CTX_init(a) # endif +# ifndef HAVE_EVP_MD_CTX_INIT +# define EVP_MD_CTX_init(a) +# endif + +# ifndef HAVE_EVP_MD_CTX_CLEANUP +# define EVP_MD_CTX_cleanup(a) +# endif + #endif /* SSH_DONT_OVERLOAD_OPENSSL_FUNCS */ diff --git a/openbsd-compat/setproctitle.c b/openbsd-compat/setproctitle.c index 2965f689e702..9f7ca14c207d 100644 --- a/openbsd-compat/setproctitle.c +++ b/openbsd-compat/setproctitle.c @@ -67,7 +67,8 @@ static size_t argv_env_len = 0; void compat_init_setproctitle(int argc, char *argv[]) { -#if defined(SPT_TYPE) && SPT_TYPE == SPT_REUSEARGV +#if !defined(HAVE_SETPROCTITLE) && \ + defined(SPT_TYPE) && SPT_TYPE == SPT_REUSEARGV extern char **environ; char *lastargv = NULL; char **envp = environ; @@ -125,6 +126,7 @@ setproctitle(const char *fmt, ...) va_list ap; char buf[1024], ptitle[1024]; size_t len; + int r; extern char *__progname; #if SPT_TYPE == SPT_PSTAT union pstun pst; @@ -137,13 +139,16 @@ setproctitle(const char *fmt, ...) strlcpy(buf, __progname, sizeof(buf)); + r = -1; va_start(ap, fmt); if (fmt != NULL) { len = strlcat(buf, ": ", sizeof(buf)); if (len < sizeof(buf)) - vsnprintf(buf + len, sizeof(buf) - len , fmt, ap); + r = vsnprintf(buf + len, sizeof(buf) - len , fmt, ap); } va_end(ap); + if (r == -1 || (size_t)r >= sizeof(buf) - len) + return; strnvis(ptitle, buf, sizeof(ptitle), VIS_CSTYLE|VIS_NL|VIS_TAB|VIS_OCTAL); diff --git a/packet.c b/packet.c index 90db33bddb28..6cf7edbb8504 100644 --- a/packet.c +++ b/packet.c @@ -1,4 +1,4 @@ -/* $OpenBSD: packet.c,v 1.189 2013/11/08 00:39:15 djm Exp $ */ +/* $OpenBSD: packet.c,v 1.191 2013/12/06 13:34:54 markus Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -713,9 +713,10 @@ packet_send1(void) buffer_append(&active_state->output, buf, 4); cp = buffer_append_space(&active_state->output, buffer_len(&active_state->outgoing_packet)); - cipher_crypt(&active_state->send_context, cp, + if (cipher_crypt(&active_state->send_context, 0, cp, buffer_ptr(&active_state->outgoing_packet), - buffer_len(&active_state->outgoing_packet), 0, 0); + buffer_len(&active_state->outgoing_packet), 0, 0) != 0) + fatal("%s: cipher_crypt failed", __func__); #ifdef PACKET_DEBUG fprintf(stderr, "encrypted: "); @@ -946,9 +947,10 @@ packet_send2_wrapped(void) } /* encrypt packet and append to output buffer. */ cp = buffer_append_space(&active_state->output, len + authlen); - cipher_crypt(&active_state->send_context, cp, - buffer_ptr(&active_state->outgoing_packet), - len - aadlen, aadlen, authlen); + if (cipher_crypt(&active_state->send_context, active_state->p_send.seqnr, + cp, buffer_ptr(&active_state->outgoing_packet), + len - aadlen, aadlen, authlen) != 0) + fatal("%s: cipher_crypt failed", __func__); /* append unencrypted MAC */ if (mac && mac->enabled) { if (mac->etm) { @@ -1208,8 +1210,9 @@ packet_read_poll1(void) /* Decrypt data to incoming_packet. */ buffer_clear(&active_state->incoming_packet); cp = buffer_append_space(&active_state->incoming_packet, padded_len); - cipher_crypt(&active_state->receive_context, cp, - buffer_ptr(&active_state->input), padded_len, 0, 0); + if (cipher_crypt(&active_state->receive_context, 0, cp, + buffer_ptr(&active_state->input), padded_len, 0, 0) != 0) + fatal("%s: cipher_crypt failed", __func__); buffer_consume(&active_state->input, padded_len); @@ -1279,10 +1282,12 @@ packet_read_poll2(u_int32_t *seqnr_p) aadlen = (mac && mac->enabled && mac->etm) || authlen ? 4 : 0; if (aadlen && active_state->packlen == 0) { - if (buffer_len(&active_state->input) < 4) + if (cipher_get_length(&active_state->receive_context, + &active_state->packlen, + active_state->p_read.seqnr, + buffer_ptr(&active_state->input), + buffer_len(&active_state->input)) != 0) return SSH_MSG_NONE; - cp = buffer_ptr(&active_state->input); - active_state->packlen = get_u32(cp); if (active_state->packlen < 1 + 4 || active_state->packlen > PACKET_MAX_SIZE) { #ifdef PACKET_DEBUG @@ -1302,8 +1307,10 @@ packet_read_poll2(u_int32_t *seqnr_p) buffer_clear(&active_state->incoming_packet); cp = buffer_append_space(&active_state->incoming_packet, block_size); - cipher_crypt(&active_state->receive_context, cp, - buffer_ptr(&active_state->input), block_size, 0, 0); + if (cipher_crypt(&active_state->receive_context, + active_state->p_read.seqnr, cp, + buffer_ptr(&active_state->input), block_size, 0, 0) != 0) + fatal("Decryption integrity check failed"); cp = buffer_ptr(&active_state->incoming_packet); active_state->packlen = get_u32(cp); if (active_state->packlen < 1 + 4 || @@ -1357,8 +1364,10 @@ packet_read_poll2(u_int32_t *seqnr_p) macbuf = mac_compute(mac, active_state->p_read.seqnr, buffer_ptr(&active_state->input), aadlen + need); cp = buffer_append_space(&active_state->incoming_packet, aadlen + need); - cipher_crypt(&active_state->receive_context, cp, - buffer_ptr(&active_state->input), need, aadlen, authlen); + if (cipher_crypt(&active_state->receive_context, + active_state->p_read.seqnr, cp, + buffer_ptr(&active_state->input), need, aadlen, authlen) != 0) + fatal("Decryption integrity check failed"); buffer_consume(&active_state->input, aadlen + need + authlen); /* * compute MAC over seqnr and packet, diff --git a/pathnames.h b/pathnames.h index 5027fbaed695..ec89fc66650b 100644 --- a/pathnames.h +++ b/pathnames.h @@ -1,4 +1,4 @@ -/* $OpenBSD: pathnames.h,v 1.23 2013/04/05 00:31:49 djm Exp $ */ +/* $OpenBSD: pathnames.h,v 1.24 2013/12/06 13:39:49 markus Exp $ */ /* * Author: Tatu Ylonen @@ -39,6 +39,7 @@ #define _PATH_HOST_KEY_FILE SSHDIR "/ssh_host_key" #define _PATH_HOST_DSA_KEY_FILE SSHDIR "/ssh_host_dsa_key" #define _PATH_HOST_ECDSA_KEY_FILE SSHDIR "/ssh_host_ecdsa_key" +#define _PATH_HOST_ED25519_KEY_FILE SSHDIR "/ssh_host_ed25519_key" #define _PATH_HOST_RSA_KEY_FILE SSHDIR "/ssh_host_rsa_key" #define _PATH_DH_MODULI SSHDIR "/moduli" /* Backwards compatibility */ @@ -77,6 +78,7 @@ #define _PATH_SSH_CLIENT_ID_DSA _PATH_SSH_USER_DIR "/id_dsa" #define _PATH_SSH_CLIENT_ID_ECDSA _PATH_SSH_USER_DIR "/id_ecdsa" #define _PATH_SSH_CLIENT_ID_RSA _PATH_SSH_USER_DIR "/id_rsa" +#define _PATH_SSH_CLIENT_ID_ED25519 _PATH_SSH_USER_DIR "/id_ed25519" /* * Configuration file in user's home directory. This file need not be diff --git a/pkcs11.h b/pkcs11.h index 2cde5b3f4fae..b01d58f9483a 100644 --- a/pkcs11.h +++ b/pkcs11.h @@ -1,4 +1,4 @@ -/* $OpenBSD: pkcs11.h,v 1.2 2010/02/24 06:12:53 djm Exp $ */ +/* $OpenBSD: pkcs11.h,v 1.3 2013/11/26 19:15:09 deraadt Exp $ */ /* pkcs11.h Copyright 2006, 2007 g10 Code GmbH Copyright 2006 Andreas Jellinghaus @@ -319,7 +319,7 @@ typedef unsigned long ck_object_class_t; #define CKO_HW_FEATURE (5) #define CKO_DOMAIN_PARAMETERS (6) #define CKO_MECHANISM (7) -#define CKO_VENDOR_DEFINED ((unsigned long) (1 << 31)) +#define CKO_VENDOR_DEFINED (1U << 31) typedef unsigned long ck_hw_feature_type_t; @@ -327,7 +327,7 @@ typedef unsigned long ck_hw_feature_type_t; #define CKH_MONOTONIC_COUNTER (1) #define CKH_CLOCK (2) #define CKH_USER_INTERFACE (3) -#define CKH_VENDOR_DEFINED ((unsigned long) (1 << 31)) +#define CKH_VENDOR_DEFINED (1U << 31) typedef unsigned long ck_key_type_t; @@ -357,14 +357,14 @@ typedef unsigned long ck_key_type_t; #define CKK_AES (0x1f) #define CKK_BLOWFISH (0x20) #define CKK_TWOFISH (0x21) -#define CKK_VENDOR_DEFINED ((unsigned long) (1 << 31)) +#define CKK_VENDOR_DEFINED (1U << 31) typedef unsigned long ck_certificate_type_t; #define CKC_X_509 (0) #define CKC_X_509_ATTR_CERT (1) #define CKC_WTLS (2) -#define CKC_VENDOR_DEFINED ((unsigned long) (1 << 31)) +#define CKC_VENDOR_DEFINED (1U << 31) typedef unsigned long ck_attribute_type_t; @@ -453,7 +453,7 @@ typedef unsigned long ck_attribute_type_t; #define CKA_WRAP_TEMPLATE (CKF_ARRAY_ATTRIBUTE | 0x211) #define CKA_UNWRAP_TEMPLATE (CKF_ARRAY_ATTRIBUTE | 0x212) #define CKA_ALLOWED_MECHANISMS (CKF_ARRAY_ATTRIBUTE | 0x600) -#define CKA_VENDOR_DEFINED ((unsigned long) (1 << 31)) +#define CKA_VENDOR_DEFINED (1U << 31) struct ck_attribute @@ -672,7 +672,7 @@ typedef unsigned long ck_mechanism_type_t; #define CKM_DSA_PARAMETER_GEN (0x2000) #define CKM_DH_PKCS_PARAMETER_GEN (0x2001) #define CKM_X9_42_DH_PARAMETER_GEN (0x2002) -#define CKM_VENDOR_DEFINED ((unsigned long) (1 << 31)) +#define CKM_VENDOR_DEFINED (1U << 31) struct ck_mechanism @@ -703,7 +703,7 @@ struct ck_mechanism_info #define CKF_WRAP (1 << 17) #define CKF_UNWRAP (1 << 18) #define CKF_DERIVE (1 << 19) -#define CKF_EXTENSION ((unsigned long) (1 << 31)) +#define CKF_EXTENSION (1U << 31) /* Flags for C_WaitForSlotEvent. */ @@ -1179,7 +1179,7 @@ struct ck_c_initialize_args #define CKR_MUTEX_BAD (0x1a0) #define CKR_MUTEX_NOT_LOCKED (0x1a1) #define CKR_FUNCTION_REJECTED (0x200) -#define CKR_VENDOR_DEFINED ((unsigned long) (1 << 31)) +#define CKR_VENDOR_DEFINED (1U << 31) diff --git a/platform.c b/platform.c index 3262b2478444..30fc60909c8b 100644 --- a/platform.c +++ b/platform.c @@ -1,4 +1,4 @@ -/* $Id: platform.c,v 1.19 2013/03/12 00:31:05 dtucker Exp $ */ +/* $Id: platform.c,v 1.21 2014/01/21 01:59:29 tim Exp $ */ /* * Copyright (c) 2006 Darren Tucker. All rights reserved. @@ -54,6 +54,14 @@ platform_pre_fork(void) #endif } +void +platform_pre_restart(void) +{ +#ifdef LINUX_OOM_ADJUST + oom_adjust_restore(); +#endif +} + void platform_post_fork_parent(pid_t child_pid) { @@ -156,12 +164,6 @@ platform_setusercontext_post_groups(struct passwd *pw) aix_usrinfo(pw); #endif /* _AIX */ -#if !defined(HAVE_LOGIN_CAP) && defined(USE_LIBIAF) - if (set_id(pw->pw_name) != 0) { - exit(1); - } -# endif /* USE_LIBIAF */ - #ifdef HAVE_SETPCRED /* * If we have a chroot directory, we set all creds except real diff --git a/platform.h b/platform.h index 19f6bfdd31ee..1c7a45d8fc29 100644 --- a/platform.h +++ b/platform.h @@ -1,4 +1,4 @@ -/* $Id: platform.h,v 1.8 2013/03/12 00:31:05 dtucker Exp $ */ +/* $Id: platform.h,v 1.9 2013/09/22 09:02:40 dtucker Exp $ */ /* * Copyright (c) 2006 Darren Tucker. All rights reserved. @@ -22,6 +22,7 @@ void platform_pre_listen(void); void platform_pre_fork(void); +void platform_pre_restart(void); void platform_post_fork_parent(pid_t child_pid); void platform_post_fork_child(void); int platform_privileged_uidswap(void); diff --git a/poly1305.c b/poly1305.c new file mode 100644 index 000000000000..6fd1fc8cd13c --- /dev/null +++ b/poly1305.c @@ -0,0 +1,160 @@ +/* + * Public Domain poly1305 from Andrew Moon + * poly1305-donna-unrolled.c from https://github.com/floodyberry/poly1305-donna + */ + +/* $OpenBSD: poly1305.c,v 1.3 2013/12/19 22:57:13 djm Exp $ */ + +#include "includes.h" + +#include +#ifdef HAVE_STDINT_H +# include +#endif + +#include "poly1305.h" + +#define mul32x32_64(a,b) ((uint64_t)(a) * (b)) + +#define U8TO32_LE(p) \ + (((uint32_t)((p)[0])) | \ + ((uint32_t)((p)[1]) << 8) | \ + ((uint32_t)((p)[2]) << 16) | \ + ((uint32_t)((p)[3]) << 24)) + +#define U32TO8_LE(p, v) \ + do { \ + (p)[0] = (uint8_t)((v)); \ + (p)[1] = (uint8_t)((v) >> 8); \ + (p)[2] = (uint8_t)((v) >> 16); \ + (p)[3] = (uint8_t)((v) >> 24); \ + } while (0) + +void +poly1305_auth(unsigned char out[POLY1305_TAGLEN], const unsigned char *m, size_t inlen, const unsigned char key[POLY1305_KEYLEN]) { + uint32_t t0,t1,t2,t3; + uint32_t h0,h1,h2,h3,h4; + uint32_t r0,r1,r2,r3,r4; + uint32_t s1,s2,s3,s4; + uint32_t b, nb; + size_t j; + uint64_t t[5]; + uint64_t f0,f1,f2,f3; + uint32_t g0,g1,g2,g3,g4; + uint64_t c; + unsigned char mp[16]; + + /* clamp key */ + t0 = U8TO32_LE(key+0); + t1 = U8TO32_LE(key+4); + t2 = U8TO32_LE(key+8); + t3 = U8TO32_LE(key+12); + + /* precompute multipliers */ + r0 = t0 & 0x3ffffff; t0 >>= 26; t0 |= t1 << 6; + r1 = t0 & 0x3ffff03; t1 >>= 20; t1 |= t2 << 12; + r2 = t1 & 0x3ffc0ff; t2 >>= 14; t2 |= t3 << 18; + r3 = t2 & 0x3f03fff; t3 >>= 8; + r4 = t3 & 0x00fffff; + + s1 = r1 * 5; + s2 = r2 * 5; + s3 = r3 * 5; + s4 = r4 * 5; + + /* init state */ + h0 = 0; + h1 = 0; + h2 = 0; + h3 = 0; + h4 = 0; + + /* full blocks */ + if (inlen < 16) goto poly1305_donna_atmost15bytes; +poly1305_donna_16bytes: + m += 16; + inlen -= 16; + + t0 = U8TO32_LE(m-16); + t1 = U8TO32_LE(m-12); + t2 = U8TO32_LE(m-8); + t3 = U8TO32_LE(m-4); + + h0 += t0 & 0x3ffffff; + h1 += ((((uint64_t)t1 << 32) | t0) >> 26) & 0x3ffffff; + h2 += ((((uint64_t)t2 << 32) | t1) >> 20) & 0x3ffffff; + h3 += ((((uint64_t)t3 << 32) | t2) >> 14) & 0x3ffffff; + h4 += (t3 >> 8) | (1 << 24); + + +poly1305_donna_mul: + t[0] = mul32x32_64(h0,r0) + mul32x32_64(h1,s4) + mul32x32_64(h2,s3) + mul32x32_64(h3,s2) + mul32x32_64(h4,s1); + t[1] = mul32x32_64(h0,r1) + mul32x32_64(h1,r0) + mul32x32_64(h2,s4) + mul32x32_64(h3,s3) + mul32x32_64(h4,s2); + t[2] = mul32x32_64(h0,r2) + mul32x32_64(h1,r1) + mul32x32_64(h2,r0) + mul32x32_64(h3,s4) + mul32x32_64(h4,s3); + t[3] = mul32x32_64(h0,r3) + mul32x32_64(h1,r2) + mul32x32_64(h2,r1) + mul32x32_64(h3,r0) + mul32x32_64(h4,s4); + t[4] = mul32x32_64(h0,r4) + mul32x32_64(h1,r3) + mul32x32_64(h2,r2) + mul32x32_64(h3,r1) + mul32x32_64(h4,r0); + + h0 = (uint32_t)t[0] & 0x3ffffff; c = (t[0] >> 26); + t[1] += c; h1 = (uint32_t)t[1] & 0x3ffffff; b = (uint32_t)(t[1] >> 26); + t[2] += b; h2 = (uint32_t)t[2] & 0x3ffffff; b = (uint32_t)(t[2] >> 26); + t[3] += b; h3 = (uint32_t)t[3] & 0x3ffffff; b = (uint32_t)(t[3] >> 26); + t[4] += b; h4 = (uint32_t)t[4] & 0x3ffffff; b = (uint32_t)(t[4] >> 26); + h0 += b * 5; + + if (inlen >= 16) goto poly1305_donna_16bytes; + + /* final bytes */ +poly1305_donna_atmost15bytes: + if (!inlen) goto poly1305_donna_finish; + + for (j = 0; j < inlen; j++) mp[j] = m[j]; + mp[j++] = 1; + for (; j < 16; j++) mp[j] = 0; + inlen = 0; + + t0 = U8TO32_LE(mp+0); + t1 = U8TO32_LE(mp+4); + t2 = U8TO32_LE(mp+8); + t3 = U8TO32_LE(mp+12); + + h0 += t0 & 0x3ffffff; + h1 += ((((uint64_t)t1 << 32) | t0) >> 26) & 0x3ffffff; + h2 += ((((uint64_t)t2 << 32) | t1) >> 20) & 0x3ffffff; + h3 += ((((uint64_t)t3 << 32) | t2) >> 14) & 0x3ffffff; + h4 += (t3 >> 8); + + goto poly1305_donna_mul; + +poly1305_donna_finish: + b = h0 >> 26; h0 = h0 & 0x3ffffff; + h1 += b; b = h1 >> 26; h1 = h1 & 0x3ffffff; + h2 += b; b = h2 >> 26; h2 = h2 & 0x3ffffff; + h3 += b; b = h3 >> 26; h3 = h3 & 0x3ffffff; + h4 += b; b = h4 >> 26; h4 = h4 & 0x3ffffff; + h0 += b * 5; b = h0 >> 26; h0 = h0 & 0x3ffffff; + h1 += b; + + g0 = h0 + 5; b = g0 >> 26; g0 &= 0x3ffffff; + g1 = h1 + b; b = g1 >> 26; g1 &= 0x3ffffff; + g2 = h2 + b; b = g2 >> 26; g2 &= 0x3ffffff; + g3 = h3 + b; b = g3 >> 26; g3 &= 0x3ffffff; + g4 = h4 + b - (1 << 26); + + b = (g4 >> 31) - 1; + nb = ~b; + h0 = (h0 & nb) | (g0 & b); + h1 = (h1 & nb) | (g1 & b); + h2 = (h2 & nb) | (g2 & b); + h3 = (h3 & nb) | (g3 & b); + h4 = (h4 & nb) | (g4 & b); + + f0 = ((h0 ) | (h1 << 26)) + (uint64_t)U8TO32_LE(&key[16]); + f1 = ((h1 >> 6) | (h2 << 20)) + (uint64_t)U8TO32_LE(&key[20]); + f2 = ((h2 >> 12) | (h3 << 14)) + (uint64_t)U8TO32_LE(&key[24]); + f3 = ((h3 >> 18) | (h4 << 8)) + (uint64_t)U8TO32_LE(&key[28]); + + U32TO8_LE(&out[ 0], f0); f1 += (f0 >> 32); + U32TO8_LE(&out[ 4], f1); f2 += (f1 >> 32); + U32TO8_LE(&out[ 8], f2); f3 += (f2 >> 32); + U32TO8_LE(&out[12], f3); +} diff --git a/poly1305.h b/poly1305.h new file mode 100644 index 000000000000..221efc462e1b --- /dev/null +++ b/poly1305.h @@ -0,0 +1,22 @@ +/* $OpenBSD: poly1305.h,v 1.2 2013/12/19 22:57:13 djm Exp $ */ + +/* + * Public Domain poly1305 from Andrew Moon + * poly1305-donna-unrolled.c from https://github.com/floodyberry/poly1305-donna + */ + +#ifndef POLY1305_H +#define POLY1305_H + +#include + +#define POLY1305_KEYLEN 32 +#define POLY1305_TAGLEN 16 + +void poly1305_auth(u_char out[POLY1305_TAGLEN], const u_char *m, size_t inlen, + const u_char key[POLY1305_KEYLEN]) + __attribute__((__bounded__(__minbytes__, 1, POLY1305_TAGLEN))) + __attribute__((__bounded__(__buffer__, 2, 3))) + __attribute__((__bounded__(__minbytes__, 4, POLY1305_KEYLEN))); + +#endif /* POLY1305_H */ diff --git a/progressmeter.c b/progressmeter.c index 332bd3c9902f..bbbc7066bcb7 100644 --- a/progressmeter.c +++ b/progressmeter.c @@ -1,4 +1,4 @@ -/* $OpenBSD: progressmeter.c,v 1.39 2013/06/02 13:33:05 dtucker Exp $ */ +/* $OpenBSD: progressmeter.c,v 1.40 2013/09/19 00:24:52 djm Exp $ */ /* * Copyright (c) 2003 Nils Nordman. All rights reserved. * @@ -66,6 +66,7 @@ static void update_progress_meter(int); static time_t start; /* start progress */ static time_t last_update; /* last progress update */ static char *file; /* name of the file being transferred */ +static off_t start_pos; /* initial position of transfer */ static off_t end_pos; /* ending position of transfer */ static off_t cur_pos; /* transfer position as of last refresh */ static volatile off_t *counter; /* progress counter */ @@ -129,7 +130,7 @@ refresh_progress_meter(void) int i, len; int file_len; - transferred = *counter - cur_pos; + transferred = *counter - (cur_pos ? cur_pos : start_pos); cur_pos = *counter; now = monotime(); bytes_left = end_pos - cur_pos; @@ -139,7 +140,7 @@ refresh_progress_meter(void) else { elapsed = now - start; /* Calculate true total speed when done */ - transferred = end_pos; + transferred = end_pos - start_pos; bytes_per_second = 0; } @@ -251,6 +252,7 @@ start_progress_meter(char *f, off_t filesize, off_t *ctr) { start = last_update = monotime(); file = f; + start_pos = *ctr; end_pos = filesize; cur_pos = 0; counter = ctr; diff --git a/readconf.c b/readconf.c index 1464430a4025..9c7e73d7d8a6 100644 --- a/readconf.c +++ b/readconf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: readconf.c,v 1.204 2013/06/10 19:19:44 dtucker Exp $ */ +/* $OpenBSD: readconf.c,v 1.215 2013/12/06 13:39:49 markus Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -17,6 +17,7 @@ #include #include #include +#include #include #include @@ -24,7 +25,12 @@ #include #include +#include #include +#ifdef HAVE_PATHS_H +# include +#endif +#include #include #include #include @@ -47,6 +53,7 @@ #include "buffer.h" #include "kex.h" #include "mac.h" +#include "uidswap.h" /* Format of the configuration file: @@ -115,12 +122,13 @@ typedef enum { oBadOption, + oHost, oMatch, oForwardAgent, oForwardX11, oForwardX11Trusted, oForwardX11Timeout, oGatewayPorts, oExitOnForwardFailure, oPasswordAuthentication, oRSAAuthentication, oChallengeResponseAuthentication, oXAuthLocation, oIdentityFile, oHostName, oPort, oCipher, oRemoteForward, oLocalForward, - oUser, oHost, oEscapeChar, oRhostsRSAAuthentication, oProxyCommand, + oUser, oEscapeChar, oRhostsRSAAuthentication, oProxyCommand, oGlobalKnownHostsFile, oUserKnownHostsFile, oConnectionAttempts, oBatchMode, oCheckHostIP, oStrictHostKeyChecking, oCompression, oCompressionLevel, oTCPKeepAlive, oNumberOfPasswordPrompts, @@ -137,7 +145,9 @@ typedef enum { oHashKnownHosts, oTunnel, oTunnelDevice, oLocalCommand, oPermitLocalCommand, oVisualHostKey, oUseRoaming, oZeroKnowledgePasswordAuthentication, - oKexAlgorithms, oIPQoS, oRequestTTY, oIgnoreUnknown, + oKexAlgorithms, oIPQoS, oRequestTTY, oIgnoreUnknown, oProxyUseFdpass, + oCanonicalDomains, oCanonicalizeHostname, oCanonicalizeMaxDots, + oCanonicalizeFallbackLocal, oCanonicalizePermittedCNAMEs, oIgnoredUnknownOption, oDeprecated, oUnsupported } OpCodes; @@ -194,6 +204,7 @@ static struct { { "localforward", oLocalForward }, { "user", oUser }, { "host", oHost }, + { "match", oMatch }, { "escapechar", oEscapeChar }, { "globalknownhostsfile", oGlobalKnownHostsFile }, { "globalknownhostsfile2", oDeprecated }, @@ -249,6 +260,12 @@ static struct { { "kexalgorithms", oKexAlgorithms }, { "ipqos", oIPQoS }, { "requesttty", oRequestTTY }, + { "proxyusefdpass", oProxyUseFdpass }, + { "canonicaldomains", oCanonicalDomains }, + { "canonicalizefallbacklocal", oCanonicalizeFallbackLocal }, + { "canonicalizehostname", oCanonicalizeHostname }, + { "canonicalizemaxdots", oCanonicalizeMaxDots }, + { "canonicalizepermittedcnames", oCanonicalizePermittedCNAMEs }, { "ignoreunknown", oIgnoreUnknown }, { NULL, oBadOption } @@ -348,10 +365,243 @@ add_identity_file(Options *options, const char *dir, const char *filename, options->identity_files[options->num_identity_files++] = path; } +int +default_ssh_port(void) +{ + static int port; + struct servent *sp; + + if (port == 0) { + sp = getservbyname(SSH_SERVICE_NAME, "tcp"); + port = sp ? ntohs(sp->s_port) : SSH_DEFAULT_PORT; + } + return port; +} + +/* + * Execute a command in a shell. + * Return its exit status or -1 on abnormal exit. + */ +static int +execute_in_shell(const char *cmd) +{ + char *shell, *command_string; + pid_t pid; + int devnull, status; + extern uid_t original_real_uid; + + if ((shell = getenv("SHELL")) == NULL) + shell = _PATH_BSHELL; + + /* + * Use "exec" to avoid "sh -c" processes on some platforms + * (e.g. Solaris) + */ + xasprintf(&command_string, "exec %s", cmd); + + /* Need this to redirect subprocess stdin/out */ + if ((devnull = open(_PATH_DEVNULL, O_RDWR)) == -1) + fatal("open(/dev/null): %s", strerror(errno)); + + debug("Executing command: '%.500s'", cmd); + + /* Fork and execute the command. */ + if ((pid = fork()) == 0) { + char *argv[4]; + + /* Child. Permanently give up superuser privileges. */ + permanently_drop_suid(original_real_uid); + + /* Redirect child stdin and stdout. Leave stderr */ + if (dup2(devnull, STDIN_FILENO) == -1) + fatal("dup2: %s", strerror(errno)); + if (dup2(devnull, STDOUT_FILENO) == -1) + fatal("dup2: %s", strerror(errno)); + if (devnull > STDERR_FILENO) + close(devnull); + closefrom(STDERR_FILENO + 1); + + argv[0] = shell; + argv[1] = "-c"; + argv[2] = command_string; + argv[3] = NULL; + + execv(argv[0], argv); + error("Unable to execute '%.100s': %s", cmd, strerror(errno)); + /* Die with signal to make this error apparent to parent. */ + signal(SIGTERM, SIG_DFL); + kill(getpid(), SIGTERM); + _exit(1); + } + /* Parent. */ + if (pid < 0) + fatal("%s: fork: %.100s", __func__, strerror(errno)); + + close(devnull); + free(command_string); + + while (waitpid(pid, &status, 0) == -1) { + if (errno != EINTR && errno != EAGAIN) + fatal("%s: waitpid: %s", __func__, strerror(errno)); + } + if (!WIFEXITED(status)) { + error("command '%.100s' exited abnormally", cmd); + return -1; + } + debug3("command returned status %d", WEXITSTATUS(status)); + return WEXITSTATUS(status); +} + +/* + * Parse and execute a Match directive. + */ +static int +match_cfg_line(Options *options, char **condition, struct passwd *pw, + const char *host_arg, const char *filename, int linenum) +{ + char *arg, *attrib, *cmd, *cp = *condition, *host; + const char *ruser; + int r, port, result = 1, attributes = 0; + size_t len; + char thishost[NI_MAXHOST], shorthost[NI_MAXHOST], portstr[NI_MAXSERV]; + + /* + * Configuration is likely to be incomplete at this point so we + * must be prepared to use default values. + */ + port = options->port <= 0 ? default_ssh_port() : options->port; + ruser = options->user == NULL ? pw->pw_name : options->user; + if (options->hostname != NULL) { + /* NB. Please keep in sync with ssh.c:main() */ + host = percent_expand(options->hostname, + "h", host_arg, (char *)NULL); + } else + host = xstrdup(host_arg); + + debug3("checking match for '%s' host %s", cp, host); + while ((attrib = strdelim(&cp)) && *attrib != '\0') { + attributes++; + if (strcasecmp(attrib, "all") == 0) { + if (attributes != 1 || + ((arg = strdelim(&cp)) != NULL && *arg != '\0')) { + error("'all' cannot be combined with other " + "Match attributes"); + result = -1; + goto out; + } + *condition = cp; + result = 1; + goto out; + } + if ((arg = strdelim(&cp)) == NULL || *arg == '\0') { + error("Missing Match criteria for %s", attrib); + result = -1; + goto out; + } + len = strlen(arg); + if (strcasecmp(attrib, "host") == 0) { + if (match_hostname(host, arg, len) != 1) + result = 0; + else + debug("%.200s line %d: matched 'Host %.100s' ", + filename, linenum, host); + } else if (strcasecmp(attrib, "originalhost") == 0) { + if (match_hostname(host_arg, arg, len) != 1) + result = 0; + else + debug("%.200s line %d: matched " + "'OriginalHost %.100s' ", + filename, linenum, host_arg); + } else if (strcasecmp(attrib, "user") == 0) { + if (match_pattern_list(ruser, arg, len, 0) != 1) + result = 0; + else + debug("%.200s line %d: matched 'User %.100s' ", + filename, linenum, ruser); + } else if (strcasecmp(attrib, "localuser") == 0) { + if (match_pattern_list(pw->pw_name, arg, len, 0) != 1) + result = 0; + else + debug("%.200s line %d: matched " + "'LocalUser %.100s' ", + filename, linenum, pw->pw_name); + } else if (strcasecmp(attrib, "exec") == 0) { + if (gethostname(thishost, sizeof(thishost)) == -1) + fatal("gethostname: %s", strerror(errno)); + strlcpy(shorthost, thishost, sizeof(shorthost)); + shorthost[strcspn(thishost, ".")] = '\0'; + snprintf(portstr, sizeof(portstr), "%d", port); + + cmd = percent_expand(arg, + "L", shorthost, + "d", pw->pw_dir, + "h", host, + "l", thishost, + "n", host_arg, + "p", portstr, + "r", ruser, + "u", pw->pw_name, + (char *)NULL); + r = execute_in_shell(cmd); + if (r == -1) { + fatal("%.200s line %d: match exec '%.100s' " + "error", filename, linenum, cmd); + } else if (r == 0) { + debug("%.200s line %d: matched " + "'exec \"%.100s\"' ", + filename, linenum, cmd); + } else + result = 0; + free(cmd); + } else { + error("Unsupported Match attribute %s", attrib); + result = -1; + goto out; + } + } + if (attributes == 0) { + error("One or more attributes required for Match"); + result = -1; + goto out; + } + debug3("match %sfound", result ? "" : "not "); + *condition = cp; + out: + free(host); + return result; +} + +/* Check and prepare a domain name: removes trailing '.' and lowercases */ +static void +valid_domain(char *name, const char *filename, int linenum) +{ + size_t i, l = strlen(name); + u_char c, last = '\0'; + + if (l == 0) + fatal("%s line %d: empty hostname suffix", filename, linenum); + if (!isalpha((u_char)name[0]) && !isdigit((u_char)name[0])) + fatal("%s line %d: hostname suffix \"%.100s\" " + "starts with invalid character", filename, linenum, name); + for (i = 0; i < l; i++) { + c = tolower((u_char)name[i]); + name[i] = (char)c; + if (last == '.' && c == '.') + fatal("%s line %d: hostname suffix \"%.100s\" contains " + "consecutive separators", filename, linenum, name); + if (c != '.' && c != '-' && !isalnum(c) && + c != '_') /* technically invalid, but common */ + fatal("%s line %d: hostname suffix \"%.100s\" contains " + "invalid characters", filename, linenum, name); + last = c; + } + if (name[l - 1] == '.') + name[l - 1] = '\0'; +} + /* * Returns the number of the token pointed to by cp or oBadOption. */ - static OpCodes parse_token(const char *cp, const char *filename, int linenum, const char *ignored_unknown) @@ -369,25 +619,93 @@ parse_token(const char *cp, const char *filename, int linenum, return oBadOption; } +/* Multistate option parsing */ +struct multistate { + char *key; + int value; +}; +static const struct multistate multistate_flag[] = { + { "true", 1 }, + { "false", 0 }, + { "yes", 1 }, + { "no", 0 }, + { NULL, -1 } +}; +static const struct multistate multistate_yesnoask[] = { + { "true", 1 }, + { "false", 0 }, + { "yes", 1 }, + { "no", 0 }, + { "ask", 2 }, + { NULL, -1 } +}; +static const struct multistate multistate_addressfamily[] = { + { "inet", AF_INET }, + { "inet6", AF_INET6 }, + { "any", AF_UNSPEC }, + { NULL, -1 } +}; +static const struct multistate multistate_controlmaster[] = { + { "true", SSHCTL_MASTER_YES }, + { "yes", SSHCTL_MASTER_YES }, + { "false", SSHCTL_MASTER_NO }, + { "no", SSHCTL_MASTER_NO }, + { "auto", SSHCTL_MASTER_AUTO }, + { "ask", SSHCTL_MASTER_ASK }, + { "autoask", SSHCTL_MASTER_AUTO_ASK }, + { NULL, -1 } +}; +static const struct multistate multistate_tunnel[] = { + { "ethernet", SSH_TUNMODE_ETHERNET }, + { "point-to-point", SSH_TUNMODE_POINTOPOINT }, + { "true", SSH_TUNMODE_DEFAULT }, + { "yes", SSH_TUNMODE_DEFAULT }, + { "false", SSH_TUNMODE_NO }, + { "no", SSH_TUNMODE_NO }, + { NULL, -1 } +}; +static const struct multistate multistate_requesttty[] = { + { "true", REQUEST_TTY_YES }, + { "yes", REQUEST_TTY_YES }, + { "false", REQUEST_TTY_NO }, + { "no", REQUEST_TTY_NO }, + { "force", REQUEST_TTY_FORCE }, + { "auto", REQUEST_TTY_AUTO }, + { NULL, -1 } +}; +static const struct multistate multistate_canonicalizehostname[] = { + { "true", SSH_CANONICALISE_YES }, + { "false", SSH_CANONICALISE_NO }, + { "yes", SSH_CANONICALISE_YES }, + { "no", SSH_CANONICALISE_NO }, + { "always", SSH_CANONICALISE_ALWAYS }, + { NULL, -1 } +}; + /* * Processes a single option line as used in the configuration files. This * only sets those values that have not already been set. */ #define WHITESPACE " \t\r\n" - int -process_config_line(Options *options, const char *host, - char *line, const char *filename, int linenum, - int *activep, int userconfig) +process_config_line(Options *options, struct passwd *pw, const char *host, + char *line, const char *filename, int linenum, int *activep, int userconfig) { char *s, **charptr, *endofnumber, *keyword, *arg, *arg2; char **cpptr, fwdarg[256]; u_int i, *uintptr, max_entries = 0; - int negated, opcode, *intptr, value, value2; + int negated, opcode, *intptr, value, value2, cmdline = 0; LogLevel *log_level_ptr; long long val64; size_t len; Forward fwd; + const struct multistate *multistate_ptr; + struct allowed_cname *cname; + + if (activep == NULL) { /* We are processing a command line directive */ + cmdline = 1; + activep = &cmdline; + } /* Strip trailing whitespace */ for (len = strlen(line) - 1; len > 0; len--) { @@ -406,8 +724,7 @@ process_config_line(Options *options, const char *host, if (keyword == NULL || !*keyword || *keyword == '\n' || *keyword == '#') return 0; /* Match lowercase keyword */ - for (i = 0; i < strlen(keyword); i++) - keyword[i] = tolower(keyword[i]); + lowercase(keyword); opcode = parse_token(keyword, filename, linenum, options->ignored_unknown); @@ -437,17 +754,23 @@ process_config_line(Options *options, const char *host, case oForwardAgent: intptr = &options->forward_agent; -parse_flag: + parse_flag: + multistate_ptr = multistate_flag; + parse_multistate: arg = strdelim(&s); if (!arg || *arg == '\0') - fatal("%.200s line %d: Missing yes/no argument.", filename, linenum); - value = 0; /* To avoid compiler warning... */ - if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0) - value = 1; - else if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0) - value = 0; - else - fatal("%.200s line %d: Bad yes/no argument.", filename, linenum); + fatal("%s line %d: missing argument.", + filename, linenum); + value = -1; + for (i = 0; multistate_ptr[i].key != NULL; i++) { + if (strcasecmp(arg, multistate_ptr[i].key) == 0) { + value = multistate_ptr[i].value; + break; + } + } + if (value == -1) + fatal("%s line %d: unsupported option \"%s\".", + filename, linenum, arg); if (*activep && *intptr == -1) *intptr = value; break; @@ -530,27 +853,13 @@ process_config_line(Options *options, const char *host, case oVerifyHostKeyDNS: intptr = &options->verify_host_key_dns; - goto parse_yesnoask; + multistate_ptr = multistate_yesnoask; + goto parse_multistate; case oStrictHostKeyChecking: intptr = &options->strict_host_key_checking; -parse_yesnoask: - arg = strdelim(&s); - if (!arg || *arg == '\0') - fatal("%.200s line %d: Missing yes/no/ask argument.", - filename, linenum); - value = 0; /* To avoid compiler warning... */ - if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0) - value = 1; - else if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0) - value = 0; - else if (strcmp(arg, "ask") == 0) - value = 2; - else - fatal("%.200s line %d: Bad yes/no/ask argument.", filename, linenum); - if (*activep && *intptr == -1) - *intptr = value; - break; + multistate_ptr = multistate_yesnoask; + goto parse_multistate; case oCompression: intptr = &options->compression; @@ -827,6 +1136,9 @@ process_config_line(Options *options, const char *host, goto parse_flag; case oHost: + if (cmdline) + fatal("Host directive not supported as a command-line " + "option"); *activep = 0; arg2 = NULL; while ((arg = strdelim(&s)) != NULL && *arg != '\0') { @@ -853,6 +1165,18 @@ process_config_line(Options *options, const char *host, /* Avoid garbage check below, as strdelim is done. */ return 0; + case oMatch: + if (cmdline) + fatal("Host directive not supported as a command-line " + "option"); + value = match_cfg_line(options, &s, pw, host, + filename, linenum); + if (value < 0) + fatal("%.200s line %d: Bad Match condition", filename, + linenum); + *activep = value; + break; + case oEscapeChar: intptr = &options->escape_char; arg = strdelim(&s); @@ -876,22 +1200,9 @@ process_config_line(Options *options, const char *host, break; case oAddressFamily: - arg = strdelim(&s); - if (!arg || *arg == '\0') - fatal("%s line %d: missing address family.", - filename, linenum); intptr = &options->address_family; - if (strcasecmp(arg, "inet") == 0) - value = AF_INET; - else if (strcasecmp(arg, "inet6") == 0) - value = AF_INET6; - else if (strcasecmp(arg, "any") == 0) - value = AF_UNSPEC; - else - fatal("Unsupported AddressFamily \"%s\"", arg); - if (*activep && *intptr == -1) - *intptr = value; - break; + multistate_ptr = multistate_addressfamily; + goto parse_multistate; case oEnableSSHKeysign: intptr = &options->enable_ssh_keysign; @@ -930,27 +1241,8 @@ process_config_line(Options *options, const char *host, case oControlMaster: intptr = &options->control_master; - arg = strdelim(&s); - if (!arg || *arg == '\0') - fatal("%.200s line %d: Missing ControlMaster argument.", - filename, linenum); - value = 0; /* To avoid compiler warning... */ - if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0) - value = SSHCTL_MASTER_YES; - else if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0) - value = SSHCTL_MASTER_NO; - else if (strcmp(arg, "auto") == 0) - value = SSHCTL_MASTER_AUTO; - else if (strcmp(arg, "ask") == 0) - value = SSHCTL_MASTER_ASK; - else if (strcmp(arg, "autoask") == 0) - value = SSHCTL_MASTER_AUTO_ASK; - else - fatal("%.200s line %d: Bad ControlMaster argument.", - filename, linenum); - if (*activep && *intptr == -1) - *intptr = value; - break; + multistate_ptr = multistate_controlmaster; + goto parse_multistate; case oControlPersist: /* no/false/yes/true, or a time spec */ @@ -982,25 +1274,8 @@ process_config_line(Options *options, const char *host, case oTunnel: intptr = &options->tun_open; - arg = strdelim(&s); - if (!arg || *arg == '\0') - fatal("%s line %d: Missing yes/point-to-point/" - "ethernet/no argument.", filename, linenum); - value = 0; /* silence compiler */ - if (strcasecmp(arg, "ethernet") == 0) - value = SSH_TUNMODE_ETHERNET; - else if (strcasecmp(arg, "point-to-point") == 0) - value = SSH_TUNMODE_POINTOPOINT; - else if (strcasecmp(arg, "yes") == 0) - value = SSH_TUNMODE_DEFAULT; - else if (strcasecmp(arg, "no") == 0) - value = SSH_TUNMODE_NO; - else - fatal("%s line %d: Bad yes/point-to-point/ethernet/" - "no argument: %s", filename, linenum, arg); - if (*activep) - *intptr = value; - break; + multistate_ptr = multistate_tunnel; + goto parse_multistate; case oTunnelDevice: arg = strdelim(&s); @@ -1049,29 +1324,74 @@ process_config_line(Options *options, const char *host, goto parse_flag; case oRequestTTY: - arg = strdelim(&s); - if (!arg || *arg == '\0') - fatal("%s line %d: missing argument.", - filename, linenum); intptr = &options->request_tty; - if (strcasecmp(arg, "yes") == 0) - value = REQUEST_TTY_YES; - else if (strcasecmp(arg, "no") == 0) - value = REQUEST_TTY_NO; - else if (strcasecmp(arg, "force") == 0) - value = REQUEST_TTY_FORCE; - else if (strcasecmp(arg, "auto") == 0) - value = REQUEST_TTY_AUTO; - else - fatal("Unsupported RequestTTY \"%s\"", arg); - if (*activep && *intptr == -1) - *intptr = value; - break; + multistate_ptr = multistate_requesttty; + goto parse_multistate; case oIgnoreUnknown: charptr = &options->ignored_unknown; goto parse_string; + case oProxyUseFdpass: + intptr = &options->proxy_use_fdpass; + goto parse_flag; + + case oCanonicalDomains: + value = options->num_canonical_domains != 0; + while ((arg = strdelim(&s)) != NULL && *arg != '\0') { + valid_domain(arg, filename, linenum); + if (!*activep || value) + continue; + if (options->num_canonical_domains >= MAX_CANON_DOMAINS) + fatal("%s line %d: too many hostname suffixes.", + filename, linenum); + options->canonical_domains[ + options->num_canonical_domains++] = xstrdup(arg); + } + break; + + case oCanonicalizePermittedCNAMEs: + value = options->num_permitted_cnames != 0; + while ((arg = strdelim(&s)) != NULL && *arg != '\0') { + /* Either '*' for everything or 'list:list' */ + if (strcmp(arg, "*") == 0) + arg2 = arg; + else { + lowercase(arg); + if ((arg2 = strchr(arg, ':')) == NULL || + arg2[1] == '\0') { + fatal("%s line %d: " + "Invalid permitted CNAME \"%s\"", + filename, linenum, arg); + } + *arg2 = '\0'; + arg2++; + } + if (!*activep || value) + continue; + if (options->num_permitted_cnames >= MAX_CANON_DOMAINS) + fatal("%s line %d: too many permitted CNAMEs.", + filename, linenum); + cname = options->permitted_cnames + + options->num_permitted_cnames++; + cname->source_list = xstrdup(arg); + cname->target_list = xstrdup(arg2); + } + break; + + case oCanonicalizeHostname: + intptr = &options->canonicalize_hostname; + multistate_ptr = multistate_canonicalizehostname; + goto parse_multistate; + + case oCanonicalizeMaxDots: + intptr = &options->canonicalize_max_dots; + goto parse_int; + + case oCanonicalizeFallbackLocal: + intptr = &options->canonicalize_fallback_local; + goto parse_flag; + case oDeprecated: debug("%s line %d: Deprecated option \"%s\"", filename, linenum, keyword); @@ -1102,8 +1422,8 @@ process_config_line(Options *options, const char *host, */ int -read_config_file(const char *filename, const char *host, Options *options, - int flags) +read_config_file(const char *filename, struct passwd *pw, const char *host, + Options *options, int flags) { FILE *f; char line[1024]; @@ -1134,8 +1454,8 @@ read_config_file(const char *filename, const char *host, Options *options, while (fgets(line, sizeof(line), f)) { /* Update line number counter. */ linenum++; - if (process_config_line(options, host, line, filename, linenum, - &active, flags & SSHCONF_USERCONF) != 0) + if (process_config_line(options, pw, host, line, filename, + linenum, &active, flags & SSHCONF_USERCONF) != 0) bad_options++; } fclose(f); @@ -1233,7 +1553,13 @@ initialize_options(Options * options) options->ip_qos_interactive = -1; options->ip_qos_bulk = -1; options->request_tty = -1; + options->proxy_use_fdpass = -1; options->ignored_unknown = NULL; + options->num_canonical_domains = 0; + options->num_permitted_cnames = 0; + options->canonicalize_max_dots = -1; + options->canonicalize_fallback_local = -1; + options->canonicalize_hostname = -1; } /* @@ -1321,6 +1647,8 @@ fill_default_options(Options * options) add_identity_file(options, "~/", _PATH_SSH_CLIENT_ID_ECDSA, 0); #endif + add_identity_file(options, "~/", + _PATH_SSH_CLIENT_ID_ED25519, 0); } } if (options->escape_char == -1) @@ -1385,8 +1713,24 @@ fill_default_options(Options * options) options->ip_qos_bulk = IPTOS_THROUGHPUT; if (options->request_tty == -1) options->request_tty = REQUEST_TTY_AUTO; - /* options->local_command should not be set by default */ - /* options->proxy_command should not be set by default */ + if (options->proxy_use_fdpass == -1) + options->proxy_use_fdpass = 0; + if (options->canonicalize_max_dots == -1) + options->canonicalize_max_dots = 1; + if (options->canonicalize_fallback_local == -1) + options->canonicalize_fallback_local = 1; + if (options->canonicalize_hostname == -1) + options->canonicalize_hostname = SSH_CANONICALISE_NO; +#define CLEAR_ON_NONE(v) \ + do { \ + if (v != NULL && strcasecmp(v, "none") == 0) { \ + free(v); \ + v = NULL; \ + } \ + } while(0) + CLEAR_ON_NONE(options->local_command); + CLEAR_ON_NONE(options->proxy_command); + CLEAR_ON_NONE(options->control_path); /* options->user will be set in the main program if appropriate */ /* options->hostname will be set in the main program if appropriate */ /* options->host_key_alias should not be set by default */ @@ -1413,7 +1757,7 @@ parse_forward(Forward *fwd, const char *fwdspec, int dynamicfwd, int remotefwd) cp = p = xstrdup(fwdspec); /* skip leading spaces */ - while (isspace(*cp)) + while (isspace((u_char)*cp)) cp++; for (i = 0; i < 4; ++i) diff --git a/readconf.h b/readconf.h index 23fc500da6ca..2d7ea9fc4971 100644 --- a/readconf.h +++ b/readconf.h @@ -1,4 +1,4 @@ -/* $OpenBSD: readconf.h,v 1.95 2013/05/16 04:27:50 djm Exp $ */ +/* $OpenBSD: readconf.h,v 1.99 2013/10/16 22:49:38 djm Exp $ */ /* * Author: Tatu Ylonen @@ -29,7 +29,13 @@ typedef struct { /* Data structure for representing option data. */ #define MAX_SEND_ENV 256 -#define SSH_MAX_HOSTS_FILES 256 +#define SSH_MAX_HOSTS_FILES 32 +#define MAX_CANON_DOMAINS 32 + +struct allowed_cname { + char *source_list; + char *target_list; +}; typedef struct { int forward_agent; /* Forward authentication agent. */ @@ -138,9 +144,23 @@ typedef struct { int request_tty; + int proxy_use_fdpass; + + int num_canonical_domains; + char *canonical_domains[MAX_CANON_DOMAINS]; + int canonicalize_hostname; + int canonicalize_max_dots; + int canonicalize_fallback_local; + int num_permitted_cnames; + struct allowed_cname permitted_cnames[MAX_CANON_DOMAINS]; + char *ignored_unknown; /* Pattern list of unknown tokens to ignore */ } Options; +#define SSH_CANONICALISE_NO 0 +#define SSH_CANONICALISE_YES 1 +#define SSH_CANONICALISE_ALWAYS 2 + #define SSHCTL_MASTER_NO 0 #define SSHCTL_MASTER_YES 1 #define SSHCTL_MASTER_AUTO 2 @@ -157,12 +177,12 @@ typedef struct { void initialize_options(Options *); void fill_default_options(Options *); -int read_config_file(const char *, const char *, Options *, int); +int process_config_line(Options *, struct passwd *, const char *, char *, + const char *, int, int *, int); +int read_config_file(const char *, struct passwd *, const char *, + Options *, int); int parse_forward(Forward *, const char *, int, int); - -int -process_config_line(Options *, const char *, char *, const char *, int, int *, - int); +int default_ssh_port(void); void add_local_forward(Options *, const Forward *); void add_remote_forward(Options *, const Forward *); diff --git a/regress/Makefile b/regress/Makefile index ab2a6ae7bee7..0c66b17745fc 100644 --- a/regress/Makefile +++ b/regress/Makefile @@ -1,6 +1,6 @@ -# $OpenBSD: Makefile,v 1.65 2013/04/18 02:46:12 djm Exp $ +# $OpenBSD: Makefile,v 1.67 2013/12/06 13:52:46 markus Exp $ -REGRESS_TARGETS= t1 t2 t3 t4 t5 t6 t7 t8 t9 t-exec +REGRESS_TARGETS= t1 t2 t3 t4 t5 t6 t7 t8 t9 t10 t-exec tests: $(REGRESS_TARGETS) # Interop tests are not run by default @@ -44,6 +44,7 @@ LTESTS= connect \ sftp-badcmds \ sftp-batch \ sftp-glob \ + sftp-perm \ reconfigure \ dynamic-forward \ forwarding \ @@ -72,7 +73,7 @@ INTEROP_TESTS= putty-transfer putty-ciphers putty-kex conch-ciphers USER!= id -un CLEANFILES= t2.out t3.out t6.out1 t6.out2 t7.out t7.out.pub copy.1 copy.2 \ - t8.out t8.out.pub t9.out t9.out.pub \ + t8.out t8.out.pub t9.out t9.out.pub t10.out t10.out.pub \ authorized_keys_${USER} known_hosts pidfile testdata \ ssh_config sshd_config.orig ssh_proxy sshd_config sshd_proxy \ rsa.pub rsa rsa1.pub rsa1 host.rsa host.rsa1 \ @@ -86,7 +87,10 @@ CLEANFILES= t2.out t3.out t6.out1 t6.out2 t7.out t7.out.pub copy.1 copy.2 \ authorized_principals_${USER} expect actual ready \ sshd_proxy.* authorized_keys_${USER}.* modpipe revoked-* krl-* \ ssh.log failed-ssh.log sshd.log failed-sshd.log \ - regress.log failed-regress.log ssh-log-wrapper.sh + regress.log failed-regress.log ssh-log-wrapper.sh \ + sftp-server.sh sftp-server.log sftp.log setuid-allowed \ + data ed25519-agent ed25519-agent.pub key.ed25519-512 \ + key.ed25519-512.pub SUDO_CLEAN+= /var/run/testdata_${USER} /var/run/keycommand_${USER} @@ -151,6 +155,14 @@ t9: $(OBJ)/t9.out test "${TEST_SSH_ECC}" != yes || \ ${TEST_SSH_SSHKEYGEN} -Bf $(OBJ)/t9.out > /dev/null + +$(OBJ)/t10.out: + ${TEST_SSH_SSHKEYGEN} -q -t ed25519 -N '' -f $@ + +t10: $(OBJ)/t10.out + ${TEST_SSH_SSHKEYGEN} -lf $(OBJ)/t10.out > /dev/null + ${TEST_SSH_SSHKEYGEN} -Bf $(OBJ)/t10.out > /dev/null + t-exec: ${LTESTS:=.sh} @if [ "x$?" = "x" ]; then exit 0; fi; \ for TEST in ""$?; do \ diff --git a/regress/agent-ptrace.sh b/regress/agent-ptrace.sh index 9f29464c59cc..ae150641fc8a 100644 --- a/regress/agent-ptrace.sh +++ b/regress/agent-ptrace.sh @@ -19,6 +19,13 @@ else exit 0 fi +if $OBJ/setuid-allowed ${SSHAGENT} ; then + : ok +else + echo "skipped (${SSHAGENT} is mounted on a no-setuid filesystem)" + exit 0 +fi + if test -z "$SUDO" ; then echo "skipped (SUDO not set)" exit 0 @@ -38,8 +45,9 @@ else gdb ${SSHAGENT} ${SSH_AGENT_PID} > ${OBJ}/gdb.out 2>&1 << EOF quit EOF - if [ $? -ne 0 ]; then - fail "gdb failed: exit code $?" + r=$? + if [ $r -ne 0 ]; then + fail "gdb failed: exit code $r" fi egrep 'ptrace: Operation not permitted.|procfs:.*Permission denied.|ttrace.*Permission denied.|procfs:.*: Invalid argument.|Unable to access task ' >/dev/null ${OBJ}/gdb.out r=$? diff --git a/regress/agent.sh b/regress/agent.sh index be7d91334d65..cf1a45fe04b0 100644 --- a/regress/agent.sh +++ b/regress/agent.sh @@ -1,4 +1,4 @@ -# $OpenBSD: agent.sh,v 1.8 2013/05/17 00:37:40 dtucker Exp $ +# $OpenBSD: agent.sh,v 1.9 2013/12/06 13:52:46 markus Exp $ # Placed in the Public Domain. tid="simple agent test" @@ -20,7 +20,7 @@ else fi trace "overwrite authorized keys" printf '' > $OBJ/authorized_keys_$USER - for t in rsa rsa1; do + for t in ed25519 rsa rsa1; do # generate user key for agent rm -f $OBJ/$t-agent ${SSHKEYGEN} -q -N '' -t $t -f $OBJ/$t-agent ||\ @@ -34,40 +34,46 @@ else fi done ${SSHADD} -l > /dev/null 2>&1 - if [ $? -ne 0 ]; then - fail "ssh-add -l failed: exit code $?" + r=$? + if [ $r -ne 0 ]; then + fail "ssh-add -l failed: exit code $r" fi # the same for full pubkey output ${SSHADD} -L > /dev/null 2>&1 - if [ $? -ne 0 ]; then - fail "ssh-add -L failed: exit code $?" + r=$? + if [ $r -ne 0 ]; then + fail "ssh-add -L failed: exit code $r" fi trace "simple connect via agent" for p in 1 2; do ${SSH} -$p -F $OBJ/ssh_proxy somehost exit 5$p - if [ $? -ne 5$p ]; then - fail "ssh connect with protocol $p failed (exit code $?)" + r=$? + if [ $r -ne 5$p ]; then + fail "ssh connect with protocol $p failed (exit code $r)" fi done trace "agent forwarding" for p in 1 2; do ${SSH} -A -$p -F $OBJ/ssh_proxy somehost ${SSHADD} -l > /dev/null 2>&1 - if [ $? -ne 0 ]; then - fail "ssh-add -l via agent fwd proto $p failed (exit code $?)" + r=$? + if [ $r -ne 0 ]; then + fail "ssh-add -l via agent fwd proto $p failed (exit code $r)" fi ${SSH} -A -$p -F $OBJ/ssh_proxy somehost \ "${SSH} -$p -F $OBJ/ssh_proxy somehost exit 5$p" - if [ $? -ne 5$p ]; then - fail "agent fwd proto $p failed (exit code $?)" + r=$? + if [ $r -ne 5$p ]; then + fail "agent fwd proto $p failed (exit code $r)" fi done trace "delete all agent keys" ${SSHADD} -D > /dev/null 2>&1 - if [ $? -ne 0 ]; then - fail "ssh-add -D failed: exit code $?" + r=$? + if [ $r -ne 0 ]; then + fail "ssh-add -D failed: exit code $r" fi trace "kill agent" diff --git a/regress/cert-hostkey.sh b/regress/cert-hostkey.sh index 35cd392930a8..a1318cd536bb 100755 --- a/regress/cert-hostkey.sh +++ b/regress/cert-hostkey.sh @@ -1,14 +1,8 @@ -# $OpenBSD: cert-hostkey.sh,v 1.7 2013/05/17 00:37:40 dtucker Exp $ +# $OpenBSD: cert-hostkey.sh,v 1.8 2013/12/06 13:52:46 markus Exp $ # Placed in the Public Domain. tid="certified host keys" -# used to disable ECC based tests on platforms without ECC -ecdsa="" -if test "x$TEST_SSH_ECC" = "xyes"; then - ecdsa=ecdsa -fi - rm -f $OBJ/known_hosts-cert $OBJ/host_ca_key* $OBJ/cert_host_key* cp $OBJ/sshd_proxy $OBJ/sshd_proxy_bak @@ -23,8 +17,17 @@ ${SSHKEYGEN} -q -N '' -t rsa -f $OBJ/host_ca_key ||\ cat $OBJ/host_ca_key.pub ) > $OBJ/known_hosts-cert +PLAIN_TYPES=`$SSH -Q key-plain | sed 's/^ssh-dss/ssh-dsa/g;s/^ssh-//'` + +type_has_legacy() { + case $1 in + ed25519*|ecdsa*) return 1 ;; + esac + return 0 +} + # Generate and sign host keys -for ktype in rsa dsa $ecdsa ; do +for ktype in $PLAIN_TYPES ; do verbose "$tid: sign host ${ktype} cert" # Generate and sign a host key ${SSHKEYGEN} -q -N '' -t ${ktype} \ @@ -34,10 +37,10 @@ for ktype in rsa dsa $ecdsa ; do -I "regress host key for $USER" \ -n $HOSTS $OBJ/cert_host_key_${ktype} || fail "couldn't sign cert_host_key_${ktype}" - # v00 ecdsa certs do not exist - test "${ktype}" = "ecdsa" && continue + type_has_legacy $ktype || continue cp $OBJ/cert_host_key_${ktype} $OBJ/cert_host_key_${ktype}_v00 cp $OBJ/cert_host_key_${ktype}.pub $OBJ/cert_host_key_${ktype}_v00.pub + verbose "$tid: sign host ${ktype}_v00 cert" ${SSHKEYGEN} -t v00 -h -q -s $OBJ/host_ca_key \ -I "regress host key for $USER" \ -n $HOSTS $OBJ/cert_host_key_${ktype}_v00 || @@ -46,7 +49,7 @@ done # Basic connect tests for privsep in yes no ; do - for ktype in rsa dsa $ecdsa rsa_v00 dsa_v00; do + for ktype in $PLAIN_TYPES rsa_v00 dsa_v00; do verbose "$tid: host ${ktype} cert connect privsep $privsep" ( cat $OBJ/sshd_proxy_bak @@ -69,26 +72,13 @@ done printf '@cert-authority ' printf "$HOSTS " cat $OBJ/host_ca_key.pub - printf '@revoked ' - printf "* " - cat $OBJ/cert_host_key_rsa.pub - if test "x$TEST_SSH_ECC" = "xyes"; then - printf '@revoked ' - printf "* " - cat $OBJ/cert_host_key_ecdsa.pub - fi - printf '@revoked ' - printf "* " - cat $OBJ/cert_host_key_dsa.pub - printf '@revoked ' - printf "* " - cat $OBJ/cert_host_key_rsa_v00.pub - printf '@revoked ' - printf "* " - cat $OBJ/cert_host_key_dsa_v00.pub + for ktype in $PLAIN_TYPES rsa_v00 dsa_v00; do + test -f "$OBJ/cert_host_key_${ktype}.pub" || fatal "no pubkey" + printf "@revoked * `cat $OBJ/cert_host_key_${ktype}.pub`\n" + done ) > $OBJ/known_hosts-cert for privsep in yes no ; do - for ktype in rsa dsa $ecdsa rsa_v00 dsa_v00; do + for ktype in $PLAIN_TYPES rsa_v00 dsa_v00; do verbose "$tid: host ${ktype} revoked cert privsep $privsep" ( cat $OBJ/sshd_proxy_bak @@ -115,7 +105,7 @@ done printf "* " cat $OBJ/host_ca_key.pub ) > $OBJ/known_hosts-cert -for ktype in rsa dsa $ecdsa rsa_v00 dsa_v00 ; do +for ktype in $PLAIN_TYPES rsa_v00 dsa_v00 ; do verbose "$tid: host ${ktype} revoked cert" ( cat $OBJ/sshd_proxy_bak @@ -186,9 +176,8 @@ test_one "cert has constraints" failure "-h -Oforce-command=false" # Check downgrade of cert to raw key when no CA found for v in v01 v00 ; do - for ktype in rsa dsa $ecdsa ; do - # v00 ecdsa certs do not exist. - test "${v}${ktype}" = "v00ecdsa" && continue + for ktype in $PLAIN_TYPES ; do + type_has_legacy $ktype || continue rm -f $OBJ/known_hosts-cert $OBJ/cert_host_key* verbose "$tid: host ${ktype} ${v} cert downgrade to raw key" # Generate and sign a host key @@ -225,9 +214,8 @@ done cat $OBJ/host_ca_key.pub ) > $OBJ/known_hosts-cert for v in v01 v00 ; do - for kt in rsa dsa $ecdsa ; do - # v00 ecdsa certs do not exist. - test "${v}${ktype}" = "v00ecdsa" && continue + for kt in $PLAIN_TYPES ; do + type_has_legacy $kt || continue rm -f $OBJ/cert_host_key* # Self-sign key ${SSHKEYGEN} -q -N '' -t ${kt} \ diff --git a/regress/cert-userkey.sh b/regress/cert-userkey.sh index 6018b38f49ea..b093a9196147 100755 --- a/regress/cert-userkey.sh +++ b/regress/cert-userkey.sh @@ -1,23 +1,26 @@ -# $OpenBSD: cert-userkey.sh,v 1.11 2013/05/17 00:37:40 dtucker Exp $ +# $OpenBSD: cert-userkey.sh,v 1.12 2013/12/06 13:52:46 markus Exp $ # Placed in the Public Domain. tid="certified user keys" -# used to disable ECC based tests on platforms without ECC -ecdsa="" -if test "x$TEST_SSH_ECC" = "xyes"; then - ecdsa=ecdsa -fi - rm -f $OBJ/authorized_keys_$USER $OBJ/user_ca_key* $OBJ/cert_user_key* cp $OBJ/sshd_proxy $OBJ/sshd_proxy_bak +PLAIN_TYPES=`$SSH -Q key-plain | sed 's/^ssh-dss/ssh-dsa/;s/^ssh-//'` + +type_has_legacy() { + case $1 in + ed25519*|ecdsa*) return 1 ;; + esac + return 0 +} + # Create a CA key ${SSHKEYGEN} -q -N '' -t rsa -f $OBJ/user_ca_key ||\ fail "ssh-keygen of user_ca_key failed" # Generate and sign user keys -for ktype in rsa dsa $ecdsa ; do +for ktype in $PLAIN_TYPES ; do verbose "$tid: sign user ${ktype} cert" ${SSHKEYGEN} -q -N '' -t ${ktype} \ -f $OBJ/cert_user_key_${ktype} || \ @@ -25,18 +28,18 @@ for ktype in rsa dsa $ecdsa ; do ${SSHKEYGEN} -q -s $OBJ/user_ca_key -I "regress user key for $USER" \ -z $$ -n ${USER},mekmitasdigoat $OBJ/cert_user_key_${ktype} || fail "couldn't sign cert_user_key_${ktype}" - # v00 ecdsa certs do not exist - test "${ktype}" = "ecdsa" && continue + type_has_legacy $ktype || continue cp $OBJ/cert_user_key_${ktype} $OBJ/cert_user_key_${ktype}_v00 cp $OBJ/cert_user_key_${ktype}.pub $OBJ/cert_user_key_${ktype}_v00.pub + verbose "$tid: sign host ${ktype}_v00 cert" ${SSHKEYGEN} -q -t v00 -s $OBJ/user_ca_key -I \ "regress user key for $USER" \ -n ${USER},mekmitasdigoat $OBJ/cert_user_key_${ktype}_v00 || - fail "couldn't sign cert_user_key_${ktype}_v00" + fatal "couldn't sign cert_user_key_${ktype}_v00" done # Test explicitly-specified principals -for ktype in rsa dsa $ecdsa rsa_v00 dsa_v00 ; do +for ktype in $PLAIN_TYPES rsa_v00 dsa_v00 ; do for privsep in yes no ; do _prefix="${ktype} privsep $privsep" @@ -162,7 +165,7 @@ basic_tests() { extra_sshd="TrustedUserCAKeys $OBJ/user_ca_key.pub" fi - for ktype in rsa dsa $ecdsa rsa_v00 dsa_v00 ; do + for ktype in $PLAIN_TYPES rsa_v00 dsa_v00 ; do for privsep in yes no ; do _prefix="${ktype} privsep $privsep $auth" # Simple connect @@ -332,7 +335,7 @@ test_one "principals key option no principals" failure "" \ # Wrong certificate cat $OBJ/sshd_proxy_bak > $OBJ/sshd_proxy -for ktype in rsa dsa $ecdsa rsa_v00 dsa_v00 ; do +for ktype in $PLAIN_TYPES rsa_v00 dsa_v00 ; do case $ktype in *_v00) args="-t v00" ;; *) args="" ;; diff --git a/regress/cipher-speed.sh b/regress/cipher-speed.sh index 489d9f5fa920..a6d53a78d11f 100644 --- a/regress/cipher-speed.sh +++ b/regress/cipher-speed.sh @@ -1,4 +1,4 @@ -# $OpenBSD: cipher-speed.sh,v 1.9 2013/05/17 04:29:14 dtucker Exp $ +# $OpenBSD: cipher-speed.sh,v 1.11 2013/11/21 03:18:51 djm Exp $ # Placed in the Public Domain. tid="cipher speed" @@ -11,18 +11,7 @@ getbytes () tries="1 2" -ciphers="aes128-cbc 3des-cbc blowfish-cbc cast128-cbc - arcfour128 arcfour256 arcfour - aes192-cbc aes256-cbc rijndael-cbc@lysator.liu.se - aes128-ctr aes192-ctr aes256-ctr" -config_defined OPENSSL_HAVE_EVPGCM && \ - ciphers="$ciphers aes128-gcm@openssh.com aes256-gcm@openssh.com" -macs="hmac-sha1 hmac-md5 umac-64@openssh.com umac-128@openssh.com - hmac-sha1-96 hmac-md5-96" -config_defined HAVE_EVP_SHA256 && \ - macs="$macs hmac-sha2-256 hmac-sha2-512" - -for c in $ciphers; do n=0; for m in $macs; do +for c in `${SSH} -Q cipher`; do n=0; for m in `${SSH} -Q mac`; do trace "proto 2 cipher $c mac $m" for x in $tries; do printf "%-60s" "$c/$m:" @@ -35,10 +24,10 @@ for c in $ciphers; do n=0; for m in $macs; do fail "ssh -2 failed with mac $m cipher $c" fi done - # No point trying all MACs for GCM since they are ignored. - case $c in - aes*-gcm@openssh.com) test $n -gt 0 && break;; - esac + # No point trying all MACs for AEAD ciphers since they are ignored. + if ssh -Q cipher-auth | grep "^${c}\$" >/dev/null 2>&1 ; then + break + fi n=`expr $n + 1` done; done diff --git a/regress/forward-control.sh b/regress/forward-control.sh index 80ddb41672bb..7f7d105e85a6 100755 --- a/regress/forward-control.sh +++ b/regress/forward-control.sh @@ -1,4 +1,4 @@ -# $OpenBSD: forward-control.sh,v 1.1 2012/12/02 20:47:48 djm Exp $ +# $OpenBSD: forward-control.sh,v 1.2 2013/11/18 05:09:32 naddy Exp $ # Placed in the Public Domain. tid="sshd control of local and remote forwarding" diff --git a/regress/integrity.sh b/regress/integrity.sh index 1d17fe10a650..852d82690e9c 100755 --- a/regress/integrity.sh +++ b/regress/integrity.sh @@ -1,4 +1,4 @@ -# $OpenBSD: integrity.sh,v 1.10 2013/05/17 01:32:11 dtucker Exp $ +# $OpenBSD: integrity.sh,v 1.12 2013/11/21 03:18:51 djm Exp $ # Placed in the Public Domain. tid="integrity" @@ -8,18 +8,10 @@ tid="integrity" # XXX and ssh tries to read... tries=10 startoffset=2900 -macs="hmac-sha1 hmac-md5 umac-64@openssh.com umac-128@openssh.com - hmac-sha1-96 hmac-md5-96 - hmac-sha1-etm@openssh.com hmac-md5-etm@openssh.com - umac-64-etm@openssh.com umac-128-etm@openssh.com - hmac-sha1-96-etm@openssh.com hmac-md5-96-etm@openssh.com" -config_defined HAVE_EVP_SHA256 && - macs="$macs hmac-sha2-256 hmac-sha2-512 - hmac-sha2-256-etm@openssh.com hmac-sha2-512-etm@openssh.com" +macs=`${SSH} -Q mac` # The following are not MACs, but ciphers with integrated integrity. They are # handled specially below. -config_defined OPENSSL_HAVE_EVPGCM && \ - macs="$macs aes128-gcm@openssh.com aes256-gcm@openssh.com" +macs="$macs `${SSH} -Q cipher-auth`" # avoid DH group exchange as the extra traffic makes it harder to get the # offset into the stream right. @@ -44,12 +36,14 @@ for m in $macs; do fi # modify output from sshd at offset $off pxy="proxycommand=$cmd | $OBJ/modpipe -wm xor:$off:1" - case $m in - aes*gcm*) macopt="-c $m";; - *) macopt="-m $m";; - esac + if ssh -Q cipher-auth | grep "^${m}\$" >/dev/null 2>&1 ; then + macopt="-c $m" + else + macopt="-m $m -c aes128-ctr" + fi verbose "test $tid: $m @$off" ${SSH} $macopt -2F $OBJ/ssh_proxy -o "$pxy" \ + -oServerAliveInterval=1 -oServerAliveCountMax=30 \ 999.999.999.999 'printf "%4096s" " "' >/dev/null if [ $? -eq 0 ]; then fail "ssh -m $m succeeds with bit-flip at $off" diff --git a/regress/kextype.sh b/regress/kextype.sh index 79c0817bb05c..8c2ac09d66d7 100755 --- a/regress/kextype.sh +++ b/regress/kextype.sh @@ -1,4 +1,4 @@ -# $OpenBSD: kextype.sh,v 1.1 2010/09/22 12:26:05 djm Exp $ +# $OpenBSD: kextype.sh,v 1.4 2013/11/07 04:26:56 dtucker Exp $ # Placed in the Public Domain. tid="login with different key exchange algorithms" @@ -7,18 +7,8 @@ TIME=/usr/bin/time cp $OBJ/sshd_proxy $OBJ/sshd_proxy_bak cp $OBJ/ssh_proxy $OBJ/ssh_proxy_bak -if test "$TEST_SSH_ECC" = "yes"; then - kextypes="ecdh-sha2-nistp256 ecdh-sha2-nistp384 ecdh-sha2-nistp521" -fi -if test "$TEST_SSH_SHA256" = "yes"; then - kextypes="$kextypes diffie-hellman-group-exchange-sha256" -fi -kextypes="$kextypes diffie-hellman-group-exchange-sha1" -kextypes="$kextypes diffie-hellman-group14-sha1" -kextypes="$kextypes diffie-hellman-group1-sha1" - tries="1 2 3 4" -for k in $kextypes; do +for k in `${SSH} -Q kex`; do verbose "kex $k" for i in $tries; do ${SSH} -F $OBJ/ssh_proxy -o KexAlgorithms=$k x true diff --git a/regress/keytype.sh b/regress/keytype.sh index 59586bf0d3d4..9752acb0a080 100755 --- a/regress/keytype.sh +++ b/regress/keytype.sh @@ -1,4 +1,4 @@ -# $OpenBSD: keytype.sh,v 1.2 2013/05/17 00:37:40 dtucker Exp $ +# $OpenBSD: keytype.sh,v 1.3 2013/12/06 13:52:46 markus Exp $ # Placed in the Public Domain. tid="login with different key types" @@ -11,10 +11,16 @@ fi cp $OBJ/sshd_proxy $OBJ/sshd_proxy_bak cp $OBJ/ssh_proxy $OBJ/ssh_proxy_bak -ktypes="dsa-1024 rsa-2048 rsa-3072" -if test "$TEST_SSH_ECC" = "yes"; then - ktypes="$ktypes ecdsa-256 ecdsa-384 ecdsa-521" -fi +# Traditional and builtin key types. +ktypes="dsa-1024 rsa-2048 rsa-3072 ed25519-512" +# Types not present in all OpenSSL versions. +for i in `$SSH -Q key`; do + case "$i" in + ecdsa-sha2-nistp256) ktypes="$ktypes ecdsa-256" ;; + ecdsa-sha2-nistp384) ktypes="$ktypes ecdsa-384" ;; + ecdsa-sha2-nistp521) ktypes="$ktypes ecdsa-521" ;; + esac +done for kt in $ktypes; do rm -f $OBJ/key.$kt diff --git a/regress/krl.sh b/regress/krl.sh index de9cc8764de1..09246371c558 100755 --- a/regress/krl.sh +++ b/regress/krl.sh @@ -1,4 +1,4 @@ -# $OpenBSD: krl.sh,v 1.1 2013/01/18 00:45:29 djm Exp $ +# $OpenBSD: krl.sh,v 1.2 2013/11/21 03:15:46 djm Exp $ # Placed in the Public Domain. tid="key revocation lists" @@ -101,6 +101,9 @@ $SSHKEYGEN $OPTS -kf $OBJ/krl-keyid -s $OBJ/revoked-ca.pub $OBJ/revoked-keyid \ >/dev/null || fatal "$SSHKEYGEN KRL failed" } +## XXX dump with trace and grep for set cert serials +## XXX test ranges near (u64)-1, etc. + verbose "$tid: generating KRLs" genkrls diff --git a/regress/modpipe.c b/regress/modpipe.c index 85747cf7d29e..e854f9e0707d 100755 --- a/regress/modpipe.c +++ b/regress/modpipe.c @@ -14,7 +14,7 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* $OpenBSD: modpipe.c,v 1.5 2013/05/10 03:46:14 djm Exp $ */ +/* $OpenBSD: modpipe.c,v 1.6 2013/11/21 03:16:47 djm Exp $ */ #include "includes.h" @@ -68,7 +68,7 @@ usage(void) #define MAX_MODIFICATIONS 256 struct modification { enum { MOD_XOR, MOD_AND_OR } what; - u_int64_t offset; + unsigned long long offset; u_int8_t m1, m2; }; @@ -79,7 +79,7 @@ parse_modification(const char *s, struct modification *m) int n, m1, m2; bzero(m, sizeof(*m)); - if ((n = sscanf(s, "%16[^:]%*[:]%lli%*[:]%i%*[:]%i", + if ((n = sscanf(s, "%16[^:]%*[:]%llu%*[:]%i%*[:]%i", what, &m->offset, &m1, &m2)) < 3) errx(1, "Invalid modification spec \"%s\"", s); if (strcasecmp(what, "xor") == 0) { diff --git a/regress/rekey.sh b/regress/rekey.sh index 8eb7efaf9e4c..cf9401ea014f 100644 --- a/regress/rekey.sh +++ b/regress/rekey.sh @@ -1,4 +1,4 @@ -# $OpenBSD: rekey.sh,v 1.8 2013/05/17 04:29:14 dtucker Exp $ +# $OpenBSD: rekey.sh,v 1.14 2013/11/21 03:18:51 djm Exp $ # Placed in the Public Domain. tid="rekey" @@ -7,34 +7,67 @@ LOG=${TEST_SSH_LOGFILE} rm -f ${LOG} -for s in 16 1k 128k 256k; do - verbose "client rekeylimit ${s}" +# Test rekeying based on data volume only. +# Arguments will be passed to ssh. +ssh_data_rekeying() +{ rm -f ${COPY} ${LOG} - cat $DATA | \ - ${SSH} -oCompression=no -oRekeyLimit=$s \ - -v -F $OBJ/ssh_proxy somehost "cat > ${COPY}" + ${SSH} <${DATA} -oCompression=no $@ -v -F $OBJ/ssh_proxy somehost \ + "cat > ${COPY}" if [ $? -ne 0 ]; then - fail "ssh failed" + fail "ssh failed ($@)" fi - cmp $DATA ${COPY} || fail "corrupted copy" + cmp ${DATA} ${COPY} || fail "corrupted copy ($@)" n=`grep 'NEWKEYS sent' ${LOG} | wc -l` n=`expr $n - 1` trace "$n rekeying(s)" if [ $n -lt 1 ]; then - fail "no rekeying occured" + fail "no rekeying occured ($@)" fi +} + +increase_datafile_size 300 + +opts="" +for i in `${SSH} -Q kex`; do + opts="$opts KexAlgorithms=$i" +done +for i in `${SSH} -Q cipher`; do + opts="$opts Ciphers=$i" +done +for i in `${SSH} -Q mac`; do + opts="$opts MACs=$i" +done + +for opt in $opts; do + verbose "client rekey $opt" + ssh_data_rekeying -oRekeyLimit=256k -o$opt +done + +# AEAD ciphers are magical so test with all KexAlgorithms +if ${SSH} -Q cipher-auth | grep '^.*$' >/dev/null 2>&1 ; then + for c in `${SSH} -Q cipher-auth`; do + for kex in `${SSH} -Q kex`; do + verbose "client rekey $c $kex" + ssh_data_rekeying -oRekeyLimit=256k -oCiphers=$c -oKexAlgorithms=$kex + done + done +fi + +for s in 16 1k 128k 256k; do + verbose "client rekeylimit ${s}" + ssh_data_rekeying -oCompression=no -oRekeyLimit=$s done for s in 5 10; do verbose "client rekeylimit default ${s}" rm -f ${COPY} ${LOG} - cat $DATA | \ - ${SSH} -oCompression=no -oRekeyLimit="default $s" -F \ - $OBJ/ssh_proxy somehost "cat >${COPY};sleep $s;sleep 3" + ${SSH} < ${DATA} -oCompression=no -oRekeyLimit="default $s" -F \ + $OBJ/ssh_proxy somehost "cat >${COPY};sleep $s;sleep 3" if [ $? -ne 0 ]; then fail "ssh failed" fi - cmp $DATA ${COPY} || fail "corrupted copy" + cmp ${DATA} ${COPY} || fail "corrupted copy" n=`grep 'NEWKEYS sent' ${LOG} | wc -l` n=`expr $n - 1` trace "$n rekeying(s)" @@ -98,10 +131,10 @@ for size in 16 1k 1K 1m 1M 1g 1G; do awk '/rekeylimit/{print $3}'` if [ "$bytes" != "$b" ]; then - fatal "rekeylimit size: expected $bytes got $b" + fatal "rekeylimit size: expected $bytes bytes got $b" fi if [ "$seconds" != "$s" ]; then - fatal "rekeylimit time: expected $time got $s" + fatal "rekeylimit time: expected $time seconds got $s" fi done done diff --git a/regress/scp-ssh-wrapper.sh b/regress/scp-ssh-wrapper.sh index d1005a995a17..c63bc2bc1944 100644 --- a/regress/scp-ssh-wrapper.sh +++ b/regress/scp-ssh-wrapper.sh @@ -17,7 +17,7 @@ printname () { } # Discard all but last argument. We use arg later. -while test "$1" != ""; do +while test "x$1" != "x"; do arg="$1" shift done @@ -52,6 +52,8 @@ badserver_4) echo "X" ;; *) - exec $arg + set -- $arg + shift + exec $SCP "$@" ;; esac diff --git a/regress/scp.sh b/regress/scp.sh index 29c5b35d44e0..c2da2a862543 100644 --- a/regress/scp.sh +++ b/regress/scp.sh @@ -20,6 +20,7 @@ SRC=`dirname ${SCRIPT}` cp ${SRC}/scp-ssh-wrapper.sh ${OBJ}/scp-ssh-wrapper.scp chmod 755 ${OBJ}/scp-ssh-wrapper.scp scpopts="-q -S ${OBJ}/scp-ssh-wrapper.scp" +export SCP # used in scp-ssh-wrapper.scp scpclean() { rm -rf ${COPY} ${COPY2} ${DIR} ${DIR2} diff --git a/regress/setuid-allowed.c b/regress/setuid-allowed.c new file mode 100644 index 000000000000..37b7dc8ad65d --- /dev/null +++ b/regress/setuid-allowed.c @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2013 Damien Miller + * + * 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. + */ + +/* $OpenBSD$ */ + +#include "includes.h" + +#include +#ifdef HAVE_SYS_STATVFS_H +# include +#endif +#include +#include + +void +usage(void) +{ + fprintf(stderr, "check-setuid [path]\n"); + exit(1); +} + +int +main(int argc, char **argv) +{ + const char *path = "."; + struct statvfs sb; + + if (argc > 2) + usage(); + else if (argc == 2) + path = argv[1]; + + if (statvfs(path, &sb) != 0) { + /* Don't return an error if the host doesn't support statvfs */ + if (errno == ENOSYS) + return 0; + fprintf(stderr, "statvfs for \"%s\" failed: %s\n", + path, strerror(errno)); + } + return (sb.f_flag & ST_NOSUID) ? 1 : 0; +} + + diff --git a/regress/sftp-perm.sh b/regress/sftp-perm.sh new file mode 100644 index 000000000000..304ca0ac5877 --- /dev/null +++ b/regress/sftp-perm.sh @@ -0,0 +1,269 @@ +# $OpenBSD: sftp-perm.sh,v 1.2 2013/10/17 22:00:18 djm Exp $ +# Placed in the Public Domain. + +tid="sftp permissions" + +SERVER_LOG=${OBJ}/sftp-server.log +CLIENT_LOG=${OBJ}/sftp.log +TEST_SFTP_SERVER=${OBJ}/sftp-server.sh + +prepare_server() { + printf "#!/bin/sh\nexec $SFTPSERVER -el debug3 $* 2>$SERVER_LOG\n" \ + > $TEST_SFTP_SERVER + chmod a+x $TEST_SFTP_SERVER +} + +run_client() { + echo "$@" | ${SFTP} -D ${TEST_SFTP_SERVER} -vvvb - >$CLIENT_LOG 2>&1 +} + +prepare_files() { + _prep="$1" + rm -f ${COPY} ${COPY}.1 + test -d ${COPY}.dd && { rmdir ${COPY}.dd || fatal "rmdir ${COPY}.dd"; } + test -z "$_prep" && return + sh -c "$_prep" || fail "preparation failed: \"$_prep\"" +} + +postcondition() { + _title="$1" + _check="$2" + test -z "$_check" && return + ${TEST_SHELL} -c "$_check" || fail "postcondition check failed: $_title" +} + +ro_test() { + _desc=$1 + _cmd="$2" + _prep="$3" + _expect_success_post="$4" + _expect_fail_post="$5" + verbose "$tid: read-only $_desc" + # Plain (no options, mostly to test that _cmd is good) + prepare_files "$_prep" + prepare_server + run_client "$_cmd" || fail "plain $_desc failed" + postcondition "$_desc no-readonly" "$_expect_success_post" + # Read-only enabled + prepare_files "$_prep" + prepare_server -R + run_client "$_cmd" && fail "read-only $_desc succeeded" + postcondition "$_desc readonly" "$_expect_fail_post" +} + +perm_test() { + _op=$1 + _whitelist_ops=$2 + _cmd="$3" + _prep="$4" + _expect_success_post="$5" + _expect_fail_post="$6" + verbose "$tid: explicit $_op" + # Plain (no options, mostly to test that _cmd is good) + prepare_files "$_prep" + prepare_server + run_client "$_cmd" || fail "plain $_op failed" + postcondition "$_op no white/blacklists" "$_expect_success_post" + # Whitelist + prepare_files "$_prep" + prepare_server -p $_op,$_whitelist_ops + run_client "$_cmd" || fail "whitelisted $_op failed" + postcondition "$_op whitelisted" "$_expect_success_post" + # Blacklist + prepare_files "$_prep" + prepare_server -P $_op + run_client "$_cmd" && fail "blacklisted $_op succeeded" + postcondition "$_op blacklisted" "$_expect_fail_post" + # Whitelist with op missing. + prepare_files "$_prep" + prepare_server -p $_whitelist_ops + run_client "$_cmd" && fail "no whitelist $_op succeeded" + postcondition "$_op not in whitelist" "$_expect_fail_post" +} + +ro_test \ + "upload" \ + "put $DATA $COPY" \ + "" \ + "cmp $DATA $COPY" \ + "test ! -f $COPY" + +ro_test \ + "setstat" \ + "chmod 0700 $COPY" \ + "touch $COPY; chmod 0400 $COPY" \ + "test -x $COPY" \ + "test ! -x $COPY" + +ro_test \ + "rm" \ + "rm $COPY" \ + "touch $COPY" \ + "test ! -f $COPY" \ + "test -f $COPY" + +ro_test \ + "mkdir" \ + "mkdir ${COPY}.dd" \ + "" \ + "test -d ${COPY}.dd" \ + "test ! -d ${COPY}.dd" + +ro_test \ + "rmdir" \ + "rmdir ${COPY}.dd" \ + "mkdir ${COPY}.dd" \ + "test ! -d ${COPY}.dd" \ + "test -d ${COPY}.dd" + +ro_test \ + "posix-rename" \ + "rename $COPY ${COPY}.1" \ + "touch $COPY" \ + "test -f ${COPY}.1 -a ! -f $COPY" \ + "test -f $COPY -a ! -f ${COPY}.1" + +ro_test \ + "oldrename" \ + "rename -l $COPY ${COPY}.1" \ + "touch $COPY" \ + "test -f ${COPY}.1 -a ! -f $COPY" \ + "test -f $COPY -a ! -f ${COPY}.1" + +ro_test \ + "symlink" \ + "ln -s $COPY ${COPY}.1" \ + "touch $COPY" \ + "test -h ${COPY}.1" \ + "test ! -h ${COPY}.1" + +ro_test \ + "hardlink" \ + "ln $COPY ${COPY}.1" \ + "touch $COPY" \ + "test -f ${COPY}.1" \ + "test ! -f ${COPY}.1" + +# Test explicit permissions + +perm_test \ + "open" \ + "realpath,stat,lstat,read,close" \ + "get $DATA $COPY" \ + "" \ + "cmp $DATA $COPY" \ + "! cmp $DATA $COPY 2>/dev/null" + +perm_test \ + "read" \ + "realpath,stat,lstat,open,close" \ + "get $DATA $COPY" \ + "" \ + "cmp $DATA $COPY" \ + "! cmp $DATA $COPY 2>/dev/null" + +perm_test \ + "write" \ + "realpath,stat,lstat,open,close" \ + "put $DATA $COPY" \ + "" \ + "cmp $DATA $COPY" \ + "! cmp $DATA $COPY 2>/dev/null" + +perm_test \ + "lstat" \ + "realpath,stat,open,read,close" \ + "get $DATA $COPY" \ + "" \ + "cmp $DATA $COPY" \ + "! cmp $DATA $COPY 2>/dev/null" + +perm_test \ + "opendir" \ + "realpath,readdir,stat,lstat" \ + "ls -ln $OBJ" + +perm_test \ + "readdir" \ + "realpath,opendir,stat,lstat" \ + "ls -ln $OBJ" + +perm_test \ + "setstat" \ + "realpath,stat,lstat" \ + "chmod 0700 $COPY" \ + "touch $COPY; chmod 0400 $COPY" \ + "test -x $COPY" \ + "test ! -x $COPY" + +perm_test \ + "remove" \ + "realpath,stat,lstat" \ + "rm $COPY" \ + "touch $COPY" \ + "test ! -f $COPY" \ + "test -f $COPY" + +perm_test \ + "mkdir" \ + "realpath,stat,lstat" \ + "mkdir ${COPY}.dd" \ + "" \ + "test -d ${COPY}.dd" \ + "test ! -d ${COPY}.dd" + +perm_test \ + "rmdir" \ + "realpath,stat,lstat" \ + "rmdir ${COPY}.dd" \ + "mkdir ${COPY}.dd" \ + "test ! -d ${COPY}.dd" \ + "test -d ${COPY}.dd" + +perm_test \ + "posix-rename" \ + "realpath,stat,lstat" \ + "rename $COPY ${COPY}.1" \ + "touch $COPY" \ + "test -f ${COPY}.1 -a ! -f $COPY" \ + "test -f $COPY -a ! -f ${COPY}.1" + +perm_test \ + "rename" \ + "realpath,stat,lstat" \ + "rename -l $COPY ${COPY}.1" \ + "touch $COPY" \ + "test -f ${COPY}.1 -a ! -f $COPY" \ + "test -f $COPY -a ! -f ${COPY}.1" + +perm_test \ + "symlink" \ + "realpath,stat,lstat" \ + "ln -s $COPY ${COPY}.1" \ + "touch $COPY" \ + "test -h ${COPY}.1" \ + "test ! -h ${COPY}.1" + +perm_test \ + "hardlink" \ + "realpath,stat,lstat" \ + "ln $COPY ${COPY}.1" \ + "touch $COPY" \ + "test -f ${COPY}.1" \ + "test ! -f ${COPY}.1" + +perm_test \ + "statvfs" \ + "realpath,stat,lstat" \ + "df /" + +# XXX need good tests for: +# fstat +# fsetstat +# realpath +# stat +# readlink +# fstatvfs + +rm -rf ${COPY} ${COPY}.1 ${COPY}.dd + diff --git a/regress/test-exec.sh b/regress/test-exec.sh index eee44626491e..aac8aa5c2f6e 100644 --- a/regress/test-exec.sh +++ b/regress/test-exec.sh @@ -1,4 +1,4 @@ -# $OpenBSD: test-exec.sh,v 1.46 2013/06/21 02:26:26 djm Exp $ +# $OpenBSD: test-exec.sh,v 1.47 2013/11/09 05:41:34 dtucker Exp $ # Placed in the Public Domain. #SUDO=sudo @@ -133,7 +133,12 @@ fi # Path to sshd must be absolute for rexec case "$SSHD" in /*) ;; -*) SSHD=`which sshd` ;; +*) SSHD=`which $SSHD` ;; +esac + +case "$SSHAGENT" in +/*) ;; +*) SSHAGENT=`which $SSHAGENT` ;; esac # Logfiles. @@ -166,14 +171,22 @@ SSH="$SSHLOGWRAP" # Some test data. We make a copy because some tests will overwrite it. # The tests may assume that $DATA exists and is writable and $COPY does -# not exist. +# not exist. Tests requiring larger data files can call increase_datafile_size +# [kbytes] to ensure the file is at least that large. DATANAME=data DATA=$OBJ/${DATANAME} -cat $SSHD $SSHD $SSHD $SSHD >${DATA} +cat ${SSHAGENT} >${DATA} chmod u+w ${DATA} COPY=$OBJ/copy rm -f ${COPY} +increase_datafile_size() +{ + while [ `du -k ${DATA} | cut -f1` -lt $1 ]; do + cat ${SSHAGENT} >>${DATA} + done +} + # these should be used in tests export SSH SSHD SSHAGENT SSHADD SSHKEYGEN SSHKEYSCAN SFTP SFTPSERVER SCP #echo $SSH $SSHD $SSHAGENT $SSHADD $SSHKEYGEN $SSHKEYSCAN $SFTP $SFTPSERVER $SCP diff --git a/regress/try-ciphers.sh b/regress/try-ciphers.sh index e17c9f5e96db..ac34cedbf910 100644 --- a/regress/try-ciphers.sh +++ b/regress/try-ciphers.sh @@ -1,37 +1,22 @@ -# $OpenBSD: try-ciphers.sh,v 1.20 2013/05/17 10:16:26 dtucker Exp $ +# $OpenBSD: try-ciphers.sh,v 1.22 2013/11/21 03:18:51 djm Exp $ # Placed in the Public Domain. tid="try ciphers" -ciphers="aes128-cbc 3des-cbc blowfish-cbc cast128-cbc - arcfour128 arcfour256 arcfour - aes192-cbc aes256-cbc rijndael-cbc@lysator.liu.se - aes128-ctr aes192-ctr aes256-ctr" -config_defined OPENSSL_HAVE_EVPGCM && \ - ciphers="$ciphers aes128-gcm@openssh.com aes256-gcm@openssh.com" -macs="hmac-sha1 hmac-md5 umac-64@openssh.com umac-128@openssh.com - hmac-sha1-96 hmac-md5-96 - hmac-sha1-etm@openssh.com hmac-md5-etm@openssh.com - umac-64-etm@openssh.com umac-128-etm@openssh.com - hmac-sha1-96-etm@openssh.com hmac-md5-96-etm@openssh.com - hmac-ripemd160-etm@openssh.com" -config_defined HAVE_EVP_SHA256 && - macs="$macs hmac-sha2-256 hmac-sha2-512 - hmac-sha2-256-etm@openssh.com hmac-sha2-512-etm@openssh.com" - -for c in $ciphers; do +for c in `${SSH} -Q cipher`; do n=0 - for m in $macs; do + for m in `${SSH} -Q mac`; do trace "proto 2 cipher $c mac $m" verbose "test $tid: proto 2 cipher $c mac $m" ${SSH} -F $OBJ/ssh_proxy -2 -m $m -c $c somehost true if [ $? -ne 0 ]; then fail "ssh -2 failed with mac $m cipher $c" fi - # No point trying all MACs for GCM since they are ignored. - case $c in - aes*-gcm@openssh.com) test $n -gt 0 && break;; - esac + # No point trying all MACs for AEAD ciphers since they + # are ignored. + if ssh -Q cipher-auth | grep "^${c}\$" >/dev/null 2>&1 ; then + break + fi n=`expr $n + 1` done done diff --git a/roaming_client.c b/roaming_client.c index 81c496827ecd..de049cdc1ccf 100644 --- a/roaming_client.c +++ b/roaming_client.c @@ -1,4 +1,4 @@ -/* $OpenBSD: roaming_client.c,v 1.5 2013/05/17 00:13:14 djm Exp $ */ +/* $OpenBSD: roaming_client.c,v 1.7 2014/01/09 23:20:00 djm Exp $ */ /* * Copyright (c) 2004-2009 AppGate Network Security AB * @@ -48,6 +48,7 @@ #include "roaming.h" #include "ssh2.h" #include "sshconnect.h" +#include "digest.h" /* import */ extern Options options; @@ -90,10 +91,8 @@ request_roaming(void) static void roaming_auth_required(void) { - u_char digest[SHA_DIGEST_LENGTH]; - EVP_MD_CTX md; + u_char digest[SSH_DIGEST_MAX_LENGTH]; Buffer b; - const EVP_MD *evp_md = EVP_sha1(); u_int64_t chall, oldchall; chall = packet_get_int64(); @@ -107,14 +106,13 @@ roaming_auth_required(void) buffer_init(&b); buffer_put_int64(&b, cookie); buffer_put_int64(&b, chall); - EVP_DigestInit(&md, evp_md); - EVP_DigestUpdate(&md, buffer_ptr(&b), buffer_len(&b)); - EVP_DigestFinal(&md, digest, NULL); + if (ssh_digest_buffer(SSH_DIGEST_SHA1, &b, digest, sizeof(digest)) != 0) + fatal("%s: ssh_digest_buffer failed", __func__); buffer_free(&b); packet_start(SSH2_MSG_KEX_ROAMING_AUTH); packet_put_int64(key1 ^ get_recv_bytes()); - packet_put_raw(digest, sizeof(digest)); + packet_put_raw(digest, ssh_digest_bytes(SSH_DIGEST_SHA1)); packet_send(); oldkey1 = key1; @@ -259,10 +257,10 @@ wait_for_roaming_reconnect(void) if (c != '\n' && c != '\r') continue; - if (ssh_connect(host, &hostaddr, options.port, + if (ssh_connect(host, NULL, &hostaddr, options.port, options.address_family, 1, &timeout_ms, - options.tcp_keep_alive, options.use_privileged_port, - options.proxy_command) == 0 && roaming_resume() == 0) { + options.tcp_keep_alive, options.use_privileged_port) == 0 && + roaming_resume() == 0) { packet_restore_state(); reenter_guard = 0; fprintf(stderr, "[connection resumed]\n"); diff --git a/roaming_common.c b/roaming_common.c index 50d6177d0c37..787bef04a6ff 100644 --- a/roaming_common.c +++ b/roaming_common.c @@ -1,4 +1,4 @@ -/* $OpenBSD: roaming_common.c,v 1.10 2013/07/12 00:19:59 djm Exp $ */ +/* $OpenBSD: roaming_common.c,v 1.12 2014/01/09 23:20:00 djm Exp $ */ /* * Copyright (c) 2004-2009 AppGate Network Security AB * @@ -36,6 +36,7 @@ #include "cipher.h" #include "buffer.h" #include "roaming.h" +#include "digest.h" static size_t out_buf_size = 0; static char *out_buf = NULL; @@ -49,7 +50,7 @@ int roaming_enabled = 0; int resume_in_progress = 0; int -get_snd_buf_size() +get_snd_buf_size(void) { int fd = packet_get_connection_out(); int optval; @@ -61,7 +62,7 @@ get_snd_buf_size() } int -get_recv_buf_size() +get_recv_buf_size(void) { int fd = packet_get_connection_in(); int optval; @@ -225,9 +226,7 @@ resend_bytes(int fd, u_int64_t *offset) void calculate_new_key(u_int64_t *key, u_int64_t cookie, u_int64_t challenge) { - const EVP_MD *md = EVP_sha1(); - EVP_MD_CTX ctx; - u_char hash[EVP_MAX_MD_SIZE]; + u_char hash[SSH_DIGEST_MAX_LENGTH]; Buffer b; buffer_init(&b); @@ -235,12 +234,11 @@ calculate_new_key(u_int64_t *key, u_int64_t cookie, u_int64_t challenge) buffer_put_int64(&b, cookie); buffer_put_int64(&b, challenge); - EVP_DigestInit(&ctx, md); - EVP_DigestUpdate(&ctx, buffer_ptr(&b), buffer_len(&b)); - EVP_DigestFinal(&ctx, hash, NULL); + if (ssh_digest_buffer(SSH_DIGEST_SHA1, &b, hash, sizeof(hash)) != 0) + fatal("%s: digest_buffer failed", __func__); buffer_clear(&b); - buffer_append(&b, hash, EVP_MD_size(md)); + buffer_append(&b, hash, ssh_digest_bytes(SSH_DIGEST_SHA1)); *key = buffer_get_int64(&b); buffer_free(&b); } diff --git a/sandbox-capsicum.c b/sandbox-capsicum.c new file mode 100644 index 000000000000..ee2a7e79eafa --- /dev/null +++ b/sandbox-capsicum.c @@ -0,0 +1,120 @@ +/* + * Copyright (c) 2011 Dag-Erling Smorgrav + * + * 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" + +#ifdef SANDBOX_CAPSICUM + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "log.h" +#include "monitor.h" +#include "ssh-sandbox.h" +#include "xmalloc.h" + +/* + * Capsicum sandbox that sets zero nfiles, nprocs and filesize rlimits, + * limits rights on stdout, stdin, stderr, monitor and switches to + * capability mode. + */ + +struct ssh_sandbox { + struct monitor *monitor; + pid_t child_pid; +}; + +struct ssh_sandbox * +ssh_sandbox_init(struct monitor *monitor) +{ + struct ssh_sandbox *box; + + /* + * Strictly, we don't need to maintain any state here but we need + * to return non-NULL to satisfy the API. + */ + debug3("%s: preparing capsicum sandbox", __func__); + box = xcalloc(1, sizeof(*box)); + box->monitor = monitor; + box->child_pid = 0; + + return box; +} + +void +ssh_sandbox_child(struct ssh_sandbox *box) +{ + struct rlimit rl_zero; + cap_rights_t rights; + + rl_zero.rlim_cur = rl_zero.rlim_max = 0; + + if (setrlimit(RLIMIT_FSIZE, &rl_zero) == -1) + fatal("%s: setrlimit(RLIMIT_FSIZE, { 0, 0 }): %s", + __func__, strerror(errno)); +#ifndef SANDBOX_SKIP_RLIMIT_NOFILE + if (setrlimit(RLIMIT_NOFILE, &rl_zero) == -1) + fatal("%s: setrlimit(RLIMIT_NOFILE, { 0, 0 }): %s", + __func__, strerror(errno)); +#endif + if (setrlimit(RLIMIT_NPROC, &rl_zero) == -1) + fatal("%s: setrlimit(RLIMIT_NPROC, { 0, 0 }): %s", + __func__, strerror(errno)); + + cap_rights_init(&rights); + + if (cap_rights_limit(STDIN_FILENO, &rights) < 0 && errno != ENOSYS) + fatal("can't limit stdin: %m"); + if (cap_rights_limit(STDOUT_FILENO, &rights) < 0 && errno != ENOSYS) + fatal("can't limit stdout: %m"); + if (cap_rights_limit(STDERR_FILENO, &rights) < 0 && errno != ENOSYS) + fatal("can't limit stderr: %m"); + + cap_rights_init(&rights, CAP_READ, CAP_WRITE); + if (cap_rights_limit(box->monitor->m_recvfd, &rights) == -1) + fatal("%s: failed to limit the network socket", __func__); + cap_rights_init(&rights, CAP_WRITE); + if (cap_rights_limit(box->monitor->m_log_sendfd, &rights) == -1) + fatal("%s: failed to limit the logging socket", __func__); + if (cap_enter() < 0 && errno != ENOSYS) + fatal("%s: failed to enter capability mode", __func__); + +} + +void +ssh_sandbox_parent_finish(struct ssh_sandbox *box) +{ + free(box); + debug3("%s: finished", __func__); +} + +void +ssh_sandbox_parent_preauth(struct ssh_sandbox *box, pid_t child_pid) +{ + box->child_pid = child_pid; +} + +#endif /* SANDBOX_CAPSICUM */ diff --git a/sandbox-darwin.c b/sandbox-darwin.c index 69901ef143a5..35f0c4d1a998 100644 --- a/sandbox-darwin.c +++ b/sandbox-darwin.c @@ -40,7 +40,7 @@ struct ssh_sandbox { }; struct ssh_sandbox * -ssh_sandbox_init(void) +ssh_sandbox_init(struct monitor *monitor) { struct ssh_sandbox *box; diff --git a/sandbox-null.c b/sandbox-null.c index 29fa9669fd85..d4cb9188b61d 100644 --- a/sandbox-null.c +++ b/sandbox-null.c @@ -39,7 +39,7 @@ struct ssh_sandbox { }; struct ssh_sandbox * -ssh_sandbox_init(void) +ssh_sandbox_init(struct monitor *monitor) { struct ssh_sandbox *box; diff --git a/sandbox-rlimit.c b/sandbox-rlimit.c index a00386337cfd..bba80778b1a1 100644 --- a/sandbox-rlimit.c +++ b/sandbox-rlimit.c @@ -42,7 +42,7 @@ struct ssh_sandbox { }; struct ssh_sandbox * -ssh_sandbox_init(void) +ssh_sandbox_init(struct monitor *monitor) { struct ssh_sandbox *box; @@ -69,9 +69,11 @@ ssh_sandbox_child(struct ssh_sandbox *box) fatal("%s: setrlimit(RLIMIT_FSIZE, { 0, 0 }): %s", __func__, strerror(errno)); #endif +#ifndef SANDBOX_SKIP_RLIMIT_NOFILE if (setrlimit(RLIMIT_NOFILE, &rl_zero) == -1) fatal("%s: setrlimit(RLIMIT_NOFILE, { 0, 0 }): %s", __func__, strerror(errno)); +#endif #ifdef HAVE_RLIMIT_NPROC if (setrlimit(RLIMIT_NPROC, &rl_zero) == -1) fatal("%s: setrlimit(RLIMIT_NPROC, { 0, 0 }): %s", diff --git a/sandbox-seccomp-filter.c b/sandbox-seccomp-filter.c index cc146530599d..2f73067e1a32 100644 --- a/sandbox-seccomp-filter.c +++ b/sandbox-seccomp-filter.c @@ -132,7 +132,7 @@ struct ssh_sandbox { }; struct ssh_sandbox * -ssh_sandbox_init(void) +ssh_sandbox_init(struct monitor *monitor) { struct ssh_sandbox *box; diff --git a/sandbox-systrace.c b/sandbox-systrace.c index cc0db46c4aad..53fbd47cb5aa 100644 --- a/sandbox-systrace.c +++ b/sandbox-systrace.c @@ -78,7 +78,7 @@ struct ssh_sandbox { }; struct ssh_sandbox * -ssh_sandbox_init(void) +ssh_sandbox_init(struct monitor *monitor) { struct ssh_sandbox *box; diff --git a/sc25519.c b/sc25519.c new file mode 100644 index 000000000000..1568d9a58c98 --- /dev/null +++ b/sc25519.c @@ -0,0 +1,308 @@ +/* $OpenBSD: sc25519.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/sc25519.c + */ + +#include "includes.h" + +#include "sc25519.h" + +/*Arithmetic modulo the group order m = 2^252 + 27742317777372353535851937790883648493 = 7237005577332262213973186563042994240857116359379907606001950938285454250989 */ + +static const crypto_uint32 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 crypto_uint32 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 crypto_uint32 lt(crypto_uint32 a,crypto_uint32 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) +{ + crypto_uint32 pb = 0; + crypto_uint32 b; + crypto_uint32 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 crypto_uint32 x[64]) +{ + /* See HAC, Alg. 14.42 */ + int i,j; + crypto_uint32 q2[66]; + crypto_uint32 *q3 = q2 + 33; + crypto_uint32 r1[33]; + crypto_uint32 r2[33]; + crypto_uint32 carry; + crypto_uint32 pb = 0; + crypto_uint32 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; + crypto_uint32 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; + crypto_uint32 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) +{ + crypto_uint32 b = 0; + crypto_uint32 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; + crypto_uint32 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); +} diff --git a/sc25519.h b/sc25519.h new file mode 100644 index 000000000000..a2c15d5ff996 --- /dev/null +++ b/sc25519.h @@ -0,0 +1,80 @@ +/* $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 + +#include "crypto_api.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 +{ + crypto_uint32 v[32]; +} +sc25519; + +typedef struct +{ + crypto_uint32 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 diff --git a/schnorr.c b/schnorr.c index 93822fed4bbd..aa3a57770d37 100644 --- a/schnorr.c +++ b/schnorr.c @@ -1,4 +1,4 @@ -/* $OpenBSD: schnorr.c,v 1.8 2013/11/08 00:39:15 djm Exp $ */ +/* $OpenBSD: schnorr.c,v 1.9 2014/01/09 23:20:00 djm Exp $ */ /* * Copyright (c) 2008 Damien Miller. All rights reserved. * @@ -41,6 +41,7 @@ #include "log.h" #include "schnorr.h" +#include "digest.h" #include "openbsd-compat/openssl-compat.h" @@ -57,12 +58,12 @@ /* * Calculate hash component of Schnorr signature H(g || g^v || g^x || id) - * using the hash function defined by "evp_md". Returns signature as + * using the hash function defined by "hash_alg". Returns signature as * bignum or NULL on error. */ static BIGNUM * schnorr_hash(const BIGNUM *p, const BIGNUM *q, const BIGNUM *g, - const EVP_MD *evp_md, const BIGNUM *g_v, const BIGNUM *g_x, + int hash_alg, const BIGNUM *g_v, const BIGNUM *g_x, const u_char *id, u_int idlen) { u_char *digest; @@ -88,7 +89,7 @@ schnorr_hash(const BIGNUM *p, const BIGNUM *q, const BIGNUM *g, SCHNORR_DEBUG_BUF((buffer_ptr(&b), buffer_len(&b), "%s: hashblob", __func__)); - if (hash_buffer(buffer_ptr(&b), buffer_len(&b), evp_md, + if (hash_buffer(buffer_ptr(&b), buffer_len(&b), hash_alg, &digest, &digest_len) != 0) { error("%s: hash_buffer", __func__); goto out; @@ -113,7 +114,7 @@ schnorr_hash(const BIGNUM *p, const BIGNUM *q, const BIGNUM *g, /* * Generate Schnorr signature to prove knowledge of private value 'x' used * in public exponent g^x, under group defined by 'grp_p', 'grp_q' and 'grp_g' - * using the hash function "evp_md". + * using the hash function "hash_alg". * 'idlen' bytes from 'id' will be included in the signature hash as an anti- * replay salt. * @@ -123,7 +124,7 @@ schnorr_hash(const BIGNUM *p, const BIGNUM *q, const BIGNUM *g, */ int schnorr_sign(const BIGNUM *grp_p, const BIGNUM *grp_q, const BIGNUM *grp_g, - const EVP_MD *evp_md, const BIGNUM *x, const BIGNUM *g_x, + int hash_alg, const BIGNUM *x, const BIGNUM *g_x, const u_char *id, u_int idlen, BIGNUM **r_p, BIGNUM **e_p) { int success = -1; @@ -173,7 +174,7 @@ schnorr_sign(const BIGNUM *grp_p, const BIGNUM *grp_q, const BIGNUM *grp_g, SCHNORR_DEBUG_BN((g_v, "%s: g_v = ", __func__)); /* h = H(g || g^v || g^x || id) */ - if ((h = schnorr_hash(grp_p, grp_q, grp_g, evp_md, g_v, g_x, + if ((h = schnorr_hash(grp_p, grp_q, grp_g, hash_alg, g_v, g_x, id, idlen)) == NULL) { error("%s: schnorr_hash failed", __func__); goto out; @@ -223,7 +224,7 @@ schnorr_sign_buf(const BIGNUM *grp_p, const BIGNUM *grp_q, const BIGNUM *grp_g, Buffer b; BIGNUM *r, *e; - if (schnorr_sign(grp_p, grp_q, grp_g, EVP_sha256(), + if (schnorr_sign(grp_p, grp_q, grp_g, SSH_DIGEST_SHA256, x, g_x, id, idlen, &r, &e) != 0) return -1; @@ -248,13 +249,13 @@ schnorr_sign_buf(const BIGNUM *grp_p, const BIGNUM *grp_q, const BIGNUM *grp_g, /* * Verify Schnorr signature { r (v - xh mod q), e (g^v mod p) } against * public exponent g_x (g^x) under group defined by 'grp_p', 'grp_q' and - * 'grp_g' using hash "evp_md". + * 'grp_g' using hash "hash_alg". * Signature hash will be salted with 'idlen' bytes from 'id'. * Returns -1 on failure, 0 on incorrect signature or 1 on matching signature. */ int schnorr_verify(const BIGNUM *grp_p, const BIGNUM *grp_q, const BIGNUM *grp_g, - const EVP_MD *evp_md, const BIGNUM *g_x, const u_char *id, u_int idlen, + int hash_alg, const BIGNUM *g_x, const u_char *id, u_int idlen, const BIGNUM *r, const BIGNUM *e) { int success = -1; @@ -302,7 +303,7 @@ schnorr_verify(const BIGNUM *grp_p, const BIGNUM *grp_q, const BIGNUM *grp_g, SCHNORR_DEBUG_BN((g_xh, "%s: g_xh = ", __func__)); /* h = H(g || g^v || g^x || id) */ - if ((h = schnorr_hash(grp_p, grp_q, grp_g, evp_md, e, g_x, + if ((h = schnorr_hash(grp_p, grp_q, grp_g, hash_alg, e, g_x, id, idlen)) == NULL) { error("%s: schnorr_hash failed", __func__); goto out; @@ -385,7 +386,7 @@ schnorr_verify_buf(const BIGNUM *grp_p, const BIGNUM *grp_q, goto out; } - ret = schnorr_verify(grp_p, grp_q, grp_g, EVP_sha256(), + ret = schnorr_verify(grp_p, grp_q, grp_g, SSH_DIGEST_SHA256, g_x, id, idlen, r, e); out: BN_clear_free(e); @@ -443,43 +444,33 @@ bn_rand_range_gt_one(const BIGNUM *high) return NULL; } +/* XXX convert all callers of this to use ssh_digest_memory() directly */ /* * Hash contents of buffer 'b' with hash 'md'. Returns 0 on success, * with digest via 'digestp' (caller to free) and length via 'lenp'. * Returns -1 on failure. */ int -hash_buffer(const u_char *buf, u_int len, const EVP_MD *md, +hash_buffer(const u_char *buf, u_int len, int hash_alg, u_char **digestp, u_int *lenp) { - u_char digest[EVP_MAX_MD_SIZE]; - u_int digest_len; - EVP_MD_CTX evp_md_ctx; - int success = -1; + u_char digest[SSH_DIGEST_MAX_LENGTH]; + u_int digest_len = ssh_digest_bytes(hash_alg); - EVP_MD_CTX_init(&evp_md_ctx); - - if (EVP_DigestInit_ex(&evp_md_ctx, md, NULL) != 1) { - error("%s: EVP_DigestInit_ex", __func__); - goto out; + if (digest_len == 0) { + error("%s: invalid hash", __func__); + return -1; } - if (EVP_DigestUpdate(&evp_md_ctx, buf, len) != 1) { - error("%s: EVP_DigestUpdate", __func__); - goto out; - } - if (EVP_DigestFinal_ex(&evp_md_ctx, digest, &digest_len) != 1) { - error("%s: EVP_DigestFinal_ex", __func__); - goto out; + if (ssh_digest_memory(hash_alg, buf, len, digest, digest_len) != 0) { + error("%s: digest_memory failed", __func__); + return -1; } *digestp = xmalloc(digest_len); *lenp = digest_len; memcpy(*digestp, digest, *lenp); - success = 0; - out: - EVP_MD_CTX_cleanup(&evp_md_ctx); bzero(digest, sizeof(digest)); digest_len = 0; - return success; + return 0; } /* print formatted string followed by bignum */ diff --git a/schnorr.h b/schnorr.h index 9730b47cef31..e2405c102904 100644 --- a/schnorr.h +++ b/schnorr.h @@ -1,4 +1,4 @@ -/* $OpenBSD: schnorr.h,v 1.1 2009/03/05 07:18:19 djm Exp $ */ +/* $OpenBSD: schnorr.h,v 1.2 2014/01/09 23:20:00 djm Exp $ */ /* * Copyright (c) 2009 Damien Miller. All rights reserved. * @@ -27,7 +27,7 @@ struct modp_group { }; BIGNUM *bn_rand_range_gt_one(const BIGNUM *high); -int hash_buffer(const u_char *, u_int, const EVP_MD *, u_char **, u_int *); +int hash_buffer(const u_char *, u_int, int, u_char **, u_int *); void debug3_bn(const BIGNUM *, const char *, ...) __attribute__((__nonnull__ (2))) __attribute__((format(printf, 2, 3))); @@ -40,7 +40,7 @@ void modp_group_free(struct modp_group *); /* Signature and verification functions */ int schnorr_sign(const BIGNUM *grp_p, const BIGNUM *grp_q, const BIGNUM *grp_g, - const EVP_MD *evp_md, const BIGNUM *x, const BIGNUM *g_x, + int hash_alg, const BIGNUM *x, const BIGNUM *g_x, const u_char *id, u_int idlen, BIGNUM **r_p, BIGNUM **e_p); int schnorr_sign_buf(const BIGNUM *grp_p, const BIGNUM *grp_q, const BIGNUM *grp_g, @@ -48,7 +48,7 @@ schnorr_sign_buf(const BIGNUM *grp_p, const BIGNUM *grp_q, const BIGNUM *grp_g, u_char **sig, u_int *siglen); int schnorr_verify(const BIGNUM *grp_p, const BIGNUM *grp_q, const BIGNUM *grp_g, - const EVP_MD *evp_md, const BIGNUM *g_x, const u_char *id, u_int idlen, + int hash_alg, const BIGNUM *g_x, const u_char *id, u_int idlen, const BIGNUM *r, const BIGNUM *e); int schnorr_verify_buf(const BIGNUM *grp_p, const BIGNUM *grp_q, diff --git a/scp.0 b/scp.0 index fe7087bc4260..ced71546b04d 100644 --- a/scp.0 +++ b/scp.0 @@ -67,6 +67,11 @@ DESCRIPTION AddressFamily BatchMode BindAddress + CanonicalDomains + CanonicalizeFallbackLocal + CanonicalizeHostname + CanonicalizeMaxDots + CanonicalizePermittedCNAMEs ChallengeResponseAuthentication CheckHostIP Cipher @@ -155,4 +160,4 @@ AUTHORS Timo Rinne Tatu Ylonen -OpenBSD 5.4 July 16, 2013 OpenBSD 5.4 +OpenBSD 5.4 October 20, 2013 OpenBSD 5.4 diff --git a/scp.1 b/scp.1 index c83012c92425..3b67cff0eefb 100644 --- a/scp.1 +++ b/scp.1 @@ -8,9 +8,9 @@ .\" .\" Created: Sun May 7 00:14:37 1995 ylo .\" -.\" $OpenBSD: scp.1,v 1.59 2013/07/16 00:07:52 schwarze Exp $ +.\" $OpenBSD: scp.1,v 1.61 2013/10/20 09:51:26 djm Exp $ .\" -.Dd $Mdocdate: July 16 2013 $ +.Dd $Mdocdate: October 20 2013 $ .Dt SCP 1 .Os .Sh NAME @@ -130,6 +130,11 @@ For full details of the options listed below, and their possible values, see .It AddressFamily .It BatchMode .It BindAddress +.It CanonicalDomains +.It CanonicalizeFallbackLocal +.It CanonicalizeHostname +.It CanonicalizeMaxDots +.It CanonicalizePermittedCNAMEs .It ChallengeResponseAuthentication .It CheckHostIP .It Cipher @@ -232,8 +237,9 @@ debugging connection, authentication, and configuration problems. .Nm is based on the .Xr rcp 1 -program in BSD source code from the Regents of the University of -California. +program in +.Bx +source code from the Regents of the University of California. .Sh AUTHORS .An Timo Rinne Aq Mt tri@iki.fi .An Tatu Ylonen Aq Mt ylo@cs.hut.fi diff --git a/scp.c b/scp.c index 28ded5e9a00a..18d3b1dc9698 100644 --- a/scp.c +++ b/scp.c @@ -1,4 +1,4 @@ -/* $OpenBSD: scp.c,v 1.178 2013/06/22 06:31:57 djm Exp $ */ +/* $OpenBSD: scp.c,v 1.179 2013/11/20 20:53:10 deraadt Exp $ */ /* * scp - secure remote copy. This is basically patched BSD rcp which * uses ssh to do the data transfer (instead of using rcmd). @@ -1023,7 +1023,7 @@ sink(int argc, char **argv) if (*cp++ != ' ') SCREWUP("mode not delimited"); - for (size = 0; isdigit(*cp);) + for (size = 0; isdigit((unsigned char)*cp);) size = size * 10 + (*cp++ - '0'); if (*cp++ != ' ') SCREWUP("size not delimited"); @@ -1287,7 +1287,7 @@ okname(char *cp0) c = (int)*cp; if (c & 0200) goto bad; - if (!isalpha(c) && !isdigit(c)) { + if (!isalpha(c) && !isdigit((unsigned char)c)) { switch (c) { case '\'': case '"': diff --git a/servconf.c b/servconf.c index 747edde6c5f9..9bcd05bf25c0 100644 --- a/servconf.c +++ b/servconf.c @@ -1,5 +1,5 @@ -/* $OpenBSD: servconf.c,v 1.240 2013/07/19 07:37:48 markus Exp $ */ +/* $OpenBSD: servconf.c,v 1.248 2013/12/06 13:39:49 markus Exp $ */ /* * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland * All rights reserved @@ -92,6 +92,7 @@ initialize_server_options(ServerOptions *options) options->x11_forwarding = -1; options->x11_display_offset = -1; options->x11_use_localhost = -1; + options->permit_tty = -1; options->xauth_location = NULL; options->strict_modes = -1; options->tcp_keep_alive = -1; @@ -179,6 +180,8 @@ fill_default_server_options(ServerOptions *options) options->host_key_files[options->num_host_key_files++] = _PATH_HOST_ECDSA_KEY_FILE; #endif + options->host_key_files[options->num_host_key_files++] = + _PATH_HOST_ED25519_KEY_FILE; } } /* No certificates by default */ @@ -212,6 +215,8 @@ fill_default_server_options(ServerOptions *options) options->x11_use_localhost = 1; if (options->xauth_location == NULL) options->xauth_location = _PATH_XAUTH; + if (options->permit_tty == -1) + options->permit_tty = 1; if (options->strict_modes == -1) options->strict_modes = 1; if (options->tcp_keep_alive == -1) @@ -329,7 +334,7 @@ typedef enum { sListenAddress, sAddressFamily, sPrintMotd, sPrintLastLog, sIgnoreRhosts, sX11Forwarding, sX11DisplayOffset, sX11UseLocalhost, - sStrictModes, sEmptyPasswd, sTCPKeepAlive, + sPermitTTY, sStrictModes, sEmptyPasswd, sTCPKeepAlive, sPermitUserEnvironment, sUseLogin, sAllowTcpForwarding, sCompression, sRekeyLimit, sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups, sIgnoreUserKnownHosts, sCiphers, sMacs, sProtocol, sPidFile, @@ -462,6 +467,7 @@ static struct { { "useprivilegeseparation", sUsePrivilegeSeparation, SSHCFG_GLOBAL}, { "acceptenv", sAcceptEnv, SSHCFG_ALL }, { "permittunnel", sPermitTunnel, SSHCFG_ALL }, + { "permittty", sPermitTTY, SSHCFG_ALL }, { "match", sMatch, SSHCFG_ALL }, { "permitopen", sPermitOpen, SSHCFG_ALL }, { "forcecommand", sForceCommand, SSHCFG_ALL }, @@ -641,13 +647,13 @@ match_cfg_line_group(const char *grps, int line, const char *user) /* * All of the attributes on a single Match line are ANDed together, so we need - * to check every * attribute and set the result to zero if any attribute does + * to check every attribute and set the result to zero if any attribute does * not match. */ static int match_cfg_line(char **condition, int line, struct connection_info *ci) { - int result = 1, port; + int result = 1, attributes = 0, port; char *arg, *attrib, *cp = *condition; size_t len; @@ -661,6 +667,17 @@ match_cfg_line(char **condition, int line, struct connection_info *ci) ci->laddress ? ci->laddress : "(null)", ci->lport); while ((attrib = strdelim(&cp)) && *attrib != '\0') { + attributes++; + if (strcasecmp(attrib, "all") == 0) { + if (attributes != 1 || + ((arg = strdelim(&cp)) != NULL && *arg != '\0')) { + error("'all' cannot be combined with other " + "Match attributes"); + return -1; + } + *condition = cp; + return 1; + } if ((arg = strdelim(&cp)) == NULL || *arg == '\0') { error("Missing Match criteria for %s", attrib); return -1; @@ -754,6 +771,10 @@ match_cfg_line(char **condition, int line, struct connection_info *ci) return -1; } } + if (attributes == 0) { + error("One or more attributes required for Match"); + return -1; + } if (ci != NULL) debug3("match %sfound", result ? "" : "not "); *condition = cp; @@ -1117,6 +1138,10 @@ process_server_config_line(ServerOptions *options, char *line, charptr = &options->xauth_location; goto parse_filename; + case sPermitTTY: + intptr = &options->permit_tty; + goto parse_flag; + case sStrictModes: intptr = &options->strict_modes; goto parse_flag; @@ -1719,24 +1744,6 @@ int server_match_spec_complete(struct connection_info *ci) return 0; /* partial */ } -/* Helper macros */ -#define M_CP_INTOPT(n) do {\ - if (src->n != -1) \ - dst->n = src->n; \ -} while (0) -#define M_CP_STROPT(n) do {\ - if (src->n != NULL) { \ - free(dst->n); \ - dst->n = src->n; \ - } \ -} while(0) -#define M_CP_STRARRAYOPT(n, num_n) do {\ - if (src->num_n != 0) { \ - for (dst->num_n = 0; dst->num_n < src->num_n; dst->num_n++) \ - dst->n[dst->num_n] = xstrdup(src->n[dst->num_n]); \ - } \ -} while(0) - /* * Copy any supported values that are set. * @@ -1747,6 +1754,11 @@ int server_match_spec_complete(struct connection_info *ci) void copy_set_server_options(ServerOptions *dst, ServerOptions *src, int preauth) { +#define M_CP_INTOPT(n) do {\ + if (src->n != -1) \ + dst->n = src->n; \ +} while (0) + M_CP_INTOPT(password_authentication); M_CP_INTOPT(gss_authentication); M_CP_INTOPT(rsa_authentication); @@ -1756,8 +1768,6 @@ copy_set_server_options(ServerOptions *dst, ServerOptions *src, int preauth) M_CP_INTOPT(hostbased_uses_name_from_packet_only); M_CP_INTOPT(kbd_interactive_authentication); M_CP_INTOPT(zero_knowledge_password_authentication); - M_CP_STROPT(authorized_keys_command); - M_CP_STROPT(authorized_keys_command_user); M_CP_INTOPT(permit_root_login); M_CP_INTOPT(permit_empty_passwd); @@ -1768,6 +1778,7 @@ copy_set_server_options(ServerOptions *dst, ServerOptions *src, int preauth) M_CP_INTOPT(x11_display_offset); M_CP_INTOPT(x11_forwarding); M_CP_INTOPT(x11_use_localhost); + M_CP_INTOPT(permit_tty); M_CP_INTOPT(max_sessions); M_CP_INTOPT(max_authtries); M_CP_INTOPT(ip_qos_interactive); @@ -1775,6 +1786,20 @@ copy_set_server_options(ServerOptions *dst, ServerOptions *src, int preauth) M_CP_INTOPT(rekey_limit); M_CP_INTOPT(rekey_interval); + /* M_CP_STROPT and M_CP_STRARRAYOPT should not appear before here */ +#define M_CP_STROPT(n) do {\ + if (src->n != NULL && dst->n != src->n) { \ + free(dst->n); \ + dst->n = src->n; \ + } \ +} while(0) +#define M_CP_STRARRAYOPT(n, num_n) do {\ + if (src->num_n != 0) { \ + for (dst->num_n = 0; dst->num_n < src->num_n; dst->num_n++) \ + dst->n[dst->num_n] = xstrdup(src->n[dst->num_n]); \ + } \ +} while(0) + /* See comment in servconf.h */ COPY_MATCH_STRING_OPTS(); @@ -1998,6 +2023,7 @@ dump_config(ServerOptions *o) dump_cfg_fmtint(sPrintLastLog, o->print_lastlog); dump_cfg_fmtint(sX11Forwarding, o->x11_forwarding); dump_cfg_fmtint(sX11UseLocalhost, o->x11_use_localhost); + dump_cfg_fmtint(sPermitTTY, o->permit_tty); dump_cfg_fmtint(sStrictModes, o->strict_modes); dump_cfg_fmtint(sTCPKeepAlive, o->tcp_keep_alive); dump_cfg_fmtint(sEmptyPasswd, o->permit_empty_passwd); @@ -2012,8 +2038,9 @@ dump_config(ServerOptions *o) /* string arguments */ dump_cfg_string(sPidFile, o->pid_file); dump_cfg_string(sXAuthLocation, o->xauth_location); - dump_cfg_string(sCiphers, o->ciphers); - dump_cfg_string(sMacs, o->macs); + dump_cfg_string(sCiphers, o->ciphers ? o->ciphers : + cipher_alg_list(',', 0)); + dump_cfg_string(sMacs, o->macs ? o->macs : mac_alg_list(',')); dump_cfg_string(sBanner, o->banner); dump_cfg_string(sForceCommand, o->adm_forced_command); dump_cfg_string(sChrootDirectory, o->chroot_directory); @@ -2025,6 +2052,8 @@ dump_config(ServerOptions *o) dump_cfg_string(sAuthorizedKeysCommand, o->authorized_keys_command); dump_cfg_string(sAuthorizedKeysCommandUser, o->authorized_keys_command_user); dump_cfg_string(sHostKeyAgent, o->host_key_agent); + dump_cfg_string(sKexAlgorithms, o->kex_algorithms ? o->kex_algorithms : + kex_alg_list(',')); /* string arguments requiring a lookup */ dump_cfg_string(sLogLevel, log_level_name(o->log_level)); @@ -2063,7 +2092,8 @@ dump_config(ServerOptions *o) printf("ipqos %s ", iptos2str(o->ip_qos_interactive)); printf("%s\n", iptos2str(o->ip_qos_bulk)); - printf("rekeylimit %lld %d\n", o->rekey_limit, o->rekey_interval); + printf("rekeylimit %lld %d\n", (long long)o->rekey_limit, + o->rekey_interval); channel_print_adm_permitted_opens(); } diff --git a/servconf.h b/servconf.h index 98aad8ba2b0f..8812c5aab96c 100644 --- a/servconf.h +++ b/servconf.h @@ -1,4 +1,4 @@ -/* $OpenBSD: servconf.h,v 1.109 2013/07/19 07:37:48 markus Exp $ */ +/* $OpenBSD: servconf.h,v 1.111 2013/12/05 01:16:41 djm Exp $ */ /* * Author: Tatu Ylonen @@ -82,6 +82,7 @@ typedef struct { * searching at */ int x11_use_localhost; /* If true, use localhost for fake X11 server. */ char *xauth_location; /* Location of xauth program */ + int permit_tty; /* If false, deny pty allocation */ int strict_modes; /* If true, require string home dir modes. */ int tcp_keep_alive; /* If true, set SO_KEEPALIVE. */ int ip_qos_interactive; /* IP ToS/DSCP/class for interactive */ @@ -201,6 +202,9 @@ struct connection_info { * Match sub-config and the main config, and must be sent from the * privsep slave to the privsep master. We use a macro to ensure all * the options are copied and the copies are done in the correct order. + * + * NB. an option must appear in servconf.c:copy_set_server_options() or + * COPY_MATCH_STRING_OPTS here but never both. */ #define COPY_MATCH_STRING_OPTS() do { \ M_CP_STROPT(banner); \ diff --git a/serverloop.c b/serverloop.c index ccbad617d51d..5b2f8028d20a 100644 --- a/serverloop.c +++ b/serverloop.c @@ -1,4 +1,4 @@ -/* $OpenBSD: serverloop.c,v 1.168 2013/07/12 00:19:59 djm Exp $ */ +/* $OpenBSD: serverloop.c,v 1.169 2013/12/19 00:19:12 dtucker Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -304,7 +304,8 @@ wait_until_can_do_something(fd_set **readsetp, fd_set **writesetp, int *maxfdp, if (compat20 && max_time_milliseconds == 0 && options.client_alive_interval) { client_alive_scheduled = 1; - max_time_milliseconds = options.client_alive_interval * 1000; + max_time_milliseconds = + (u_int64_t)options.client_alive_interval * 1000; } if (compat20) { diff --git a/session.c b/session.c index d4b57bdfbc08..12dd9ab102be 100644 --- a/session.c +++ b/session.c @@ -1,4 +1,4 @@ -/* $OpenBSD: session.c,v 1.266 2013/07/19 07:37:48 markus Exp $ */ +/* $OpenBSD: session.c,v 1.269 2014/01/18 09:36:26 dtucker Exp $ */ /* * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland * All rights reserved @@ -441,7 +441,7 @@ do_authenticated1(Authctxt *authctxt) } } -#define USE_PIPES +#define USE_PIPES 1 /* * This is called to fork and execute a command when we have no tty. This * will call do_child from the child, and server_loop from the parent after @@ -794,27 +794,50 @@ int do_exec(Session *s, const char *command) { int ret; + const char *forced = NULL; + char session_type[1024], *tty = NULL; if (options.adm_forced_command) { original_command = command; command = options.adm_forced_command; - if (IS_INTERNAL_SFTP(command)) { - s->is_subsystem = s->is_subsystem ? - SUBSYSTEM_INT_SFTP : SUBSYSTEM_INT_SFTP_ERROR; - } else if (s->is_subsystem) - s->is_subsystem = SUBSYSTEM_EXT; - debug("Forced command (config) '%.900s'", command); + forced = "(config)"; } else if (forced_command) { original_command = command; command = forced_command; + forced = "(key-option)"; + } + if (forced != NULL) { if (IS_INTERNAL_SFTP(command)) { s->is_subsystem = s->is_subsystem ? SUBSYSTEM_INT_SFTP : SUBSYSTEM_INT_SFTP_ERROR; } else if (s->is_subsystem) s->is_subsystem = SUBSYSTEM_EXT; - debug("Forced command (key option) '%.900s'", command); + snprintf(session_type, sizeof(session_type), + "forced-command %s '%.900s'", forced, command); + } else if (s->is_subsystem) { + snprintf(session_type, sizeof(session_type), + "subsystem '%.900s'", s->subsys); + } else if (command == NULL) { + snprintf(session_type, sizeof(session_type), "shell"); + } else { + /* NB. we don't log unforced commands to preserve privacy */ + snprintf(session_type, sizeof(session_type), "command"); } + if (s->ttyfd != -1) { + tty = s->tty; + if (strncmp(tty, "/dev/", 5) == 0) + tty += 5; + } + + verbose("Starting session: %s%s%s for %s from %.200s port %d", + session_type, + tty == NULL ? "" : " on ", + tty == NULL ? "" : tty, + s->pw->pw_name, + get_remote_ipaddr(), + get_remote_port()); + #ifdef SSH_AUDIT_EVENTS if (command != NULL) PRIVSEP(audit_run_command(command)); @@ -1529,6 +1552,11 @@ do_setusercontext(struct passwd *pw) */ (void) setusercontext(lc, pw, pw->pw_uid, LOGIN_SETUMASK); #else +# ifdef USE_LIBIAF + if (set_id(pw->pw_name) != 0) { + fatal("set_id(%s) Failed", pw->pw_name); + } +# endif /* USE_LIBIAF */ /* Permanently switch to the desired uid. */ permanently_set_uid(pw); #endif @@ -2039,7 +2067,7 @@ session_pty_req(Session *s) u_int len; int n_bytes; - if (no_pty_flag) { + if (no_pty_flag || !options.permit_tty) { debug("Allocating a pty not permitted for this authentication."); return 0; } @@ -2100,15 +2128,16 @@ session_subsystem_req(Session *s) struct stat st; u_int len; int success = 0; - char *prog, *cmd, *subsys = packet_get_string(&len); + char *prog, *cmd; u_int i; + s->subsys = packet_get_string(&len); packet_check_eom(); - logit("subsystem request for %.100s by user %s", subsys, + debug2("subsystem request for %.100s by user %s", s->subsys, s->pw->pw_name); for (i = 0; i < options.num_subsystems; i++) { - if (strcmp(subsys, options.subsystem_name[i]) == 0) { + if (strcmp(s->subsys, options.subsystem_name[i]) == 0) { prog = options.subsystem_command[i]; cmd = options.subsystem_args[i]; if (strcmp(INTERNAL_SFTP_NAME, prog) == 0) { @@ -2127,10 +2156,9 @@ session_subsystem_req(Session *s) } if (!success) - logit("subsystem request for %.100s failed, subsystem not found", - subsys); + logit("subsystem request for %.100s by user %s failed, " + "subsystem not found", s->subsys, s->pw->pw_name); - free(subsys); return success; } @@ -2481,6 +2509,7 @@ session_close(Session *s) free(s->auth_display); free(s->auth_data); free(s->auth_proto); + free(s->subsys); if (s->env != NULL) { for (i = 0; i < s->num_env; i++) { free(s->env[i].name); diff --git a/session.h b/session.h index cbb8e3a32d18..6a2f35e41ffd 100644 --- a/session.h +++ b/session.h @@ -1,4 +1,4 @@ -/* $OpenBSD: session.h,v 1.30 2008/05/08 12:21:16 djm Exp $ */ +/* $OpenBSD: session.h,v 1.31 2013/10/14 21:20:52 djm Exp $ */ /* * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. @@ -55,6 +55,7 @@ struct Session { int chanid; int *x11_chanids; int is_subsystem; + char *subsys; u_int num_env; struct { char *name; diff --git a/sftp-client.c b/sftp-client.c index 2f9793778f97..fc035f2ef577 100644 --- a/sftp-client.c +++ b/sftp-client.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sftp-client.c,v 1.108 2013/11/08 00:39:15 djm Exp $ */ +/* $OpenBSD: sftp-client.c,v 1.113 2014/01/17 00:21:06 djm Exp $ */ /* * Copyright (c) 2001-2004 Damien Miller * @@ -42,6 +42,7 @@ #include #include #include +#include #include #include @@ -76,6 +77,7 @@ struct sftp_conn { #define SFTP_EXT_STATVFS 0x00000002 #define SFTP_EXT_FSTATVFS 0x00000004 #define SFTP_EXT_HARDLINK 0x00000008 +#define SFTP_EXT_FSYNC 0x00000010 u_int exts; u_int64_t limit_kbps; struct bwlimit bwlimit_in, bwlimit_out; @@ -337,7 +339,8 @@ do_init(int fd_in, int fd_out, u_int transfer_buflen, u_int num_requests, Buffer msg; struct sftp_conn *ret; - ret = xmalloc(sizeof(*ret)); + ret = xcalloc(1, sizeof(*ret)); + ret->msg_id = 1; ret->fd_in = fd_in; ret->fd_out = fd_out; ret->transfer_buflen = transfer_buflen; @@ -387,6 +390,10 @@ do_init(int fd_in, int fd_out, u_int transfer_buflen, u_int num_requests, strcmp(value, "1") == 0) { ret->exts |= SFTP_EXT_HARDLINK; known = 1; + } else if (strcmp(name, "fsync@openssh.com") == 0 && + strcmp(value, "1") == 0) { + ret->exts |= SFTP_EXT_FSYNC; + known = 1; } if (known) { debug2("Server supports extension \"%s\" revision %s", @@ -447,12 +454,16 @@ do_close(struct sftp_conn *conn, char *handle, u_int handle_len) static int -do_lsreaddir(struct sftp_conn *conn, char *path, int printflag, +do_lsreaddir(struct sftp_conn *conn, char *path, int print_flag, SFTP_DIRENT ***dir) { Buffer msg; u_int count, type, id, handle_len, i, expected_id, ents = 0; char *handle; + int status = SSH2_FX_FAILURE; + + if (dir) + *dir = NULL; id = conn->msg_id++; @@ -499,20 +510,12 @@ do_lsreaddir(struct sftp_conn *conn, char *path, int printflag, fatal("ID mismatch (%u != %u)", id, expected_id); if (type == SSH2_FXP_STATUS) { - int status = buffer_get_int(&msg); - + status = buffer_get_int(&msg); debug3("Received SSH2_FXP_STATUS %d", status); - - if (status == SSH2_FX_EOF) { + if (status == SSH2_FX_EOF) break; - } else { - error("Couldn't read directory: %s", - fx2txt(status)); - do_close(conn, handle, handle_len); - free(handle); - buffer_free(&msg); - return(status); - } + error("Couldn't read directory: %s", fx2txt(status)); + goto out; } else if (type != SSH2_FXP_NAME) fatal("Expected SSH2_FXP_NAME(%u) packet, got %u", SSH2_FXP_NAME, type); @@ -529,7 +532,7 @@ do_lsreaddir(struct sftp_conn *conn, char *path, int printflag, longname = buffer_get_string(&msg, NULL); a = decode_attrib(&msg); - if (printflag) + if (print_flag) printf("%s\n", longname); /* @@ -540,10 +543,7 @@ do_lsreaddir(struct sftp_conn *conn, char *path, int printflag, if (strchr(filename, '/') != NULL) { error("Server sent suspect path \"%s\" " "during readdir of \"%s\"", filename, path); - goto next; - } - - if (dir) { + } else if (dir) { *dir = xrealloc(*dir, ents + 2, sizeof(**dir)); (*dir)[ents] = xcalloc(1, sizeof(***dir)); (*dir)[ents]->filename = xstrdup(filename); @@ -551,24 +551,29 @@ do_lsreaddir(struct sftp_conn *conn, char *path, int printflag, memcpy(&(*dir)[ents]->a, a, sizeof(*a)); (*dir)[++ents] = NULL; } - next: free(filename); free(longname); } } + status = 0; + out: buffer_free(&msg); do_close(conn, handle, handle_len); free(handle); - /* Don't return partial matches on interrupt */ - if (interrupted && dir != NULL && *dir != NULL) { + if (status != 0 && dir != NULL) { + /* Don't return results on error */ + free_sftp_dirents(*dir); + *dir = NULL; + } else if (interrupted && dir != NULL && *dir != NULL) { + /* Don't return partial matches on interrupt */ free_sftp_dirents(*dir); *dir = xcalloc(1, sizeof(**dir)); **dir = NULL; } - return 0; + return status; } int @@ -581,6 +586,8 @@ void free_sftp_dirents(SFTP_DIRENT **s) { int i; + if (s == NULL) + return; for (i = 0; s[i]; i++) { free(s[i]->filename); free(s[i]->longname); @@ -605,7 +612,7 @@ do_rm(struct sftp_conn *conn, char *path) } int -do_mkdir(struct sftp_conn *conn, char *path, Attrib *a, int printflag) +do_mkdir(struct sftp_conn *conn, char *path, Attrib *a, int print_flag) { u_int status, id; @@ -614,7 +621,7 @@ do_mkdir(struct sftp_conn *conn, char *path, Attrib *a, int printflag) strlen(path), a); status = get_status(conn, id); - if (status != SSH2_FX_OK && printflag) + if (status != SSH2_FX_OK && print_flag) error("Couldn't create directory: %s", fx2txt(status)); return(status); @@ -742,7 +749,7 @@ do_realpath(struct sftp_conn *conn, char *path) if (type == SSH2_FXP_STATUS) { u_int status = buffer_get_int(&msg); - error("Couldn't canonicalise: %s", fx2txt(status)); + error("Couldn't canonicalize: %s", fx2txt(status)); buffer_free(&msg); return NULL; } else if (type != SSH2_FXP_NAME) @@ -768,16 +775,18 @@ do_realpath(struct sftp_conn *conn, char *path) } int -do_rename(struct sftp_conn *conn, char *oldpath, char *newpath) +do_rename(struct sftp_conn *conn, char *oldpath, char *newpath, + int force_legacy) { Buffer msg; u_int status, id; + int use_ext = (conn->exts & SFTP_EXT_POSIX_RENAME) && !force_legacy; buffer_init(&msg); /* Send rename request */ id = conn->msg_id++; - if ((conn->exts & SFTP_EXT_POSIX_RENAME)) { + if (use_ext) { buffer_put_char(&msg, SSH2_FXP_EXTENDED); buffer_put_int(&msg, id); buffer_put_cstring(&msg, "posix-rename@openssh.com"); @@ -789,8 +798,8 @@ do_rename(struct sftp_conn *conn, char *oldpath, char *newpath) buffer_put_cstring(&msg, newpath); send_msg(conn, &msg); debug3("Sent message %s \"%s\" -> \"%s\"", - (conn->exts & SFTP_EXT_POSIX_RENAME) ? "posix-rename@openssh.com" : - "SSH2_FXP_RENAME", oldpath, newpath); + use_ext ? "posix-rename@openssh.com" : "SSH2_FXP_RENAME", + oldpath, newpath); buffer_free(&msg); status = get_status(conn, id); @@ -866,6 +875,36 @@ do_symlink(struct sftp_conn *conn, char *oldpath, char *newpath) return(status); } +int +do_fsync(struct sftp_conn *conn, char *handle, u_int handle_len) +{ + Buffer msg; + u_int status, id; + + /* Silently return if the extension is not supported */ + if ((conn->exts & SFTP_EXT_FSYNC) == 0) + return -1; + + buffer_init(&msg); + + /* Send fsync request */ + id = conn->msg_id++; + + buffer_put_char(&msg, SSH2_FXP_EXTENDED); + buffer_put_int(&msg, id); + buffer_put_cstring(&msg, "fsync@openssh.com"); + buffer_put_string(&msg, handle, handle_len); + send_msg(conn, &msg); + debug3("Sent message fsync@openssh.com I:%u", id); + buffer_free(&msg); + + status = get_status(conn, id); + if (status != SSH2_FX_OK) + error("Couldn't sync file: %s", fx2txt(status)); + + return status; +} + #ifdef notyet char * do_readlink(struct sftp_conn *conn, char *path) @@ -988,7 +1027,7 @@ send_read_request(struct sftp_conn *conn, u_int id, u_int64_t offset, int do_download(struct sftp_conn *conn, char *remote_path, char *local_path, - Attrib *a, int pflag, int resume) + Attrib *a, int preserve_flag, int resume_flag, int fsync_flag) { Attrib junk; Buffer msg; @@ -1051,27 +1090,33 @@ do_download(struct sftp_conn *conn, char *remote_path, char *local_path, return(-1); } - local_fd = open(local_path, O_WRONLY | O_CREAT | (resume ? 0 : O_TRUNC), - mode | S_IWUSR); + local_fd = open(local_path, + O_WRONLY | O_CREAT | (resume_flag ? 0 : O_TRUNC), mode | S_IWUSR); if (local_fd == -1) { error("Couldn't open local file \"%s\" for writing: %s", local_path, strerror(errno)); goto fail; } offset = highwater = 0; - if (resume) { + if (resume_flag) { if (fstat(local_fd, &st) == -1) { error("Unable to stat local file \"%s\": %s", local_path, strerror(errno)); goto fail; } - if ((size_t)st.st_size > size) { + if (st.st_size < 0) { + error("\"%s\" has negative size", local_path); + goto fail; + } + if ((u_int64_t)st.st_size > size) { error("Unable to resume download of \"%s\": " "local file is larger than remote", local_path); fail: do_close(conn, handle, handle_len); buffer_free(&msg); free(handle); + if (local_fd != -1) + close(local_fd); return -1; } offset = highwater = st.st_size; @@ -1209,7 +1254,7 @@ do_download(struct sftp_conn *conn, char *remote_path, char *local_path, fatal("Transfer complete, but requests still in queue"); /* Truncate at highest contiguous point to avoid holes on interrupt */ if (read_error || write_error || interrupted) { - if (reordered && resume) { + if (reordered && resume_flag) { error("Unable to resume download of \"%s\": " "server reordered requests", local_path); } @@ -1219,6 +1264,7 @@ do_download(struct sftp_conn *conn, char *remote_path, char *local_path, if (read_error) { error("Couldn't read from remote file \"%s\" : %s", remote_path, fx2txt(status)); + status = -1; do_close(conn, handle, handle_len); } else if (write_error) { error("Couldn't write to \"%s\": %s", local_path, @@ -1227,17 +1273,18 @@ do_download(struct sftp_conn *conn, char *remote_path, char *local_path, do_close(conn, handle, handle_len); } else { status = do_close(conn, handle, handle_len); - if (interrupted) + if (interrupted || status != SSH2_FX_OK) status = -1; /* Override umask and utimes if asked */ #ifdef HAVE_FCHMOD - if (pflag && fchmod(local_fd, mode) == -1) + if (preserve_flag && fchmod(local_fd, mode) == -1) #else - if (pflag && chmod(local_path, mode) == -1) + if (preserve_flag && chmod(local_path, mode) == -1) #endif /* HAVE_FCHMOD */ error("Couldn't set mode on \"%s\": %s", local_path, strerror(errno)); - if (pflag && (a->flags & SSH2_FILEXFER_ATTR_ACMODTIME)) { + if (preserve_flag && + (a->flags & SSH2_FILEXFER_ATTR_ACMODTIME)) { struct timeval tv[2]; tv[0].tv_sec = a->atime; tv[1].tv_sec = a->mtime; @@ -1246,6 +1293,12 @@ do_download(struct sftp_conn *conn, char *remote_path, char *local_path, error("Can't set times on \"%s\": %s", local_path, strerror(errno)); } + if (fsync_flag) { + debug("syncing \"%s\"", local_path); + if (fsync(local_fd) == -1) + error("Couldn't sync file \"%s\": %s", + local_path, strerror(errno)); + } } close(local_fd); buffer_free(&msg); @@ -1255,8 +1308,9 @@ do_download(struct sftp_conn *conn, char *remote_path, char *local_path, } static int -download_dir_internal(struct sftp_conn *conn, char *src, char *dst, - Attrib *dirattrib, int pflag, int printflag, int depth, int resume) +download_dir_internal(struct sftp_conn *conn, char *src, char *dst, int depth, + Attrib *dirattrib, int preserve_flag, int print_flag, int resume_flag, + int fsync_flag) { int i, ret = 0; SFTP_DIRENT **dir_entries; @@ -1277,7 +1331,7 @@ download_dir_internal(struct sftp_conn *conn, char *src, char *dst, error("\"%s\" is not a directory", src); return -1; } - if (printflag) + if (print_flag) printf("Retrieving %s\n", src); if (dirattrib->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) @@ -1308,12 +1362,13 @@ download_dir_internal(struct sftp_conn *conn, char *src, char *dst, strcmp(filename, "..") == 0) continue; if (download_dir_internal(conn, new_src, new_dst, - &(dir_entries[i]->a), pflag, printflag, - depth + 1, resume) == -1) + depth + 1, &(dir_entries[i]->a), preserve_flag, + print_flag, resume_flag, fsync_flag) == -1) ret = -1; } else if (S_ISREG(dir_entries[i]->a.perm) ) { if (do_download(conn, new_src, new_dst, - &(dir_entries[i]->a), pflag, resume) == -1) { + &(dir_entries[i]->a), preserve_flag, + resume_flag, fsync_flag) == -1) { error("Download of file %s to %s failed", new_src, new_dst); ret = -1; @@ -1325,7 +1380,7 @@ download_dir_internal(struct sftp_conn *conn, char *src, char *dst, free(new_src); } - if (pflag) { + if (preserve_flag) { if (dirattrib->flags & SSH2_FILEXFER_ATTR_ACMODTIME) { struct timeval tv[2]; tv[0].tv_sec = dirattrib->atime; @@ -1346,25 +1401,26 @@ download_dir_internal(struct sftp_conn *conn, char *src, char *dst, int download_dir(struct sftp_conn *conn, char *src, char *dst, - Attrib *dirattrib, int pflag, int printflag, int resume) + Attrib *dirattrib, int preserve_flag, int print_flag, + int resume_flag, int fsync_flag) { char *src_canon; int ret; if ((src_canon = do_realpath(conn, src)) == NULL) { - error("Unable to canonicalise path \"%s\"", src); + error("Unable to canonicalize path \"%s\"", src); return -1; } - ret = download_dir_internal(conn, src_canon, dst, - dirattrib, pflag, printflag, 0, resume); + ret = download_dir_internal(conn, src_canon, dst, 0, + dirattrib, preserve_flag, print_flag, resume_flag, fsync_flag); free(src_canon); return ret; } int do_upload(struct sftp_conn *conn, char *local_path, char *remote_path, - int pflag) + int preserve_flag, int fsync_flag) { int local_fd; int status = SSH2_FX_OK; @@ -1408,7 +1464,7 @@ do_upload(struct sftp_conn *conn, char *local_path, char *remote_path, a.flags &= ~SSH2_FILEXFER_ATTR_SIZE; a.flags &= ~SSH2_FILEXFER_ATTR_UIDGID; a.perm &= 0777; - if (!pflag) + if (!preserve_flag) a.flags &= ~SSH2_FILEXFER_ATTR_ACMODTIME; buffer_init(&msg); @@ -1537,9 +1593,12 @@ do_upload(struct sftp_conn *conn, char *local_path, char *remote_path, } /* Override umask and utimes if asked */ - if (pflag) + if (preserve_flag) do_fsetstat(conn, handle, handle_len, &a); + if (fsync_flag) + (void)do_fsync(conn, handle, handle_len); + if (do_close(conn, handle, handle_len) != SSH2_FX_OK) status = -1; free(handle); @@ -1548,8 +1607,8 @@ do_upload(struct sftp_conn *conn, char *local_path, char *remote_path, } static int -upload_dir_internal(struct sftp_conn *conn, char *src, char *dst, - int pflag, int printflag, int depth) +upload_dir_internal(struct sftp_conn *conn, char *src, char *dst, int depth, + int preserve_flag, int print_flag, int fsync_flag) { int ret = 0, status; DIR *dirp; @@ -1572,7 +1631,7 @@ upload_dir_internal(struct sftp_conn *conn, char *src, char *dst, error("\"%s\" is not a directory", src); return -1; } - if (printflag) + if (print_flag) printf("Entering %s\n", src); attrib_clear(&a); @@ -1580,7 +1639,7 @@ upload_dir_internal(struct sftp_conn *conn, char *src, char *dst, a.flags &= ~SSH2_FILEXFER_ATTR_SIZE; a.flags &= ~SSH2_FILEXFER_ATTR_UIDGID; a.perm &= 01777; - if (!pflag) + if (!preserve_flag) a.flags &= ~SSH2_FILEXFER_ATTR_ACMODTIME; status = do_mkdir(conn, dst, &a, 0); @@ -1618,10 +1677,12 @@ upload_dir_internal(struct sftp_conn *conn, char *src, char *dst, continue; if (upload_dir_internal(conn, new_src, new_dst, - pflag, printflag, depth + 1) == -1) + depth + 1, preserve_flag, print_flag, + fsync_flag) == -1) ret = -1; } else if (S_ISREG(sb.st_mode)) { - if (do_upload(conn, new_src, new_dst, pflag) == -1) { + if (do_upload(conn, new_src, new_dst, + preserve_flag, fsync_flag) == -1) { error("Uploading of file %s to %s failed!", new_src, new_dst); ret = -1; @@ -1639,18 +1700,20 @@ upload_dir_internal(struct sftp_conn *conn, char *src, char *dst, } int -upload_dir(struct sftp_conn *conn, char *src, char *dst, int printflag, - int pflag) +upload_dir(struct sftp_conn *conn, char *src, char *dst, int preserve_flag, + int print_flag, int fsync_flag) { char *dst_canon; int ret; if ((dst_canon = do_realpath(conn, dst)) == NULL) { - error("Unable to canonicalise path \"%s\"", dst); + error("Unable to canonicalize path \"%s\"", dst); return -1; } - ret = upload_dir_internal(conn, src, dst_canon, pflag, printflag, 0); + ret = upload_dir_internal(conn, src, dst_canon, 0, preserve_flag, + print_flag, fsync_flag); + free(dst_canon); return ret; } diff --git a/sftp-client.h b/sftp-client.h index 111a998c84c6..ba92ad01a586 100644 --- a/sftp-client.h +++ b/sftp-client.h @@ -1,4 +1,4 @@ -/* $OpenBSD: sftp-client.h,v 1.21 2013/07/25 00:56:51 djm Exp $ */ +/* $OpenBSD: sftp-client.h,v 1.24 2013/10/17 00:30:13 djm Exp $ */ /* * Copyright (c) 2001-2004 Damien Miller @@ -92,7 +92,7 @@ char *do_realpath(struct sftp_conn *, char *); int do_statvfs(struct sftp_conn *, const char *, struct sftp_statvfs *, int); /* Rename 'oldpath' to 'newpath' */ -int do_rename(struct sftp_conn *, char *, char *); +int do_rename(struct sftp_conn *, char *, char *m, int force_legacy); /* Link 'oldpath' to 'newpath' */ int do_hardlink(struct sftp_conn *, char *, char *); @@ -100,31 +100,33 @@ int do_hardlink(struct sftp_conn *, char *, char *); /* Rename 'oldpath' to 'newpath' */ int do_symlink(struct sftp_conn *, char *, char *); -/* XXX: add callbacks to do_download/do_upload so we can do progress meter */ +/* Call fsync() on open file 'handle' */ +int do_fsync(struct sftp_conn *conn, char *, u_int); /* * Download 'remote_path' to 'local_path'. Preserve permissions and times * if 'pflag' is set */ -int do_download(struct sftp_conn *, char *, char *, Attrib *, int, int); +int do_download(struct sftp_conn *, char *, char *, Attrib *, int, int, int); /* * Recursively download 'remote_directory' to 'local_directory'. Preserve * times if 'pflag' is set */ -int download_dir(struct sftp_conn *, char *, char *, Attrib *, int, int, int); +int download_dir(struct sftp_conn *, char *, char *, Attrib *, int, + int, int, int); /* * Upload 'local_path' to 'remote_path'. Preserve permissions and times * if 'pflag' is set */ -int do_upload(struct sftp_conn *, char *, char *, int); +int do_upload(struct sftp_conn *, char *, char *, int, int); /* * Recursively upload 'local_directory' to 'remote_directory'. Preserve * times if 'pflag' is set */ -int upload_dir(struct sftp_conn *, char *, char *, int, int); +int upload_dir(struct sftp_conn *, char *, char *, int, int, int); /* Concatenate paths, taking care of slashes. Caller must free result. */ char *path_append(char *, char *); diff --git a/sftp-common.c b/sftp-common.c index 413efc20980a..70a929ccc070 100644 --- a/sftp-common.c +++ b/sftp-common.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sftp-common.c,v 1.24 2013/05/17 00:13:14 djm Exp $ */ +/* $OpenBSD: sftp-common.c,v 1.26 2014/01/09 03:26:00 guenther Exp $ */ /* * Copyright (c) 2001 Markus Friedl. All rights reserved. * Copyright (c) 2001 Damien Miller. All rights reserved. @@ -33,6 +33,7 @@ #include #include #include +#include #include #include #include @@ -194,6 +195,7 @@ ls_file(const char *name, const struct stat *st, int remote, int si_units) char *user, *group; char buf[1024], mode[11+1], tbuf[12+1], ubuf[11+1], gbuf[11+1]; char sbuf[FMT_SCALED_STRSIZE]; + time_t now; strmode(st->st_mode, mode); if (!remote) { @@ -209,7 +211,9 @@ ls_file(const char *name, const struct stat *st, int remote, int si_units) group = gbuf; } if (ltime != NULL) { - if (time(NULL) - st->st_mtime < (365*24*60*60)/2) + now = time(NULL); + if (now - (365*24*60*60)/2 < st->st_mtime && + now >= st->st_mtime) sz = strftime(tbuf, sizeof tbuf, "%b %e %H:%M", ltime); else sz = strftime(tbuf, sizeof tbuf, "%b %e %Y", ltime); diff --git a/sftp-glob.c b/sftp-glob.c index e1f5a6109d6f..d85aecc9ab76 100644 --- a/sftp-glob.c +++ b/sftp-glob.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sftp-glob.c,v 1.25 2013/11/08 00:39:15 djm Exp $ */ +/* $OpenBSD: sftp-glob.c,v 1.26 2013/11/08 11:15:19 dtucker Exp $ */ /* * Copyright (c) 2001-2004 Damien Miller * @@ -23,6 +23,7 @@ #endif #include +#include #include #include "xmalloc.h" diff --git a/sftp-server.0 b/sftp-server.0 index 391f42736f69..5bf8da6006ab 100644 --- a/sftp-server.0 +++ b/sftp-server.0 @@ -5,7 +5,9 @@ NAME SYNOPSIS sftp-server [-ehR] [-d start_directory] [-f log_facility] [-l log_level] + [-P blacklisted_requests] [-p whitelisted_requests] [-u umask] + sftp-server -Q protocol_feature DESCRIPTION sftp-server is a program that speaks the server side of SFTP protocol to @@ -46,6 +48,26 @@ DESCRIPTION DEBUG1 are equivalent. DEBUG2 and DEBUG3 each specify higher levels of debugging output. The default is ERROR. + -P blacklisted_requests + Specify a comma-separated list of SFTP protocol requests that are + banned by the server. sftp-server will reply to any blacklisted + request with a failure. The -Q flag can be used to determine the + supported request types. If both a blacklist and a whitelist are + specified, then the blacklist is applied before the whitelist. + + -p whitelisted_requests + Specify a comma-separated list of SFTP protocol requests that are + permitted by the server. All request types that are not on the + whitelist will be logged and replied to with a failure message. + + Care must be taken when using this feature to ensure that + requests made implicitly by SFTP clients are permitted. + + -Q protocol_feature + Query protocol features supported by sftp-server. At present the + only feature that may be queried is ``requests'', which may be + used for black or whitelisting (flags -P and -p respectively). + -R Places this instance of sftp-server into a read-only mode. Attempts to open files for writing, as well as other operations that change the state of the filesystem, will be denied. @@ -70,4 +92,4 @@ HISTORY AUTHORS Markus Friedl -OpenBSD 5.4 July 16, 2013 OpenBSD 5.4 +OpenBSD 5.4 October 14, 2013 OpenBSD 5.4 diff --git a/sftp-server.8 b/sftp-server.8 index cc925b96ec65..1e0b277b4363 100644 --- a/sftp-server.8 +++ b/sftp-server.8 @@ -1,4 +1,4 @@ -.\" $OpenBSD: sftp-server.8,v 1.23 2013/07/16 00:07:52 schwarze Exp $ +.\" $OpenBSD: sftp-server.8,v 1.25 2013/10/14 14:18:56 jmc Exp $ .\" .\" Copyright (c) 2000 Markus Friedl. All rights reserved. .\" @@ -22,7 +22,7 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.Dd $Mdocdate: July 16 2013 $ +.Dd $Mdocdate: October 14 2013 $ .Dt SFTP-SERVER 8 .Os .Sh NAME @@ -30,11 +30,17 @@ .Nd SFTP server subsystem .Sh SYNOPSIS .Nm sftp-server +.Bk -words .Op Fl ehR .Op Fl d Ar start_directory .Op Fl f Ar log_facility .Op Fl l Ar log_level +.Op Fl P Ar blacklisted_requests +.Op Fl p Ar whitelisted_requests .Op Fl u Ar umask +.Ek +.Nm +.Fl Q Ar protocol_feature .Sh DESCRIPTION .Nm is a program that speaks the server side of SFTP protocol @@ -93,6 +99,34 @@ performs on behalf of the client. DEBUG and DEBUG1 are equivalent. DEBUG2 and DEBUG3 each specify higher levels of debugging output. The default is ERROR. +.It Fl P Ar blacklisted_requests +Specify a comma-separated list of SFTP protocol requests that are banned by +the server. +.Nm +will reply to any blacklisted request with a failure. +The +.Fl Q +flag can be used to determine the supported request types. +If both a blacklist and a whitelist are specified, then the blacklist is +applied before the whitelist. +.It Fl p Ar whitelisted_requests +Specify a comma-separated list of SFTP protocol requests that are permitted +by the server. +All request types that are not on the whitelist will be logged and replied +to with a failure message. +.Pp +Care must be taken when using this feature to ensure that requests made +implicitly by SFTP clients are permitted. +.It Fl Q Ar protocol_feature +Query protocol features supported by +.Nm . +At present the only feature that may be queried is +.Dq requests , +which may be used for black or whitelisting (flags +.Fl P +and +.Fl p +respectively). .It Fl R Places this instance of .Nm diff --git a/sftp-server.c b/sftp-server.c index 285f21aafe70..b8eb59c36a20 100644 --- a/sftp-server.c +++ b/sftp-server.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sftp-server.c,v 1.97 2013/05/17 00:13:14 djm Exp $ */ +/* $OpenBSD: sftp-server.c,v 1.103 2014/01/17 06:23:24 dtucker Exp $ */ /* * Copyright (c) 2000-2004 Markus Friedl. All rights reserved. * @@ -46,6 +46,7 @@ #include "buffer.h" #include "log.h" #include "misc.h" +#include "match.h" #include "uidswap.h" #include "sftp.h" @@ -57,24 +58,29 @@ #define get_string(lenp) buffer_get_string(&iqueue, lenp); /* Our verbosity */ -LogLevel log_level = SYSLOG_LEVEL_ERROR; +static LogLevel log_level = SYSLOG_LEVEL_ERROR; /* Our client */ -struct passwd *pw = NULL; -char *client_addr = NULL; +static struct passwd *pw = NULL; +static char *client_addr = NULL; /* input and output queue */ -Buffer iqueue; -Buffer oqueue; +static Buffer iqueue; +static Buffer oqueue; /* Version of client */ -u_int version; +static u_int version; + +/* SSH2_FXP_INIT received */ +static int init_done; /* Disable writes */ -int readonly; +static int readonly; + +/* Requests that are allowed/denied */ +static char *request_whitelist, *request_blacklist; /* portable attributes, etc. */ - typedef struct Stat Stat; struct Stat { @@ -83,6 +89,102 @@ struct Stat { Attrib attrib; }; +/* Packet handlers */ +static void process_open(u_int32_t id); +static void process_close(u_int32_t id); +static void process_read(u_int32_t id); +static void process_write(u_int32_t id); +static void process_stat(u_int32_t id); +static void process_lstat(u_int32_t id); +static void process_fstat(u_int32_t id); +static void process_setstat(u_int32_t id); +static void process_fsetstat(u_int32_t id); +static void process_opendir(u_int32_t id); +static void process_readdir(u_int32_t id); +static void process_remove(u_int32_t id); +static void process_mkdir(u_int32_t id); +static void process_rmdir(u_int32_t id); +static void process_realpath(u_int32_t id); +static void process_rename(u_int32_t id); +static void process_readlink(u_int32_t id); +static void process_symlink(u_int32_t id); +static void process_extended_posix_rename(u_int32_t id); +static void process_extended_statvfs(u_int32_t id); +static void process_extended_fstatvfs(u_int32_t id); +static void process_extended_hardlink(u_int32_t id); +static void process_extended_fsync(u_int32_t id); +static void process_extended(u_int32_t id); + +struct sftp_handler { + const char *name; /* user-visible name for fine-grained perms */ + const char *ext_name; /* extended request name */ + u_int type; /* packet type, for non extended packets */ + void (*handler)(u_int32_t); + int does_write; /* if nonzero, banned for readonly mode */ +}; + +struct sftp_handler handlers[] = { + /* NB. SSH2_FXP_OPEN does the readonly check in the handler itself */ + { "open", NULL, SSH2_FXP_OPEN, process_open, 0 }, + { "close", NULL, SSH2_FXP_CLOSE, process_close, 0 }, + { "read", NULL, SSH2_FXP_READ, process_read, 0 }, + { "write", NULL, SSH2_FXP_WRITE, process_write, 1 }, + { "lstat", NULL, SSH2_FXP_LSTAT, process_lstat, 0 }, + { "fstat", NULL, SSH2_FXP_FSTAT, process_fstat, 0 }, + { "setstat", NULL, SSH2_FXP_SETSTAT, process_setstat, 1 }, + { "fsetstat", NULL, SSH2_FXP_FSETSTAT, process_fsetstat, 1 }, + { "opendir", NULL, SSH2_FXP_OPENDIR, process_opendir, 0 }, + { "readdir", NULL, SSH2_FXP_READDIR, process_readdir, 0 }, + { "remove", NULL, SSH2_FXP_REMOVE, process_remove, 1 }, + { "mkdir", NULL, SSH2_FXP_MKDIR, process_mkdir, 1 }, + { "rmdir", NULL, SSH2_FXP_RMDIR, process_rmdir, 1 }, + { "realpath", NULL, SSH2_FXP_REALPATH, process_realpath, 0 }, + { "stat", NULL, SSH2_FXP_STAT, process_stat, 0 }, + { "rename", NULL, SSH2_FXP_RENAME, process_rename, 1 }, + { "readlink", NULL, SSH2_FXP_READLINK, process_readlink, 0 }, + { "symlink", NULL, SSH2_FXP_SYMLINK, process_symlink, 1 }, + { NULL, NULL, 0, NULL, 0 } +}; + +/* SSH2_FXP_EXTENDED submessages */ +struct sftp_handler extended_handlers[] = { + { "posix-rename", "posix-rename@openssh.com", 0, + process_extended_posix_rename, 1 }, + { "statvfs", "statvfs@openssh.com", 0, process_extended_statvfs, 0 }, + { "fstatvfs", "fstatvfs@openssh.com", 0, process_extended_fstatvfs, 0 }, + { "hardlink", "hardlink@openssh.com", 0, process_extended_hardlink, 1 }, + { "fsync", "fsync@openssh.com", 0, process_extended_fsync, 1 }, + { NULL, NULL, 0, NULL, 0 } +}; + +static int +request_permitted(struct sftp_handler *h) +{ + char *result; + + if (readonly && h->does_write) { + verbose("Refusing %s request in read-only mode", h->name); + return 0; + } + if (request_blacklist != NULL && + ((result = match_list(h->name, request_blacklist, NULL))) != NULL) { + free(result); + verbose("Refusing blacklisted %s request", h->name); + return 0; + } + if (request_whitelist != NULL && + ((result = match_list(h->name, request_whitelist, NULL))) != NULL) { + free(result); + debug2("Permitting whitelisted %s request", h->name); + return 1; + } + if (request_whitelist != NULL) { + verbose("Refusing non-whitelisted %s request", h->name); + return 0; + } + return 1; +} + static int errno_to_portable(int unixerrno) { @@ -130,6 +232,8 @@ flags_from_portable(int pflags) } else if (pflags & SSH2_FXF_WRITE) { flags = O_WRONLY; } + if (pflags & SSH2_FXF_APPEND) + flags |= O_APPEND; if (pflags & SSH2_FXF_CREAT) flags |= O_CREAT; if (pflags & SSH2_FXF_TRUNC) @@ -156,6 +260,8 @@ string_from_portable(int pflags) PAPPEND("READ") if (pflags & SSH2_FXF_WRITE) PAPPEND("WRITE") + if (pflags & SSH2_FXF_APPEND) + PAPPEND("APPEND") if (pflags & SSH2_FXF_CREAT) PAPPEND("CREATE") if (pflags & SSH2_FXF_TRUNC) @@ -179,6 +285,7 @@ struct Handle { int use; DIR *dirp; int fd; + int flags; char *name; u_int64_t bytes_read, bytes_write; int next_unused; @@ -202,7 +309,7 @@ static void handle_unused(int i) } static int -handle_new(int use, const char *name, int fd, DIR *dirp) +handle_new(int use, const char *name, int fd, int flags, DIR *dirp) { int i; @@ -220,6 +327,7 @@ handle_new(int use, const char *name, int fd, DIR *dirp) handles[i].use = use; handles[i].dirp = dirp; handles[i].fd = fd; + handles[i].flags = flags; handles[i].name = xstrdup(name); handles[i].bytes_read = handles[i].bytes_write = 0; @@ -282,6 +390,14 @@ handle_to_fd(int handle) return -1; } +static int +handle_to_flags(int handle) +{ + if (handle_is_ok(handle, HANDLE_FILE)) + return handles[handle].flags; + return 0; +} + static void handle_update_read(int handle, ssize_t bytes) { @@ -538,19 +654,21 @@ process_init(void) /* hardlink extension */ buffer_put_cstring(&msg, "hardlink@openssh.com"); buffer_put_cstring(&msg, "1"); /* version */ + /* fsync extension */ + buffer_put_cstring(&msg, "fsync@openssh.com"); + buffer_put_cstring(&msg, "1"); /* version */ send_msg(&msg); buffer_free(&msg); } static void -process_open(void) +process_open(u_int32_t id) { - u_int32_t id, pflags; + u_int32_t pflags; Attrib *a; char *name; int handle, fd, flags, mode, status = SSH2_FX_FAILURE; - id = get_int(); name = get_string(NULL); pflags = get_int(); /* portable flags */ debug3("request %u: open flags %d", id, pflags); @@ -560,14 +678,16 @@ process_open(void) logit("open \"%s\" flags %s mode 0%o", name, string_from_portable(pflags), mode); if (readonly && - ((flags & O_ACCMODE) == O_WRONLY || (flags & O_ACCMODE) == O_RDWR)) - status = SSH2_FX_PERMISSION_DENIED; - else { + ((flags & O_ACCMODE) == O_WRONLY || + (flags & O_ACCMODE) == O_RDWR)) { + verbose("Refusing open request in read-only mode"); + status = SSH2_FX_PERMISSION_DENIED; + } else { fd = open(name, flags, mode); if (fd < 0) { status = errno_to_portable(errno); } else { - handle = handle_new(HANDLE_FILE, name, fd, NULL); + handle = handle_new(HANDLE_FILE, name, fd, flags, NULL); if (handle < 0) { close(fd); } else { @@ -582,12 +702,10 @@ process_open(void) } static void -process_close(void) +process_close(u_int32_t id) { - u_int32_t id; int handle, ret, status = SSH2_FX_FAILURE; - id = get_int(); handle = get_handle(); debug3("request %u: close handle %u", id, handle); handle_log_close(handle, NULL); @@ -597,14 +715,13 @@ process_close(void) } static void -process_read(void) +process_read(u_int32_t id) { char buf[64*1024]; - u_int32_t id, len; + u_int32_t len; int handle, fd, ret, status = SSH2_FX_FAILURE; u_int64_t off; - id = get_int(); handle = get_handle(); off = get_int64(); len = get_int(); @@ -638,15 +755,13 @@ process_read(void) } static void -process_write(void) +process_write(u_int32_t id) { - u_int32_t id; u_int64_t off; u_int len; int handle, fd, ret, status; char *data; - id = get_int(); handle = get_handle(); off = get_int64(); data = get_string(&len); @@ -657,10 +772,9 @@ process_write(void) if (fd < 0) status = SSH2_FX_FAILURE; - else if (readonly) - status = SSH2_FX_PERMISSION_DENIED; else { - if (lseek(fd, off, SEEK_SET) < 0) { + if (!(handle_to_flags(handle) & O_APPEND) && + lseek(fd, off, SEEK_SET) < 0) { status = errno_to_portable(errno); error("process_write: seek failed"); } else { @@ -683,15 +797,13 @@ process_write(void) } static void -process_do_stat(int do_lstat) +process_do_stat(u_int32_t id, int do_lstat) { Attrib a; struct stat st; - u_int32_t id; char *name; int ret, status = SSH2_FX_FAILURE; - id = get_int(); name = get_string(NULL); debug3("request %u: %sstat", id, do_lstat ? "l" : ""); verbose("%sstat name \"%s\"", do_lstat ? "l" : "", name); @@ -709,26 +821,24 @@ process_do_stat(int do_lstat) } static void -process_stat(void) +process_stat(u_int32_t id) { - process_do_stat(0); + process_do_stat(id, 0); } static void -process_lstat(void) +process_lstat(u_int32_t id) { - process_do_stat(1); + process_do_stat(id, 1); } static void -process_fstat(void) +process_fstat(u_int32_t id) { Attrib a; struct stat st; - u_int32_t id; int fd, ret, handle, status = SSH2_FX_FAILURE; - id = get_int(); handle = get_handle(); debug("request %u: fstat \"%s\" (handle %u)", id, handle_to_name(handle), handle); @@ -760,21 +870,15 @@ attrib_to_tv(const Attrib *a) } static void -process_setstat(void) +process_setstat(u_int32_t id) { Attrib *a; - u_int32_t id; char *name; int status = SSH2_FX_OK, ret; - id = get_int(); name = get_string(NULL); a = get_attrib(); debug("request %u: setstat name \"%s\"", id, name); - if (readonly) { - status = SSH2_FX_PERMISSION_DENIED; - a->flags = 0; - } if (a->flags & SSH2_FILEXFER_ATTR_SIZE) { logit("set \"%s\" size %llu", name, (unsigned long long)a->size); @@ -811,22 +915,18 @@ process_setstat(void) } static void -process_fsetstat(void) +process_fsetstat(u_int32_t id) { Attrib *a; - u_int32_t id; int handle, fd, ret; int status = SSH2_FX_OK; - id = get_int(); handle = get_handle(); a = get_attrib(); debug("request %u: fsetstat handle %d", id, handle); fd = handle_to_fd(handle); if (fd < 0) status = SSH2_FX_FAILURE; - else if (readonly) - status = SSH2_FX_PERMISSION_DENIED; else { char *name = handle_to_name(handle); @@ -878,14 +978,12 @@ process_fsetstat(void) } static void -process_opendir(void) +process_opendir(u_int32_t id) { DIR *dirp = NULL; char *path; int handle, status = SSH2_FX_FAILURE; - u_int32_t id; - id = get_int(); path = get_string(NULL); debug3("request %u: opendir", id); logit("opendir \"%s\"", path); @@ -893,7 +991,7 @@ process_opendir(void) if (dirp == NULL) { status = errno_to_portable(errno); } else { - handle = handle_new(HANDLE_DIR, path, 0, dirp); + handle = handle_new(HANDLE_DIR, path, 0, 0, dirp); if (handle < 0) { closedir(dirp); } else { @@ -908,15 +1006,13 @@ process_opendir(void) } static void -process_readdir(void) +process_readdir(u_int32_t id) { DIR *dirp; struct dirent *dp; char *path; int handle; - u_int32_t id; - id = get_int(); handle = get_handle(); debug("request %u: readdir \"%s\" (handle %d)", id, handle_to_name(handle), handle); @@ -964,81 +1060,61 @@ process_readdir(void) } static void -process_remove(void) +process_remove(u_int32_t id) { char *name; - u_int32_t id; int status = SSH2_FX_FAILURE; int ret; - id = get_int(); name = get_string(NULL); debug3("request %u: remove", id); logit("remove name \"%s\"", name); - if (readonly) - status = SSH2_FX_PERMISSION_DENIED; - else { - ret = unlink(name); - status = (ret == -1) ? errno_to_portable(errno) : SSH2_FX_OK; - } + ret = unlink(name); + status = (ret == -1) ? errno_to_portable(errno) : SSH2_FX_OK; send_status(id, status); free(name); } static void -process_mkdir(void) +process_mkdir(u_int32_t id) { Attrib *a; - u_int32_t id; char *name; int ret, mode, status = SSH2_FX_FAILURE; - id = get_int(); name = get_string(NULL); a = get_attrib(); mode = (a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) ? a->perm & 07777 : 0777; debug3("request %u: mkdir", id); logit("mkdir name \"%s\" mode 0%o", name, mode); - if (readonly) - status = SSH2_FX_PERMISSION_DENIED; - else { - ret = mkdir(name, mode); - status = (ret == -1) ? errno_to_portable(errno) : SSH2_FX_OK; - } + ret = mkdir(name, mode); + status = (ret == -1) ? errno_to_portable(errno) : SSH2_FX_OK; send_status(id, status); free(name); } static void -process_rmdir(void) +process_rmdir(u_int32_t id) { - u_int32_t id; char *name; int ret, status; - id = get_int(); name = get_string(NULL); debug3("request %u: rmdir", id); logit("rmdir name \"%s\"", name); - if (readonly) - status = SSH2_FX_PERMISSION_DENIED; - else { - ret = rmdir(name); - status = (ret == -1) ? errno_to_portable(errno) : SSH2_FX_OK; - } + ret = rmdir(name); + status = (ret == -1) ? errno_to_portable(errno) : SSH2_FX_OK; send_status(id, status); free(name); } static void -process_realpath(void) +process_realpath(u_int32_t id) { char resolvedname[MAXPATHLEN]; - u_int32_t id; char *path; - id = get_int(); path = get_string(NULL); if (path[0] == '\0') { free(path); @@ -1058,22 +1134,18 @@ process_realpath(void) } static void -process_rename(void) +process_rename(u_int32_t id) { - u_int32_t id; char *oldpath, *newpath; int status; struct stat sb; - id = get_int(); oldpath = get_string(NULL); newpath = get_string(NULL); debug3("request %u: rename", id); logit("rename old \"%s\" new \"%s\"", oldpath, newpath); status = SSH2_FX_FAILURE; - if (readonly) - status = SSH2_FX_PERMISSION_DENIED; - else if (lstat(oldpath, &sb) == -1) + if (lstat(oldpath, &sb) == -1) status = errno_to_portable(errno); else if (S_ISREG(sb.st_mode)) { /* Race-free rename of regular files */ @@ -1120,14 +1192,12 @@ process_rename(void) } static void -process_readlink(void) +process_readlink(u_int32_t id) { - u_int32_t id; int len; char buf[MAXPATHLEN]; char *path; - id = get_int(); path = get_string(NULL); debug3("request %u: readlink", id); verbose("readlink \"%s\"", path); @@ -1145,24 +1215,18 @@ process_readlink(void) } static void -process_symlink(void) +process_symlink(u_int32_t id) { - u_int32_t id; char *oldpath, *newpath; int ret, status; - id = get_int(); oldpath = get_string(NULL); newpath = get_string(NULL); debug3("request %u: symlink", id); logit("symlink old \"%s\" new \"%s\"", oldpath, newpath); /* this will fail if 'newpath' exists */ - if (readonly) - status = SSH2_FX_PERMISSION_DENIED; - else { - ret = symlink(oldpath, newpath); - status = (ret == -1) ? errno_to_portable(errno) : SSH2_FX_OK; - } + ret = symlink(oldpath, newpath); + status = (ret == -1) ? errno_to_portable(errno) : SSH2_FX_OK; send_status(id, status); free(oldpath); free(newpath); @@ -1178,12 +1242,8 @@ process_extended_posix_rename(u_int32_t id) newpath = get_string(NULL); debug3("request %u: posix-rename", id); logit("posix-rename old \"%s\" new \"%s\"", oldpath, newpath); - if (readonly) - status = SSH2_FX_PERMISSION_DENIED; - else { - ret = rename(oldpath, newpath); - status = (ret == -1) ? errno_to_portable(errno) : SSH2_FX_OK; - } + ret = rename(oldpath, newpath); + status = (ret == -1) ? errno_to_portable(errno) : SSH2_FX_OK; send_status(id, status); free(oldpath); free(newpath); @@ -1196,8 +1256,8 @@ process_extended_statvfs(u_int32_t id) struct statvfs st; path = get_string(NULL); - debug3("request %u: statfs", id); - logit("statfs \"%s\"", path); + debug3("request %u: statvfs", id); + logit("statvfs \"%s\"", path); if (statvfs(path, &st) != 0) send_status(id, errno_to_portable(errno)); @@ -1235,35 +1295,50 @@ process_extended_hardlink(u_int32_t id) newpath = get_string(NULL); debug3("request %u: hardlink", id); logit("hardlink old \"%s\" new \"%s\"", oldpath, newpath); - if (readonly) - status = SSH2_FX_PERMISSION_DENIED; - else { - ret = link(oldpath, newpath); - status = (ret == -1) ? errno_to_portable(errno) : SSH2_FX_OK; - } + ret = link(oldpath, newpath); + status = (ret == -1) ? errno_to_portable(errno) : SSH2_FX_OK; send_status(id, status); free(oldpath); free(newpath); } static void -process_extended(void) +process_extended_fsync(u_int32_t id) { - u_int32_t id; - char *request; + int handle, fd, ret, status = SSH2_FX_OP_UNSUPPORTED; + + handle = get_handle(); + debug3("request %u: fsync (handle %u)", id, handle); + verbose("fsync \"%s\"", handle_to_name(handle)); + if ((fd = handle_to_fd(handle)) < 0) + status = SSH2_FX_NO_SUCH_FILE; + else if (handle_is_ok(handle, HANDLE_FILE)) { + ret = fsync(fd); + status = (ret == -1) ? errno_to_portable(errno) : SSH2_FX_OK; + } + send_status(id, status); +} + +static void +process_extended(u_int32_t id) +{ + char *request; + u_int i; - id = get_int(); request = get_string(NULL); - if (strcmp(request, "posix-rename@openssh.com") == 0) - process_extended_posix_rename(id); - else if (strcmp(request, "statvfs@openssh.com") == 0) - process_extended_statvfs(id); - else if (strcmp(request, "fstatvfs@openssh.com") == 0) - process_extended_fstatvfs(id); - else if (strcmp(request, "hardlink@openssh.com") == 0) - process_extended_hardlink(id); - else + for (i = 0; extended_handlers[i].handler != NULL; i++) { + if (strcmp(request, extended_handlers[i].ext_name) == 0) { + if (!request_permitted(&extended_handlers[i])) + send_status(id, SSH2_FX_PERMISSION_DENIED); + else + extended_handlers[i].handler(id); + break; + } + } + if (extended_handlers[i].handler == NULL) { + error("Unknown extended request \"%.100s\"", request); send_status(id, SSH2_FX_OP_UNSUPPORTED); /* MUST */ + } free(request); } @@ -1272,11 +1347,9 @@ process_extended(void) static void process(void) { - u_int msg_len; - u_int buf_len; - u_int consumed; - u_int type; + u_int msg_len, buf_len, consumed, type, i; u_char *cp; + u_int32_t id; buf_len = buffer_len(&iqueue); if (buf_len < 5) @@ -1293,70 +1366,35 @@ process(void) buffer_consume(&iqueue, 4); buf_len -= 4; type = buffer_get_char(&iqueue); + switch (type) { case SSH2_FXP_INIT: process_init(); - break; - case SSH2_FXP_OPEN: - process_open(); - break; - case SSH2_FXP_CLOSE: - process_close(); - break; - case SSH2_FXP_READ: - process_read(); - break; - case SSH2_FXP_WRITE: - process_write(); - break; - case SSH2_FXP_LSTAT: - process_lstat(); - break; - case SSH2_FXP_FSTAT: - process_fstat(); - break; - case SSH2_FXP_SETSTAT: - process_setstat(); - break; - case SSH2_FXP_FSETSTAT: - process_fsetstat(); - break; - case SSH2_FXP_OPENDIR: - process_opendir(); - break; - case SSH2_FXP_READDIR: - process_readdir(); - break; - case SSH2_FXP_REMOVE: - process_remove(); - break; - case SSH2_FXP_MKDIR: - process_mkdir(); - break; - case SSH2_FXP_RMDIR: - process_rmdir(); - break; - case SSH2_FXP_REALPATH: - process_realpath(); - break; - case SSH2_FXP_STAT: - process_stat(); - break; - case SSH2_FXP_RENAME: - process_rename(); - break; - case SSH2_FXP_READLINK: - process_readlink(); - break; - case SSH2_FXP_SYMLINK: - process_symlink(); + init_done = 1; break; case SSH2_FXP_EXTENDED: - process_extended(); + if (!init_done) + fatal("Received extended request before init"); + id = get_int(); + process_extended(id); break; default: - error("Unknown message %d", type); - break; + if (!init_done) + fatal("Received %u request before init", type); + id = get_int(); + for (i = 0; handlers[i].handler != NULL; i++) { + if (type == handlers[i].type) { + if (!request_permitted(&handlers[i])) { + send_status(id, + SSH2_FX_PERMISSION_DENIED); + } else { + handlers[i].handler(id); + } + break; + } + } + if (handlers[i].handler == NULL) + error("Unknown message %u", type); } /* discard the remaining bytes from the current packet */ if (buf_len < buffer_len(&iqueue)) { @@ -1365,7 +1403,7 @@ process(void) } consumed = buf_len - buffer_len(&iqueue); if (msg_len < consumed) { - error("msg_len %d < consumed %d", msg_len, consumed); + error("msg_len %u < consumed %u", msg_len, consumed); sftp_server_cleanup_exit(255); } if (msg_len > consumed) @@ -1391,8 +1429,10 @@ sftp_server_usage(void) fprintf(stderr, "usage: %s [-ehR] [-d start_directory] [-f log_facility] " - "[-l log_level]\n\t[-u umask]\n", - __progname); + "[-l log_level]\n\t[-P blacklisted_requests] " + "[-p whitelisted_requests] [-u umask]\n" + " %s -Q protocol_feature\n", + __progname, __progname); exit(1); } @@ -1400,7 +1440,7 @@ int sftp_server_main(int argc, char **argv, struct passwd *user_pw) { fd_set *rset, *wset; - int in, out, max, ch, skipargs = 0, log_stderr = 0; + int i, in, out, max, ch, skipargs = 0, log_stderr = 0; ssize_t len, olen, set_size; SyslogFacility log_facility = SYSLOG_FACILITY_AUTH; char *cp, *homedir = NULL, buf[4*4096]; @@ -1414,8 +1454,20 @@ sftp_server_main(int argc, char **argv, struct passwd *user_pw) pw = pwcopy(user_pw); - while (!skipargs && (ch = getopt(argc, argv, "d:f:l:u:cehR")) != -1) { + while (!skipargs && (ch = getopt(argc, argv, + "d:f:l:P:p:Q:u:cehR")) != -1) { switch (ch) { + case 'Q': + if (strcasecmp(optarg, "requests") != 0) { + fprintf(stderr, "Invalid query type\n"); + exit(1); + } + for (i = 0; handlers[i].handler != NULL; i++) + printf("%s\n", handlers[i].name); + for (i = 0; extended_handlers[i].handler != NULL; i++) + printf("%s\n", extended_handlers[i].name); + exit(0); + break; case 'R': readonly = 1; break; @@ -1445,6 +1497,16 @@ sftp_server_main(int argc, char **argv, struct passwd *user_pw) "u", user_pw->pw_name, (char *)NULL); free(cp); break; + case 'p': + if (request_whitelist != NULL) + fatal("Permitted requests already set"); + request_whitelist = xstrdup(optarg); + break; + case 'P': + if (request_blacklist != NULL) + fatal("Refused requests already set"); + request_blacklist = xstrdup(optarg); + break; case 'u': errno = 0; mask = strtol(optarg, &cp, 8); diff --git a/sftp.0 b/sftp.0 index 8bfc8086bc89..248737046ef7 100644 --- a/sftp.0 +++ b/sftp.0 @@ -4,7 +4,7 @@ NAME sftp - secure file transfer program SYNOPSIS - sftp [-1246Cpqrv] [-B buffer_size] [-b batchfile] [-c cipher] + sftp [-1246aCfpqrv] [-B buffer_size] [-b batchfile] [-c cipher] [-D sftp_server_path] [-F ssh_config] [-i identity_file] [-l limit] [-o ssh_option] [-P port] [-R num_requests] [-S program] [-s subsystem | sftp_server] host @@ -44,6 +44,11 @@ DESCRIPTION -6 Forces sftp to use IPv6 addresses only. + -a Attempt to continue interrupted downloads rather than overwriting + existing partial or complete copies of files. If the remote file + contents differ from the partial local copy then the resultant + file is likely to be corrupt. + -B buffer_size Specify the size of the buffer that sftp uses when transferring files. Larger buffers require fewer round trips at the cost of @@ -74,6 +79,10 @@ DESCRIPTION Specifies an alternative per-user configuration file for ssh(1). This option is directly passed to ssh(1). + -f Requests that files be flushed to disk immediately after + transfer. When uploading files, this feature is only enabled if + the server implements the "fsync@openssh.com" extension. + -i identity_file Selects the file from which the identity (private key) for public key authentication is read. This option is directly passed to @@ -93,6 +102,11 @@ DESCRIPTION AddressFamily BatchMode BindAddress + CanonicalDomains + CanonicalizeFallbackLocal + CanonicalizeHostname + CanonicalizeMaxDots + CanonicalizePermittedCNAMEs ChallengeResponseAuthentication CheckHostIP Cipher @@ -209,7 +223,7 @@ INTERACTIVE COMMANDS exit Quit sftp. - get [-aPpr] remote-path [local-path] + get [-afPpr] remote-path [local-path] Retrieve the remote-path and store it on the local machine. If the local path name is not specified, it is given the same name it has on the remote machine. remote-path may contain glob(3) @@ -220,8 +234,11 @@ INTERACTIVE COMMANDS If the -a flag is specified, then attempt to resume partial transfers of existing files. Note that resumption assumes that any partial copy of the local file matches the remote copy. If - the remote file differs from the partial local copy then the - resultant file is likely to be corrupt. + the remote file contents differ from the partial local copy then + the resultant file is likely to be corrupt. + + If the -f flag is specified, then fsync(2) will be called after + the file transfer has completed to flush the file to disk. If either the -P or -p flag is specified, then full file permissions and access times are copied too. @@ -293,7 +310,7 @@ INTERACTIVE COMMANDS progress Toggle display of progress meter. - put [-Ppr] local-path [remote-path] + put [-fPpr] local-path [remote-path] Upload local-path and store it on the remote machine. If the remote path name is not specified, it is given the same name it has on the local machine. local-path may contain glob(3) @@ -301,6 +318,11 @@ INTERACTIVE COMMANDS remote-path is specified, then remote-path must specify a directory. + If the -f flag is specified, then a request will be sent to the + server to call fsync(2) after the file has been transferred. + Note that this is only supported by servers that implement the + "fsync@openssh.com" extension. + If either the -P or -p flag is specified, then full file permissions and access times are copied too. @@ -345,4 +367,4 @@ SEE ALSO T. Ylonen and S. Lehtinen, SSH File Transfer Protocol, draft-ietf-secsh- filexfer-00.txt, January 2001, work in progress material. -OpenBSD 5.4 July 25, 2013 OpenBSD 5.4 +OpenBSD 5.4 October 20, 2013 OpenBSD 5.4 diff --git a/sftp.1 b/sftp.1 index 2577fe875514..a700c2adb4fe 100644 --- a/sftp.1 +++ b/sftp.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: sftp.1,v 1.92 2013/07/25 00:56:51 djm Exp $ +.\" $OpenBSD: sftp.1,v 1.97 2013/10/20 09:51:26 djm Exp $ .\" .\" Copyright (c) 2001 Damien Miller. All rights reserved. .\" @@ -22,7 +22,7 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.Dd $Mdocdate: July 25 2013 $ +.Dd $Mdocdate: October 20 2013 $ .Dt SFTP 1 .Os .Sh NAME @@ -31,7 +31,7 @@ .Sh SYNOPSIS .Nm sftp .Bk -words -.Op Fl 1246Cpqrv +.Op Fl 1246aCfpqrv .Op Fl B Ar buffer_size .Op Fl b Ar batchfile .Op Fl c Ar cipher @@ -107,6 +107,11 @@ to use IPv4 addresses only. Forces .Nm to use IPv6 addresses only. +.It Fl a +Attempt to continue interrupted downloads rather than overwriting existing +partial or complete copies of files. +If the remote file contents differ from the partial local copy then the +resultant file is likely to be corrupt. .It Fl B Ar buffer_size Specify the size of the buffer that .Nm @@ -159,6 +164,10 @@ per-user configuration file for .Xr ssh 1 . This option is directly passed to .Xr ssh 1 . +.It Fl f +Requests that files be flushed to disk immediately after transfer. +When uploading files, this feature is only enabled if the server +implements the "fsync@openssh.com" extension. .It Fl i Ar identity_file Selects the file from which the identity (private key) for public key authentication is read. @@ -184,6 +193,11 @@ For full details of the options listed below, and their possible values, see .It AddressFamily .It BatchMode .It BindAddress +.It CanonicalDomains +.It CanonicalizeFallbackLocal +.It CanonicalizeHostname +.It CanonicalizeMaxDots +.It CanonicalizePermittedCNAMEs .It ChallengeResponseAuthentication .It CheckHostIP .It Cipher @@ -343,7 +357,7 @@ extension. Quit .Nm sftp . .It Xo Ic get -.Op Fl aPpr +.Op Fl afPpr .Ar remote-path .Op Ar local-path .Xc @@ -368,8 +382,15 @@ If the flag is specified, then attempt to resume partial transfers of existing files. Note that resumption assumes that any partial copy of the local file matches the remote copy. -If the remote file differs from the partial local copy then the resultant file -is likely to be corrupt. +If the remote file contents differ from the partial local copy then the +resultant file is likely to be corrupt. +.Pp +If the +.Fl f +flag is specified, then +.Xr fsync 2 +will be called after the file transfer has completed to flush the file +to disk. .Pp If either the .Fl P @@ -474,7 +495,7 @@ Create remote directory specified by .It Ic progress Toggle display of progress meter. .It Xo Ic put -.Op Fl Ppr +.Op Fl fPpr .Ar local-path .Op Ar remote-path .Xc @@ -493,6 +514,14 @@ is specified, then .Ar remote-path must specify a directory. .Pp +If the +.Fl f +flag is specified, then a request will be sent to the server to call +.Xr fsync 2 +after the file has been transferred. +Note that this is only supported by servers that implement +the "fsync@openssh.com" extension. +.Pp If either the .Fl P or diff --git a/sftp.c b/sftp.c index 969328de4df0..ad1f8c84d317 100644 --- a/sftp.c +++ b/sftp.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sftp.c,v 1.148 2013/07/25 00:56:52 djm Exp $ */ +/* $OpenBSD: sftp.c,v 1.158 2013/11/20 20:54:10 deraadt Exp $ */ /* * Copyright (c) 2001-2004 Damien Miller * @@ -94,6 +94,9 @@ int global_aflag = 0; /* When this option is set, the file transfers will always preserve times */ int global_pflag = 0; +/* When this option is set, transfers will have fsync() called on each file */ +int global_fflag = 0; + /* SIGINT received during command processing */ volatile sig_atomic_t interrupted = 0; @@ -129,32 +132,34 @@ extern char *__progname; #define SORT_FLAGS (LS_NAME_SORT|LS_TIME_SORT|LS_SIZE_SORT) /* Commands for interactive mode */ -#define I_CHDIR 1 -#define I_CHGRP 2 -#define I_CHMOD 3 -#define I_CHOWN 4 -#define I_DF 24 -#define I_GET 5 -#define I_HELP 6 -#define I_LCHDIR 7 -#define I_LINK 25 -#define I_LLS 8 -#define I_LMKDIR 9 -#define I_LPWD 10 -#define I_LS 11 -#define I_LUMASK 12 -#define I_MKDIR 13 -#define I_PUT 14 -#define I_PWD 15 -#define I_QUIT 16 -#define I_RENAME 17 -#define I_RM 18 -#define I_RMDIR 19 -#define I_SHELL 20 -#define I_SYMLINK 21 -#define I_VERSION 22 -#define I_PROGRESS 23 -#define I_REGET 26 +enum sftp_command { + I_CHDIR = 1, + I_CHGRP, + I_CHMOD, + I_CHOWN, + I_DF, + I_GET, + I_HELP, + I_LCHDIR, + I_LINK, + I_LLS, + I_LMKDIR, + I_LPWD, + I_LS, + I_LUMASK, + I_MKDIR, + I_PUT, + I_PWD, + I_QUIT, + I_RENAME, + I_RM, + I_RMDIR, + I_SHELL, + I_SYMLINK, + I_VERSION, + I_PROGRESS, + I_REGET, +}; struct CMD { const char *c; @@ -357,7 +362,7 @@ make_absolute(char *p, char *pwd) static int parse_getput_flags(const char *cmd, char **argv, int argc, - int *aflag, int *pflag, int *rflag) + int *aflag, int *fflag, int *pflag, int *rflag) { extern int opterr, optind, optopt, optreset; int ch; @@ -365,12 +370,15 @@ parse_getput_flags(const char *cmd, char **argv, int argc, optind = optreset = 1; opterr = 0; - *aflag = *rflag = *pflag = 0; - while ((ch = getopt(argc, argv, "aPpRr")) != -1) { + *aflag = *fflag = *rflag = *pflag = 0; + while ((ch = getopt(argc, argv, "afPpRr")) != -1) { switch (ch) { case 'a': *aflag = 1; break; + case 'f': + *fflag = 1; + break; case 'p': case 'P': *pflag = 1; @@ -412,6 +420,30 @@ parse_link_flags(const char *cmd, char **argv, int argc, int *sflag) return optind; } +static int +parse_rename_flags(const char *cmd, char **argv, int argc, int *lflag) +{ + extern int opterr, optind, optopt, optreset; + int ch; + + optind = optreset = 1; + opterr = 0; + + *lflag = 0; + while ((ch = getopt(argc, argv, "l")) != -1) { + switch (ch) { + case 'l': + *lflag = 1; + break; + default: + error("%s: Invalid flag -%c", cmd, optopt); + return -1; + } + } + + return optind; +} + static int parse_ls_flags(char **argv, int argc, int *lflag) { @@ -492,6 +524,26 @@ parse_df_flags(const char *cmd, char **argv, int argc, int *hflag, int *iflag) return optind; } +static int +parse_no_flags(const char *cmd, char **argv, int argc) +{ + extern int opterr, optind, optopt, optreset; + int ch; + + optind = optreset = 1; + opterr = 0; + + while ((ch = getopt(argc, argv, "")) != -1) { + switch (ch) { + default: + error("%s: Invalid flag -%c", cmd, optopt); + return -1; + } + } + + return optind; +} + static int is_dir(char *path) { @@ -528,7 +580,7 @@ pathname_is_dir(char *pathname) static int process_get(struct sftp_conn *conn, char *src, char *dst, char *pwd, - int pflag, int rflag, int resume) + int pflag, int rflag, int resume, int fflag) { char *abs_src = NULL; char *abs_dst = NULL; @@ -587,11 +639,13 @@ process_get(struct sftp_conn *conn, char *src, char *dst, char *pwd, printf("Fetching %s to %s\n", g.gl_pathv[i], abs_dst); if (pathname_is_dir(g.gl_pathv[i]) && (rflag || global_rflag)) { if (download_dir(conn, g.gl_pathv[i], abs_dst, NULL, - pflag || global_pflag, 1, resume) == -1) + pflag || global_pflag, 1, resume, + fflag || global_fflag) == -1) err = -1; } else { if (do_download(conn, g.gl_pathv[i], abs_dst, NULL, - pflag || global_pflag, resume) == -1) + pflag || global_pflag, resume, + fflag || global_fflag) == -1) err = -1; } free(abs_dst); @@ -606,7 +660,7 @@ process_get(struct sftp_conn *conn, char *src, char *dst, char *pwd, static int process_put(struct sftp_conn *conn, char *src, char *dst, char *pwd, - int pflag, int rflag) + int pflag, int rflag, int fflag) { char *tmp_dst = NULL; char *abs_dst = NULL; @@ -647,7 +701,7 @@ process_put(struct sftp_conn *conn, char *src, char *dst, char *pwd, error("stat %s: %s", g.gl_pathv[i], strerror(errno)); continue; } - + tmp = xstrdup(g.gl_pathv[i]); if ((filename = basename(tmp)) == NULL) { error("basename %s: %s", tmp, strerror(errno)); @@ -673,11 +727,13 @@ process_put(struct sftp_conn *conn, char *src, char *dst, char *pwd, printf("Uploading %s to %s\n", g.gl_pathv[i], abs_dst); if (pathname_is_dir(g.gl_pathv[i]) && (rflag || global_rflag)) { if (upload_dir(conn, g.gl_pathv[i], abs_dst, - pflag || global_pflag, 1) == -1) + pflag || global_pflag, 1, + fflag || global_fflag) == -1) err = -1; } else { if (do_upload(conn, g.gl_pathv[i], abs_dst, - pflag || global_pflag) == -1) + pflag || global_pflag, + fflag || global_fflag) == -1) err = -1; } } @@ -975,7 +1031,7 @@ undo_glob_escape(char *s) * * If "lastquote" is not NULL, the quoting character used for the last * argument is placed in *lastquote ("\0", "'" or "\""). - * + * * If "terminated" is not NULL, *terminated will be set to 1 when the * last argument's quote has been properly terminated or 0 otherwise. * This parameter is only of use if "sloppy" is set. @@ -1009,7 +1065,7 @@ makeargv(const char *arg, int *argcp, int sloppy, char *lastquote, error("Too many arguments."); return NULL; } - if (isspace(arg[i])) { + if (isspace((unsigned char)arg[i])) { if (state == MA_UNQUOTED) { /* Terminate current argument */ argvs[j++] = '\0'; @@ -1024,7 +1080,7 @@ makeargv(const char *arg, int *argcp, int sloppy, char *lastquote, state = q; if (lastquote != NULL) *lastquote = arg[i]; - } else if (state == MA_UNQUOTED) + } else if (state == MA_UNQUOTED) state = q; else if (state == q) state = MA_UNQUOTED; @@ -1130,9 +1186,9 @@ makeargv(const char *arg, int *argcp, int sloppy, char *lastquote, } static int -parse_args(const char **cpp, int *aflag, int *hflag, int *iflag, int *lflag, - int *pflag, int *rflag, int *sflag, unsigned long *n_arg, - char **path1, char **path2) +parse_args(const char **cpp, int *ignore_errors, int *aflag, int *fflag, + int *hflag, int *iflag, int *lflag, int *pflag, int *rflag, int *sflag, + unsigned long *n_arg, char **path1, char **path2) { const char *cmd, *cp = *cpp; char *cp2, **argv; @@ -1144,9 +1200,9 @@ parse_args(const char **cpp, int *aflag, int *hflag, int *iflag, int *lflag, cp = cp + strspn(cp, WHITESPACE); /* Check for leading '-' (disable error processing) */ - *iflag = 0; + *ignore_errors = 0; if (*cp == '-') { - *iflag = 1; + *ignore_errors = 1; cp++; cp = cp + strspn(cp, WHITESPACE); } @@ -1176,7 +1232,8 @@ parse_args(const char **cpp, int *aflag, int *hflag, int *iflag, int *lflag, } /* Get arguments and parse flags */ - *aflag = *lflag = *pflag = *rflag = *hflag = *n_arg = 0; + *aflag = *fflag = *hflag = *iflag = *lflag = *pflag = 0; + *rflag = *sflag = 0; *path1 = *path2 = NULL; optidx = 1; switch (cmdnum) { @@ -1184,7 +1241,7 @@ parse_args(const char **cpp, int *aflag, int *hflag, int *iflag, int *lflag, case I_REGET: case I_PUT: if ((optidx = parse_getput_flags(cmd, argv, argc, - aflag, pflag, rflag)) == -1) + aflag, fflag, pflag, rflag)) == -1) return -1; /* Get first pathname (mandatory) */ if (argc - optidx < 1) { @@ -1208,8 +1265,15 @@ parse_args(const char **cpp, int *aflag, int *hflag, int *iflag, int *lflag, case I_LINK: if ((optidx = parse_link_flags(cmd, argv, argc, sflag)) == -1) return -1; - case I_SYMLINK: + goto parse_two_paths; case I_RENAME: + if ((optidx = parse_rename_flags(cmd, argv, argc, lflag)) == -1) + return -1; + goto parse_two_paths; + case I_SYMLINK: + if ((optidx = parse_no_flags(cmd, argv, argc)) == -1) + return -1; + parse_two_paths: if (argc - optidx < 2) { error("You must specify two paths after a %s " "command.", cmd); @@ -1227,6 +1291,8 @@ parse_args(const char **cpp, int *aflag, int *hflag, int *iflag, int *lflag, case I_CHDIR: case I_LCHDIR: case I_LMKDIR: + if ((optidx = parse_no_flags(cmd, argv, argc)) == -1) + return -1; /* Get pathname (mandatory) */ if (argc - optidx < 1) { error("You must specify a path after a %s command.", @@ -1268,6 +1334,8 @@ parse_args(const char **cpp, int *aflag, int *hflag, int *iflag, int *lflag, base = 8; case I_CHOWN: case I_CHGRP: + if ((optidx = parse_no_flags(cmd, argv, argc)) == -1) + return -1; /* Get numeric arg (mandatory) */ if (argc - optidx < 1) goto need_num_arg; @@ -1298,6 +1366,8 @@ parse_args(const char **cpp, int *aflag, int *hflag, int *iflag, int *lflag, case I_HELP: case I_VERSION: case I_PROGRESS: + if ((optidx = parse_no_flags(cmd, argv, argc)) == -1) + return -1; break; default: fatal("Command not implemented"); @@ -1312,8 +1382,8 @@ parse_dispatch_command(struct sftp_conn *conn, const char *cmd, char **pwd, int err_abort) { char *path1, *path2, *tmp; - int aflag = 0, hflag = 0, iflag = 0, lflag = 0, pflag = 0; - int rflag = 0, sflag = 0; + int ignore_errors = 0, aflag = 0, fflag = 0, hflag = 0, iflag = 0; + int lflag = 0, pflag = 0, rflag = 0, sflag = 0; int cmdnum, i; unsigned long n_arg = 0; Attrib a, *aa; @@ -1322,9 +1392,9 @@ parse_dispatch_command(struct sftp_conn *conn, const char *cmd, char **pwd, glob_t g; path1 = path2 = NULL; - cmdnum = parse_args(&cmd, &aflag, &hflag, &iflag, &lflag, &pflag, - &rflag, &sflag, &n_arg, &path1, &path2); - if (iflag != 0) + cmdnum = parse_args(&cmd, &ignore_errors, &aflag, &fflag, &hflag, + &iflag, &lflag, &pflag, &rflag, &sflag, &n_arg, &path1, &path2); + if (ignore_errors != 0) err_abort = 0; memset(&g, 0, sizeof(g)); @@ -1343,20 +1413,22 @@ parse_dispatch_command(struct sftp_conn *conn, const char *cmd, char **pwd, /* FALLTHROUGH */ case I_GET: err = process_get(conn, path1, path2, *pwd, pflag, - rflag, aflag); + rflag, aflag, fflag); break; case I_PUT: - err = process_put(conn, path1, path2, *pwd, pflag, rflag); + err = process_put(conn, path1, path2, *pwd, pflag, + rflag, fflag); break; case I_RENAME: path1 = make_absolute(path1, *pwd); path2 = make_absolute(path2, *pwd); - err = do_rename(conn, path1, path2); + err = do_rename(conn, path1, path2, lflag); break; case I_SYMLINK: sflag = 1; case I_LINK: - path1 = make_absolute(path1, *pwd); + if (!sflag) + path1 = make_absolute(path1, *pwd); path2 = make_absolute(path2, *pwd); err = (sflag ? do_symlink : do_hardlink)(conn, path1, path2); break; @@ -1567,7 +1639,7 @@ complete_display(char **list, u_int len) char *tmp; /* Count entries for sort and find longest */ - for (y = 0; list[y]; y++) + for (y = 0; list[y]; y++) m = MAX(m, strlen(list[y])); if (ioctl(fileno(stdin), TIOCGWINSZ, &ws) != -1) @@ -1612,8 +1684,8 @@ complete_ambiguous(const char *word, char **list, size_t count) for (y = 1; list[y]; y++) { u_int x; - for (x = 0; x < matchlen; x++) - if (list[0][x] != list[y][x]) + for (x = 0; x < matchlen; x++) + if (list[0][x] != list[y][x]) break; matchlen = x; @@ -1625,7 +1697,7 @@ complete_ambiguous(const char *word, char **list, size_t count) tmp[matchlen] = '\0'; return tmp; } - } + } return xstrdup(word); } @@ -1645,12 +1717,12 @@ complete_cmd_parse(EditLine *el, char *cmd, int lastarg, char quote, if (cmd == NULL) { for (y = 0; cmds[y].c; y++) list[count++] = xstrdup(cmds[y].c); - + list[count] = NULL; complete_display(list, 0); - for (y = 0; list[y] != NULL; y++) - free(list[y]); + for (y = 0; list[y] != NULL; y++) + free(list[y]); free(list); return count; } @@ -1658,7 +1730,7 @@ complete_cmd_parse(EditLine *el, char *cmd, int lastarg, char quote, /* Prepare subset of commands that start with "cmd" */ cmdlen = strlen(cmd); for (y = 0; cmds[y].c; y++) { - if (!strncasecmp(cmd, cmds[y].c, cmdlen)) + if (!strncasecmp(cmd, cmds[y].c, cmdlen)) list[count++] = xstrdup(cmds[y].c); } list[count] = NULL; @@ -1673,8 +1745,8 @@ complete_cmd_parse(EditLine *el, char *cmd, int lastarg, char quote, if (count > 1) complete_display(list, 0); - for (y = 0; list[y]; y++) - free(list[y]); + for (y = 0; list[y]; y++) + free(list[y]); free(list); if (tmp != NULL) { @@ -1714,7 +1786,7 @@ complete_is_remote(char *cmd) { return -1; for (i = 0; cmds[i].c; i++) { - if (!strncasecmp(cmd, cmds[i].c, strlen(cmds[i].c))) + if (!strncasecmp(cmd, cmds[i].c, strlen(cmds[i].c))) return cmds[i].t; } @@ -1731,7 +1803,7 @@ complete_match(EditLine *el, struct sftp_conn *conn, char *remote_path, u_int i, hadglob, pwdlen, len, tmplen, filelen, cesc, isesc, isabs; int clen; const LineInfo *lf; - + /* Glob from "file" location */ if (file == NULL) tmp = xstrdup("*"); @@ -1745,9 +1817,9 @@ complete_match(EditLine *el, struct sftp_conn *conn, char *remote_path, if (remote != LOCAL) { tmp = make_absolute(tmp, remote_path); remote_glob(conn, tmp, GLOB_DOOFFS|GLOB_MARK, NULL, &g); - } else + } else glob(tmp, GLOB_DOOFFS|GLOB_MARK, NULL, &g); - + /* Determine length of pwd so we can trim completion display */ for (hadglob = tmplen = pwdlen = 0; tmp[tmplen] != 0; tmplen++) { /* Terminate counting on first unescaped glob metacharacter */ @@ -1763,7 +1835,7 @@ complete_match(EditLine *el, struct sftp_conn *conn, char *remote_path, } free(tmp); - if (g.gl_matchc == 0) + if (g.gl_matchc == 0) goto out; if (g.gl_matchc > 1) @@ -1796,7 +1868,7 @@ complete_match(EditLine *el, struct sftp_conn *conn, char *remote_path, if (tmplen > (filelen - cesc)) { tmp2 = tmp + filelen - cesc; - len = strlen(tmp2); + len = strlen(tmp2); /* quote argument on way out */ for (i = 0; i < len; i += clen) { if ((clen = mblen(tmp2 + i, len - i)) < 0 || @@ -1852,7 +1924,7 @@ complete_match(EditLine *el, struct sftp_conn *conn, char *remote_path, static unsigned char complete(EditLine *el, int ch) { - char **argv, *line, quote; + char **argv, *line, quote; int argc, carg; u_int cursor, len, terminated, ret = CC_ERROR; const LineInfo *lf; @@ -1891,7 +1963,7 @@ complete(EditLine *el, int ch) } else if (carg == 1 && cursor > 0 && line[cursor - 1] != ' ') { /* Handle the command parsing */ if (complete_cmd_parse(el, argv[0], argc == carg, - quote, terminated) != 0) + quote, terminated) != 0) ret = CC_REDISPLAY; } else if (carg >= 1) { /* Handle file parsing */ @@ -1904,11 +1976,11 @@ complete(EditLine *el, int ch) if (remote != 0 && complete_match(el, complete_ctx->conn, *complete_ctx->remote_pathp, filematch, - remote, carg == argc, quote, terminated) != 0) + remote, carg == argc, quote, terminated) != 0) ret = CC_REDISPLAY; } - free(line); + free(line); return ret; } #endif /* USE_LIBEDIT */ @@ -1942,12 +2014,19 @@ interactive_loop(struct sftp_conn *conn, char *file1, char *file2) el_source(el, NULL); /* Tab Completion */ - el_set(el, EL_ADDFN, "ftp-complete", + el_set(el, EL_ADDFN, "ftp-complete", "Context sensitive argument completion", complete); complete_ctx.conn = conn; complete_ctx.remote_pathp = &remote_path; el_set(el, EL_CLIENTDATA, (void*)&complete_ctx); el_set(el, EL_BIND, "^I", "ftp-complete", NULL); + /* enable ctrl-left-arrow and ctrl-right-arrow */ + el_set(el, EL_BIND, "\\e[1;5C", "em-next-word", NULL); + el_set(el, EL_BIND, "\\e[5C", "em-next-word", NULL); + el_set(el, EL_BIND, "\\e[1;5D", "ed-prev-word", NULL); + el_set(el, EL_BIND, "\\e\\e[D", "ed-prev-word", NULL); + /* make ^w match ksh behaviour */ + el_set(el, EL_BIND, "^w", "ed-delete-prev-word", NULL); } #endif /* USE_LIBEDIT */ @@ -2116,7 +2195,7 @@ usage(void) extern char *__progname; fprintf(stderr, - "usage: %s [-1246Cpqrv] [-B buffer_size] [-b batchfile] [-c cipher]\n" + "usage: %s [-1246aCfpqrv] [-B buffer_size] [-b batchfile] [-c cipher]\n" " [-D sftp_server_path] [-F ssh_config] " "[-i identity_file] [-l limit]\n" " [-o ssh_option] [-P port] [-R num_requests] " @@ -2164,7 +2243,7 @@ main(int argc, char **argv) infile = stdin; while ((ch = getopt(argc, argv, - "1246ahpqrvCc:D:i:l:o:s:S:b:B:F:P:R:")) != -1) { + "1246afhpqrvCc:D:i:l:o:s:S:b:B:F:P:R:")) != -1) { switch (ch) { /* Passed through to ssh(1) */ case '4': @@ -2224,6 +2303,9 @@ main(int argc, char **argv) quiet = batchmode = 1; addargs(&args, "-obatchmode yes"); break; + case 'f': + global_fflag = 1; + break; case 'p': global_pflag = 1; break; diff --git a/smult_curve25519_ref.c b/smult_curve25519_ref.c new file mode 100644 index 000000000000..2e69934d4dea --- /dev/null +++ b/smult_curve25519_ref.c @@ -0,0 +1,265 @@ +/* $OpenBSD: smult_curve25519_ref.c,v 1.2 2013/11/02 22:02:14 markus Exp $ */ +/* +version 20081011 +Matthew Dempsky +Public domain. +Derived from public domain code by D. J. Bernstein. +*/ + +int crypto_scalarmult_curve25519(unsigned char *, const unsigned char *, const unsigned char *); + +static void add(unsigned int out[32],const unsigned int a[32],const unsigned int b[32]) +{ + unsigned int j; + unsigned int u; + u = 0; + for (j = 0;j < 31;++j) { u += a[j] + b[j]; out[j] = u & 255; u >>= 8; } + u += a[31] + b[31]; out[31] = u; +} + +static void sub(unsigned int out[32],const unsigned int a[32],const unsigned int b[32]) +{ + unsigned int j; + unsigned int u; + u = 218; + for (j = 0;j < 31;++j) { + u += a[j] + 65280 - b[j]; + out[j] = u & 255; + u >>= 8; + } + u += a[31] - b[31]; + out[31] = u; +} + +static void squeeze(unsigned int a[32]) +{ + unsigned int j; + unsigned int u; + u = 0; + for (j = 0;j < 31;++j) { u += a[j]; a[j] = u & 255; u >>= 8; } + u += a[31]; a[31] = u & 127; + u = 19 * (u >> 7); + for (j = 0;j < 31;++j) { u += a[j]; a[j] = u & 255; u >>= 8; } + u += a[31]; a[31] = u; +} + +static const unsigned int minusp[32] = { + 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128 +} ; + +static void freeze(unsigned int a[32]) +{ + unsigned int aorig[32]; + unsigned int j; + unsigned int negative; + + for (j = 0;j < 32;++j) aorig[j] = a[j]; + add(a,a,minusp); + negative = -((a[31] >> 7) & 1); + for (j = 0;j < 32;++j) a[j] ^= negative & (aorig[j] ^ a[j]); +} + +static void mult(unsigned int out[32],const unsigned int a[32],const unsigned int b[32]) +{ + unsigned int i; + unsigned int j; + unsigned int u; + + for (i = 0;i < 32;++i) { + u = 0; + for (j = 0;j <= i;++j) u += a[j] * b[i - j]; + for (j = i + 1;j < 32;++j) u += 38 * a[j] * b[i + 32 - j]; + out[i] = u; + } + squeeze(out); +} + +static void mult121665(unsigned int out[32],const unsigned int a[32]) +{ + unsigned int j; + unsigned int u; + + u = 0; + for (j = 0;j < 31;++j) { u += 121665 * a[j]; out[j] = u & 255; u >>= 8; } + u += 121665 * a[31]; out[31] = u & 127; + u = 19 * (u >> 7); + for (j = 0;j < 31;++j) { u += out[j]; out[j] = u & 255; u >>= 8; } + u += out[j]; out[j] = u; +} + +static void square(unsigned int out[32],const unsigned int a[32]) +{ + unsigned int i; + unsigned int j; + unsigned int u; + + for (i = 0;i < 32;++i) { + u = 0; + for (j = 0;j < i - j;++j) u += a[j] * a[i - j]; + for (j = i + 1;j < i + 32 - j;++j) u += 38 * a[j] * a[i + 32 - j]; + u *= 2; + if ((i & 1) == 0) { + u += a[i / 2] * a[i / 2]; + u += 38 * a[i / 2 + 16] * a[i / 2 + 16]; + } + out[i] = u; + } + squeeze(out); +} + +static void select(unsigned int p[64],unsigned int q[64],const unsigned int r[64],const unsigned int s[64],unsigned int b) +{ + unsigned int j; + unsigned int t; + unsigned int bminus1; + + bminus1 = b - 1; + for (j = 0;j < 64;++j) { + t = bminus1 & (r[j] ^ s[j]); + p[j] = s[j] ^ t; + q[j] = r[j] ^ t; + } +} + +static void mainloop(unsigned int work[64],const unsigned char e[32]) +{ + unsigned int xzm1[64]; + unsigned int xzm[64]; + unsigned int xzmb[64]; + unsigned int xzm1b[64]; + unsigned int xznb[64]; + unsigned int xzn1b[64]; + unsigned int a0[64]; + unsigned int a1[64]; + unsigned int b0[64]; + unsigned int b1[64]; + unsigned int c1[64]; + unsigned int r[32]; + unsigned int s[32]; + unsigned int t[32]; + unsigned int u[32]; + unsigned int j; + unsigned int b; + int pos; + + for (j = 0;j < 32;++j) xzm1[j] = work[j]; + xzm1[32] = 1; + for (j = 33;j < 64;++j) xzm1[j] = 0; + + xzm[0] = 1; + for (j = 1;j < 64;++j) xzm[j] = 0; + + for (pos = 254;pos >= 0;--pos) { + b = e[pos / 8] >> (pos & 7); + b &= 1; + select(xzmb,xzm1b,xzm,xzm1,b); + add(a0,xzmb,xzmb + 32); + sub(a0 + 32,xzmb,xzmb + 32); + add(a1,xzm1b,xzm1b + 32); + sub(a1 + 32,xzm1b,xzm1b + 32); + square(b0,a0); + square(b0 + 32,a0 + 32); + mult(b1,a1,a0 + 32); + mult(b1 + 32,a1 + 32,a0); + add(c1,b1,b1 + 32); + sub(c1 + 32,b1,b1 + 32); + square(r,c1 + 32); + sub(s,b0,b0 + 32); + mult121665(t,s); + add(u,t,b0); + mult(xznb,b0,b0 + 32); + mult(xznb + 32,s,u); + square(xzn1b,c1); + mult(xzn1b + 32,r,work); + select(xzm,xzm1,xznb,xzn1b,b); + } + + for (j = 0;j < 64;++j) work[j] = xzm[j]; +} + +static void recip(unsigned int out[32],const unsigned int z[32]) +{ + unsigned int z2[32]; + unsigned int z9[32]; + unsigned int z11[32]; + unsigned int z2_5_0[32]; + unsigned int z2_10_0[32]; + unsigned int z2_20_0[32]; + unsigned int z2_50_0[32]; + unsigned int z2_100_0[32]; + unsigned int t0[32]; + unsigned int t1[32]; + int i; + + /* 2 */ square(z2,z); + /* 4 */ square(t1,z2); + /* 8 */ square(t0,t1); + /* 9 */ mult(z9,t0,z); + /* 11 */ mult(z11,z9,z2); + /* 22 */ square(t0,z11); + /* 2^5 - 2^0 = 31 */ mult(z2_5_0,t0,z9); + + /* 2^6 - 2^1 */ square(t0,z2_5_0); + /* 2^7 - 2^2 */ square(t1,t0); + /* 2^8 - 2^3 */ square(t0,t1); + /* 2^9 - 2^4 */ square(t1,t0); + /* 2^10 - 2^5 */ square(t0,t1); + /* 2^10 - 2^0 */ mult(z2_10_0,t0,z2_5_0); + + /* 2^11 - 2^1 */ square(t0,z2_10_0); + /* 2^12 - 2^2 */ square(t1,t0); + /* 2^20 - 2^10 */ for (i = 2;i < 10;i += 2) { square(t0,t1); square(t1,t0); } + /* 2^20 - 2^0 */ mult(z2_20_0,t1,z2_10_0); + + /* 2^21 - 2^1 */ square(t0,z2_20_0); + /* 2^22 - 2^2 */ square(t1,t0); + /* 2^40 - 2^20 */ for (i = 2;i < 20;i += 2) { square(t0,t1); square(t1,t0); } + /* 2^40 - 2^0 */ mult(t0,t1,z2_20_0); + + /* 2^41 - 2^1 */ square(t1,t0); + /* 2^42 - 2^2 */ square(t0,t1); + /* 2^50 - 2^10 */ for (i = 2;i < 10;i += 2) { square(t1,t0); square(t0,t1); } + /* 2^50 - 2^0 */ mult(z2_50_0,t0,z2_10_0); + + /* 2^51 - 2^1 */ square(t0,z2_50_0); + /* 2^52 - 2^2 */ square(t1,t0); + /* 2^100 - 2^50 */ for (i = 2;i < 50;i += 2) { square(t0,t1); square(t1,t0); } + /* 2^100 - 2^0 */ mult(z2_100_0,t1,z2_50_0); + + /* 2^101 - 2^1 */ square(t1,z2_100_0); + /* 2^102 - 2^2 */ square(t0,t1); + /* 2^200 - 2^100 */ for (i = 2;i < 100;i += 2) { square(t1,t0); square(t0,t1); } + /* 2^200 - 2^0 */ mult(t1,t0,z2_100_0); + + /* 2^201 - 2^1 */ square(t0,t1); + /* 2^202 - 2^2 */ square(t1,t0); + /* 2^250 - 2^50 */ for (i = 2;i < 50;i += 2) { square(t0,t1); square(t1,t0); } + /* 2^250 - 2^0 */ mult(t0,t1,z2_50_0); + + /* 2^251 - 2^1 */ square(t1,t0); + /* 2^252 - 2^2 */ square(t0,t1); + /* 2^253 - 2^3 */ square(t1,t0); + /* 2^254 - 2^4 */ square(t0,t1); + /* 2^255 - 2^5 */ square(t1,t0); + /* 2^255 - 21 */ mult(out,t1,z11); +} + +int crypto_scalarmult_curve25519(unsigned char *q, + const unsigned char *n, + const unsigned char *p) +{ + unsigned int work[96]; + unsigned char e[32]; + unsigned int i; + for (i = 0;i < 32;++i) e[i] = n[i]; + e[0] &= 248; + e[31] &= 127; + e[31] |= 64; + for (i = 0;i < 32;++i) work[i] = p[i]; + mainloop(work,e); + recip(work + 32,work + 32); + mult(work + 64,work,work + 32); + freeze(work + 64); + for (i = 0;i < 32;++i) q[i] = work[64 + i]; + return 0; +} diff --git a/ssh-add.0 b/ssh-add.0 index bcd1e7322893..8d10f7ff4d92 100644 --- a/ssh-add.0 +++ b/ssh-add.0 @@ -11,11 +11,11 @@ SYNOPSIS DESCRIPTION ssh-add adds private key identities to the authentication agent, ssh-agent(1). When run without arguments, it adds the files - ~/.ssh/id_rsa, ~/.ssh/id_dsa, ~/.ssh/id_ecdsa and ~/.ssh/identity. After - loading a private key, ssh-add will try to load corresponding certificate - information from the filename obtained by appending -cert.pub to the name - of the private key file. Alternative file names can be given on the - command line. + ~/.ssh/id_rsa, ~/.ssh/id_dsa, ~/.ssh/id_ecdsa, ~/.ssh/id_ed25519 and + ~/.ssh/identity. After loading a private key, ssh-add will try to load + corresponding certificate information from the filename obtained by + appending -cert.pub to the name of the private key file. Alternative + file names can be given on the command line. If any file requires a passphrase, ssh-add asks for the passphrase from the user. The passphrase is read from the user's tty. ssh-add retries @@ -95,6 +95,10 @@ FILES Contains the protocol version 2 ECDSA authentication identity of the user. + ~/.ssh/id_ed25519 + Contains the protocol version 2 ED25519 authentication identity + of the user. + ~/.ssh/id_rsa Contains the protocol version 2 RSA authentication identity of the user. @@ -116,4 +120,4 @@ AUTHORS created OpenSSH. Markus Friedl contributed the support for SSH protocol versions 1.5 and 2.0. -OpenBSD 5.4 December 3, 2012 OpenBSD 5.4 +OpenBSD 5.4 December 7, 2013 OpenBSD 5.4 diff --git a/ssh-add.1 b/ssh-add.1 index 44846b67ea60..4812448fa93d 100644 --- a/ssh-add.1 +++ b/ssh-add.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: ssh-add.1,v 1.58 2012/12/03 08:33:02 jmc Exp $ +.\" $OpenBSD: ssh-add.1,v 1.59 2013/12/07 11:58:46 naddy Exp $ .\" .\" Author: Tatu Ylonen .\" Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -35,7 +35,7 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.Dd $Mdocdate: December 3 2012 $ +.Dd $Mdocdate: December 7 2013 $ .Dt SSH-ADD 1 .Os .Sh NAME @@ -57,7 +57,8 @@ adds private key identities to the authentication agent, When run without arguments, it adds the files .Pa ~/.ssh/id_rsa , .Pa ~/.ssh/id_dsa , -.Pa ~/.ssh/id_ecdsa +.Pa ~/.ssh/id_ecdsa , +.Pa ~/.ssh/id_ed25519 and .Pa ~/.ssh/identity . After loading a private key, @@ -169,6 +170,8 @@ Contains the protocol version 1 RSA authentication identity of the user. Contains the protocol version 2 DSA authentication identity of the user. .It Pa ~/.ssh/id_ecdsa Contains the protocol version 2 ECDSA authentication identity of the user. +.It Pa ~/.ssh/id_ed25519 +Contains the protocol version 2 ED25519 authentication identity of the user. .It Pa ~/.ssh/id_rsa Contains the protocol version 2 RSA authentication identity of the user. .El diff --git a/ssh-add.c b/ssh-add.c index 5e8166f66e13..63ce72083587 100644 --- a/ssh-add.c +++ b/ssh-add.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-add.c,v 1.106 2013/05/17 00:13:14 djm Exp $ */ +/* $OpenBSD: ssh-add.c,v 1.108 2013/12/19 00:10:30 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -73,6 +73,7 @@ static char *default_files[] = { #ifdef OPENSSL_HAS_ECC _PATH_SSH_CLIENT_ID_ECDSA, #endif + _PATH_SSH_CLIENT_ID_ED25519, _PATH_SSH_CLIENT_IDENTITY, NULL }; @@ -292,14 +293,17 @@ add_file(AuthenticationConnection *ac, const char *filename, int key_only) static int update_card(AuthenticationConnection *ac, int add, const char *id) { - char *pin; + char *pin = NULL; int ret = -1; - pin = read_passphrase("Enter passphrase for PKCS#11: ", RP_ALLOW_STDIN); - if (pin == NULL) - return -1; + if (add) { + if ((pin = read_passphrase("Enter passphrase for PKCS#11: ", + RP_ALLOW_STDIN)) == NULL) + return -1; + } - if (ssh_update_card(ac, add, id, pin, lifetime, confirm)) { + if (ssh_update_card(ac, add, id, pin == NULL ? "" : pin, + lifetime, confirm)) { fprintf(stderr, "Card %s: %s\n", add ? "added" : "removed", id); ret = 0; diff --git a/ssh-agent.0 b/ssh-agent.0 index e5f0f7342b7e..c4c53ef94902 100644 --- a/ssh-agent.0 +++ b/ssh-agent.0 @@ -9,12 +9,12 @@ SYNOPSIS DESCRIPTION ssh-agent is a program to hold private keys used for public key - authentication (RSA, DSA, ECDSA). The idea is that ssh-agent is started - in the beginning of an X-session or a login session, and all other - windows or programs are started as clients to the ssh-agent program. - Through use of environment variables the agent can be located and - automatically used for authentication when logging in to other machines - using ssh(1). + authentication (RSA, DSA, ECDSA, ED25519). The idea is that ssh-agent is + started in the beginning of an X-session or a login session, and all + other windows or programs are started as clients to the ssh-agent + program. Through use of environment variables the agent can be located + and automatically used for authentication when logging in to other + machines using ssh(1). The options are as follows: @@ -46,13 +46,14 @@ DESCRIPTION The agent initially does not have any private keys. Keys are added using ssh-add(1). When executed without arguments, ssh-add(1) adds the files - ~/.ssh/id_rsa, ~/.ssh/id_dsa, ~/.ssh/id_ecdsa and ~/.ssh/identity. If - the identity has a passphrase, ssh-add(1) asks for the passphrase on the - terminal if it has one or from a small X11 program if running under X11. - If neither of these is the case then the authentication will fail. It - then sends the identity to the agent. Several identities can be stored - in the agent; the agent can automatically use any of these identities. - ssh-add -l displays the identities currently held by the agent. + ~/.ssh/id_rsa, ~/.ssh/id_dsa, ~/.ssh/id_ecdsa, ~/.ssh/id_ed25519 and + ~/.ssh/identity. If the identity has a passphrase, ssh-add(1) asks for + the passphrase on the terminal if it has one or from a small X11 program + if running under X11. If neither of these is the case then the + authentication will fail. It then sends the identity to the agent. + Several identities can be stored in the agent; the agent can + automatically use any of these identities. ssh-add -l displays the + identities currently held by the agent. The idea is that the agent is run in the user's local PC, laptop, or terminal. Authentication data need not be stored on any other machine, @@ -100,6 +101,10 @@ FILES Contains the protocol version 2 ECDSA authentication identity of the user. + ~/.ssh/id_ed25519 + Contains the protocol version 2 ED25519 authentication identity + of the user. + ~/.ssh/id_rsa Contains the protocol version 2 RSA authentication identity of the user. @@ -120,4 +125,4 @@ AUTHORS created OpenSSH. Markus Friedl contributed the support for SSH protocol versions 1.5 and 2.0. -OpenBSD 5.4 November 21, 2010 OpenBSD 5.4 +OpenBSD 5.4 December 7, 2013 OpenBSD 5.4 diff --git a/ssh-agent.1 b/ssh-agent.1 index bb801c902a97..281ecbdcfcd7 100644 --- a/ssh-agent.1 +++ b/ssh-agent.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: ssh-agent.1,v 1.53 2010/11/21 01:01:13 djm Exp $ +.\" $OpenBSD: ssh-agent.1,v 1.54 2013/12/07 11:58:46 naddy Exp $ .\" .\" Author: Tatu Ylonen .\" Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -34,7 +34,7 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.Dd $Mdocdate: November 21 2010 $ +.Dd $Mdocdate: December 7 2013 $ .Dt SSH-AGENT 1 .Os .Sh NAME @@ -53,7 +53,7 @@ .Sh DESCRIPTION .Nm is a program to hold private keys used for public key authentication -(RSA, DSA, ECDSA). +(RSA, DSA, ECDSA, ED25519). The idea is that .Nm is started in the beginning of an X-session or a login session, and @@ -115,7 +115,8 @@ When executed without arguments, adds the files .Pa ~/.ssh/id_rsa , .Pa ~/.ssh/id_dsa , -.Pa ~/.ssh/id_ecdsa +.Pa ~/.ssh/id_ecdsa , +.Pa ~/.ssh/id_ed25519 and .Pa ~/.ssh/identity . If the identity has a passphrase, @@ -190,6 +191,8 @@ Contains the protocol version 1 RSA authentication identity of the user. Contains the protocol version 2 DSA authentication identity of the user. .It Pa ~/.ssh/id_ecdsa Contains the protocol version 2 ECDSA authentication identity of the user. +.It Pa ~/.ssh/id_ed25519 +Contains the protocol version 2 ED25519 authentication identity of the user. .It Pa ~/.ssh/id_rsa Contains the protocol version 2 RSA authentication identity of the user. .It Pa $TMPDIR/ssh-XXXXXXXXXX/agent.\*(Ltppid\*(Gt diff --git a/ssh-agent.c b/ssh-agent.c index c3b11729c04a..95117e0764dd 100644 --- a/ssh-agent.c +++ b/ssh-agent.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-agent.c,v 1.177 2013/07/20 01:50:20 djm Exp $ */ +/* $OpenBSD: ssh-agent.c,v 1.181 2013/12/19 01:19:41 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -464,16 +464,9 @@ process_add_identity(SocketEntry *e, int version) Idtab *tab = idtab_lookup(version); Identity *id; int type, success = 0, confirm = 0; - char *type_name, *comment; + char *comment; time_t death = 0; Key *k = NULL; -#ifdef OPENSSL_HAS_ECC - BIGNUM *exponent; - EC_POINT *q; - char *curve; -#endif - u_char *cert; - u_int len; switch (version) { case 1: @@ -490,125 +483,21 @@ process_add_identity(SocketEntry *e, int version) /* Generate additional parameters */ rsa_generate_additional_parameters(k->rsa); - break; - case 2: - type_name = buffer_get_string(&e->request, NULL); - type = key_type_from_name(type_name); - switch (type) { - case KEY_DSA: - k = key_new_private(type); - buffer_get_bignum2(&e->request, k->dsa->p); - buffer_get_bignum2(&e->request, k->dsa->q); - buffer_get_bignum2(&e->request, k->dsa->g); - buffer_get_bignum2(&e->request, k->dsa->pub_key); - buffer_get_bignum2(&e->request, k->dsa->priv_key); - break; - case KEY_DSA_CERT_V00: - case KEY_DSA_CERT: - cert = buffer_get_string(&e->request, &len); - if ((k = key_from_blob(cert, len)) == NULL) - fatal("Certificate parse failed"); - free(cert); - key_add_private(k); - buffer_get_bignum2(&e->request, k->dsa->priv_key); - break; -#ifdef OPENSSL_HAS_ECC - case KEY_ECDSA: - k = key_new_private(type); - k->ecdsa_nid = key_ecdsa_nid_from_name(type_name); - curve = buffer_get_string(&e->request, NULL); - if (k->ecdsa_nid != key_curve_name_to_nid(curve)) - fatal("%s: curve names mismatch", __func__); - free(curve); - k->ecdsa = EC_KEY_new_by_curve_name(k->ecdsa_nid); - if (k->ecdsa == NULL) - fatal("%s: EC_KEY_new_by_curve_name failed", - __func__); - q = EC_POINT_new(EC_KEY_get0_group(k->ecdsa)); - if (q == NULL) - fatal("%s: BN_new failed", __func__); - if ((exponent = BN_new()) == NULL) - fatal("%s: BN_new failed", __func__); - buffer_get_ecpoint(&e->request, - EC_KEY_get0_group(k->ecdsa), q); - buffer_get_bignum2(&e->request, exponent); - if (EC_KEY_set_public_key(k->ecdsa, q) != 1) - fatal("%s: EC_KEY_set_public_key failed", - __func__); - if (EC_KEY_set_private_key(k->ecdsa, exponent) != 1) - fatal("%s: EC_KEY_set_private_key failed", - __func__); - if (key_ec_validate_public(EC_KEY_get0_group(k->ecdsa), - EC_KEY_get0_public_key(k->ecdsa)) != 0) - fatal("%s: bad ECDSA public key", __func__); - if (key_ec_validate_private(k->ecdsa) != 0) - fatal("%s: bad ECDSA private key", __func__); - BN_clear_free(exponent); - EC_POINT_free(q); - break; - case KEY_ECDSA_CERT: - cert = buffer_get_string(&e->request, &len); - if ((k = key_from_blob(cert, len)) == NULL) - fatal("Certificate parse failed"); - free(cert); - key_add_private(k); - if ((exponent = BN_new()) == NULL) - fatal("%s: BN_new failed", __func__); - buffer_get_bignum2(&e->request, exponent); - if (EC_KEY_set_private_key(k->ecdsa, exponent) != 1) - fatal("%s: EC_KEY_set_private_key failed", - __func__); - if (key_ec_validate_public(EC_KEY_get0_group(k->ecdsa), - EC_KEY_get0_public_key(k->ecdsa)) != 0 || - key_ec_validate_private(k->ecdsa) != 0) - fatal("%s: bad ECDSA key", __func__); - BN_clear_free(exponent); - break; -#endif /* OPENSSL_HAS_ECC */ - case KEY_RSA: - k = key_new_private(type); - buffer_get_bignum2(&e->request, k->rsa->n); - buffer_get_bignum2(&e->request, k->rsa->e); - buffer_get_bignum2(&e->request, k->rsa->d); - buffer_get_bignum2(&e->request, k->rsa->iqmp); - buffer_get_bignum2(&e->request, k->rsa->p); - buffer_get_bignum2(&e->request, k->rsa->q); - /* Generate additional parameters */ - rsa_generate_additional_parameters(k->rsa); - break; - case KEY_RSA_CERT_V00: - case KEY_RSA_CERT: - cert = buffer_get_string(&e->request, &len); - if ((k = key_from_blob(cert, len)) == NULL) - fatal("Certificate parse failed"); - free(cert); - key_add_private(k); - buffer_get_bignum2(&e->request, k->rsa->d); - buffer_get_bignum2(&e->request, k->rsa->iqmp); - buffer_get_bignum2(&e->request, k->rsa->p); - buffer_get_bignum2(&e->request, k->rsa->q); - break; - default: - free(type_name); - buffer_clear(&e->request); - goto send; - } - free(type_name); - break; - } - /* enable blinding */ - switch (k->type) { - case KEY_RSA: - case KEY_RSA_CERT_V00: - case KEY_RSA_CERT: - case KEY_RSA1: + /* enable blinding */ if (RSA_blinding_on(k->rsa, NULL) != 1) { error("process_add_identity: RSA_blinding_on failed"); key_free(k); goto send; } break; + case 2: + k = key_private_deserialize(&e->request); + if (k == NULL) { + buffer_clear(&e->request); + goto send; + } + break; } comment = buffer_get_string(&e->request, NULL); if (k == NULL) { @@ -771,6 +660,9 @@ process_remove_smartcard_key(SocketEntry *e) tab = idtab_lookup(version); for (id = TAILQ_FIRST(&tab->idlist); id; id = nxt) { nxt = TAILQ_NEXT(id, next); + /* Skip file--based keys */ + if (id->provider == NULL) + continue; if (!strcmp(provider, id->provider)) { TAILQ_REMOVE(&tab->idlist, id, next); free_identity(id); diff --git a/ssh-dss.c b/ssh-dss.c index 322ec9fd80d8..7b897475c1a7 100644 --- a/ssh-dss.c +++ b/ssh-dss.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-dss.c,v 1.28 2013/05/17 00:13:14 djm Exp $ */ +/* $OpenBSD: ssh-dss.c,v 1.30 2014/01/09 23:20:00 djm Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. * @@ -38,6 +38,7 @@ #include "compat.h" #include "log.h" #include "key.h" +#include "digest.h" #define INTBLOB_LEN 20 #define SIGBLOB_LEN (2*INTBLOB_LEN) @@ -47,20 +48,21 @@ ssh_dss_sign(const Key *key, u_char **sigp, u_int *lenp, const u_char *data, u_int datalen) { DSA_SIG *sig; - const EVP_MD *evp_md = EVP_sha1(); - EVP_MD_CTX md; - u_char digest[EVP_MAX_MD_SIZE], sigblob[SIGBLOB_LEN]; - u_int rlen, slen, len, dlen; + u_char digest[SSH_DIGEST_MAX_LENGTH], sigblob[SIGBLOB_LEN]; + u_int rlen, slen, len, dlen = ssh_digest_bytes(SSH_DIGEST_SHA1); Buffer b; - if (key == NULL || key->dsa == NULL || (key->type != KEY_DSA && - key->type != KEY_DSA_CERT && key->type != KEY_DSA_CERT_V00)) { - error("ssh_dss_sign: no DSA key"); + if (key == NULL || key_type_plain(key->type) != KEY_DSA || + key->dsa == NULL) { + error("%s: no DSA key", __func__); + return -1; + } + + if (ssh_digest_memory(SSH_DIGEST_SHA1, data, datalen, + digest, sizeof(digest)) != 0) { + error("%s: ssh_digest_memory failed", __func__); return -1; } - EVP_DigestInit(&md, evp_md); - EVP_DigestUpdate(&md, data, datalen); - EVP_DigestFinal(&md, digest, &dlen); sig = DSA_do_sign(digest, dlen, key->dsa); memset(digest, 'd', sizeof(digest)); @@ -110,16 +112,14 @@ ssh_dss_verify(const Key *key, const u_char *signature, u_int signaturelen, const u_char *data, u_int datalen) { DSA_SIG *sig; - const EVP_MD *evp_md = EVP_sha1(); - EVP_MD_CTX md; - u_char digest[EVP_MAX_MD_SIZE], *sigblob; - u_int len, dlen; + u_char digest[SSH_DIGEST_MAX_LENGTH], *sigblob; + u_int len, dlen = ssh_digest_bytes(SSH_DIGEST_SHA1); int rlen, ret; Buffer b; - if (key == NULL || key->dsa == NULL || (key->type != KEY_DSA && - key->type != KEY_DSA_CERT && key->type != KEY_DSA_CERT_V00)) { - error("ssh_dss_verify: no DSA key"); + if (key == NULL || key_type_plain(key->type) != KEY_DSA || + key->dsa == NULL) { + error("%s: no DSA key", __func__); return -1; } @@ -135,7 +135,7 @@ ssh_dss_verify(const Key *key, const u_char *signature, u_int signaturelen, buffer_append(&b, signature, signaturelen); ktype = buffer_get_cstring(&b, NULL); if (strcmp("ssh-dss", ktype) != 0) { - error("ssh_dss_verify: cannot handle type %s", ktype); + error("%s: cannot handle type %s", __func__, ktype); buffer_free(&b); free(ktype); return -1; @@ -145,8 +145,8 @@ ssh_dss_verify(const Key *key, const u_char *signature, u_int signaturelen, rlen = buffer_len(&b); buffer_free(&b); if (rlen != 0) { - error("ssh_dss_verify: " - "remaining bytes in signature %d", rlen); + error("%s: remaining bytes in signature %d", + __func__, rlen); free(sigblob); return -1; } @@ -158,30 +158,32 @@ ssh_dss_verify(const Key *key, const u_char *signature, u_int signaturelen, /* parse signature */ if ((sig = DSA_SIG_new()) == NULL) - fatal("ssh_dss_verify: DSA_SIG_new failed"); + fatal("%s: DSA_SIG_new failed", __func__); if ((sig->r = BN_new()) == NULL) - fatal("ssh_dss_verify: BN_new failed"); + fatal("%s: BN_new failed", __func__); if ((sig->s = BN_new()) == NULL) fatal("ssh_dss_verify: BN_new failed"); if ((BN_bin2bn(sigblob, INTBLOB_LEN, sig->r) == NULL) || (BN_bin2bn(sigblob+ INTBLOB_LEN, INTBLOB_LEN, sig->s) == NULL)) - fatal("ssh_dss_verify: BN_bin2bn failed"); + fatal("%s: BN_bin2bn failed", __func__); /* clean up */ memset(sigblob, 0, len); free(sigblob); /* sha1 the data */ - EVP_DigestInit(&md, evp_md); - EVP_DigestUpdate(&md, data, datalen); - EVP_DigestFinal(&md, digest, &dlen); + if (ssh_digest_memory(SSH_DIGEST_SHA1, data, datalen, + digest, sizeof(digest)) != 0) { + error("%s: digest_memory failed", __func__); + return -1; + } ret = DSA_do_verify(digest, dlen, sig, key->dsa); memset(digest, 'd', sizeof(digest)); DSA_SIG_free(sig); - debug("ssh_dss_verify: signature %s", + debug("%s: signature %s", __func__, ret == 1 ? "correct" : ret == 0 ? "incorrect" : "error"); return ret; } diff --git a/ssh-ecdsa.c b/ssh-ecdsa.c index 766338941744..10ad9da608f3 100644 --- a/ssh-ecdsa.c +++ b/ssh-ecdsa.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-ecdsa.c,v 1.6 2013/05/17 00:13:14 djm Exp $ */ +/* $OpenBSD: ssh-ecdsa.c,v 1.8 2014/01/09 23:20:00 djm Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. * Copyright (c) 2010 Damien Miller. All rights reserved. @@ -42,27 +42,34 @@ #include "compat.h" #include "log.h" #include "key.h" +#include "digest.h" int ssh_ecdsa_sign(const Key *key, u_char **sigp, u_int *lenp, const u_char *data, u_int datalen) { ECDSA_SIG *sig; - const EVP_MD *evp_md; - EVP_MD_CTX md; - u_char digest[EVP_MAX_MD_SIZE]; + int hash_alg; + u_char digest[SSH_DIGEST_MAX_LENGTH]; u_int len, dlen; Buffer b, bb; - if (key == NULL || key->ecdsa == NULL || - (key->type != KEY_ECDSA && key->type != KEY_ECDSA_CERT)) { + if (key == NULL || key_type_plain(key->type) != KEY_ECDSA || + key->ecdsa == NULL) { error("%s: no ECDSA key", __func__); return -1; } - evp_md = key_ec_nid_to_evpmd(key->ecdsa_nid); - EVP_DigestInit(&md, evp_md); - EVP_DigestUpdate(&md, data, datalen); - EVP_DigestFinal(&md, digest, &dlen); + + hash_alg = key_ec_nid_to_hash_alg(key->ecdsa_nid); + if ((dlen = ssh_digest_bytes(hash_alg)) == 0) { + error("%s: bad hash algorithm %d", __func__, hash_alg); + return -1; + } + if (ssh_digest_memory(hash_alg, data, datalen, + digest, sizeof(digest)) != 0) { + error("%s: digest_memory failed", __func__); + return -1; + } sig = ECDSA_do_sign(digest, dlen, key->ecdsa); memset(digest, 'd', sizeof(digest)); @@ -97,20 +104,18 @@ ssh_ecdsa_verify(const Key *key, const u_char *signature, u_int signaturelen, const u_char *data, u_int datalen) { ECDSA_SIG *sig; - const EVP_MD *evp_md; - EVP_MD_CTX md; - u_char digest[EVP_MAX_MD_SIZE], *sigblob; + int hash_alg; + u_char digest[SSH_DIGEST_MAX_LENGTH], *sigblob; u_int len, dlen; int rlen, ret; Buffer b, bb; char *ktype; - if (key == NULL || key->ecdsa == NULL || - (key->type != KEY_ECDSA && key->type != KEY_ECDSA_CERT)) { + if (key == NULL || key_type_plain(key->type) != KEY_ECDSA || + key->ecdsa == NULL) { error("%s: no ECDSA key", __func__); return -1; } - evp_md = key_ec_nid_to_evpmd(key->ecdsa_nid); /* fetch signature */ buffer_init(&b); @@ -152,9 +157,16 @@ ssh_ecdsa_verify(const Key *key, const u_char *signature, u_int signaturelen, free(sigblob); /* hash the data */ - EVP_DigestInit(&md, evp_md); - EVP_DigestUpdate(&md, data, datalen); - EVP_DigestFinal(&md, digest, &dlen); + hash_alg = key_ec_nid_to_hash_alg(key->ecdsa_nid); + if ((dlen = ssh_digest_bytes(hash_alg)) == 0) { + error("%s: bad hash algorithm %d", __func__, hash_alg); + return -1; + } + if (ssh_digest_memory(hash_alg, data, datalen, + digest, sizeof(digest)) != 0) { + error("%s: digest_memory failed", __func__); + return -1; + } ret = ECDSA_do_verify(digest, dlen, sig, key->ecdsa); memset(digest, 'd', sizeof(digest)); diff --git a/ssh-ed25519.c b/ssh-ed25519.c new file mode 100644 index 000000000000..1aedcf83ae4b --- /dev/null +++ b/ssh-ed25519.c @@ -0,0 +1,143 @@ +/* $OpenBSD: ssh-ed25519.c,v 1.1 2013/12/06 13:39:49 markus Exp $ */ +/* + * Copyright (c) 2013 Markus Friedl + * + * 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" + +#include + +#include "crypto_api.h" + +#include +#include + +#include "xmalloc.h" +#include "log.h" +#include "buffer.h" +#include "key.h" +#include "ssh.h" + +int +ssh_ed25519_sign(const Key *key, u_char **sigp, u_int *lenp, + const u_char *data, u_int datalen) +{ + u_char *sig; + u_int slen, len; + unsigned long long smlen; + int ret; + Buffer b; + + if (key == NULL || key_type_plain(key->type) != KEY_ED25519 || + key->ed25519_sk == NULL) { + error("%s: no ED25519 key", __func__); + return -1; + } + smlen = slen = datalen + crypto_sign_ed25519_BYTES; + sig = xmalloc(slen); + + if ((ret = crypto_sign_ed25519(sig, &smlen, data, datalen, + key->ed25519_sk)) != 0 || smlen <= datalen) { + error("%s: crypto_sign_ed25519 failed: %d", __func__, ret); + free(sig); + return -1; + } + /* encode signature */ + buffer_init(&b); + buffer_put_cstring(&b, "ssh-ed25519"); + buffer_put_string(&b, sig, smlen - datalen); + len = buffer_len(&b); + if (lenp != NULL) + *lenp = len; + if (sigp != NULL) { + *sigp = xmalloc(len); + memcpy(*sigp, buffer_ptr(&b), len); + } + buffer_free(&b); + memset(sig, 's', slen); + free(sig); + + return 0; +} + +int +ssh_ed25519_verify(const Key *key, const u_char *signature, u_int signaturelen, + const u_char *data, u_int datalen) +{ + Buffer b; + char *ktype; + u_char *sigblob, *sm, *m; + u_int len; + unsigned long long smlen, mlen; + int rlen, ret; + + if (key == NULL || key_type_plain(key->type) != KEY_ED25519 || + key->ed25519_pk == NULL) { + error("%s: no ED25519 key", __func__); + return -1; + } + buffer_init(&b); + buffer_append(&b, signature, signaturelen); + ktype = buffer_get_cstring(&b, NULL); + if (strcmp("ssh-ed25519", ktype) != 0) { + error("%s: cannot handle type %s", __func__, ktype); + buffer_free(&b); + free(ktype); + return -1; + } + free(ktype); + sigblob = buffer_get_string(&b, &len); + rlen = buffer_len(&b); + buffer_free(&b); + if (rlen != 0) { + error("%s: remaining bytes in signature %d", __func__, rlen); + free(sigblob); + return -1; + } + if (len > crypto_sign_ed25519_BYTES) { + error("%s: len %u > crypto_sign_ed25519_BYTES %u", __func__, + len, crypto_sign_ed25519_BYTES); + free(sigblob); + return -1; + } + smlen = len + datalen; + sm = xmalloc(smlen); + memcpy(sm, sigblob, len); + memcpy(sm+len, data, datalen); + mlen = smlen; + m = xmalloc(mlen); + if ((ret = crypto_sign_ed25519_open(m, &mlen, sm, smlen, + key->ed25519_pk)) != 0) { + debug2("%s: crypto_sign_ed25519_open failed: %d", + __func__, ret); + } + if (ret == 0 && mlen != datalen) { + debug2("%s: crypto_sign_ed25519_open " + "mlen != datalen (%llu != %u)", __func__, mlen, datalen); + ret = -1; + } + /* XXX compare 'm' and 'data' ? */ + + memset(sigblob, 's', len); + memset(sm, 'S', smlen); + memset(m, 'm', smlen); /* NB. mlen may be invalid if ret != 0 */ + free(sigblob); + free(sm); + free(m); + debug("%s: signature %scorrect", __func__, (ret != 0) ? "in" : ""); + + /* translate return code carefully */ + return (ret == 0) ? 1 : -1; +} diff --git a/ssh-keygen.0 b/ssh-keygen.0 index 2b0e9a692487..a69b37d6792f 100644 --- a/ssh-keygen.0 +++ b/ssh-keygen.0 @@ -19,8 +19,8 @@ SYNOPSIS ssh-keygen -R hostname [-f known_hosts_file] ssh-keygen -r hostname [-f input_keyfile] [-g] ssh-keygen -G output_file [-v] [-b bits] [-M memory] [-S start_point] - ssh-keygen -T output_file -f input_file [-v] [-a num_trials] - [-J num_lines] [-j start_line] [-K checkpt] [-W generator] + ssh-keygen -T output_file -f input_file [-v] [-a rounds] [-J num_lines] + [-j start_line] [-K checkpt] [-W generator] ssh-keygen -s ca_key -I certificate_identity [-h] [-n principals] [-O option] [-V validity_interval] [-z serial_number] file ... ssh-keygen -L [-f input_keyfile] @@ -32,10 +32,10 @@ SYNOPSIS DESCRIPTION ssh-keygen generates, manages and converts authentication keys for ssh(1). ssh-keygen can create RSA keys for use by SSH protocol version 1 - and DSA, ECDSA or RSA keys for use by SSH protocol version 2. The type - of key to be generated is specified with the -t option. If invoked - without any arguments, ssh-keygen will generate an RSA key for use in SSH - protocol 2 connections. + and DSA, ECDSA, ED25519 or RSA keys for use by SSH protocol version 2. + The type of key to be generated is specified with the -t option. If + invoked without any arguments, ssh-keygen will generate an RSA key for + use in SSH protocol 2 connections. ssh-keygen is also used to generate groups for use in Diffie-Hellman group exchange (DH-GEX). See the MODULI GENERATION section for details. @@ -46,9 +46,9 @@ DESCRIPTION Normally each user wishing to use SSH with public key authentication runs this once to create the authentication key in ~/.ssh/identity, - ~/.ssh/id_ecdsa, ~/.ssh/id_dsa or ~/.ssh/id_rsa. Additionally, the - system administrator may use this to generate host keys, as seen in - /etc/rc. + ~/.ssh/id_dsa, ~/.ssh/id_ecdsa, ~/.ssh/id_ed25519 or ~/.ssh/id_rsa. + Additionally, the system administrator may use this to generate host + keys, as seen in /etc/rc. Normally this program generates the key and asks for a file in which to store the private key. The public key is stored in a file with the same @@ -79,15 +79,22 @@ DESCRIPTION The options are as follows: - -A For each of the key types (rsa1, rsa, dsa and ecdsa) for which - host keys do not exist, generate the host keys with the default - key file path, an empty passphrase, default bits for the key - type, and default comment. This is used by /etc/rc to generate - new host keys. + -A For each of the key types (rsa1, rsa, dsa, ecdsa and ed25519) for + which host keys do not exist, generate the host keys with the + default key file path, an empty passphrase, default bits for the + key type, and default comment. This is used by /etc/rc to + generate new host keys. - -a trials - Specifies the number of primality tests to perform when screening - DH-GEX candidates using the -T command. + -a rounds + When saving a new-format private key (i.e. an ed25519 key or any + SSH protocol 2 key when the -o flag is set), this option + specifies the number of KDF (key derivation function) rounds + used. Higher numbers result in slower passphrase verification + and increased resistance to brute-force password cracking (should + the keys be stolen). + + When screening DH-GEX candidates ( using the -T command). This + option specifies the number of primality tests to perform. -B Show the bubblebabble digest of specified private or public key file. @@ -100,7 +107,8 @@ DESCRIPTION the -b flag determines the key length by selecting from one of three elliptic curve sizes: 256, 384 or 521 bits. Attempting to use bit lengths other than these three values for ECDSA keys will - fail. + fail. ED25519 keys have a fixed length and the -b flag will be + ignored. -C comment Provides a new comment. @@ -262,6 +270,12 @@ DESCRIPTION At present, no options are valid for host keys. + -o Causes ssh-keygen to save SSH protocol 2 private keys using the + new OpenSSH format rather than the more compatible PEM format. + The new format has increased resistance to brute-force password + cracking but is not supported by versions of OpenSSH prior to + 6.5. Ed25519 keys always use the new private key format. + -P passphrase Provides the (old) passphrase. @@ -301,8 +315,8 @@ DESCRIPTION -t type Specifies the type of key to create. The possible values are - ``rsa1'' for protocol version 1 and ``dsa'', ``ecdsa'' or ``rsa'' - for protocol version 2. + ``rsa1'' for protocol version 1 and ``dsa'', ``ecdsa'', + ``ed25519'', or ``rsa'' for protocol version 2. -u Update a KRL. When specified with -k, keys listed via the command line are added to the existing KRL rather than a new KRL @@ -441,7 +455,7 @@ CERTIFICATES KEY REVOCATION LISTS ssh-keygen is able to manage OpenSSH format Key Revocation Lists (KRLs). These binary files specify keys or certificates to be revoked using a - compact format, taking as little a one bit per certificate if they are + compact format, taking as little as one bit per certificate if they are being revoked by serial number. KRLs may be generated using the -k flag. This option reads one or more @@ -508,24 +522,26 @@ FILES ~/.ssh/id_dsa ~/.ssh/id_ecdsa + ~/.ssh/id_ed25519 ~/.ssh/id_rsa - Contains the protocol version 2 DSA, ECDSA or RSA authentication - identity of the user. This file should not be readable by anyone - but the user. It is possible to specify a passphrase when - generating the key; that passphrase will be used to encrypt the - private part of this file using 128-bit AES. This file is not - automatically accessed by ssh-keygen but it is offered as the - default file for the private key. ssh(1) will read this file - when a login attempt is made. + Contains the protocol version 2 DSA, ECDSA, ED25519 or RSA + authentication identity of the user. This file should not be + readable by anyone but the user. It is possible to specify a + passphrase when generating the key; that passphrase will be used + to encrypt the private part of this file using 128-bit AES. This + file is not automatically accessed by ssh-keygen but it is + offered as the default file for the private key. ssh(1) will + read this file when a login attempt is made. ~/.ssh/id_dsa.pub ~/.ssh/id_ecdsa.pub + ~/.ssh/id_ed25519.pub ~/.ssh/id_rsa.pub - Contains the protocol version 2 DSA, ECDSA or RSA public key for - authentication. The contents of this file should be added to - ~/.ssh/authorized_keys on all machines where the user wishes to - log in using public key authentication. There is no need to keep - the contents of this file secret. + Contains the protocol version 2 DSA, ECDSA, ED25519 or RSA public + key for authentication. The contents of this file should be + added to ~/.ssh/authorized_keys on all machines where the user + wishes to log in using public key authentication. There is no + need to keep the contents of this file secret. /etc/moduli Contains Diffie-Hellman groups used for DH-GEX. The file format @@ -543,4 +559,4 @@ AUTHORS created OpenSSH. Markus Friedl contributed the support for SSH protocol versions 1.5 and 2.0. -OpenBSD 5.4 June 27, 2013 OpenBSD 5.4 +OpenBSD 5.4 December 21, 2013 OpenBSD 5.4 diff --git a/ssh-keygen.1 b/ssh-keygen.1 index 0d55854e93df..0e0ed989f9ae 100644 --- a/ssh-keygen.1 +++ b/ssh-keygen.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: ssh-keygen.1,v 1.116 2013/06/27 14:05:37 jmc Exp $ +.\" $OpenBSD: ssh-keygen.1,v 1.119 2013/12/21 07:10:47 tedu Exp $ .\" .\" Author: Tatu Ylonen .\" Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -35,7 +35,7 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.Dd $Mdocdate: June 27 2013 $ +.Dd $Mdocdate: December 21 2013 $ .Dt SSH-KEYGEN 1 .Os .Sh NAME @@ -103,7 +103,7 @@ .Fl T Ar output_file .Fl f Ar input_file .Op Fl v -.Op Fl a Ar num_trials +.Op Fl a Ar rounds .Op Fl J Ar num_lines .Op Fl j Ar start_line .Op Fl K Ar checkpt @@ -139,8 +139,8 @@ generates, manages and converts authentication keys for .Xr ssh 1 . .Nm -can create RSA keys for use by SSH protocol version 1 and DSA, ECDSA or RSA -keys for use by SSH protocol version 2. +can create RSA keys for use by SSH protocol version 1 and +DSA, ECDSA, ED25519 or RSA keys for use by SSH protocol version 2. The type of key to be generated is specified with the .Fl t option. @@ -167,8 +167,9 @@ Normally each user wishing to use SSH with public key authentication runs this once to create the authentication key in .Pa ~/.ssh/identity , +.Pa ~/.ssh/id_dsa , .Pa ~/.ssh/id_ecdsa , -.Pa ~/.ssh/id_dsa +.Pa ~/.ssh/id_ed25519 or .Pa ~/.ssh/id_rsa . Additionally, the system administrator may use this to generate host keys, @@ -216,17 +217,27 @@ should be placed to be activated. The options are as follows: .Bl -tag -width Ds .It Fl A -For each of the key types (rsa1, rsa, dsa and ecdsa) for which host keys +For each of the key types (rsa1, rsa, dsa, ecdsa and ed25519) +for which host keys do not exist, generate the host keys with the default key file path, an empty passphrase, default bits for the key type, and default comment. This is used by .Pa /etc/rc to generate new host keys. -.It Fl a Ar trials -Specifies the number of primality tests to perform when screening DH-GEX -candidates using the +.It Fl a Ar rounds +When saving a new-format private key (i.e. an ed25519 key or any SSH protocol +2 key when the +.Fl o +flag is set), this option specifies the number of KDF (key derivation function) +rounds used. +Higher numbers result in slower passphrase verification and increased +resistance to brute-force password cracking (should the keys be stolen). +.Pp +When screening DH-GEX candidates ( +using the .Fl T -command. +command). +This option specifies the number of primality tests to perform. .It Fl B Show the bubblebabble digest of specified private or public key file. .It Fl b Ar bits @@ -240,6 +251,9 @@ flag determines the key length by selecting from one of three elliptic curve sizes: 256, 384 or 521 bits. Attempting to use bit lengths other than these three values for ECDSA keys will fail. +ED25519 keys have a fixed length and the +.Fl b +flag will be ignored. .It Fl C Ar comment Provides a new comment. .It Fl c @@ -447,6 +461,14 @@ format. .El .Pp At present, no options are valid for host keys. +.It Fl o +Causes +.Nm +to save SSH protocol 2 private keys using the new OpenSSH format rather than +the more compatible PEM format. +The new format has increased resistance to brute-force password cracking +but is not supported by versions of OpenSSH prior to 6.5. +Ed25519 keys always use the new private key format. .It Fl P Ar passphrase Provides the (old) passphrase. .It Fl p @@ -498,7 +520,8 @@ The possible values are .Dq rsa1 for protocol version 1 and .Dq dsa , -.Dq ecdsa +.Dq ecdsa , +.Dq ed25519 , or .Dq rsa for protocol version 2. @@ -691,7 +714,7 @@ Please refer to those manual pages for details. .Nm is able to manage OpenSSH format Key Revocation Lists (KRLs). These binary files specify keys or certificates to be revoked using a -compact format, taking as little a one bit per certificate if they are being +compact format, taking as little as one bit per certificate if they are being revoked by serial number. .Pp KRLs may be generated using the @@ -778,8 +801,10 @@ There is no need to keep the contents of this file secret. .Pp .It Pa ~/.ssh/id_dsa .It Pa ~/.ssh/id_ecdsa +.It Pa ~/.ssh/id_ed25519 .It Pa ~/.ssh/id_rsa -Contains the protocol version 2 DSA, ECDSA or RSA authentication identity of the user. +Contains the protocol version 2 DSA, ECDSA, ED25519 or RSA +authentication identity of the user. This file should not be readable by anyone but the user. It is possible to specify a passphrase when generating the key; that passphrase will be @@ -792,8 +817,10 @@ will read this file when a login attempt is made. .Pp .It Pa ~/.ssh/id_dsa.pub .It Pa ~/.ssh/id_ecdsa.pub +.It Pa ~/.ssh/id_ed25519.pub .It Pa ~/.ssh/id_rsa.pub -Contains the protocol version 2 DSA, ECDSA or RSA public key for authentication. +Contains the protocol version 2 DSA, ECDSA, ED25519 or RSA +public key for authentication. The contents of this file should be added to .Pa ~/.ssh/authorized_keys on all machines diff --git a/ssh-keygen.c b/ssh-keygen.c index 03c444d42dc3..eae83a4612f2 100644 --- a/ssh-keygen.c +++ b/ssh-keygen.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-keygen.c,v 1.230 2013/07/20 01:44:37 djm Exp $ */ +/* $OpenBSD: ssh-keygen.c,v 1.238 2013/12/06 13:39:49 markus Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1994 Tatu Ylonen , Espoo, Finland @@ -150,6 +150,18 @@ char *key_type_name = NULL; /* Load key from this PKCS#11 provider */ char *pkcs11provider = NULL; +/* Use new OpenSSH private key format when writing SSH2 keys instead of PEM */ +int use_new_format = 0; + +/* Cipher for new-format private keys */ +char *new_format_cipher = NULL; + +/* + * Number of KDF rounds to derive new format keys / + * number of primality trials when screening moduli. + */ +int rounds = 0; + /* argv0 */ extern char *__progname; @@ -185,7 +197,7 @@ type_bits_valid(int type, u_int32_t *bitsp) } if (type == KEY_DSA && *bitsp != 1024) fatal("DSA keys must be 1024 bits"); - else if (type != KEY_ECDSA && *bitsp < 768) + else if (type != KEY_ECDSA && type != KEY_ED25519 && *bitsp < 768) fatal("Key must at least be 768 bits"); else if (type == KEY_ECDSA && key_ecdsa_bits_to_nid(*bitsp) == -1) fatal("Invalid ECDSA key length - valid lengths are " @@ -221,6 +233,10 @@ ask_filename(struct passwd *pw, const char *prompt) case KEY_RSA: name = _PATH_SSH_CLIENT_ID_RSA; break; + case KEY_ED25519: + case KEY_ED25519_CERT: + name = _PATH_SSH_CLIENT_ID_ED25519; + break; default: fprintf(stderr, "bad key type\n"); exit(1); @@ -884,6 +900,7 @@ do_gen_all_hostkeys(struct passwd *pw) #ifdef OPENSSL_HAS_ECC { "ecdsa", "ECDSA",_PATH_HOST_ECDSA_KEY_FILE }, #endif + { "ed25519", "ED25519",_PATH_HOST_ED25519_KEY_FILE }, { NULL, NULL, NULL } }; @@ -910,7 +927,6 @@ do_gen_all_hostkeys(struct passwd *pw) } printf("%s ", key_types[i].key_type_display); fflush(stdout); - arc4random_stir(); type = key_type_from_name(key_types[i].key_type); strlcpy(identity_file, key_types[i].path, sizeof(identity_file)); bits = 0; @@ -924,7 +940,8 @@ do_gen_all_hostkeys(struct passwd *pw) public = key_from_private(private); snprintf(comment, sizeof comment, "%s@%s", pw->pw_name, hostname); - if (!key_save_private(private, identity_file, "", comment)) { + if (!key_save_private(private, identity_file, "", comment, + use_new_format, new_format_cipher, rounds)) { printf("Saving the key failed: %s.\n", identity_file); key_free(private); key_free(public); @@ -932,7 +949,6 @@ do_gen_all_hostkeys(struct passwd *pw) continue; } key_free(private); - arc4random_stir(); strlcat(identity_file, ".pub", sizeof(identity_file)); fd = open(identity_file, O_WRONLY | O_CREAT | O_TRUNC, 0644); if (fd == -1) { @@ -1001,6 +1017,7 @@ do_known_hosts(struct passwd *pw, const char *name) char line[16*1024], tmp[MAXPATHLEN], old[MAXPATHLEN]; int c, skip = 0, inplace = 0, num = 0, invalid = 0, has_unhashed = 0; int ca; + int found_key = 0; if (!have_identity) { cp = tilde_expand_filename(_PATH_SSH_USER_HOSTFILE, pw->pw_uid); @@ -1103,11 +1120,13 @@ do_known_hosts(struct passwd *pw, const char *name) } c = (strcmp(cp2, cp) == 0); if (find_host && c) { - printf("# Host %s found: " - "line %d type %s%s\n", name, - num, key_type(pub), - ca ? " (CA key)" : ""); + if (!quiet) + printf("# Host %s found: " + "line %d type %s%s\n", name, + num, key_type(pub), + ca ? " (CA key)" : ""); printhost(out, cp, pub, ca, 0); + found_key = 1; } if (delete_host) { if (!c && !ca) @@ -1124,12 +1143,14 @@ do_known_hosts(struct passwd *pw, const char *name) c = (match_hostname(name, cp, strlen(cp)) == 1); if (find_host && c) { - printf("# Host %s found: " - "line %d type %s%s\n", name, - num, key_type(pub), - ca ? " (CA key)" : ""); + if (!quiet) + printf("# Host %s found: " + "line %d type %s%s\n", name, + num, key_type(pub), + ca ? " (CA key)" : ""); printhost(out, name, pub, ca, hash_hosts && !ca); + found_key = 1; } if (delete_host) { if (!c && !ca) @@ -1205,7 +1226,7 @@ do_known_hosts(struct passwd *pw, const char *name) } } - exit(0); + exit (find_host && !found_key); } /* @@ -1272,7 +1293,8 @@ do_change_passphrase(struct passwd *pw) } /* Save the file using the new passphrase. */ - if (!key_save_private(private, identity_file, passphrase1, comment)) { + if (!key_save_private(private, identity_file, passphrase1, comment, + use_new_format, new_format_cipher, rounds)) { printf("Saving the key failed: %s.\n", identity_file); memset(passphrase1, 0, strlen(passphrase1)); free(passphrase1); @@ -1382,7 +1404,8 @@ do_change_comment(struct passwd *pw) } /* Save the file using the new passphrase. */ - if (!key_save_private(private, identity_file, passphrase, new_comment)) { + if (!key_save_private(private, identity_file, passphrase, new_comment, + use_new_format, new_format_cipher, rounds)) { printf("Saving the key failed: %s.\n", identity_file); memset(passphrase, 0, strlen(passphrase)); free(passphrase); @@ -1593,7 +1616,7 @@ do_ca_sign(struct passwd *pw, int argc, char **argv) if ((public = key_load_public(tmp, &comment)) == NULL) fatal("%s: unable to open \"%s\"", __func__, tmp); if (public->type != KEY_RSA && public->type != KEY_DSA && - public->type != KEY_ECDSA) + public->type != KEY_ECDSA && public->type != KEY_ED25519) fatal("%s: key \"%s\" type %s cannot be certified", __func__, tmp, key_type(public)); @@ -1738,7 +1761,7 @@ parse_cert_times(char *timespec) cert_valid_from = parse_absolute_time(from); if (*to == '-' || *to == '+') - cert_valid_to = parse_relative_time(to, cert_valid_from); + cert_valid_to = parse_relative_time(to, now); else cert_valid_to = parse_absolute_time(to); @@ -1963,7 +1986,7 @@ update_krl_from_file(struct passwd *pw, const char *file, const Key *ca, continue; if (strncasecmp(cp, "serial:", 7) == 0) { if (ca == NULL) { - fatal("revoking certificated by serial number " + fatal("revoking certificates by serial number " "requires specification of a CA key"); } cp += 7; @@ -2000,7 +2023,7 @@ update_krl_from_file(struct passwd *pw, const char *file, const Key *ca, } } else if (strncasecmp(cp, "id:", 3) == 0) { if (ca == NULL) { - fatal("revoking certificated by key ID " + fatal("revoking certificates by key ID " "requires specification of a CA key"); } cp += 3; @@ -2129,7 +2152,7 @@ usage(void) fprintf(stderr, "usage: %s [options]\n", __progname); fprintf(stderr, "Options:\n"); fprintf(stderr, " -A Generate non-existent host keys for all key types.\n"); - fprintf(stderr, " -a trials Number of trials for screening DH-GEX moduli.\n"); + fprintf(stderr, " -a number Number of KDF rounds for new key format or moduli primality tests.\n"); fprintf(stderr, " -B Show bubblebabble digest of key file.\n"); fprintf(stderr, " -b bits Number of bits in the key to create.\n"); fprintf(stderr, " -C comment Provide new comment.\n"); @@ -2157,6 +2180,7 @@ usage(void) fprintf(stderr, " -N phrase Provide new passphrase.\n"); fprintf(stderr, " -n name,... User/host principal names to include in certificate\n"); fprintf(stderr, " -O option Specify a certificate option.\n"); + fprintf(stderr, " -o Enforce new private key format.\n"); fprintf(stderr, " -P phrase Provide old passphrase.\n"); fprintf(stderr, " -p Change passphrase of private key file.\n"); fprintf(stderr, " -Q Test whether key(s) are revoked in KRL.\n"); @@ -2173,6 +2197,7 @@ usage(void) fprintf(stderr, " -W gen Generator to use for generating DH-GEX moduli.\n"); fprintf(stderr, " -y Read private key file and print public key.\n"); fprintf(stderr, " -z serial Specify a serial number.\n"); + fprintf(stderr, " -Z cipher Specify a cipher for new private key format.\n"); exit(1); } @@ -2190,7 +2215,7 @@ main(int argc, char **argv) struct passwd *pw; struct stat st; int opt, type, fd; - u_int32_t memory = 0, generator_wanted = 0, trials = 100; + u_int32_t memory = 0, generator_wanted = 0; int do_gen_candidates = 0, do_screen_candidates = 0; int gen_all_hostkeys = 0, gen_krl = 0, update_krl = 0, check_krl = 0; unsigned long start_lineno = 0, lines_to_process = 0; @@ -2222,8 +2247,9 @@ main(int argc, char **argv) exit(1); } - while ((opt = getopt(argc, argv, "ABHLQXceghiklpquvxy" - "C:D:F:G:I:J:K:M:N:O:P:R:S:T:V:W:a:b:f:g:j:m:n:r:s:t:z:")) != -1) { + /* Remaining characters: EUYdw */ + while ((opt = getopt(argc, argv, "ABHLQXceghiklopquvxy" + "C:D:F:G:I:J:K:M:N:O:P:R:S:T:V:W:Z:a:b:f:g:j:m:n:r:s:t:z:")) != -1) { switch (opt) { case 'A': gen_all_hostkeys = 1; @@ -2281,6 +2307,9 @@ main(int argc, char **argv) case 'n': cert_principals = optarg; break; + case 'o': + use_new_format = 1; + break; case 'p': change_passphrase = 1; break; @@ -2308,6 +2337,9 @@ main(int argc, char **argv) case 'O': add_cert_option(optarg); break; + case 'Z': + new_format_cipher = optarg; + break; case 'C': identity_comment = optarg; break; @@ -2366,9 +2398,9 @@ main(int argc, char **argv) optarg, errstr); break; case 'a': - trials = (u_int32_t)strtonum(optarg, 1, UINT_MAX, &errstr); + rounds = (int)strtonum(optarg, 1, INT_MAX, &errstr); if (errstr) - fatal("Invalid number of trials: %s (%s)", + fatal("Invalid number: %s (%s)", optarg, errstr); break; case 'M': @@ -2527,7 +2559,8 @@ main(int argc, char **argv) fatal("Couldn't open moduli file \"%s\": %s", out_file, strerror(errno)); } - if (prime_test(in, out, trials, generator_wanted, checkpoint, + if (prime_test(in, out, rounds == 0 ? 100 : rounds, + generator_wanted, checkpoint, start_lineno, lines_to_process) != 0) fatal("modulus screening failed"); return (0); @@ -2538,8 +2571,6 @@ main(int argc, char **argv) return (0); } - arc4random_stir(); - if (key_type_name == NULL) key_type_name = "rsa"; @@ -2621,7 +2652,8 @@ main(int argc, char **argv) } /* Save the key with the given passphrase and comment. */ - if (!key_save_private(private, identity_file, passphrase1, comment)) { + if (!key_save_private(private, identity_file, passphrase1, comment, + use_new_format, new_format_cipher, rounds)) { printf("Saving the key failed: %s.\n", identity_file); memset(passphrase1, 0, strlen(passphrase1)); free(passphrase1); @@ -2633,7 +2665,6 @@ main(int argc, char **argv) /* Clear the private key and the random number generator. */ key_free(private); - arc4random_stir(); if (!quiet) printf("Your identification has been saved in %s.\n", identity_file); diff --git a/ssh-keyscan.0 b/ssh-keyscan.0 index 3ea99c320418..09cfa0afa028 100644 --- a/ssh-keyscan.0 +++ b/ssh-keyscan.0 @@ -48,9 +48,9 @@ DESCRIPTION -t type Specifies the type of the key to fetch from the scanned hosts. The possible values are ``rsa1'' for protocol version 1 and - ``dsa'', ``ecdsa'' or ``rsa'' for protocol version 2. Multiple - values may be specified by separating them with commas. The - default is to fetch ``rsa'' and ``ecdsa'' keys. + ``dsa'', ``ecdsa'', ``ed25519'', or ``rsa'' for protocol version + 2. Multiple values may be specified by separating them with + commas. The default is to fetch ``rsa'' and ``ecdsa'' keys. -v Verbose mode. Causes ssh-keyscan to print debugging messages about its progress. @@ -77,7 +77,7 @@ FILES host-or-namelist keytype base64-encoded-key Where keytype is either ``ecdsa-sha2-nistp256'', ``ecdsa-sha2-nistp384'', - ``ecdsa-sha2-nistp521'', ``ssh-dss'' or ``ssh-rsa''. + ``ecdsa-sha2-nistp521'', ``ssh-ed25519'', ``ssh-dss'' or ``ssh-rsa''. /etc/ssh/ssh_known_hosts @@ -106,4 +106,4 @@ BUGS This is because it opens a connection to the ssh port, reads the public key, and drops the connection as soon as it gets the key. -OpenBSD 5.4 July 16, 2013 OpenBSD 5.4 +OpenBSD 5.4 December 7, 2013 OpenBSD 5.4 diff --git a/ssh-keyscan.1 b/ssh-keyscan.1 index c35ea05e0480..65ef43efd03c 100644 --- a/ssh-keyscan.1 +++ b/ssh-keyscan.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: ssh-keyscan.1,v 1.31 2013/07/16 00:07:52 schwarze Exp $ +.\" $OpenBSD: ssh-keyscan.1,v 1.33 2013/12/07 11:58:46 naddy Exp $ .\" .\" Copyright 1995, 1996 by David Mazieres . .\" @@ -6,7 +6,7 @@ .\" permitted provided that due credit is given to the author and the .\" OpenBSD project by leaving this copyright notice intact. .\" -.Dd $Mdocdate: July 16 2013 $ +.Dd $Mdocdate: December 7 2013 $ .Dt SSH-KEYSCAN 1 .Os .Sh NAME @@ -89,7 +89,8 @@ The possible values are .Dq rsa1 for protocol version 1 and .Dq dsa , -.Dq ecdsa +.Dq ecdsa , +.Dq ed25519 , or .Dq rsa for protocol version 2. @@ -137,6 +138,7 @@ is either .Dq ecdsa-sha2-nistp256 , .Dq ecdsa-sha2-nistp384 , .Dq ecdsa-sha2-nistp521 , +.Dq ssh-ed25519 , .Dq ssh-dss or .Dq ssh-rsa . diff --git a/ssh-keyscan.c b/ssh-keyscan.c index 8b807c10a0c2..8d0a6b8d866d 100644 --- a/ssh-keyscan.c +++ b/ssh-keyscan.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-keyscan.c,v 1.87 2013/05/17 00:13:14 djm Exp $ */ +/* $OpenBSD: ssh-keyscan.c,v 1.89 2013/12/06 13:39:49 markus Exp $ */ /* * Copyright 1995, 1996 by David Mazieres . * @@ -56,6 +56,7 @@ int ssh_port = SSH_DEFAULT_PORT; #define KT_DSA 2 #define KT_RSA 4 #define KT_ECDSA 8 +#define KT_ED25519 16 int get_keytypes = KT_RSA|KT_ECDSA;/* Get RSA and ECDSA keys by default */ @@ -245,15 +246,18 @@ keygrab_ssh2(con *c) packet_set_connection(c->c_fd, c->c_fd); enable_compat20(); - myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = c->c_keytype == KT_DSA? - "ssh-dss" : (c->c_keytype == KT_RSA ? "ssh-rsa" : - "ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521"); + myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = + c->c_keytype == KT_DSA ? "ssh-dss" : + (c->c_keytype == KT_RSA ? "ssh-rsa" : + (c->c_keytype == KT_ED25519 ? "ssh-ed25519" : + "ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521")); c->c_kex = kex_setup(myproposal); c->c_kex->kex[KEX_DH_GRP1_SHA1] = kexdh_client; c->c_kex->kex[KEX_DH_GRP14_SHA1] = kexdh_client; c->c_kex->kex[KEX_DH_GEX_SHA1] = kexgex_client; c->c_kex->kex[KEX_DH_GEX_SHA256] = kexgex_client; c->c_kex->kex[KEX_ECDH_SHA2] = kexecdh_client; + c->c_kex->kex[KEX_C25519_SHA256] = kexc25519_client; c->c_kex->verify_host_key = hostjump; if (!(j = setjmp(kexjmp))) { @@ -574,7 +578,7 @@ do_host(char *host) if (name == NULL) return; - for (j = KT_RSA1; j <= KT_ECDSA; j *= 2) { + for (j = KT_RSA1; j <= KT_ED25519; j *= 2) { if (get_keytypes & j) { while (ncon >= MAXCON) conloop(); @@ -681,6 +685,9 @@ main(int argc, char **argv) case KEY_RSA: get_keytypes |= KT_RSA; break; + case KEY_ED25519: + get_keytypes |= KT_ED25519; + break; case KEY_UNSPEC: fatal("unknown key type %s", tname); } diff --git a/ssh-keysign.0 b/ssh-keysign.0 index 808828a07a53..78a20e894414 100644 --- a/ssh-keysign.0 +++ b/ssh-keysign.0 @@ -25,6 +25,7 @@ FILES /etc/ssh/ssh_host_dsa_key /etc/ssh/ssh_host_ecdsa_key + /etc/ssh/ssh_host_ed25519_key /etc/ssh/ssh_host_rsa_key These files contain the private parts of the host keys used to generate the digital signature. They should be owned by root, @@ -34,6 +35,7 @@ FILES /etc/ssh/ssh_host_dsa_key-cert.pub /etc/ssh/ssh_host_ecdsa_key-cert.pub + /etc/ssh/ssh_host_ed25519_key-cert.pub /etc/ssh/ssh_host_rsa_key-cert.pub If these files exist they are assumed to contain public certificate information corresponding with the private keys @@ -48,4 +50,4 @@ HISTORY AUTHORS Markus Friedl -OpenBSD 5.4 July 16, 2013 OpenBSD 5.4 +OpenBSD 5.4 December 7, 2013 OpenBSD 5.4 diff --git a/ssh-keysign.8 b/ssh-keysign.8 index 5e0b2d232468..69d082954df6 100644 --- a/ssh-keysign.8 +++ b/ssh-keysign.8 @@ -1,4 +1,4 @@ -.\" $OpenBSD: ssh-keysign.8,v 1.13 2013/07/16 00:07:52 schwarze Exp $ +.\" $OpenBSD: ssh-keysign.8,v 1.14 2013/12/07 11:58:46 naddy Exp $ .\" .\" Copyright (c) 2002 Markus Friedl. All rights reserved. .\" @@ -22,7 +22,7 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.Dd $Mdocdate: July 16 2013 $ +.Dd $Mdocdate: December 7 2013 $ .Dt SSH-KEYSIGN 8 .Os .Sh NAME @@ -63,6 +63,7 @@ is enabled. .Pp .It Pa /etc/ssh/ssh_host_dsa_key .It Pa /etc/ssh/ssh_host_ecdsa_key +.It Pa /etc/ssh/ssh_host_ed25519_key .It Pa /etc/ssh/ssh_host_rsa_key These files contain the private parts of the host keys used to generate the digital signature. @@ -74,6 +75,7 @@ must be set-uid root if host-based authentication is used. .Pp .It Pa /etc/ssh/ssh_host_dsa_key-cert.pub .It Pa /etc/ssh/ssh_host_ecdsa_key-cert.pub +.It Pa /etc/ssh/ssh_host_ed25519_key-cert.pub .It Pa /etc/ssh/ssh_host_rsa_key-cert.pub If these files exist they are assumed to contain public certificate information corresponding with the private keys above. diff --git a/ssh-keysign.c b/ssh-keysign.c index 9a6653c7c03a..6bde8ad17e8b 100644 --- a/ssh-keysign.c +++ b/ssh-keysign.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-keysign.c,v 1.37 2013/05/17 00:13:14 djm Exp $ */ +/* $OpenBSD: ssh-keysign.c,v 1.39 2013/12/06 13:39:49 markus Exp $ */ /* * Copyright (c) 2002 Markus Friedl. All rights reserved. * @@ -150,7 +150,7 @@ main(int argc, char **argv) { Buffer b; Options options; -#define NUM_KEYTYPES 3 +#define NUM_KEYTYPES 4 Key *keys[NUM_KEYTYPES], *key = NULL; struct passwd *pw; int key_fd[NUM_KEYTYPES], i, found, version = 2, fd; @@ -169,6 +169,7 @@ main(int argc, char **argv) i = 0; key_fd[i++] = open(_PATH_HOST_DSA_KEY_FILE, O_RDONLY); key_fd[i++] = open(_PATH_HOST_ECDSA_KEY_FILE, O_RDONLY); + key_fd[i++] = open(_PATH_HOST_ED25519_KEY_FILE, O_RDONLY); key_fd[i++] = open(_PATH_HOST_RSA_KEY_FILE, O_RDONLY); original_real_uid = getuid(); /* XXX readconf.c needs this */ @@ -179,7 +180,6 @@ main(int argc, char **argv) permanently_set_uid(pw); seed_rng(); - arc4random_stir(); #ifdef DEBUG_SSH_KEYSIGN log_init("ssh-keysign", SYSLOG_LEVEL_DEBUG3, SYSLOG_FACILITY_AUTH, 0); @@ -187,7 +187,7 @@ main(int argc, char **argv) /* verify that ssh-keysign is enabled by the admin */ initialize_options(&options); - (void)read_config_file(_PATH_HOST_CONFIG_FILE, "", &options, 0); + (void)read_config_file(_PATH_HOST_CONFIG_FILE, pw, "", &options, 0); fill_default_options(&options); if (options.enable_ssh_keysign != 1) fatal("ssh-keysign not enabled in %s", diff --git a/ssh-pkcs11-helper.c b/ssh-pkcs11-helper.c index 39b2e7c56641..b7c52beb8e66 100644 --- a/ssh-pkcs11-helper.c +++ b/ssh-pkcs11-helper.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-pkcs11-helper.c,v 1.6 2013/05/17 00:13:14 djm Exp $ */ +/* $OpenBSD: ssh-pkcs11-helper.c,v 1.7 2013/12/02 02:56:17 djm Exp $ */ /* * Copyright (c) 2010 Markus Friedl. All rights reserved. * @@ -127,7 +127,8 @@ process_add(void) buffer_put_char(&msg, SSH2_AGENT_IDENTITIES_ANSWER); buffer_put_int(&msg, nkeys); for (i = 0; i < nkeys; i++) { - key_to_blob(keys[i], &blob, &blen); + if (key_to_blob(keys[i], &blob, &blen) == 0) + continue; buffer_put_string(&msg, blob, blen); buffer_put_cstring(&msg, name); free(blob); diff --git a/ssh-pkcs11.c b/ssh-pkcs11.c index 618c07526fb9..c49cbf42b133 100644 --- a/ssh-pkcs11.c +++ b/ssh-pkcs11.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-pkcs11.c,v 1.8 2013/07/12 00:20:00 djm Exp $ */ +/* $OpenBSD: ssh-pkcs11.c,v 1.11 2013/11/13 13:48:20 markus Exp $ */ /* * Copyright (c) 2010 Markus Friedl. All rights reserved. * @@ -31,6 +31,8 @@ #include "openbsd-compat/sys-queue.h" +#include + #define CRYPTOKI_COMPAT #include "pkcs11.h" @@ -225,7 +227,7 @@ pkcs11_rsa_private_encrypt(int flen, const u_char *from, u_char *to, RSA *rsa, CK_OBJECT_HANDLE obj; CK_ULONG tlen = 0; CK_RV rv; - CK_OBJECT_CLASS private_key_class = CKO_PRIVATE_KEY; + CK_OBJECT_CLASS private_key_class = CKO_PRIVATE_KEY; CK_BBOOL true_val = CK_TRUE; CK_MECHANISM mech = { CKM_RSA_PKCS, NULL_PTR, 0 @@ -238,8 +240,6 @@ pkcs11_rsa_private_encrypt(int flen, const u_char *from, u_char *to, RSA *rsa, char *pin, prompt[1024]; int rval = -1; - /* some compilers complain about non-constant initializer so we - use NULL in CK_ATTRIBUTE above and set the values here */ key_filter[0].pValue = &private_key_class; key_filter[2].pValue = &true_val; @@ -384,36 +384,75 @@ pkcs11_open_session(struct pkcs11_provider *p, CK_ULONG slotidx, char *pin) * add 'wrapped' public keys to the 'keysp' array and increment nkeys. * keysp points to an (possibly empty) array with *nkeys keys. */ +static int pkcs11_fetch_keys_filter(struct pkcs11_provider *, CK_ULONG, + CK_ATTRIBUTE [], CK_ATTRIBUTE [3], Key ***, int *) + __attribute__((__bounded__(__minbytes__,4, 3 * sizeof(CK_ATTRIBUTE)))); + static int -pkcs11_fetch_keys(struct pkcs11_provider *p, CK_ULONG slotidx, Key ***keysp, - int *nkeys) +pkcs11_fetch_keys(struct pkcs11_provider *p, CK_ULONG slotidx, + Key ***keysp, int *nkeys) +{ + CK_OBJECT_CLASS pubkey_class = CKO_PUBLIC_KEY; + CK_OBJECT_CLASS cert_class = CKO_CERTIFICATE; + CK_ATTRIBUTE pubkey_filter[] = { + { CKA_CLASS, NULL, sizeof(pubkey_class) } + }; + CK_ATTRIBUTE cert_filter[] = { + { CKA_CLASS, NULL, sizeof(cert_class) } + }; + CK_ATTRIBUTE pubkey_attribs[] = { + { CKA_ID, NULL, 0 }, + { CKA_MODULUS, NULL, 0 }, + { CKA_PUBLIC_EXPONENT, NULL, 0 } + }; + CK_ATTRIBUTE cert_attribs[] = { + { CKA_ID, NULL, 0 }, + { CKA_SUBJECT, NULL, 0 }, + { CKA_VALUE, NULL, 0 } + }; + pubkey_filter[0].pValue = &pubkey_class; + cert_filter[0].pValue = &cert_class; + + if (pkcs11_fetch_keys_filter(p, slotidx, pubkey_filter, pubkey_attribs, + keysp, nkeys) < 0 || + pkcs11_fetch_keys_filter(p, slotidx, cert_filter, cert_attribs, + keysp, nkeys) < 0) + return (-1); + return (0); +} + +static int +pkcs11_key_included(Key ***keysp, int *nkeys, Key *key) +{ + int i; + + for (i = 0; i < *nkeys; i++) + if (key_equal(key, (*keysp)[i])) + return (1); + return (0); +} + +static int +pkcs11_fetch_keys_filter(struct pkcs11_provider *p, CK_ULONG slotidx, + CK_ATTRIBUTE filter[], CK_ATTRIBUTE attribs[3], + Key ***keysp, int *nkeys) { Key *key; RSA *rsa; + X509 *x509; + EVP_PKEY *evp; int i; + const u_char *cp; CK_RV rv; CK_OBJECT_HANDLE obj; CK_ULONG nfound; CK_SESSION_HANDLE session; CK_FUNCTION_LIST *f; - CK_OBJECT_CLASS pubkey_class = CKO_PUBLIC_KEY; - CK_ATTRIBUTE pubkey_filter[] = { - { CKA_CLASS, NULL, sizeof(pubkey_class) } - }; - CK_ATTRIBUTE attribs[] = { - { CKA_ID, NULL, 0 }, - { CKA_MODULUS, NULL, 0 }, - { CKA_PUBLIC_EXPONENT, NULL, 0 } - }; - - /* some compilers complain about non-constant initializer so we - use NULL in CK_ATTRIBUTE above and set the value here */ - pubkey_filter[0].pValue = &pubkey_class; f = p->function_list; session = p->slotinfo[slotidx].session; /* setup a filter the looks for public keys */ - if ((rv = f->C_FindObjectsInit(session, pubkey_filter, 1)) != CKR_OK) { + if ((rv = f->C_FindObjectsInit(session, filter, 1)) != CKR_OK) { error("C_FindObjectsInit failed: %lu", rv); return (-1); } @@ -441,32 +480,59 @@ pkcs11_fetch_keys(struct pkcs11_provider *p, CK_ULONG slotidx, Key ***keysp, /* allocate buffers for attributes */ for (i = 0; i < 3; i++) attribs[i].pValue = xmalloc(attribs[i].ulValueLen); - /* retrieve ID, modulus and public exponent of RSA key */ + /* + * retrieve ID, modulus and public exponent of RSA key, + * or ID, subject and value for certificates. + */ + rsa = NULL; if ((rv = f->C_GetAttributeValue(session, obj, attribs, 3)) != CKR_OK) { error("C_GetAttributeValue failed: %lu", rv); - } else if ((rsa = RSA_new()) == NULL) { - error("RSA_new failed"); + } else if (attribs[1].type == CKA_MODULUS ) { + if ((rsa = RSA_new()) == NULL) { + error("RSA_new failed"); + } else { + rsa->n = BN_bin2bn(attribs[1].pValue, + attribs[1].ulValueLen, NULL); + rsa->e = BN_bin2bn(attribs[2].pValue, + attribs[2].ulValueLen, NULL); + } } else { - rsa->n = BN_bin2bn(attribs[1].pValue, - attribs[1].ulValueLen, NULL); - rsa->e = BN_bin2bn(attribs[2].pValue, - attribs[2].ulValueLen, NULL); - if (rsa->n && rsa->e && - pkcs11_rsa_wrap(p, slotidx, &attribs[0], rsa) == 0) { - key = key_new(KEY_UNSPEC); - key->rsa = rsa; - key->type = KEY_RSA; - key->flags |= KEY_FLAG_EXT; + cp = attribs[2].pValue; + if ((x509 = X509_new()) == NULL) { + error("X509_new failed"); + } else if (d2i_X509(&x509, &cp, attribs[2].ulValueLen) + == NULL) { + error("d2i_X509 failed"); + } else if ((evp = X509_get_pubkey(x509)) == NULL || + evp->type != EVP_PKEY_RSA || + evp->pkey.rsa == NULL) { + debug("X509_get_pubkey failed or no rsa"); + } else if ((rsa = RSAPublicKey_dup(evp->pkey.rsa)) + == NULL) { + error("RSAPublicKey_dup"); + } + if (x509) + X509_free(x509); + } + if (rsa && rsa->n && rsa->e && + pkcs11_rsa_wrap(p, slotidx, &attribs[0], rsa) == 0) { + key = key_new(KEY_UNSPEC); + key->rsa = rsa; + key->type = KEY_RSA; + key->flags |= KEY_FLAG_EXT; + if (pkcs11_key_included(keysp, nkeys, key)) { + key_free(key); + } else { /* expand key array and add key */ *keysp = xrealloc(*keysp, *nkeys + 1, sizeof(Key *)); (*keysp)[*nkeys] = key; *nkeys = *nkeys + 1; debug("have %d keys", *nkeys); - } else { - RSA_free(rsa); } + } else if (rsa) { + RSA_free(rsa); } for (i = 0; i < 3; i++) free(attribs[i].pValue); diff --git a/ssh-rsa.c b/ssh-rsa.c index 30f96abc2a14..a2112d033e58 100644 --- a/ssh-rsa.c +++ b/ssh-rsa.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-rsa.c,v 1.46 2013/05/17 00:13:14 djm Exp $ */ +/* $OpenBSD: ssh-rsa.c,v 1.50 2014/01/09 23:20:00 djm Exp $ */ /* * Copyright (c) 2000, 2003 Markus Friedl * @@ -32,6 +32,7 @@ #include "compat.h" #include "misc.h" #include "ssh.h" +#include "digest.h" static int openssh_RSA_verify(int, u_char *, u_int, u_char *, u_int, RSA *); @@ -40,26 +41,30 @@ int ssh_rsa_sign(const Key *key, u_char **sigp, u_int *lenp, const u_char *data, u_int datalen) { - const EVP_MD *evp_md; - EVP_MD_CTX md; - u_char digest[EVP_MAX_MD_SIZE], *sig; + int hash_alg; + u_char digest[SSH_DIGEST_MAX_LENGTH], *sig; u_int slen, dlen, len; int ok, nid; Buffer b; - if (key == NULL || key->rsa == NULL || (key->type != KEY_RSA && - key->type != KEY_RSA_CERT && key->type != KEY_RSA_CERT_V00)) { - error("ssh_rsa_sign: no RSA key"); + if (key == NULL || key_type_plain(key->type) != KEY_RSA || + key->rsa == NULL) { + error("%s: no RSA key", __func__); return -1; } - nid = (datafellows & SSH_BUG_RSASIGMD5) ? NID_md5 : NID_sha1; - if ((evp_md = EVP_get_digestbynid(nid)) == NULL) { - error("ssh_rsa_sign: EVP_get_digestbynid %d failed", nid); + + /* hash the data */ + hash_alg = SSH_DIGEST_SHA1; + nid = NID_sha1; + if ((dlen = ssh_digest_bytes(hash_alg)) == 0) { + error("%s: bad hash algorithm %d", __func__, hash_alg); + return -1; + } + if (ssh_digest_memory(hash_alg, data, datalen, + digest, sizeof(digest)) != 0) { + error("%s: ssh_digest_memory failed", __func__); return -1; } - EVP_DigestInit(&md, evp_md); - EVP_DigestUpdate(&md, data, datalen); - EVP_DigestFinal(&md, digest, &dlen); slen = RSA_size(key->rsa); sig = xmalloc(slen); @@ -70,7 +75,7 @@ ssh_rsa_sign(const Key *key, u_char **sigp, u_int *lenp, if (ok != 1) { int ecode = ERR_get_error(); - error("ssh_rsa_sign: RSA_sign failed: %s", + error("%s: RSA_sign failed: %s", __func__, ERR_error_string(ecode, NULL)); free(sig); return -1; @@ -81,7 +86,7 @@ ssh_rsa_sign(const Key *key, u_char **sigp, u_int *lenp, memmove(sig + diff, sig, len); memset(sig, 0, diff); } else if (len > slen) { - error("ssh_rsa_sign: slen %u slen2 %u", slen, len); + error("%s: slen %u slen2 %u", __func__, slen, len); free(sig); return -1; } @@ -108,28 +113,29 @@ ssh_rsa_verify(const Key *key, const u_char *signature, u_int signaturelen, const u_char *data, u_int datalen) { Buffer b; - const EVP_MD *evp_md; - EVP_MD_CTX md; + int hash_alg; char *ktype; - u_char digest[EVP_MAX_MD_SIZE], *sigblob; + u_char digest[SSH_DIGEST_MAX_LENGTH], *sigblob; u_int len, dlen, modlen; - int rlen, ret, nid; + int rlen, ret; - if (key == NULL || key->rsa == NULL || (key->type != KEY_RSA && - key->type != KEY_RSA_CERT && key->type != KEY_RSA_CERT_V00)) { - error("ssh_rsa_verify: no RSA key"); + if (key == NULL || key_type_plain(key->type) != KEY_RSA || + key->rsa == NULL) { + error("%s: no RSA key", __func__); return -1; } + if (BN_num_bits(key->rsa->n) < SSH_RSA_MINIMUM_MODULUS_SIZE) { - error("ssh_rsa_verify: RSA modulus too small: %d < minimum %d bits", - BN_num_bits(key->rsa->n), SSH_RSA_MINIMUM_MODULUS_SIZE); + error("%s: RSA modulus too small: %d < minimum %d bits", + __func__, BN_num_bits(key->rsa->n), + SSH_RSA_MINIMUM_MODULUS_SIZE); return -1; } buffer_init(&b); buffer_append(&b, signature, signaturelen); ktype = buffer_get_cstring(&b, NULL); if (strcmp("ssh-rsa", ktype) != 0) { - error("ssh_rsa_verify: cannot handle type %s", ktype); + error("%s: cannot handle type %s", __func__, ktype); buffer_free(&b); free(ktype); return -1; @@ -139,40 +145,43 @@ ssh_rsa_verify(const Key *key, const u_char *signature, u_int signaturelen, rlen = buffer_len(&b); buffer_free(&b); if (rlen != 0) { - error("ssh_rsa_verify: remaining bytes in signature %d", rlen); + error("%s: remaining bytes in signature %d", __func__, rlen); free(sigblob); return -1; } /* RSA_verify expects a signature of RSA_size */ modlen = RSA_size(key->rsa); if (len > modlen) { - error("ssh_rsa_verify: len %u > modlen %u", len, modlen); + error("%s: len %u > modlen %u", __func__, len, modlen); free(sigblob); return -1; } else if (len < modlen) { u_int diff = modlen - len; - debug("ssh_rsa_verify: add padding: modlen %u > len %u", + debug("%s: add padding: modlen %u > len %u", __func__, modlen, len); sigblob = xrealloc(sigblob, 1, modlen); memmove(sigblob + diff, sigblob, len); memset(sigblob, 0, diff); len = modlen; } - nid = (datafellows & SSH_BUG_RSASIGMD5) ? NID_md5 : NID_sha1; - if ((evp_md = EVP_get_digestbynid(nid)) == NULL) { - error("ssh_rsa_verify: EVP_get_digestbynid %d failed", nid); - free(sigblob); + /* hash the data */ + hash_alg = SSH_DIGEST_SHA1; + if ((dlen = ssh_digest_bytes(hash_alg)) == 0) { + error("%s: bad hash algorithm %d", __func__, hash_alg); + return -1; + } + if (ssh_digest_memory(hash_alg, data, datalen, + digest, sizeof(digest)) != 0) { + error("%s: ssh_digest_memory failed", __func__); return -1; } - EVP_DigestInit(&md, evp_md); - EVP_DigestUpdate(&md, data, datalen); - EVP_DigestFinal(&md, digest, &dlen); - ret = openssh_RSA_verify(nid, digest, dlen, sigblob, len, key->rsa); + ret = openssh_RSA_verify(hash_alg, digest, dlen, sigblob, len, + key->rsa); memset(digest, 'd', sizeof(digest)); memset(sigblob, 's', len); free(sigblob); - debug("ssh_rsa_verify: signature %scorrect", (ret==0) ? "in" : ""); + debug("%s: signature %scorrect", __func__, (ret == 0) ? "in" : ""); return ret; } @@ -193,21 +202,9 @@ static const u_char id_sha1[] = { 0x05, 0x00, /* NULL */ 0x04, 0x14 /* Octet string, length 0x14 (20), followed by sha1 hash */ }; -/* - * id-md5 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) - * rsadsi(113549) digestAlgorithm(2) 5 } - */ -static const u_char id_md5[] = { - 0x30, 0x20, /* type Sequence, length 0x20 (32) */ - 0x30, 0x0c, /* type Sequence, length 0x09 */ - 0x06, 0x08, /* type OID, length 0x05 */ - 0x2a, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x02, 0x05, /* id-md5 */ - 0x05, 0x00, /* NULL */ - 0x04, 0x10 /* Octet string, length 0x10 (16), followed by md5 hash */ -}; static int -openssh_RSA_verify(int type, u_char *hash, u_int hashlen, +openssh_RSA_verify(int hash_alg, u_char *hash, u_int hashlen, u_char *sigbuf, u_int siglen, RSA *rsa) { u_int ret, rsasize, oidlen = 0, hlen = 0; @@ -216,17 +213,12 @@ openssh_RSA_verify(int type, u_char *hash, u_int hashlen, u_char *decrypted = NULL; ret = 0; - switch (type) { - case NID_sha1: + switch (hash_alg) { + case SSH_DIGEST_SHA1: oid = id_sha1; oidlen = sizeof(id_sha1); hlen = 20; break; - case NID_md5: - oid = id_md5; - oidlen = sizeof(id_md5); - hlen = 16; - break; default: goto done; } diff --git a/ssh-sandbox.h b/ssh-sandbox.h index dfecd5aa00a5..bd5fd83722a0 100644 --- a/ssh-sandbox.h +++ b/ssh-sandbox.h @@ -15,9 +15,10 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +struct monitor; struct ssh_sandbox; -struct ssh_sandbox *ssh_sandbox_init(void); +struct ssh_sandbox *ssh_sandbox_init(struct monitor *); void ssh_sandbox_child(struct ssh_sandbox *); void ssh_sandbox_parent_finish(struct ssh_sandbox *); void ssh_sandbox_parent_preauth(struct ssh_sandbox *, pid_t); diff --git a/ssh.0 b/ssh.0 index adc1ee421e58..3a6a0469d4d2 100644 --- a/ssh.0 +++ b/ssh.0 @@ -9,9 +9,9 @@ SYNOPSIS [-F configfile] [-I pkcs11] [-i identity_file] [-L [bind_address:]port:host:hostport] [-l login_name] [-m mac_spec] [-O ctl_cmd] [-o option] [-p port] + [-Q cipher | cipher-auth | mac | kex | key] [-R [bind_address:]port:host:hostport] [-S ctl_path] [-W host:port] [-w local_tun[:remote_tun]] [user@]hostname [command] - ssh -Q protocol_feature DESCRIPTION ssh (SSH client) is a program for logging into a remote machine and for @@ -142,13 +142,13 @@ DESCRIPTION -i identity_file Selects a file from which the identity (private key) for public key authentication is read. The default is ~/.ssh/identity for - protocol version 1, and ~/.ssh/id_dsa, ~/.ssh/id_ecdsa and - ~/.ssh/id_rsa for protocol version 2. Identity files may also be - specified on a per-host basis in the configuration file. It is - possible to have multiple -i options (and multiple identities - specified in configuration files). ssh will also try to load - certificate information from the filename obtained by appending - -cert.pub to identity filenames. + protocol version 1, and ~/.ssh/id_dsa, ~/.ssh/id_ecdsa, + ~/.ssh/id_ed25519 and ~/.ssh/id_rsa for protocol version 2. + Identity files may also be specified on a per-host basis in the + configuration file. It is possible to have multiple -i options + (and multiple identities specified in configuration files). ssh + will also try to load certificate information from the filename + obtained by appending -cert.pub to identity filenames. -K Enables GSSAPI-based authentication and forwarding (delegation) of GSSAPI credentials to the server. @@ -222,6 +222,11 @@ DESCRIPTION AddressFamily BatchMode BindAddress + CanonicalDomains + CanonicalizeFallbackLocal + CanonicalizeHostname + CanonicalizeMaxDots + CanonicalizePermittedCNAMEs ChallengeResponseAuthentication CheckHostIP Cipher @@ -261,6 +266,7 @@ DESCRIPTION LocalForward LogLevel MACs + Match NoHostAuthenticationForLocalhost NumberOfPasswordPrompts PasswordAuthentication @@ -270,6 +276,7 @@ DESCRIPTION PreferredAuthentications Protocol ProxyCommand + ProxyUseFdpass PubkeyAuthentication RekeyLimit RemoteForward @@ -294,13 +301,12 @@ DESCRIPTION Port to connect to on the remote host. This can be specified on a per-host basis in the configuration file. - -Q protocol_feature + -Q cipher | cipher-auth | mac | kex | key Queries ssh for the algorithms supported for the specified - version 2 protocol_feature. The queriable features are: - ``cipher'' (supported symmetric ciphers), ``MAC'' (supported - message integrity codes), ``KEX'' (key exchange algorithms), - ``key'' (key types). Protocol features are treated case- - insensitively. + version 2. The available features are: cipher (supported + symmetric ciphers), cipher-auth (supported symmetric ciphers that + support authenticated encryption), mac (supported message + integrity codes), kex (key exchange algorithms), key (key types). -q Quiet mode. Causes most warning and diagnostic messages to be suppressed. @@ -440,9 +446,10 @@ AUTHENTICATION creates a public/private key pair for authentication purposes. The server knows the public key, and only the user knows the private key. ssh implements public key authentication protocol automatically, using - one of the DSA, ECDSA or RSA algorithms. Protocol 1 is restricted to - using only RSA keys, but protocol 2 may use any. The HISTORY section of - ssl(8) contains a brief discussion of the DSA and RSA algorithms. + one of the DSA, ECDSA, ED25519 or RSA algorithms. Protocol 1 is + restricted to using only RSA keys, but protocol 2 may use any. The + HISTORY section of ssl(8) contains a brief discussion of the DSA and RSA + algorithms. The file ~/.ssh/authorized_keys lists the public keys that are permitted for logging in. When the user logs in, the ssh program tells the server @@ -452,10 +459,11 @@ AUTHENTICATION The user creates his/her key pair by running ssh-keygen(1). This stores the private key in ~/.ssh/identity (protocol 1), ~/.ssh/id_dsa (protocol - 2 DSA), ~/.ssh/id_ecdsa (protocol 2 ECDSA), or ~/.ssh/id_rsa (protocol 2 - RSA) and stores the public key in ~/.ssh/identity.pub (protocol 1), - ~/.ssh/id_dsa.pub (protocol 2 DSA), ~/.ssh/id_ecdsa.pub (protocol 2 - ECDSA), or ~/.ssh/id_rsa.pub (protocol 2 RSA) in the user's home + 2 DSA), ~/.ssh/id_ecdsa (protocol 2 ECDSA), ~/.ssh/id_ed25519 (protocol 2 + ED25519), or ~/.ssh/id_rsa (protocol 2 RSA) and stores the public key in + ~/.ssh/identity.pub (protocol 1), ~/.ssh/id_dsa.pub (protocol 2 DSA), + ~/.ssh/id_ecdsa.pub (protocol 2 ECDSA), ~/.ssh/id_ed25519.pub (protocol 2 + ED25519), or ~/.ssh/id_rsa.pub (protocol 2 RSA) in the user's home directory. The user should then copy the public key to ~/.ssh/authorized_keys in his/her home directory on the remote machine. The authorized_keys file corresponds to the conventional ~/.rhosts file, @@ -791,11 +799,11 @@ FILES for the user, and not accessible by others. ~/.ssh/authorized_keys - Lists the public keys (DSA/ECDSA/RSA) that can be used for - logging in as this user. The format of this file is described in - the sshd(8) manual page. This file is not highly sensitive, but - the recommended permissions are read/write for the user, and not - accessible by others. + Lists the public keys (DSA, ECDSA, ED25519, RSA) that can be used + for logging in as this user. The format of this file is + described in the sshd(8) manual page. This file is not highly + sensitive, but the recommended permissions are read/write for the + user, and not accessible by others. ~/.ssh/config This is the per-user configuration file. The file format and @@ -810,6 +818,7 @@ FILES ~/.ssh/identity ~/.ssh/id_dsa ~/.ssh/id_ecdsa + ~/.ssh/id_ed25519 ~/.ssh/id_rsa Contains the private key for authentication. These files contain sensitive data and should be readable by the user but not @@ -822,6 +831,7 @@ FILES ~/.ssh/identity.pub ~/.ssh/id_dsa.pub ~/.ssh/id_ecdsa.pub + ~/.ssh/id_ed25519.pub ~/.ssh/id_rsa.pub Contains the public key for authentication. These files are not sensitive and can (but need not) be readable by anyone. @@ -853,6 +863,7 @@ FILES /etc/ssh/ssh_host_key /etc/ssh/ssh_host_dsa_key /etc/ssh/ssh_host_ecdsa_key + /etc/ssh/ssh_host_ed25519_key /etc/ssh/ssh_host_rsa_key These files contain the private parts of the host keys and are used for host-based authentication. If protocol version 1 is @@ -932,4 +943,4 @@ AUTHORS created OpenSSH. Markus Friedl contributed the support for SSH protocol versions 1.5 and 2.0. -OpenBSD 5.4 July 18, 2013 OpenBSD 5.4 +OpenBSD 5.4 December 7, 2013 OpenBSD 5.4 diff --git a/ssh.1 b/ssh.1 index 62292cc09f91..27794e2d0360 100644 --- a/ssh.1 +++ b/ssh.1 @@ -33,8 +33,8 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.\" $OpenBSD: ssh.1,v 1.334 2013/07/18 01:12:26 djm Exp $ -.Dd $Mdocdate: July 18 2013 $ +.\" $OpenBSD: ssh.1,v 1.343 2013/12/07 11:58:46 naddy Exp $ +.Dd $Mdocdate: December 7 2013 $ .Dt SSH 1 .Os .Sh NAME @@ -58,6 +58,7 @@ .Op Fl O Ar ctl_cmd .Op Fl o Ar option .Op Fl p Ar port +.Op Fl Q Cm cipher | cipher-auth | mac | kex | key .Op Fl R Oo Ar bind_address : Oc Ns Ar port : Ns Ar host : Ns Ar hostport .Op Fl S Ar ctl_path .Op Fl W Ar host : Ns Ar port @@ -65,8 +66,6 @@ .Oo Ar user Ns @ Oc Ns Ar hostname .Op Ar command .Ek -.Nm -.Fl Q Ar protocol_feature .Sh DESCRIPTION .Nm (SSH client) is a program for logging into a remote machine and for @@ -280,7 +279,8 @@ The default is .Pa ~/.ssh/identity for protocol version 1, and .Pa ~/.ssh/id_dsa , -.Pa ~/.ssh/id_ecdsa +.Pa ~/.ssh/id_ecdsa , +.Pa ~/.ssh/id_ed25519 and .Pa ~/.ssh/id_rsa for protocol version 2. @@ -417,6 +417,11 @@ For full details of the options listed below, and their possible values, see .It AddressFamily .It BatchMode .It BindAddress +.It CanonicalDomains +.It CanonicalizeFallbackLocal +.It CanonicalizeHostname +.It CanonicalizeMaxDots +.It CanonicalizePermittedCNAMEs .It ChallengeResponseAuthentication .It CheckHostIP .It Cipher @@ -456,6 +461,7 @@ For full details of the options listed below, and their possible values, see .It LocalForward .It LogLevel .It MACs +.It Match .It NoHostAuthenticationForLocalhost .It NumberOfPasswordPrompts .It PasswordAuthentication @@ -465,6 +471,7 @@ For full details of the options listed below, and their possible values, see .It PreferredAuthentications .It Protocol .It ProxyCommand +.It ProxyUseFdpass .It PubkeyAuthentication .It RekeyLimit .It RemoteForward @@ -489,21 +496,21 @@ For full details of the options listed below, and their possible values, see Port to connect to on the remote host. This can be specified on a per-host basis in the configuration file. -.It Fl Q Ar protocol_feature +.It Fl Q Cm cipher | cipher-auth | mac | kex | key Queries .Nm -for the algorithms supported for the specified version 2 -.Ar protocol_feature . -The queriable features are: -.Dq cipher +for the algorithms supported for the specified version 2. +The available features are: +.Ar cipher (supported symmetric ciphers), -.Dq MAC +.Ar cipher-auth +(supported symmetric ciphers that support authenticated encryption), +.Ar mac (supported message integrity codes), -.Dq KEX +.Ar kex (key exchange algorithms), -.Dq key +.Ar key (key types). -Protocol features are treated case-insensitively. .It Fl q Quiet mode. Causes most warning and diagnostic messages to be suppressed. @@ -751,7 +758,7 @@ key pair for authentication purposes. The server knows the public key, and only the user knows the private key. .Nm implements public key authentication protocol automatically, -using one of the DSA, ECDSA or RSA algorithms. +using one of the DSA, ECDSA, ED25519 or RSA algorithms. Protocol 1 is restricted to using only RSA keys, but protocol 2 may use any. The HISTORY section of @@ -778,6 +785,8 @@ This stores the private key in (protocol 2 DSA), .Pa ~/.ssh/id_ecdsa (protocol 2 ECDSA), +.Pa ~/.ssh/id_ed25519 +(protocol 2 ED25519), or .Pa ~/.ssh/id_rsa (protocol 2 RSA) @@ -788,6 +797,8 @@ and stores the public key in (protocol 2 DSA), .Pa ~/.ssh/id_ecdsa.pub (protocol 2 ECDSA), +.Pa ~/.ssh/id_ed25519.pub +(protocol 2 ED25519), or .Pa ~/.ssh/id_rsa.pub (protocol 2 RSA) @@ -827,9 +838,12 @@ text, and prompts for a response. Protocol 2 allows multiple challenges and responses; protocol 1 is restricted to just one challenge/response. Examples of challenge-response authentication include -BSD Authentication (see +.Bx +Authentication (see .Xr login.conf 5 ) -and PAM (some non-OpenBSD systems). +and PAM (some +.Pf non- Ox +systems). .Pp Finally, if other authentication methods fail, .Nm @@ -1324,8 +1338,8 @@ secret, but the recommended permissions are read/write/execute for the user, and not accessible by others. .Pp .It Pa ~/.ssh/authorized_keys -Lists the public keys (DSA/ECDSA/RSA) that can be used for logging in as -this user. +Lists the public keys (DSA, ECDSA, ED25519, RSA) +that can be used for logging in as this user. The format of this file is described in the .Xr sshd 8 manual page. @@ -1347,6 +1361,7 @@ above. .It Pa ~/.ssh/identity .It Pa ~/.ssh/id_dsa .It Pa ~/.ssh/id_ecdsa +.It Pa ~/.ssh/id_ed25519 .It Pa ~/.ssh/id_rsa Contains the private key for authentication. These files @@ -1361,6 +1376,7 @@ sensitive part of this file using 3DES. .It Pa ~/.ssh/identity.pub .It Pa ~/.ssh/id_dsa.pub .It Pa ~/.ssh/id_ecdsa.pub +.It Pa ~/.ssh/id_ed25519.pub .It Pa ~/.ssh/id_rsa.pub Contains the public key for authentication. These files are not @@ -1400,6 +1416,7 @@ The file format and configuration options are described in .It Pa /etc/ssh/ssh_host_key .It Pa /etc/ssh/ssh_host_dsa_key .It Pa /etc/ssh/ssh_host_ecdsa_key +.It Pa /etc/ssh/ssh_host_ed25519_key .It Pa /etc/ssh/ssh_host_rsa_key These files contain the private parts of the host keys and are used for host-based authentication. diff --git a/ssh.c b/ssh.c index 87233bc9190f..5de8fcf43ff0 100644 --- a/ssh.c +++ b/ssh.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh.c,v 1.381 2013/07/25 00:29:10 djm Exp $ */ +/* $OpenBSD: ssh.c,v 1.397 2013/12/29 05:42:16 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -199,11 +199,11 @@ usage(void) "usage: ssh [-1246AaCfgKkMNnqsTtVvXxYy] [-b bind_address] [-c cipher_spec]\n" " [-D [bind_address:]port] [-E log_file] [-e escape_char]\n" " [-F configfile] [-I pkcs11] [-i identity_file]\n" -" [-L [bind_address:]port:host:hostport] [-Q protocol_feature]\n" -" [-l login_name] [-m mac_spec] [-O ctl_cmd] [-o option] [-p port]\n" -" [-R [bind_address:]port:host:hostport] [-S ctl_path]\n" -" [-W host:port] [-w local_tun[:remote_tun]]\n" -" [user@]hostname [command]\n" +" [-L [bind_address:]port:host:hostport] [-l login_name] [-m mac_spec]\n" +" [-O ctl_cmd] [-o option] [-p port]\n" +" [-Q cipher | cipher-auth | mac | kex | key]\n" +" [-R [bind_address:]port:host:hostport] [-S ctl_path] [-W host:port]\n" +" [-w local_tun[:remote_tun]] [user@]hostname [command]\n" ); exit(255); } @@ -231,6 +231,134 @@ tilde_expand_paths(char **paths, u_int num_paths) } } +static struct addrinfo * +resolve_host(const char *name, u_int port, int logerr, char *cname, size_t clen) +{ + char strport[NI_MAXSERV]; + struct addrinfo hints, *res; + int gaierr, loglevel = SYSLOG_LEVEL_DEBUG1; + + snprintf(strport, sizeof strport, "%u", port); + bzero(&hints, sizeof(hints)); + hints.ai_family = options.address_family; + hints.ai_socktype = SOCK_STREAM; + if (cname != NULL) + hints.ai_flags = AI_CANONNAME; + if ((gaierr = getaddrinfo(name, strport, &hints, &res)) != 0) { + if (logerr || (gaierr != EAI_NONAME && gaierr != EAI_NODATA)) + loglevel = SYSLOG_LEVEL_ERROR; + do_log2(loglevel, "%s: Could not resolve hostname %.100s: %s", + __progname, name, ssh_gai_strerror(gaierr)); + return NULL; + } + if (cname != NULL && res->ai_canonname != NULL) { + if (strlcpy(cname, res->ai_canonname, clen) >= clen) { + error("%s: host \"%s\" cname \"%s\" too long (max %lu)", + __func__, name, res->ai_canonname, (u_long)clen); + if (clen > 0) + *cname = '\0'; + } + } + return res; +} + +/* + * Check whether the cname is a permitted replacement for the hostname + * and perform the replacement if it is. + */ +static int +check_follow_cname(char **namep, const char *cname) +{ + int i; + struct allowed_cname *rule; + + if (*cname == '\0' || options.num_permitted_cnames == 0 || + strcmp(*namep, cname) == 0) + return 0; + if (options.canonicalize_hostname == SSH_CANONICALISE_NO) + return 0; + /* + * Don't attempt to canonicalize names that will be interpreted by + * a proxy unless the user specifically requests so. + */ + if (options.proxy_command != NULL && + options.canonicalize_hostname != SSH_CANONICALISE_ALWAYS) + return 0; + debug3("%s: check \"%s\" CNAME \"%s\"", __func__, *namep, cname); + for (i = 0; i < options.num_permitted_cnames; i++) { + rule = options.permitted_cnames + i; + if (match_pattern_list(*namep, rule->source_list, + strlen(rule->source_list), 1) != 1 || + match_pattern_list(cname, rule->target_list, + strlen(rule->target_list), 1) != 1) + continue; + verbose("Canonicalized DNS aliased hostname " + "\"%s\" => \"%s\"", *namep, cname); + free(*namep); + *namep = xstrdup(cname); + return 1; + } + return 0; +} + +/* + * Attempt to resolve the supplied hostname after applying the user's + * canonicalization rules. Returns the address list for the host or NULL + * if no name was found after canonicalization. + */ +static struct addrinfo * +resolve_canonicalize(char **hostp, u_int port) +{ + int i, ndots; + char *cp, *fullhost, cname_target[NI_MAXHOST]; + struct addrinfo *addrs; + + if (options.canonicalize_hostname == SSH_CANONICALISE_NO) + return NULL; + /* + * Don't attempt to canonicalize names that will be interpreted by + * a proxy unless the user specifically requests so. + */ + if (options.proxy_command != NULL && + options.canonicalize_hostname != SSH_CANONICALISE_ALWAYS) + return NULL; + /* Don't apply canonicalization to sufficiently-qualified hostnames */ + ndots = 0; + for (cp = *hostp; *cp != '\0'; cp++) { + if (*cp == '.') + ndots++; + } + if (ndots > options.canonicalize_max_dots) { + debug3("%s: not canonicalizing hostname \"%s\" (max dots %d)", + __func__, *hostp, options.canonicalize_max_dots); + return NULL; + } + /* Attempt each supplied suffix */ + for (i = 0; i < options.num_canonical_domains; i++) { + *cname_target = '\0'; + xasprintf(&fullhost, "%s.%s.", *hostp, + options.canonical_domains[i]); + if ((addrs = resolve_host(fullhost, options.port, 0, + cname_target, sizeof(cname_target))) == NULL) { + free(fullhost); + continue; + } + /* Remove trailing '.' */ + fullhost[strlen(fullhost) - 1] = '\0'; + /* Follow CNAME if requested */ + if (!check_follow_cname(&fullhost, cname_target)) { + debug("Canonicalized hostname \"%s\" => \"%s\"", + *hostp, fullhost); + } + free(*hostp); + *hostp = fullhost; + return addrs; + } + if (!options.canonicalize_fallback_local) + fatal("%s: Could not resolve host \"%s\"", __progname, host); + return NULL; +} + /* * Main program for the ssh client. */ @@ -240,14 +368,14 @@ main(int ac, char **av) int i, r, opt, exit_status, use_syslog; char *p, *cp, *line, *argv0, buf[MAXPATHLEN], *host_arg, *logfile; char thishost[NI_MAXHOST], shorthost[NI_MAXHOST], portstr[NI_MAXSERV]; + char cname[NI_MAXHOST]; struct stat st; struct passwd *pw; - int dummy, timeout_ms; + int timeout_ms; extern int optind, optreset; extern char *optarg; - - struct servent *sp; Forward fwd; + struct addrinfo *addrs = NULL; /* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */ sanitise_stdfd(); @@ -389,16 +517,22 @@ main(int ac, char **av) case 'P': /* deprecated */ options.use_privileged_port = 0; break; - case 'Q': /* deprecated */ + case 'Q': cp = NULL; - if (strcasecmp(optarg, "cipher") == 0) - cp = cipher_alg_list(); - else if (strcasecmp(optarg, "mac") == 0) - cp = mac_alg_list(); - else if (strcasecmp(optarg, "kex") == 0) - cp = kex_alg_list(); - else if (strcasecmp(optarg, "key") == 0) - cp = key_alg_list(); + if (strcmp(optarg, "cipher") == 0) + cp = cipher_alg_list('\n', 0); + else if (strcmp(optarg, "cipher-auth") == 0) + cp = cipher_alg_list('\n', 1); + else if (strcmp(optarg, "mac") == 0) + cp = mac_alg_list('\n'); + else if (strcmp(optarg, "kex") == 0) + cp = kex_alg_list('\n'); + else if (strcmp(optarg, "key") == 0) + cp = key_alg_list(0, 0); + else if (strcmp(optarg, "key-cert") == 0) + cp = key_alg_list(1, 0); + else if (strcmp(optarg, "key-plain") == 0) + cp = key_alg_list(0, 1); if (cp == NULL) fatal("Unsupported query \"%s\"", optarg); printf("%s\n", cp); @@ -595,10 +729,9 @@ main(int ac, char **av) options.request_tty = REQUEST_TTY_NO; break; case 'o': - dummy = 1; line = xstrdup(optarg); - if (process_config_line(&options, host ? host : "", - line, "command-line", 0, &dummy, SSHCONF_USERCONF) + if (process_config_line(&options, pw, host ? host : "", + line, "command-line", 0, NULL, SSHCONF_USERCONF) != 0) exit(255); free(line); @@ -633,9 +766,9 @@ main(int ac, char **av) usage(); options.user = p; *cp = '\0'; - host = ++cp; + host = xstrdup(++cp); } else - host = *av; + host = xstrdup(*av); if (ac > 1) { optind = optreset = 1; goto again; @@ -647,6 +780,9 @@ main(int ac, char **av) if (!host) usage(); + lowercase(host); + host_arg = xstrdup(host); + OpenSSL_add_all_algorithms(); ERR_load_crypto_strings(); @@ -703,18 +839,19 @@ main(int ac, char **av) */ if (config != NULL) { if (strcasecmp(config, "none") != 0 && - !read_config_file(config, host, &options, SSHCONF_USERCONF)) + !read_config_file(config, pw, host, &options, + SSHCONF_USERCONF)) fatal("Can't open user config file %.100s: " "%.100s", config, strerror(errno)); } else { r = snprintf(buf, sizeof buf, "%s/%s", pw->pw_dir, _PATH_SSH_USER_CONFFILE); if (r > 0 && (size_t)r < sizeof(buf)) - (void)read_config_file(buf, host, &options, + (void)read_config_file(buf, pw, host, &options, SSHCONF_CHECKPERM|SSHCONF_USERCONF); /* Read systemwide configuration file after user config. */ - (void)read_config_file(_PATH_HOST_CONFIG_FILE, host, + (void)read_config_file(_PATH_HOST_CONFIG_FILE, pw, host, &options, 0); } @@ -723,6 +860,18 @@ main(int ac, char **av) channel_set_af(options.address_family); + /* Tidy and check options */ + if (options.host_key_alias != NULL) + lowercase(options.host_key_alias); + if (options.proxy_command != NULL && + strcmp(options.proxy_command, "-") == 0 && + options.proxy_use_fdpass) + fatal("ProxyCommand=- and ProxyUseFDPass are incompatible"); +#ifndef HAVE_CYGWIN + if (original_effective_uid != 0) + options.use_privileged_port = 0; +#endif + /* reinit */ log_init(argv0, options.log_level, SYSLOG_FACILITY_USER, !use_syslog); @@ -752,16 +901,33 @@ main(int ac, char **av) options.user = xstrdup(pw->pw_name); /* Get default port if port has not been set. */ - if (options.port == 0) { - sp = getservbyname(SSH_SERVICE_NAME, "tcp"); - options.port = sp ? ntohs(sp->s_port) : SSH_DEFAULT_PORT; - } + if (options.port == 0) + options.port = default_ssh_port(); /* preserve host name given on command line for %n expansion */ - host_arg = host; if (options.hostname != NULL) { - host = percent_expand(options.hostname, + /* NB. Please keep in sync with readconf.c:match_cfg_line() */ + cp = percent_expand(options.hostname, "h", host, (char *)NULL); + free(host); + host = cp; + } + + /* If canonicalization requested then try to apply it */ + if (options.canonicalize_hostname != SSH_CANONICALISE_NO) + addrs = resolve_canonicalize(&host, options.port); + /* + * If canonicalization not requested, or if it failed then try to + * resolve the bare hostname name using the system resolver's usual + * search rules. Skip the lookup if a ProxyCommand is being used + * unless the user has specifically requested canonicalisation. + */ + if (addrs == NULL && (options.proxy_command == NULL || + options.canonicalize_hostname == SSH_CANONICALISE_ALWAYS)) { + if ((addrs = resolve_host(host, options.port, 1, + cname, sizeof(cname))) == NULL) + cleanup_exit(255); /* resolve_host logs the error */ + check_follow_cname(&host, cname); } if (gethostname(thishost, sizeof(thishost)) == -1) @@ -781,24 +947,6 @@ main(int ac, char **av) free(cp); } - /* force lowercase for hostkey matching */ - if (options.host_key_alias != NULL) { - for (p = options.host_key_alias; *p; p++) - if (isupper(*p)) - *p = (char)tolower(*p); - } - - if (options.proxy_command != NULL && - strcmp(options.proxy_command, "none") == 0) { - free(options.proxy_command); - options.proxy_command = NULL; - } - if (options.control_path != NULL && - strcmp(options.control_path, "none") == 0) { - free(options.control_path); - options.control_path = NULL; - } - if (options.control_path != NULL) { cp = tilde_expand_filename(options.control_path, original_real_uid); @@ -817,16 +965,17 @@ main(int ac, char **av) timeout_ms = options.connection_timeout * 1000; /* Open a connection to the remote host. */ - if (ssh_connect(host, &hostaddr, options.port, - options.address_family, options.connection_attempts, &timeout_ms, - options.tcp_keep_alive, -#ifdef HAVE_CYGWIN - options.use_privileged_port, -#else - original_effective_uid == 0 && options.use_privileged_port, -#endif - options.proxy_command) != 0) - exit(255); + if (ssh_connect(host, addrs, &hostaddr, options.port, + options.address_family, options.connection_attempts, + &timeout_ms, options.tcp_keep_alive, + options.use_privileged_port) != 0) + exit(255); + + if (addrs != NULL) + freeaddrinfo(addrs); + + packet_set_timeout(options.server_alive_interval, + options.server_alive_count_max); if (timeout_ms > 0) debug3("timeout: %d ms remain after connect", timeout_ms); @@ -844,7 +993,7 @@ main(int ac, char **av) sensitive_data.external_keysign = 0; if (options.rhosts_rsa_authentication || options.hostbased_authentication) { - sensitive_data.nkeys = 7; + sensitive_data.nkeys = 9; sensitive_data.keys = xcalloc(sensitive_data.nkeys, sizeof(Key)); for (i = 0; i < sensitive_data.nkeys; i++) @@ -861,21 +1010,26 @@ main(int ac, char **av) #endif sensitive_data.keys[3] = key_load_private_cert(KEY_RSA, _PATH_HOST_RSA_KEY_FILE, "", NULL); - sensitive_data.keys[4] = key_load_private_type(KEY_DSA, + sensitive_data.keys[4] = key_load_private_cert(KEY_ED25519, + _PATH_HOST_ED25519_KEY_FILE, "", NULL); + sensitive_data.keys[5] = key_load_private_type(KEY_DSA, _PATH_HOST_DSA_KEY_FILE, "", NULL, NULL); #ifdef OPENSSL_HAS_ECC - sensitive_data.keys[5] = key_load_private_type(KEY_ECDSA, + sensitive_data.keys[6] = key_load_private_type(KEY_ECDSA, _PATH_HOST_ECDSA_KEY_FILE, "", NULL, NULL); #endif - sensitive_data.keys[6] = key_load_private_type(KEY_RSA, + sensitive_data.keys[7] = key_load_private_type(KEY_RSA, _PATH_HOST_RSA_KEY_FILE, "", NULL, NULL); + sensitive_data.keys[8] = key_load_private_type(KEY_ED25519, + _PATH_HOST_ED25519_KEY_FILE, "", NULL, NULL); PRIV_END; if (options.hostbased_authentication == 1 && sensitive_data.keys[0] == NULL && - sensitive_data.keys[4] == NULL && sensitive_data.keys[5] == NULL && - sensitive_data.keys[6] == NULL) { + sensitive_data.keys[6] == NULL && + sensitive_data.keys[7] == NULL && + sensitive_data.keys[8] == NULL) { sensitive_data.keys[1] = key_load_cert( _PATH_HOST_DSA_KEY_FILE); #ifdef OPENSSL_HAS_ECC @@ -884,14 +1038,18 @@ main(int ac, char **av) #endif sensitive_data.keys[3] = key_load_cert( _PATH_HOST_RSA_KEY_FILE); - sensitive_data.keys[4] = key_load_public( + sensitive_data.keys[4] = key_load_cert( + _PATH_HOST_ED25519_KEY_FILE); + sensitive_data.keys[5] = key_load_public( _PATH_HOST_DSA_KEY_FILE, NULL); #ifdef OPENSSL_HAS_ECC - sensitive_data.keys[5] = key_load_public( + sensitive_data.keys[6] = key_load_public( _PATH_HOST_ECDSA_KEY_FILE, NULL); #endif - sensitive_data.keys[6] = key_load_public( + sensitive_data.keys[7] = key_load_public( _PATH_HOST_RSA_KEY_FILE, NULL); + sensitive_data.keys[8] = key_load_public( + _PATH_HOST_ED25519_KEY_FILE, NULL); sensitive_data.external_keysign = 1; } } @@ -1091,7 +1249,7 @@ ssh_init_stdio_forwarding(void) if (stdio_forward_host == NULL) return; - if (!compat20) + if (!compat20) fatal("stdio forwarding require Protocol 2"); debug3("%s: %s:%d", __func__, stdio_forward_host, stdio_forward_port); @@ -1263,7 +1421,7 @@ ssh_session(void) char *proto, *data; /* Get reasonable local authentication information. */ client_x11_get_proto(display, options.xauth_location, - options.forward_x11_trusted, + options.forward_x11_trusted, options.forward_x11_timeout, &proto, &data); /* Request forwarding with authentication spoofing. */ @@ -1635,4 +1793,3 @@ main_sigchld_handler(int sig) signal(sig, main_sigchld_handler); errno = save_errno; } - diff --git a/ssh_config b/ssh_config index bb4081936332..03a228fbd483 100644 --- a/ssh_config +++ b/ssh_config @@ -1,4 +1,4 @@ -# $OpenBSD: ssh_config,v 1.27 2013/05/16 02:00:34 dtucker Exp $ +# $OpenBSD: ssh_config,v 1.28 2013/09/16 11:35:43 sthen Exp $ # This is the ssh client system-wide configuration file. See # ssh_config(5) for more information. This file provides defaults for diff --git a/ssh_config.0 b/ssh_config.0 index bd9e1ad51fd7..e9ac54bfc85f 100644 --- a/ssh_config.0 +++ b/ssh_config.0 @@ -38,8 +38,8 @@ DESCRIPTION The possible keywords and their meanings are as follows (note that keywords are case-insensitive and arguments are case-sensitive): - Host Restricts the following declarations (up to the next Host - keyword) to be only for those hosts that match one of the + Host Restricts the following declarations (up to the next Host or + Match keyword) to be only for those hosts that match one of the patterns given after the keyword. If more than one pattern is provided, they should be separated by whitespace. A single `*' as a pattern can be used to provide global defaults for all @@ -55,6 +55,37 @@ DESCRIPTION See PATTERNS for more information on patterns. + Match Restricts the following declarations (up to the next Host or + Match keyword) to be used only when the conditions following the + Match keyword are satisfied. Match conditions are specified + using one or more keyword/criteria pairs or the single token all + which matches all criteria. The available keywords are: exec, + host, originalhost, user, and localuser. + + The exec keyword executes the specified command under the user's + shell. If the command returns a zero exit status then the + condition is considered true. Commands containing whitespace + characters must be quoted. The following character sequences in + the command will be expanded prior to execution: `%L' will be + substituted by the first component of the local host name, `%l' + will be substituted by the local host name (including any domain + name), `%h' will be substituted by the target host name, `%n' + will be substituted by the original target host name specified on + the command-line, `%p' the destination port, `%r' by the remote + login username, and `%u' by the username of the user running + ssh(1). + + The other keywords' criteria must be single entries or comma- + separated lists and may use the wildcard and negation operators + described in the PATTERNS section. The criteria for the host + keyword are matched against the target hostname, after any + substitution by the Hostname option. The originalhost keyword + matches against the hostname as it was specified on the command- + line. The user keyword matches against the target username on + the remote host. The localuser keyword matches against the name + of the local user running ssh(1) (this keyword may be useful in + system-wide ssh_config files). + AddressFamily Specifies which address family to use when connecting. Valid arguments are ``any'', ``inet'' (use IPv4 only), or ``inet6'' @@ -72,6 +103,49 @@ DESCRIPTION one address. Note that this option does not work if UsePrivilegedPort is set to ``yes''. + CanonicalDomains + When CanonicalizeHostname is enabled, this option specifies the + list of domain suffixes in which to search for the specified + destination host. + + CanonicalizeFallbackLocal + Specifies whether to fail with an error when hostname + canonicalization fails. The default, ``yes'', will attempt to + look up the unqualified hostname using the system resolver's + search rules. A value of ``no'' will cause ssh(1) to fail + instantly if CanonicalizeHostname is enabled and the target + hostname cannot be found in any of the domains specified by + CanonicalDomains. + + CanonicalizeHostname + Controls whether explicit hostname canonicalization is performed. + The default, ``no'', is not to perform any name rewriting and let + the system resolver handle all hostname lookups. If set to + ``yes'' then, for connections that do not use a ProxyCommand, + ssh(1) will attempt to canonicalize the hostname specified on the + command line using the CanonicalDomains suffixes and + CanonicalizePermittedCNAMEs rules. If CanonicalizeHostname is + set to ``always'', then canonicalization is applied to proxied + connections too. + + CanonicalizeMaxDots + Specifies the maximum number of dot characters in a hostname + before canonicalization is disabled. The default, ``1'', allows + a single dot (i.e. hostname.subdomain). + + CanonicalizePermittedCNAMEs + Specifies rules to determine whether CNAMEs should be followed + when canonicalizing hostnames. The rules consist of one or more + arguments of source_domain_list:target_domain_list, where + source_domain_list is a pattern-list of domains that may follow + CNAMEs in canonicalization, and target_domain_list is a pattern- + list of domains that they may resolve to. + + For example, ``*.a.example.com:*.b.example.com,*.c.example.com'' + will allow hostnames matching ``*.a.example.com'' to be + canonicalized to names in the ``*.b.example.com'' or + ``*.c.example.com'' domains. + ChallengeResponseAuthentication Specifies whether to use challenge-response authentication. The argument to this keyword must be ``yes'' or ``no''. The default @@ -95,18 +169,25 @@ DESCRIPTION Ciphers Specifies the ciphers allowed for protocol version 2 in order of preference. Multiple ciphers must be comma-separated. The - supported ciphers are ``3des-cbc'', ``aes128-cbc'', - ``aes192-cbc'', ``aes256-cbc'', ``aes128-ctr'', ``aes192-ctr'', - ``aes256-ctr'', ``aes128-gcm@openssh.com'', - ``aes256-gcm@openssh.com'', ``arcfour128'', ``arcfour256'', - ``arcfour'', ``blowfish-cbc'', and ``cast128-cbc''. The default - is: + supported ciphers are: + + ``3des-cbc'', ``aes128-cbc'', ``aes192-cbc'', ``aes256-cbc'', + ``aes128-ctr'', ``aes192-ctr'', ``aes256-ctr'', + ``aes128-gcm@openssh.com'', ``aes256-gcm@openssh.com'', + ``arcfour128'', ``arcfour256'', ``arcfour'', ``blowfish-cbc'', + ``cast128-cbc'', and ``chacha20-poly1305@openssh.com''. + + The default is: aes128-ctr,aes192-ctr,aes256-ctr,arcfour256,arcfour128, aes128-gcm@openssh.com,aes256-gcm@openssh.com, + chacha20-poly1305@openssh.com, aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,aes192-cbc, aes256-cbc,arcfour + The list of available ciphers may also be obtained using the -Q + option of ssh(1). + ClearAllForwardings Specifies that all local, remote, and dynamic port forwardings specified in the configuration files or on the command line be @@ -174,9 +255,9 @@ DESCRIPTION name, `%l' will be substituted by the local host name (including any domain name), `%h' will be substituted by the target host name, `%n' will be substituted by the original target host name - specified on the command line, `%p' the port, `%r' by the remote - login username, and `%u' by the username of the user running - ssh(1). It is recommended that any ControlPath used for + specified on the command line, `%p' the destination port, `%r' by + the remote login username, and `%u' by the username of the user + running ssh(1). It is recommended that any ControlPath used for opportunistic connection sharing include at least %h, %p, and %r. This ensures that shared connections are uniquely identified. @@ -331,10 +412,11 @@ DESCRIPTION ecdsa-sha2-nistp256-cert-v01@openssh.com, ecdsa-sha2-nistp384-cert-v01@openssh.com, ecdsa-sha2-nistp521-cert-v01@openssh.com, + ssh-ed25519-cert-v01@openssh.com, ssh-rsa-cert-v01@openssh.com,ssh-dss-cert-v01@openssh.com, ssh-rsa-cert-v00@openssh.com,ssh-dss-cert-v00@openssh.com, ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521, - ssh-rsa,ssh-dss + ssh-ed25519,ssh-rsa,ssh-dss If hostkeys are known for the destination host then this default is modified to prefer their algorithms. @@ -364,14 +446,15 @@ DESCRIPTION default is ``no''. IdentityFile - Specifies a file from which the user's DSA, ECDSA or RSA + Specifies a file from which the user's DSA, ECDSA, ED25519 or RSA authentication identity is read. The default is ~/.ssh/identity - for protocol version 1, and ~/.ssh/id_dsa, ~/.ssh/id_ecdsa and - ~/.ssh/id_rsa for protocol version 2. Additionally, any - identities represented by the authentication agent will be used - for authentication unless IdentitiesOnly is set. ssh(1) will try - to load certificate information from the filename obtained by - appending -cert.pub to the path of a specified IdentityFile. + for protocol version 1, and ~/.ssh/id_dsa, ~/.ssh/id_ecdsa, + ~/.ssh/id_ed25519 and ~/.ssh/id_rsa for protocol version 2. + Additionally, any identities represented by the authentication + agent will be used for authentication unless IdentitiesOnly is + set. ssh(1) will try to load certificate information from the + filename obtained by appending -cert.pub to the path of a + specified IdentityFile. The file name may use the tilde syntax to refer to a user's home directory or one of the following escape characters: `%d' (local @@ -426,6 +509,7 @@ DESCRIPTION Specifies the available KEX (Key Exchange) algorithms. Multiple algorithms must be comma-separated. The default is: + curve25519-sha256@libssh.org, ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521, diffie-hellman-group-exchange-sha256, diffie-hellman-group-exchange-sha1, @@ -557,6 +641,11 @@ DESCRIPTION ProxyCommand /usr/bin/nc -X connect -x 192.0.2.0:8080 %h %p + ProxyUseFdpass + Specifies that ProxyCommand will pass a connected file descriptor + back to ssh(1) instead of continuing to execute and pass data. + The default is ``no''. + PubkeyAuthentication Specifies whether to try public key authentication. The argument to this keyword must be ``yes'' or ``no''. The default is @@ -763,7 +852,7 @@ PATTERNS A pattern-list is a comma-separated list of patterns. Patterns within pattern-lists may be negated by preceding them with an exclamation mark (`!'). For example, to allow a key to be used from anywhere within an - organisation except from the ``dialup'' pool, the following entry (in + organization except from the ``dialup'' pool, the following entry (in authorized_keys) could be used: from="!*.dialup.example.com,*.example.com" @@ -792,4 +881,4 @@ AUTHORS created OpenSSH. Markus Friedl contributed the support for SSH protocol versions 1.5 and 2.0. -OpenBSD 5.4 June 27, 2013 OpenBSD 5.4 +OpenBSD 5.4 January 19, 2014 OpenBSD 5.4 diff --git a/ssh_config.5 b/ssh_config.5 index 5d76c6d2d609..3cadcd767788 100644 --- a/ssh_config.5 +++ b/ssh_config.5 @@ -33,8 +33,8 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.\" $OpenBSD: ssh_config.5,v 1.166 2013/06/27 14:05:37 jmc Exp $ -.Dd $Mdocdate: June 27 2013 $ +.\" $OpenBSD: ssh_config.5,v 1.184 2014/01/19 04:48:08 djm Exp $ +.Dd $Mdocdate: January 19 2014 $ .Dt SSH_CONFIG 5 .Os .Sh NAME @@ -100,6 +100,8 @@ keywords are case-insensitive and arguments are case-sensitive): .It Cm Host Restricts the following declarations (up to the next .Cm Host +or +.Cm Match keyword) to be only for those hosts that match one of the patterns given after the keyword. If more than one pattern is provided, they should be separated by whitespace. @@ -124,6 +126,73 @@ matches. See .Sx PATTERNS for more information on patterns. +.It Cm Match +Restricts the following declarations (up to the next +.Cm Host +or +.Cm Match +keyword) to be used only when the conditions following the +.Cm Match +keyword are satisfied. +Match conditions are specified using one or more keyword/criteria pairs +or the single token +.Cm all +which matches all criteria. +The available keywords are: +.Cm exec , +.Cm host , +.Cm originalhost , +.Cm user , +and +.Cm localuser . +.Pp +The +.Cm exec +keyword executes the specified command under the user's shell. +If the command returns a zero exit status then the condition is considered true. +Commands containing whitespace characters must be quoted. +The following character sequences in the command will be expanded prior to +execution: +.Ql %L +will be substituted by the first component of the local host name, +.Ql %l +will be substituted by the local host name (including any domain name), +.Ql %h +will be substituted by the target host name, +.Ql %n +will be substituted by the original target host name +specified on the command-line, +.Ql %p +the destination port, +.Ql %r +by the remote login username, and +.Ql %u +by the username of the user running +.Xr ssh 1 . +.Pp +The other keywords' criteria must be single entries or comma-separated +lists and may use the wildcard and negation operators described in the +.Sx PATTERNS +section. +The criteria for the +.Cm host +keyword are matched against the target hostname, after any substitution +by the +.Cm Hostname +option. +The +.Cm originalhost +keyword matches against the hostname as it was specified on the command-line. +The +.Cm user +keyword matches against the target username on the remote host. +The +.Cm localuser +keyword matches against the name of the local user running +.Xr ssh 1 +(this keyword may be useful in system-wide +.Nm +files). .It Cm AddressFamily Specifies which address family to use when connecting. Valid arguments are @@ -152,6 +221,75 @@ Note that this option does not work if .Cm UsePrivilegedPort is set to .Dq yes . +.It Cm CanonicalDomains +When +.Cm CanonicalizeHostname +is enabled, this option specifies the list of domain suffixes in which to +search for the specified destination host. +.It Cm CanonicalizeFallbackLocal +Specifies whether to fail with an error when hostname canonicalization fails. +The default, +.Dq yes , +will attempt to look up the unqualified hostname using the system resolver's +search rules. +A value of +.Dq no +will cause +.Xr ssh 1 +to fail instantly if +.Cm CanonicalizeHostname +is enabled and the target hostname cannot be found in any of the domains +specified by +.Cm CanonicalDomains . +.It Cm CanonicalizeHostname +Controls whether explicit hostname canonicalization is performed. +The default, +.Dq no , +is not to perform any name rewriting and let the system resolver handle all +hostname lookups. +If set to +.Dq yes +then, for connections that do not use a +.Cm ProxyCommand , +.Xr ssh 1 +will attempt to canonicalize the hostname specified on the command line +using the +.Cm CanonicalDomains +suffixes and +.Cm CanonicalizePermittedCNAMEs +rules. +If +.Cm CanonicalizeHostname +is set to +.Dq always , +then canonicalization is applied to proxied connections too. +.It Cm CanonicalizeMaxDots +Specifies the maximum number of dot characters in a hostname before +canonicalization is disabled. +The default, +.Dq 1 , +allows a single dot (i.e. hostname.subdomain). +.It Cm CanonicalizePermittedCNAMEs +Specifies rules to determine whether CNAMEs should be followed when +canonicalizing hostnames. +The rules consist of one or more arguments of +.Ar source_domain_list : Ns Ar target_domain_list , +where +.Ar source_domain_list +is a pattern-list of domains that may follow CNAMEs in canonicalization, +and +.Ar target_domain_list +is a pattern-list of domains that they may resolve to. +.Pp +For example, +.Dq *.a.example.com:*.b.example.com,*.c.example.com +will allow hostnames matching +.Dq *.a.example.com +to be canonicalized to names in the +.Dq *.b.example.com +or +.Dq *.c.example.com +domains. .It Cm ChallengeResponseAuthentication Specifies whether to use challenge-response authentication. The argument to this keyword must be @@ -196,7 +334,8 @@ The default is Specifies the ciphers allowed for protocol version 2 in order of preference. Multiple ciphers must be comma-separated. -The supported ciphers are +The supported ciphers are: +.Pp .Dq 3des-cbc , .Dq aes128-cbc , .Dq aes192-cbc , @@ -210,15 +349,23 @@ The supported ciphers are .Dq arcfour256 , .Dq arcfour , .Dq blowfish-cbc , +.Dq cast128-cbc , and -.Dq cast128-cbc . +.Dq chacha20-poly1305@openssh.com . +.Pp The default is: .Bd -literal -offset 3n aes128-ctr,aes192-ctr,aes256-ctr,arcfour256,arcfour128, aes128-gcm@openssh.com,aes256-gcm@openssh.com, +chacha20-poly1305@openssh.com, aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,aes192-cbc, aes256-cbc,arcfour .Ed +.Pp +The list of available ciphers may also be obtained using the +.Fl Q +option of +.Xr ssh 1 . .It Cm ClearAllForwardings Specifies that all local, remote, and dynamic port forwardings specified in the configuration files or on the command line be @@ -327,7 +474,7 @@ will be substituted by the target host name, will be substituted by the original target host name specified on the command line, .Ql %p -the port, +the destination port, .Ql %r by the remote login username, and .Ql %u @@ -571,10 +718,11 @@ The default for this option is: ecdsa-sha2-nistp256-cert-v01@openssh.com, ecdsa-sha2-nistp384-cert-v01@openssh.com, ecdsa-sha2-nistp521-cert-v01@openssh.com, +ssh-ed25519-cert-v01@openssh.com, ssh-rsa-cert-v01@openssh.com,ssh-dss-cert-v01@openssh.com, ssh-rsa-cert-v00@openssh.com,ssh-dss-cert-v00@openssh.com, ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521, -ssh-rsa,ssh-dss +ssh-ed25519,ssh-rsa,ssh-dss .Ed .Pp If hostkeys are known for the destination host then this default is modified @@ -616,13 +764,14 @@ offers many different identities. The default is .Dq no . .It Cm IdentityFile -Specifies a file from which the user's DSA, ECDSA or RSA authentication +Specifies a file from which the user's DSA, ECDSA, ED25519 or RSA authentication identity is read. The default is .Pa ~/.ssh/identity for protocol version 1, and .Pa ~/.ssh/id_dsa , -.Pa ~/.ssh/id_ecdsa +.Pa ~/.ssh/id_ecdsa , +.Pa ~/.ssh/id_ed25519 and .Pa ~/.ssh/id_rsa for protocol version 2. @@ -735,6 +884,7 @@ Specifies the available KEX (Key Exchange) algorithms. Multiple algorithms must be comma-separated. The default is: .Bd -literal -offset indent +curve25519-sha256@libssh.org, ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521, diffie-hellman-group-exchange-sha256, diffie-hellman-group-exchange-sha1, @@ -937,6 +1087,14 @@ For example, the following directive would connect via an HTTP proxy at .Bd -literal -offset 3n ProxyCommand /usr/bin/nc -X connect -x 192.0.2.0:8080 %h %p .Ed +.It Cm ProxyUseFdpass +Specifies that +.Cm ProxyCommand +will pass a connected file descriptor back to +.Xr ssh 1 +instead of continuing to execute and pass data. +The default is +.Dq no . .It Cm PubkeyAuthentication Specifies whether to try public key authentication. The argument to this keyword must be @@ -1298,7 +1456,7 @@ Patterns within pattern-lists may be negated by preceding them with an exclamation mark .Pq Sq !\& . For example, -to allow a key to be used from anywhere within an organisation +to allow a key to be used from anywhere within an organization except from the .Dq dialup pool, diff --git a/sshconnect.c b/sshconnect.c index 483eb85acdc5..d21781ea45b6 100644 --- a/sshconnect.c +++ b/sshconnect.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sshconnect.c,v 1.238 2013/05/17 00:13:14 djm Exp $ */ +/* $OpenBSD: sshconnect.c,v 1.244 2014/01/09 23:26:48 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -59,6 +59,7 @@ #include "misc.h" #include "dns.h" #include "roaming.h" +#include "monitor_fdpass.h" #include "ssh2.h" #include "version.h" @@ -78,47 +79,122 @@ extern uid_t original_effective_uid; static int show_other_keys(struct hostkeys *, Key *); static void warn_changed_key(Key *); +/* Expand a proxy command */ +static char * +expand_proxy_command(const char *proxy_command, const char *user, + const char *host, int port) +{ + char *tmp, *ret, strport[NI_MAXSERV]; + + snprintf(strport, sizeof strport, "%d", port); + xasprintf(&tmp, "exec %s", proxy_command); + ret = percent_expand(tmp, "h", host, "p", strport, + "r", options.user, (char *)NULL); + free(tmp); + return ret; +} + +/* + * Connect to the given ssh server using a proxy command that passes a + * a connected fd back to us. + */ +static int +ssh_proxy_fdpass_connect(const char *host, u_short port, + const char *proxy_command) +{ + char *command_string; + int sp[2], sock; + pid_t pid; + char *shell; + + if ((shell = getenv("SHELL")) == NULL) + shell = _PATH_BSHELL; + + if (socketpair(AF_UNIX, SOCK_STREAM, 0, sp) < 0) + fatal("Could not create socketpair to communicate with " + "proxy dialer: %.100s", strerror(errno)); + + command_string = expand_proxy_command(proxy_command, options.user, + host, port); + debug("Executing proxy dialer command: %.500s", command_string); + + /* Fork and execute the proxy command. */ + if ((pid = fork()) == 0) { + char *argv[10]; + + /* Child. Permanently give up superuser privileges. */ + permanently_drop_suid(original_real_uid); + + close(sp[1]); + /* Redirect stdin and stdout. */ + if (sp[0] != 0) { + if (dup2(sp[0], 0) < 0) + perror("dup2 stdin"); + } + if (sp[0] != 1) { + if (dup2(sp[0], 1) < 0) + perror("dup2 stdout"); + } + if (sp[0] >= 2) + close(sp[0]); + + /* + * Stderr is left as it is so that error messages get + * printed on the user's terminal. + */ + argv[0] = shell; + argv[1] = "-c"; + argv[2] = command_string; + argv[3] = NULL; + + /* + * Execute the proxy command. + * Note that we gave up any extra privileges above. + */ + execv(argv[0], argv); + perror(argv[0]); + exit(1); + } + /* Parent. */ + if (pid < 0) + fatal("fork failed: %.100s", strerror(errno)); + close(sp[0]); + free(command_string); + + if ((sock = mm_receive_fd(sp[1])) == -1) + fatal("proxy dialer did not pass back a connection"); + + while (waitpid(pid, NULL, 0) == -1) + if (errno != EINTR) + fatal("Couldn't wait for child: %s", strerror(errno)); + + /* Set the connection file descriptors. */ + packet_set_connection(sock, sock); + + return 0; +} + /* * Connect to the given ssh server using a proxy command. */ static int ssh_proxy_connect(const char *host, u_short port, const char *proxy_command) { - char *command_string, *tmp; + char *command_string; int pin[2], pout[2]; pid_t pid; - char *shell, strport[NI_MAXSERV]; - - if (!strcmp(proxy_command, "-")) { - packet_set_connection(STDIN_FILENO, STDOUT_FILENO); - packet_set_timeout(options.server_alive_interval, - options.server_alive_count_max); - return 0; - } + char *shell; if ((shell = getenv("SHELL")) == NULL || *shell == '\0') shell = _PATH_BSHELL; - /* Convert the port number into a string. */ - snprintf(strport, sizeof strport, "%hu", port); - - /* - * Build the final command string in the buffer by making the - * appropriate substitutions to the given proxy command. - * - * Use "exec" to avoid "sh -c" processes on some platforms - * (e.g. Solaris) - */ - xasprintf(&tmp, "exec %s", proxy_command); - command_string = percent_expand(tmp, "h", host, "p", strport, - "r", options.user, (char *)NULL); - free(tmp); - /* Create pipes for communicating with the proxy. */ if (pipe(pin) < 0 || pipe(pout) < 0) fatal("Could not create pipes to communicate with the proxy: %.100s", strerror(errno)); + command_string = expand_proxy_command(proxy_command, options.user, + host, port); debug("Executing proxy command: %.500s", command_string); /* Fork and execute the proxy command. */ @@ -170,8 +246,6 @@ ssh_proxy_connect(const char *host, u_short port, const char *proxy_command) /* Set the connection file descriptors. */ packet_set_connection(pout[0], pin[1]); - packet_set_timeout(options.server_alive_interval, - options.server_alive_count_max); /* Indicate OK return */ return 0; @@ -194,34 +268,18 @@ ssh_kill_proxy_command(void) static int ssh_create_socket(int privileged, struct addrinfo *ai) { - int sock, gaierr; + int sock, r, gaierr; struct addrinfo hints, *res; - /* - * If we are running as root and want to connect to a privileged - * port, bind our own socket to a privileged port. - */ - if (privileged) { - int p = IPPORT_RESERVED - 1; - PRIV_START; - sock = rresvport_af(&p, ai->ai_family); - PRIV_END; - if (sock < 0) - error("rresvport: af=%d %.100s", ai->ai_family, - strerror(errno)); - else - debug("Allocated local port %d.", p); - return sock; - } sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); if (sock < 0) { - error("socket: %.100s", strerror(errno)); + error("socket: %s", strerror(errno)); return -1; } fcntl(sock, F_SETFD, FD_CLOEXEC); /* Bind the socket to an alternative local IP address */ - if (options.bind_address == NULL) + if (options.bind_address == NULL && !privileged) return sock; memset(&hints, 0, sizeof(hints)); @@ -236,11 +294,28 @@ ssh_create_socket(int privileged, struct addrinfo *ai) close(sock); return -1; } - if (bind(sock, res->ai_addr, res->ai_addrlen) < 0) { - error("bind: %s: %s", options.bind_address, strerror(errno)); - close(sock); - freeaddrinfo(res); - return -1; + /* + * If we are running as root and want to connect to a privileged + * port, bind our own socket to a privileged port. + */ + if (privileged) { + PRIV_START; + r = bindresvport_sa(sock, res->ai_addr); + PRIV_END; + if (r < 0) { + error("bindresvport_sa: af=%d %s", ai->ai_family, + strerror(errno)); + goto fail; + } + } else { + if (bind(sock, res->ai_addr, res->ai_addrlen) < 0) { + error("bind: %s: %s", options.bind_address, + strerror(errno)); + fail: + close(sock); + freeaddrinfo(res); + return -1; + } } freeaddrinfo(res); return sock; @@ -340,33 +415,18 @@ timeout_connect(int sockfd, const struct sockaddr *serv_addr, * and %p substituted for host and port, respectively) to use to contact * the daemon. */ -int -ssh_connect(const char *host, struct sockaddr_storage * hostaddr, - u_short port, int family, int connection_attempts, int *timeout_ms, - int want_keepalive, int needpriv, const char *proxy_command) +static int +ssh_connect_direct(const char *host, struct addrinfo *aitop, + struct sockaddr_storage *hostaddr, u_short port, int family, + int connection_attempts, int *timeout_ms, int want_keepalive, int needpriv) { - int gaierr; int on = 1; int sock = -1, attempt; char ntop[NI_MAXHOST], strport[NI_MAXSERV]; - struct addrinfo hints, *ai, *aitop; + struct addrinfo *ai; debug2("ssh_connect: needpriv %d", needpriv); - /* If a proxy command is given, connect using it. */ - if (proxy_command != NULL) - return ssh_proxy_connect(host, port, proxy_command); - - /* No proxy command. */ - - memset(&hints, 0, sizeof(hints)); - hints.ai_family = family; - hints.ai_socktype = SOCK_STREAM; - snprintf(strport, sizeof strport, "%u", port); - if ((gaierr = getaddrinfo(host, strport, &hints, &aitop)) != 0) - fatal("%s: Could not resolve hostname %.100s: %s", __progname, - host, ssh_gai_strerror(gaierr)); - for (attempt = 0; attempt < connection_attempts; attempt++) { if (attempt > 0) { /* Sleep a moment before retrying. */ @@ -378,7 +438,8 @@ ssh_connect(const char *host, struct sockaddr_storage * hostaddr, * sequence until the connection succeeds. */ for (ai = aitop; ai; ai = ai->ai_next) { - if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6) + if (ai->ai_family != AF_INET && + ai->ai_family != AF_INET6) continue; if (getnameinfo(ai->ai_addr, ai->ai_addrlen, ntop, sizeof(ntop), strport, sizeof(strport), @@ -411,8 +472,6 @@ ssh_connect(const char *host, struct sockaddr_storage * hostaddr, break; /* Successful connection. */ } - freeaddrinfo(aitop); - /* Return failure if we didn't get a successful connection. */ if (sock == -1) { error("ssh: connect to host %s port %s: %s", @@ -430,12 +489,28 @@ ssh_connect(const char *host, struct sockaddr_storage * hostaddr, /* Set the connection. */ packet_set_connection(sock, sock); - packet_set_timeout(options.server_alive_interval, - options.server_alive_count_max); return 0; } +int +ssh_connect(const char *host, struct addrinfo *addrs, + struct sockaddr_storage *hostaddr, u_short port, int family, + int connection_attempts, int *timeout_ms, int want_keepalive, int needpriv) +{ + if (options.proxy_command == NULL) { + return ssh_connect_direct(host, addrs, hostaddr, port, family, + connection_attempts, timeout_ms, want_keepalive, needpriv); + } else if (strcmp(options.proxy_command, "-") == 0) { + packet_set_connection(STDIN_FILENO, STDOUT_FILENO); + return 0; /* Always succeeds */ + } else if (options.proxy_use_fdpass) { + return ssh_proxy_fdpass_connect(host, port, + options.proxy_command); + } + return ssh_proxy_connect(host, port, options.proxy_command); +} + static void send_client_banner(int connection_out, int minor1) { @@ -587,6 +662,12 @@ ssh_exchange_identification(int timeout_ms) fatal("Protocol major versions differ: %d vs. %d", (options.protocol & SSH_PROTO_2) ? PROTOCOL_MAJOR_2 : PROTOCOL_MAJOR_1, remote_major); + if ((datafellows & SSH_BUG_DERIVEKEY) != 0) + fatal("Server version \"%.100s\" uses unsafe key agreement; " + "refusing connection", remote_version); + if ((datafellows & SSH_BUG_RSASIGMD5) != 0) + logit("Server version \"%.100s\" uses unsafe RSA signature " + "scheme; disabling use of RSA keys", remote_version); if (!client_banner_sent) send_client_banner(connection_out, minor1); chop(server_version_string); @@ -1176,7 +1257,7 @@ void ssh_login(Sensitive *sensitive, const char *orighost, struct sockaddr *hostaddr, u_short port, struct passwd *pw, int timeout_ms) { - char *host, *cp; + char *host; char *server_user, *local_user; local_user = xstrdup(pw->pw_name); @@ -1184,9 +1265,7 @@ ssh_login(Sensitive *sensitive, const char *orighost, /* Convert the user-supplied hostname into all lowercase. */ host = xstrdup(orighost); - for (cp = host; *cp; cp++) - if (isupper(*cp)) - *cp = (char)tolower(*cp); + lowercase(host); /* Exchange protocol version identification strings with the server. */ ssh_exchange_identification(timeout_ms); @@ -1228,7 +1307,14 @@ ssh_put_password(char *password) static int show_other_keys(struct hostkeys *hostkeys, Key *key) { - int type[] = { KEY_RSA1, KEY_RSA, KEY_DSA, KEY_ECDSA, -1}; + int type[] = { + KEY_RSA1, + KEY_RSA, + KEY_DSA, + KEY_ECDSA, + KEY_ED25519, + -1 + }; int i, ret = 0; char *fp, *ra; const struct hostkey_entry *found; diff --git a/sshconnect.h b/sshconnect.h index fd7f7f7c6145..0ea6e99f6171 100644 --- a/sshconnect.h +++ b/sshconnect.h @@ -1,4 +1,4 @@ -/* $OpenBSD: sshconnect.h,v 1.27 2010/11/29 23:45:51 djm Exp $ */ +/* $OpenBSD: sshconnect.h,v 1.28 2013/10/16 02:31:47 djm Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. @@ -31,9 +31,9 @@ struct Sensitive { int external_keysign; }; -int -ssh_connect(const char *, struct sockaddr_storage *, u_short, int, int, - int *, int, int, const char *); +struct addrinfo; +int ssh_connect(const char *, struct addrinfo *, struct sockaddr_storage *, + u_short, int, int, int *, int, int); void ssh_kill_proxy_command(void); void ssh_login(Sensitive *, const char *, struct sockaddr *, u_short, diff --git a/sshconnect1.c b/sshconnect1.c index d285e23c0405..7bd6cb0189eb 100644 --- a/sshconnect1.c +++ b/sshconnect1.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sshconnect1.c,v 1.71 2013/05/17 00:13:14 djm Exp $ */ +/* $OpenBSD: sshconnect1.c,v 1.72 2013/09/02 22:00:34 deraadt Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -542,9 +542,6 @@ ssh_kex(char *host, struct sockaddr *hostaddr) derive_ssh1_session_id(host_key->rsa->n, server_key->rsa->n, cookie, session_id); - /* Generate a session key. */ - arc4random_stir(); - /* * Generate an encryption key for the session. The key is a 256 bit * random number, interpreted as a 32-byte key, with the least diff --git a/sshconnect2.c b/sshconnect2.c index 70e3cd8c95f0..8acffc5c363f 100644 --- a/sshconnect2.c +++ b/sshconnect2.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sshconnect2.c,v 1.198 2013/06/05 12:52:38 dtucker Exp $ */ +/* $OpenBSD: sshconnect2.c,v 1.201 2014/01/09 23:20:00 djm Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. * Copyright (c) 2008 Damien Miller. All rights reserved. @@ -188,11 +188,12 @@ ssh_kex2(char *host, struct sockaddr *hostaddr, u_short port) } if (options.hostkeyalgorithms != NULL) myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = - options.hostkeyalgorithms; + compat_pkalg_proposal(options.hostkeyalgorithms); else { /* Prefer algorithms that we already have keys for */ myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = - order_hostkeyalgs(host, hostaddr, port); + compat_pkalg_proposal( + order_hostkeyalgs(host, hostaddr, port)); } if (options.kex_algorithms != NULL) myproposal[PROPOSAL_KEX_ALGS] = options.kex_algorithms; @@ -208,6 +209,7 @@ ssh_kex2(char *host, struct sockaddr *hostaddr, u_short port) kex->kex[KEX_DH_GEX_SHA1] = kexgex_client; kex->kex[KEX_DH_GEX_SHA256] = kexgex_client; kex->kex[KEX_ECDH_SHA2] = kexecdh_client; + kex->kex[KEX_C25519_SHA256] = kexc25519_client; kex->client_version_string=client_version_string; kex->server_version_string=server_version_string; kex->verify_host_key=&verify_host_key_callback; @@ -1004,7 +1006,7 @@ jpake_password_to_secret(Authctxt *authctxt, const char *crypt_scheme, debug3("%s: crypted = %s", __func__, crypted); #endif - if (hash_buffer(crypted, strlen(crypted), EVP_sha256(), + if (hash_buffer(crypted, strlen(crypted), SSH_DIGEST_SHA1, &secret, &secret_len) != 0) fatal("%s: hash_buffer", __func__); @@ -1488,17 +1490,31 @@ userauth_pubkey(Authctxt *authctxt) * encrypted keys we cannot do this and have to load the * private key instead */ - if (id->key && id->key->type != KEY_RSA1) { - debug("Offering %s public key: %s", key_type(id->key), - id->filename); - sent = send_pubkey_test(authctxt, id); - } else if (id->key == NULL) { + if (id->key != NULL) { + if (key_type_plain(id->key->type) == KEY_RSA && + (datafellows & SSH_BUG_RSASIGMD5) != 0) { + debug("Skipped %s key %s for RSA/MD5 server", + key_type(id->key), id->filename); + } else if (id->key->type != KEY_RSA1) { + debug("Offering %s public key: %s", + key_type(id->key), id->filename); + sent = send_pubkey_test(authctxt, id); + } + } else { debug("Trying private key: %s", id->filename); id->key = load_identity_file(id->filename, id->userprovided); if (id->key != NULL) { id->isprivate = 1; - sent = sign_and_send_pubkey(authctxt, id); + if (key_type_plain(id->key->type) == KEY_RSA && + (datafellows & SSH_BUG_RSASIGMD5) != 0) { + debug("Skipped %s key %s for RSA/MD5 " + "server", key_type(id->key), + id->filename); + } else { + sent = sign_and_send_pubkey( + authctxt, id); + } key_free(id->key); id->key = NULL; } diff --git a/sshd.0 b/sshd.0 index c48b987f95e7..154009c9fa1d 100644 --- a/sshd.0 +++ b/sshd.0 @@ -82,10 +82,11 @@ DESCRIPTION be given if sshd is not run as root (as the normal host key files are normally not readable by anyone but root). The default is /etc/ssh/ssh_host_key for protocol version 1, and - /etc/ssh/ssh_host_dsa_key, /etc/ssh/ssh_host_ecdsa_key and - /etc/ssh/ssh_host_rsa_key for protocol version 2. It is possible - to have multiple host key files for the different protocol - versions and host key algorithms. + /etc/ssh/ssh_host_dsa_key, /etc/ssh/ssh_host_ecdsa_key. + /etc/ssh/ssh_host_ed25519_key and /etc/ssh/ssh_host_rsa_key for + protocol version 2. It is possible to have multiple host key + files for the different protocol versions and host key + algorithms. -i Specifies that sshd is being run from inetd(8). sshd is normally not run from inetd because it needs to generate the server key @@ -147,9 +148,9 @@ DESCRIPTION AUTHENTICATION The OpenSSH SSH daemon supports SSH protocols 1 and 2. The default is to use protocol 2 only, though this can be changed via the Protocol option - in sshd_config(5). Protocol 2 supports DSA, ECDSA and RSA keys; protocol - 1 only supports RSA keys. For both protocols, each host has a host- - specific key, normally 2048 bits, used to identify the host. + in sshd_config(5). Protocol 2 supports DSA, ECDSA, ED25519 and RSA keys; + protocol 1 only supports RSA keys. For both protocols, each host has a + host-specific key, normally 2048 bits, used to identify the host. Forward security for protocol 1 is provided through an additional server key, normally 768 bits, generated when the server starts. This key is @@ -278,15 +279,15 @@ AUTHORIZED_KEYS FILE FORMAT give the RSA key for protocol version 1; the comment field is not used for anything (but may be convenient for the user to identify the key). For protocol version 2 the keytype is ``ecdsa-sha2-nistp256'', - ``ecdsa-sha2-nistp384'', ``ecdsa-sha2-nistp521'', ``ssh-dss'' or - ``ssh-rsa''. + ``ecdsa-sha2-nistp384'', ``ecdsa-sha2-nistp521'', ``ssh-ed25519'', + ``ssh-dss'' or ``ssh-rsa''. Note that lines in this file are usually several hundred bytes long (because of the size of the public key encoding) up to a limit of 8 kilobytes, which permits DSA keys up to 8 kilobits and RSA keys up to 16 kilobits. You don't want to type them in; instead, copy the - identity.pub, id_dsa.pub, id_ecdsa.pub, or the id_rsa.pub file and edit - it. + identity.pub, id_dsa.pub, id_ecdsa.pub, id_ed25519.pub, or the id_rsa.pub + file and edit it. sshd enforces a minimum RSA key modulus size for protocol 1 and protocol 2 keys of 768 bits. @@ -512,11 +513,11 @@ FILES for the user, and not accessible by others. ~/.ssh/authorized_keys - Lists the public keys (DSA/ECDSA/RSA) that can be used for - logging in as this user. The format of this file is described - above. The content of the file is not highly sensitive, but the - recommended permissions are read/write for the user, and not - accessible by others. + Lists the public keys (DSA, ECDSA, ED25519, RSA) that can be used + for logging in as this user. The format of this file is + described above. The content of the file is not highly + sensitive, but the recommended permissions are read/write for the + user, and not accessible by others. If this file, the ~/.ssh directory, or the user's home directory are writable by other users, then the file could be modified or @@ -574,6 +575,7 @@ FILES /etc/ssh/ssh_host_key /etc/ssh/ssh_host_dsa_key /etc/ssh/ssh_host_ecdsa_key + /etc/ssh/ssh_host_ed25519_key /etc/ssh/ssh_host_rsa_key These files contain the private parts of the host keys. These files should only be owned by root, readable only by root, and @@ -583,6 +585,7 @@ FILES /etc/ssh/ssh_host_key.pub /etc/ssh/ssh_host_dsa_key.pub /etc/ssh/ssh_host_ecdsa_key.pub + /etc/ssh/ssh_host_ed25519_key.pub /etc/ssh/ssh_host_rsa_key.pub These files contain the public parts of the host keys. These files should be world-readable but writable only by root. Their @@ -637,4 +640,4 @@ CAVEATS System security is not improved unless rshd, rlogind, and rexecd are disabled (thus completely disabling rlogin and rsh into the machine). -OpenBSD 5.4 June 27, 2013 OpenBSD 5.4 +OpenBSD 5.4 December 7, 2013 OpenBSD 5.4 diff --git a/sshd.8 b/sshd.8 index b0c7ab6bdf6b..e6a900b0626a 100644 --- a/sshd.8 +++ b/sshd.8 @@ -33,8 +33,8 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.\" $OpenBSD: sshd.8,v 1.270 2013/06/27 14:05:37 jmc Exp $ -.Dd $Mdocdate: June 27 2013 $ +.\" $OpenBSD: sshd.8,v 1.273 2013/12/07 11:58:46 naddy Exp $ +.Dd $Mdocdate: December 7 2013 $ .Dt SSHD 8 .Os .Sh NAME @@ -175,7 +175,8 @@ The default is .Pa /etc/ssh/ssh_host_key for protocol version 1, and .Pa /etc/ssh/ssh_host_dsa_key , -.Pa /etc/ssh/ssh_host_ecdsa_key +.Pa /etc/ssh/ssh_host_ecdsa_key . +.Pa /etc/ssh/ssh_host_ed25519_key and .Pa /etc/ssh/ssh_host_rsa_key for protocol version 2. @@ -280,7 +281,7 @@ though this can be changed via the .Cm Protocol option in .Xr sshd_config 5 . -Protocol 2 supports DSA, ECDSA and RSA keys; +Protocol 2 supports DSA, ECDSA, ED25519 and RSA keys; protocol 1 only supports RSA keys. For both protocols, each host has a host-specific key, @@ -494,6 +495,7 @@ For protocol version 2 the keytype is .Dq ecdsa-sha2-nistp256 , .Dq ecdsa-sha2-nistp384 , .Dq ecdsa-sha2-nistp521 , +.Dq ssh-ed25519 , .Dq ssh-dss or .Dq ssh-rsa . @@ -506,6 +508,7 @@ You don't want to type them in; instead, copy the .Pa identity.pub , .Pa id_dsa.pub , .Pa id_ecdsa.pub , +.Pa id_ed25519.pub , or the .Pa id_rsa.pub file and edit it. @@ -805,8 +808,8 @@ secret, but the recommended permissions are read/write/execute for the user, and not accessible by others. .Pp .It Pa ~/.ssh/authorized_keys -Lists the public keys (DSA/ECDSA/RSA) that can be used for logging in -as this user. +Lists the public keys (DSA, ECDSA, ED25519, RSA) +that can be used for logging in as this user. The format of this file is described above. The content of the file is not highly sensitive, but the recommended permissions are read/write for the user, and not accessible by others. @@ -886,6 +889,7 @@ rlogin/rsh. .It Pa /etc/ssh/ssh_host_key .It Pa /etc/ssh/ssh_host_dsa_key .It Pa /etc/ssh/ssh_host_ecdsa_key +.It Pa /etc/ssh/ssh_host_ed25519_key .It Pa /etc/ssh/ssh_host_rsa_key These files contain the private parts of the host keys. These files should only be owned by root, readable only by root, and not @@ -897,6 +901,7 @@ does not start if these files are group/world-accessible. .It Pa /etc/ssh/ssh_host_key.pub .It Pa /etc/ssh/ssh_host_dsa_key.pub .It Pa /etc/ssh/ssh_host_ecdsa_key.pub +.It Pa /etc/ssh/ssh_host_ed25519_key.pub .It Pa /etc/ssh/ssh_host_rsa_key.pub These files contain the public parts of the host keys. These files should be world-readable but writable only by diff --git a/sshd.c b/sshd.c index 174cc7a4246b..25380c911c63 100644 --- a/sshd.c +++ b/sshd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sshd.c,v 1.404 2013/07/19 07:37:48 markus Exp $ */ +/* $OpenBSD: sshd.c,v 1.414 2014/01/09 23:26:48 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -315,6 +315,7 @@ static void sighup_restart(void) { logit("Received SIGHUP; restarting."); + platform_pre_restart(); close_listen_socks(); close_startup_pipes(); alarm(0); /* alarm timer persists across exec */ @@ -371,7 +372,7 @@ grace_alarm_handler(int sig) */ if (getpgid(0) == getpid()) { signal(SIGTERM, SIG_IGN); - killpg(0, SIGTERM); + kill(0, SIGTERM); } /* Log error and exit. */ @@ -397,7 +398,6 @@ generate_ephemeral_server_key(void) verbose("RSA key generation complete."); arc4random_buf(sensitive_data.ssh1_cookie, SSH_SESSION_KEY_LENGTH); - arc4random_stir(); } /*ARGSUSED*/ @@ -480,10 +480,11 @@ sshd_exchange_identification(int sock_in, int sock_out) &remote_major, &remote_minor, remote_version) != 3) { s = "Protocol mismatch.\n"; (void) atomicio(vwrite, sock_out, s, strlen(s)); + logit("Bad protocol version identification '%.100s' " + "from %s port %d", client_version_string, + get_remote_ipaddr(), get_remote_port()); close(sock_in); close(sock_out); - logit("Bad protocol version identification '%.100s' from %s", - client_version_string, get_remote_ipaddr()); cleanup_exit(255); } debug("Client protocol version %d.%d; client software version %.100s", @@ -491,17 +492,24 @@ sshd_exchange_identification(int sock_in, int sock_out) compat_datafellows(remote_version); - if (datafellows & SSH_BUG_PROBE) { + if ((datafellows & SSH_BUG_PROBE) != 0) { logit("probed from %s with %s. Don't panic.", get_remote_ipaddr(), client_version_string); cleanup_exit(255); } - - if (datafellows & SSH_BUG_SCANNER) { + if ((datafellows & SSH_BUG_SCANNER) != 0) { logit("scanned from %s with %s. Don't panic.", get_remote_ipaddr(), client_version_string); cleanup_exit(255); } + if ((datafellows & SSH_BUG_RSASIGMD5) != 0) { + logit("Client version \"%.100s\" uses unsafe RSA signature " + "scheme; disabling use of RSA keys", remote_version); + } + if ((datafellows & SSH_BUG_DERIVEKEY) != 0) { + fatal("Client version \"%.100s\" uses unsafe key agreement; " + "refusing connection", remote_version); + } mismatch = 0; switch (remote_major) { @@ -613,6 +621,7 @@ privsep_preauth_child(void) arc4random_stir(); arc4random_buf(rnd, sizeof(rnd)); RAND_seed(rnd, sizeof(rnd)); + bzero(rnd, sizeof(rnd)); /* Demote the private keys to public keys. */ demote_sensitive_data(); @@ -651,7 +660,7 @@ privsep_preauth(Authctxt *authctxt) pmonitor->m_pkex = &xxx_kex; if (use_privsep == PRIVSEP_ON) - box = ssh_sandbox_init(); + box = ssh_sandbox_init(pmonitor); pid = fork(); if (pid == -1) { fatal("fork of unprivileged child failed"); @@ -747,6 +756,7 @@ privsep_postauth(Authctxt *authctxt) arc4random_stir(); arc4random_buf(rnd, sizeof(rnd)); RAND_seed(rnd, sizeof(rnd)); + bzero(rnd, sizeof(rnd)); /* Drop privileges */ do_setusercontext(authctxt->pw); @@ -782,6 +792,7 @@ list_hostkey_types(void) case KEY_RSA: case KEY_DSA: case KEY_ECDSA: + case KEY_ED25519: if (buffer_len(&b) > 0) buffer_append(&b, ",", 1); p = key_ssh_name(key); @@ -798,6 +809,7 @@ list_hostkey_types(void) case KEY_RSA_CERT: case KEY_DSA_CERT: case KEY_ECDSA_CERT: + case KEY_ED25519_CERT: if (buffer_len(&b) > 0) buffer_append(&b, ",", 1); p = key_ssh_name(key); @@ -825,6 +837,7 @@ get_hostkey_by_type(int type, int need_private) case KEY_RSA_CERT: case KEY_DSA_CERT: case KEY_ECDSA_CERT: + case KEY_ED25519_CERT: key = sensitive_data.host_certificates[i]; break; default: @@ -1139,6 +1152,7 @@ server_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s) struct sockaddr_storage from; socklen_t fromlen; pid_t pid; + u_char rnd[256]; /* setup fd set for accept */ fdset = NULL; @@ -1339,6 +1353,9 @@ server_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s) * from that of the child */ arc4random_stir(); + arc4random_buf(rnd, sizeof(rnd)); + RAND_seed(rnd, sizeof(rnd)); + bzero(rnd, sizeof(rnd)); } /* child process check (or debug mode) */ @@ -1693,6 +1710,7 @@ main(int ac, char **av) case KEY_RSA: case KEY_DSA: case KEY_ECDSA: + case KEY_ED25519: sensitive_data.have_ssh2_key = 1; break; } @@ -1859,9 +1877,6 @@ main(int ac, char **av) /* Reinitialize the log (because of the fork above). */ log_init(__progname, options.log_level, options.log_facility, log_stderr); - /* Initialize the random number generator. */ - arc4random_stir(); - /* Chdir to the root directory so that the current disk can be unmounted if desired. */ if (chdir("/") == -1) @@ -1933,13 +1948,14 @@ main(int ac, char **av) dup2(STDIN_FILENO, STDOUT_FILENO); if (startup_pipe == -1) close(REEXEC_STARTUP_PIPE_FD); - else + else if (startup_pipe != REEXEC_STARTUP_PIPE_FD) { dup2(startup_pipe, REEXEC_STARTUP_PIPE_FD); + close(startup_pipe); + startup_pipe = REEXEC_STARTUP_PIPE_FD; + } dup2(config_s[1], REEXEC_CONFIG_PASS_FD); close(config_s[1]); - if (startup_pipe != -1) - close(startup_pipe); execv(rexec_argv[0], rexec_argv); @@ -1950,8 +1966,6 @@ main(int ac, char **av) options.log_facility, log_stderr); /* Clean up fds */ - startup_pipe = REEXEC_STARTUP_PIPE_FD; - close(config_s[1]); close(REEXEC_CONFIG_PASS_FD); newsock = sock_out = sock_in = dup(STDIN_FILENO); if ((fd = open(_PATH_DEVNULL, O_RDWR, 0)) != -1) { @@ -2033,7 +2047,9 @@ main(int ac, char **av) #endif /* LIBWRAP */ /* Log the connection. */ - verbose("Connection from %.500s port %d", remote_ip, remote_port); + verbose("Connection from %s port %d on %s port %d", + remote_ip, remote_port, + get_local_ipaddr(sock_in), get_local_port()); /* * We don't want to listen forever unless the other side @@ -2437,7 +2453,8 @@ do_ssh2_kex(void) packet_set_rekey_limits((u_int32_t)options.rekey_limit, (time_t)options.rekey_interval); - myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = list_hostkey_types(); + myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = compat_pkalg_proposal( + list_hostkey_types()); /* start key exchange */ kex = kex_setup(myproposal); @@ -2446,6 +2463,7 @@ do_ssh2_kex(void) kex->kex[KEX_DH_GEX_SHA1] = kexgex_server; kex->kex[KEX_DH_GEX_SHA256] = kexgex_server; kex->kex[KEX_ECDH_SHA2] = kexecdh_server; + kex->kex[KEX_C25519_SHA256] = kexc25519_server; kex->server = 1; kex->client_version_string=client_version_string; kex->server_version_string=server_version_string; diff --git a/sshd_config b/sshd_config index b786361d1110..e9045bc4d7d2 100644 --- a/sshd_config +++ b/sshd_config @@ -1,4 +1,4 @@ -# $OpenBSD: sshd_config,v 1.90 2013/05/16 04:09:14 dtucker Exp $ +# $OpenBSD: sshd_config,v 1.93 2014/01/10 05:59:19 djm Exp $ # This is the sshd server system-wide configuration file. See # sshd_config(5) for more information. @@ -24,6 +24,7 @@ #HostKey /etc/ssh/ssh_host_rsa_key #HostKey /etc/ssh/ssh_host_dsa_key #HostKey /etc/ssh/ssh_host_ecdsa_key +#HostKey /etc/ssh/ssh_host_ed25519_key # Lifetime and size of ephemeral version 1 server key #KeyRegenerationInterval 1h @@ -84,8 +85,8 @@ AuthorizedKeysFile .ssh/authorized_keys #GSSAPIAuthentication no #GSSAPICleanupCredentials yes -# Set this to 'yes' to enable PAM authentication, account processing, -# and session processing. If this is enabled, PAM authentication will +# Set this to 'yes' to enable PAM authentication, account processing, +# and session processing. If this is enabled, PAM authentication will # be allowed through the ChallengeResponseAuthentication and # PasswordAuthentication. Depending on your PAM configuration, # PAM authentication via ChallengeResponseAuthentication may bypass @@ -101,6 +102,7 @@ AuthorizedKeysFile .ssh/authorized_keys #X11Forwarding no #X11DisplayOffset 10 #X11UseLocalhost yes +#PermitTTY yes #PrintMotd yes #PrintLastLog yes #TCPKeepAlive yes @@ -127,4 +129,5 @@ Subsystem sftp /usr/libexec/sftp-server #Match User anoncvs # X11Forwarding no # AllowTcpForwarding no +# PermitTTY no # ForceCommand cvs server diff --git a/sshd_config.0 b/sshd_config.0 index 5f1df7b58690..5962b02b982e 100644 --- a/sshd_config.0 +++ b/sshd_config.0 @@ -198,18 +198,25 @@ DESCRIPTION Ciphers Specifies the ciphers allowed for protocol version 2. Multiple - ciphers must be comma-separated. The supported ciphers are + ciphers must be comma-separated. The supported ciphers are: + ``3des-cbc'', ``aes128-cbc'', ``aes192-cbc'', ``aes256-cbc'', ``aes128-ctr'', ``aes192-ctr'', ``aes256-ctr'', ``aes128-gcm@openssh.com'', ``aes256-gcm@openssh.com'', ``arcfour128'', ``arcfour256'', ``arcfour'', ``blowfish-cbc'', - and ``cast128-cbc''. The default is: + ``cast128-cbc'', and ``chacha20-poly1305@openssh.com''. + + The default is: aes128-ctr,aes192-ctr,aes256-ctr,arcfour256,arcfour128, aes128-gcm@openssh.com,aes256-gcm@openssh.com, + chacha20-poly1305@openssh.com, aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,aes192-cbc, aes256-cbc,arcfour + The list of available ciphers may also be obtained using the -Q + option of ssh(1). + ClientAliveCountMax Sets the number of client alive messages (see below) which may be sent without sshd(8) receiving any messages back from the client. @@ -325,15 +332,15 @@ DESCRIPTION HostKey Specifies a file containing a private host key used by SSH. The default is /etc/ssh/ssh_host_key for protocol version 1, and - /etc/ssh/ssh_host_dsa_key, /etc/ssh/ssh_host_ecdsa_key and - /etc/ssh/ssh_host_rsa_key for protocol version 2. Note that - sshd(8) will refuse to use a file if it is group/world- - accessible. It is possible to have multiple host key files. - ``rsa1'' keys are used for version 1 and ``dsa'', ``ecdsa'' or - ``rsa'' are used for version 2 of the SSH protocol. It is also - possible to specify public host key files instead. In this case - operations on the private key will be delegated to an - ssh-agent(1). + /etc/ssh/ssh_host_dsa_key, /etc/ssh/ssh_host_ecdsa_key, + /etc/ssh/ssh_host_ed25519_key and /etc/ssh/ssh_host_rsa_key for + protocol version 2. Note that sshd(8) will refuse to use a file + if it is group/world-accessible. It is possible to have multiple + host key files. ``rsa1'' keys are used for version 1 and + ``dsa'', ``ecdsa'', ``ed25519'' or ``rsa'' are used for version 2 + of the SSH protocol. It is also possible to specify public host + key files instead. In this case operations on the private key + will be delegated to an ssh-agent(1). HostKeyAgent Identifies the UNIX-domain socket used to communicate with an @@ -391,10 +398,13 @@ DESCRIPTION KexAlgorithms Specifies the available KEX (Key Exchange) algorithms. Multiple algorithms must be comma-separated. The default is - ``ecdh-sha2-nistp256'', ``ecdh-sha2-nistp384'', - ``ecdh-sha2-nistp521'', ``diffie-hellman-group-exchange-sha256'', - ``diffie-hellman-group-exchange-sha1'', - ``diffie-hellman-group14-sha1'', ``diffie-hellman-group1-sha1''. + + curve25519-sha256@libssh.org, + ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521, + diffie-hellman-group-exchange-sha256, + diffie-hellman-group-exchange-sha1, + diffie-hellman-group14-sha1, + diffie-hellman-group1-sha1 KeyRegenerationInterval In protocol version 1, the ephemeral server key is automatically @@ -452,12 +462,12 @@ DESCRIPTION override those set in the global section of the config file, until either another Match line or the end of the file. - The arguments to Match are one or more criteria-pattern pairs. - The available criteria are User, Group, Host, LocalAddress, - LocalPort, and Address. The match patterns may consist of single - entries or comma-separated lists and may use the wildcard and - negation operators described in the PATTERNS section of - ssh_config(5). + The arguments to Match are one or more criteria-pattern pairs or + the single token All which matches all criteria. The available + criteria are User, Group, Host, LocalAddress, LocalPort, and + Address. The match patterns may consist of single entries or + comma-separated lists and may use the wildcard and negation + operators described in the PATTERNS section of ssh_config(5). The patterns in an Address criteria may additionally contain addresses to match in CIDR address/masklen format, e.g. @@ -477,10 +487,10 @@ DESCRIPTION HostbasedAuthentication, HostbasedUsesNameFromPacketOnly, KbdInteractiveAuthentication, KerberosAuthentication, MaxAuthTries, MaxSessions, PasswordAuthentication, - PermitEmptyPasswords, PermitOpen, PermitRootLogin, PermitTunnel, - PubkeyAuthentication, RekeyLimit, RhostsRSAAuthentication, - RSAAuthentication, X11DisplayOffset, X11Forwarding and - X11UseLocalHost. + PermitEmptyPasswords, PermitOpen, PermitRootLogin, PermitTTY, + PermitTunnel, PubkeyAuthentication, RekeyLimit, + RhostsRSAAuthentication, RSAAuthentication, X11DisplayOffset, + X11Forwarding and X11UseLocalHost. MaxAuthTries Specifies the maximum number of authentication attempts permitted @@ -551,6 +561,10 @@ DESCRIPTION ``ethernet'' (layer 2), or ``no''. Specifying ``yes'' permits both ``point-to-point'' and ``ethernet''. The default is ``no''. + PermitTTY + Specifies whether pty(4) allocation is permitted. The default is + ``yes''. + PermitUserEnvironment Specifies whether ~/.ssh/environment and environment= options in ~/.ssh/authorized_keys are processed by sshd(8). The default is @@ -810,4 +824,4 @@ AUTHORS versions 1.5 and 2.0. Niels Provos and Markus Friedl contributed support for privilege separation. -OpenBSD 5.4 July 19, 2013 OpenBSD 5.4 +OpenBSD 5.4 December 8, 2013 OpenBSD 5.4 diff --git a/sshd_config.5 b/sshd_config.5 index 3abac6c106f1..3b21ea6e72a9 100644 --- a/sshd_config.5 +++ b/sshd_config.5 @@ -33,8 +33,8 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.\" $OpenBSD: sshd_config.5,v 1.162 2013/07/19 07:37:48 markus Exp $ -.Dd $Mdocdate: July 19 2013 $ +.\" $OpenBSD: sshd_config.5,v 1.170 2013/12/08 09:53:27 dtucker Exp $ +.Dd $Mdocdate: December 8 2013 $ .Dt SSHD_CONFIG 5 .Os .Sh NAME @@ -335,7 +335,8 @@ The default is not to .It Cm Ciphers Specifies the ciphers allowed for protocol version 2. Multiple ciphers must be comma-separated. -The supported ciphers are +The supported ciphers are: +.Pp .Dq 3des-cbc , .Dq aes128-cbc , .Dq aes192-cbc , @@ -349,15 +350,23 @@ The supported ciphers are .Dq arcfour256 , .Dq arcfour , .Dq blowfish-cbc , +.Dq cast128-cbc , and -.Dq cast128-cbc . +.Dq chacha20-poly1305@openssh.com . +.Pp The default is: .Bd -literal -offset 3n aes128-ctr,aes192-ctr,aes256-ctr,arcfour256,arcfour128, aes128-gcm@openssh.com,aes256-gcm@openssh.com, +chacha20-poly1305@openssh.com, aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,aes192-cbc, aes256-cbc,arcfour .Ed +.Pp +The list of available ciphers may also be obtained using the +.Fl Q +option of +.Xr ssh 1 . .It Cm ClientAliveCountMax Sets the number of client alive messages (see below) which may be sent without @@ -531,7 +540,8 @@ The default is .Pa /etc/ssh/ssh_host_key for protocol version 1, and .Pa /etc/ssh/ssh_host_dsa_key , -.Pa /etc/ssh/ssh_host_ecdsa_key +.Pa /etc/ssh/ssh_host_ecdsa_key , +.Pa /etc/ssh/ssh_host_ed25519_key and .Pa /etc/ssh/ssh_host_rsa_key for protocol version 2. @@ -542,7 +552,8 @@ It is possible to have multiple host key files. .Dq rsa1 keys are used for version 1 and .Dq dsa , -.Dq ecdsa +.Dq ecdsa , +.Dq ed25519 or .Dq rsa are used for version 2 of the SSH protocol. @@ -651,13 +662,14 @@ The default is Specifies the available KEX (Key Exchange) algorithms. Multiple algorithms must be comma-separated. The default is -.Dq ecdh-sha2-nistp256 , -.Dq ecdh-sha2-nistp384 , -.Dq ecdh-sha2-nistp521 , -.Dq diffie-hellman-group-exchange-sha256 , -.Dq diffie-hellman-group-exchange-sha1 , -.Dq diffie-hellman-group14-sha1 , -.Dq diffie-hellman-group1-sha1 . +.Bd -literal -offset indent +curve25519-sha256@libssh.org, +ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521, +diffie-hellman-group-exchange-sha256, +diffie-hellman-group-exchange-sha1, +diffie-hellman-group14-sha1, +diffie-hellman-group1-sha1 +.Ed .It Cm KeyRegenerationInterval In protocol version 1, the ephemeral server key is automatically regenerated after this many seconds (if it has been used). @@ -750,7 +762,9 @@ line or the end of the file. .Pp The arguments to .Cm Match -are one or more criteria-pattern pairs. +are one or more criteria-pattern pairs or the single token +.Cm All +which matches all criteria. The available criteria are .Cm User , .Cm Group , @@ -811,6 +825,7 @@ Available keywords are .Cm PermitEmptyPasswords , .Cm PermitOpen , .Cm PermitRootLogin , +.Cm PermitTTY , .Cm PermitTunnel , .Cm PubkeyAuthentication , .Cm RekeyLimit , @@ -940,6 +955,12 @@ and .Dq ethernet . The default is .Dq no . +.It Cm PermitTTY +Specifies whether +.Xr pty 4 +allocation is permitted. +The default is +.Dq yes . .It Cm PermitUserEnvironment Specifies whether .Pa ~/.ssh/environment diff --git a/uidswap.c b/uidswap.c index 26d17f93a659..1f09d58876db 100644 --- a/uidswap.c +++ b/uidswap.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uidswap.c,v 1.35 2006/08/03 03:34:42 deraadt Exp $ */ +/* $OpenBSD: uidswap.c,v 1.36 2013/11/08 11:15:19 dtucker Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -20,6 +20,7 @@ #include #include #include +#include #include @@ -133,7 +134,9 @@ temporarily_use_uid(struct passwd *pw) void permanently_drop_suid(uid_t uid) { +#ifndef HAVE_CYGWIN uid_t old_uid = getuid(); +#endif debug("permanently_drop_suid: %u", (u_int)uid); if (setresuid(uid, uid, uid) < 0) @@ -196,8 +199,10 @@ restore_uid(void) void permanently_set_uid(struct passwd *pw) { +#ifndef HAVE_CYGWIN uid_t old_uid = getuid(); gid_t old_gid = getgid(); +#endif if (pw == NULL) fatal("permanently_set_uid: no user given"); diff --git a/verify.c b/verify.c new file mode 100644 index 000000000000..1671a4132c9e --- /dev/null +++ b/verify.c @@ -0,0 +1,49 @@ +/* $OpenBSD: verify.c,v 1.3 2013/12/09 11:03:45 markus Exp $ */ + +/* + * Public Domain, Author: Daniel J. Bernstein + * Copied from nacl-20110221/crypto_verify/32/ref/verify.c + */ + +#include "includes.h" + +#include "crypto_api.h" + +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; +} diff --git a/version.h b/version.h index 39033ed3e8d3..83d70c6fc47d 100644 --- a/version.h +++ b/version.h @@ -1,6 +1,6 @@ -/* $OpenBSD: version.h,v 1.68 2013/11/08 01:38:11 djm Exp $ */ +/* $OpenBSD: version.h,v 1.69 2014/01/16 07:32:00 djm Exp $ */ -#define SSH_VERSION "OpenSSH_6.4" +#define SSH_VERSION "OpenSSH_6.5" #define SSH_PORTABLE "p1" #define SSH_RELEASE SSH_VERSION SSH_PORTABLE diff --git a/xmalloc.c b/xmalloc.c index 92f781fd08af..2f1cd2306945 100644 --- a/xmalloc.c +++ b/xmalloc.c @@ -1,4 +1,4 @@ -/* $OpenBSD: xmalloc.c,v 1.28 2013/05/17 00:13:14 djm Exp $ */ +/* $OpenBSD: xmalloc.c,v 1.29 2014/01/04 17:50:55 tedu Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -33,7 +33,7 @@ xmalloc(size_t size) fatal("xmalloc: zero size"); ptr = malloc(size); if (ptr == NULL) - fatal("xmalloc: out of memory (allocating %lu bytes)", (u_long) size); + fatal("xmalloc: out of memory (allocating %zu bytes)", size); return ptr; } @@ -48,8 +48,8 @@ xcalloc(size_t nmemb, size_t size) fatal("xcalloc: nmemb * size > SIZE_T_MAX"); ptr = calloc(nmemb, size); if (ptr == NULL) - fatal("xcalloc: out of memory (allocating %lu bytes)", - (u_long)(size * nmemb)); + fatal("xcalloc: out of memory (allocating %zu bytes)", + size * nmemb); return ptr; } @@ -68,8 +68,8 @@ xrealloc(void *ptr, size_t nmemb, size_t size) else new_ptr = realloc(ptr, new_size); if (new_ptr == NULL) - fatal("xrealloc: out of memory (new_size %lu bytes)", - (u_long) new_size); + fatal("xrealloc: out of memory (new_size %zu bytes)", + new_size); return new_ptr; }